csharptest 14 роки тому
батько
коміт
c4d1d9dfc9
89 змінених файлів з 8305 додано та 1821 видалено
  1. 92 0
      CHANGES.txt
  2. 9 9
      build/Build.bat
  3. 41 41
      build/BuildAll.bat
  4. 4 4
      build/BuildSilverlight2.bat
  5. 18 18
      build/GenerateCompletePackage.bat
  6. 12 12
      build/GenerateReleasePackage.bat
  7. 4 4
      build/RunBenchmarks.bat
  8. 8 8
      build/build35.bat
  9. 31 31
      license.txt
  10. 62 61
      protos/extest/unittest_extras_lite.proto
  11. 22 23
      protos/extest/unittest_extras_xmltest.proto
  12. 44 0
      protos/extest/unittest_issues.proto
  13. 3 0
      protos/google/protobuf/csharp_options.proto
  14. 44 0
      protos/npp.language.xml
  15. 0 40
      readme.txt
  16. 169 48
      src/AddressBook/AddressBookProtos.cs
  17. 6 6
      src/ProtoGen.Test/DependencyResolutionTest.cs
  18. 8 3
      src/ProtoGen/EnumFieldGenerator.cs
  19. 19 0
      src/ProtoGen/FieldGeneratorBase.cs
  20. 15 3
      src/ProtoGen/MessageFieldGenerator.cs
  21. 66 19
      src/ProtoGen/MessageGenerator.cs
  22. 8 3
      src/ProtoGen/PrimitiveFieldGenerator.cs
  23. 18 4
      src/ProtoGen/RepeatedEnumFieldGenerator.cs
  24. 22 4
      src/ProtoGen/RepeatedMessageFieldGenerator.cs
  25. 18 11
      src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs
  26. 2 2
      src/ProtoGen/UmbrellaClassGenerator.cs
  27. 73 0
      src/ProtocolBuffers.Test/CodedInputStreamTest.cs
  28. 79 0
      src/ProtocolBuffers.Test/CodedOutputStreamTest.cs
  29. 59 0
      src/ProtocolBuffers.Test/Collections/PopsicleListTest.cs
  30. 102 0
      src/ProtocolBuffers.Test/DeprecatedMemberTest.cs
  31. 123 0
      src/ProtocolBuffers.Test/GeneratedBuilderTest.cs
  32. 0 16
      src/ProtocolBuffers.Test/GeneratedMessageTest.cs
  33. 5 4
      src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj
  34. 170 0
      src/ProtocolBuffers.Test/ReusableBuilderTest.cs
  35. 177 0
      src/ProtocolBuffers.Test/SerializableTest.cs
  36. 38 0
      src/ProtocolBuffers.Test/TestCornerCases.cs
  37. 53 14
      src/ProtocolBuffers.Test/TestProtos/UnitTestCSharpOptionsProtoFile.cs
  38. 371 105
      src/ProtocolBuffers.Test/TestProtos/UnitTestCustomOptionsProtoFile.cs
  39. 64 21
      src/ProtocolBuffers.Test/TestProtos/UnitTestEmbedOptimizeForProtoFile.cs
  40. 1 1
      src/ProtocolBuffers.Test/TestProtos/UnitTestEmptyProtoFile.cs
  41. 2174 56
      src/ProtocolBuffers.Test/TestProtos/UnitTestExtrasIssuesProtoFile.cs
  42. 1 1
      src/ProtocolBuffers.Test/TestProtos/UnitTestGenericServices.cs
  43. 203 33
      src/ProtocolBuffers.Test/TestProtos/UnitTestGoogleSizeProtoFile.cs
  44. 202 34
      src/ProtocolBuffers.Test/TestProtos/UnitTestGoogleSpeedProtoFile.cs
  45. 49 14
      src/ProtocolBuffers.Test/TestProtos/UnitTestImportLiteProtoFile.cs
  46. 49 14
      src/ProtocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs
  47. 302 86
      src/ProtocolBuffers.Test/TestProtos/UnitTestMessageSetProtoFile.cs
  48. 49 14
      src/ProtocolBuffers.Test/TestProtos/UnitTestNoGenericServicesProtoFile.cs
  49. 151 46
      src/ProtocolBuffers.Test/TestProtos/UnitTestOptimizeForProtoFile.cs
  50. 286 111
      src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs
  51. 222 68
      src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs
  52. 303 94
      src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs
  53. 1 1
      src/ProtocolBuffers/AbstractBuilder.cs
  54. 1 1
      src/ProtocolBuffers/AbstractBuilderLite.cs
  55. 1 1
      src/ProtocolBuffers/AbstractMessage.cs
  56. 1 1
      src/ProtocolBuffers/AbstractMessageLite.cs
  57. 2 2
      src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs
  58. 2 2
      src/ProtocolBuffers/CodedOutputStream.cs
  59. 33 5
      src/ProtocolBuffers/Collections/PopsicleList.cs
  60. 188 0
      src/ProtocolBuffers/CustomSerialization.cs
  61. 297 89
      src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs
  62. 281 95
      src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
  63. 2 2
      src/ProtocolBuffers/DynamicMessage.cs
  64. 1 1
      src/ProtocolBuffers/ExtendableBuilder.cs
  65. 1 1
      src/ProtocolBuffers/ExtendableBuilderLite.cs
  66. 1 1
      src/ProtocolBuffers/ExtendableMessage.cs
  67. 1 1
      src/ProtocolBuffers/ExtendableMessageLite.cs
  68. 4 35
      src/ProtocolBuffers/GeneratedBuilder.cs
  69. 2 33
      src/ProtocolBuffers/GeneratedBuilderLite.cs
  70. 1 1
      src/ProtocolBuffers/GeneratedMessage.cs
  71. 1 1
      src/ProtocolBuffers/GeneratedMessageLite.cs
  72. 1 1
      src/ProtocolBuffers/IBuilderLite.cs
  73. 1 1
      src/ProtocolBuffers/IMessageLite.cs
  74. 1 1
      src/ProtocolBuffers/IRpcController.cs
  75. 26 2
      src/ProtocolBuffers/IRpcDispatch.cs
  76. 1 0
      src/ProtocolBuffers/ProtocolBuffers.csproj
  77. 1 0
      src/ProtocolBuffers/ProtocolBuffersLite.csproj
  78. 2 2
      src/ProtocolBuffers/UnknownFieldSet.cs
  79. 0 1
      src/ProtocolBuffers2008.sln
  80. 1 0
      src/ProtocolBuffersLite.Test/ProtocolBuffersLite.Test.csproj
  81. 53 0
      src/ProtocolBuffersLite.Test/SerializableLiteTest.cs
  82. 327 93
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasFullProtoFile.cs
  83. 295 78
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs
  84. 49 14
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportLiteProtoFile.cs
  85. 49 14
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportProtoFile.cs
  86. 54 17
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteImportNonLiteProtoFile.cs
  87. 286 111
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteProtoFile.cs
  88. 286 111
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestProtoFile.cs
  89. 0 16
      todo.txt

+ 92 - 0
CHANGES.txt

@@ -0,0 +1,92 @@
+===============================================================================
+Welcome to the C# port of Google Protocol Buffers, written by Jon Skeet
+(skeet@pobox.com) based on the work of many talented people.
+
+For more information about this port, visit its homepage:
+http://protobuf-csharp-port.googlecode.com
+
+For more information about Protocol Buffers in general, visit the project page 
+for the C++, Java and Python project:
+http://protobuf.googlecode.com
+===============================================================================
+RELEASE NOTES - Version TBD
+===============================================================================
+
+(PENDING MERGE)
+- Issue 20:	Support for decorating classes [Serializable]
+- Issue 22:	Reusable Builder classes
+- Issue 24:	Support for using Json/Xml formats with ICodedInputStream
+
+Features:
+- Added option service_generator_type to control service generation with
+  NONE, GENERIC, INTERFACE, or IRPCDISPATCH
+- Added interfaces IRpcDispatch and IRpcServerStub to provide for blocking
+  services and implementations.
+- Added ProtoGen.exe command-line argument "--protoc_dir=" to specify the 
+  location of protoc.exe.
+- Extracted interfaces for ICodedInputStream and ICodedOutputStream to allow
+  custom implementation of writers with both speed and size optimizations.
+- Addition of the "Google.ProtoBuffers.Serialization" assembly to support
+  reading and writing messages to/from XML, JSON, IDictionary<,> and others.
+- Several performance related fixes and tweeks
+- Issue 3:	Add option to mark generated code with attribute
+- Issue 21:	Decorate fields with [deprecated=true] as [System.Obsolete]
+
+Fixes:
+- Issue 13:	Message with Field same name as message causes uncompilable .cs
+- Issue 16:	Does not integrate well with other tooling
+- Issue 19:	Support for negative enum values
+- Issue 26:	AddRange in GeneratedBuilder iterates twice.
+- Issue 27:	Remove XML documentation output from test projects to clear 
+  warnings/errors.
+- Big-endian support for float, and double on Silverlight
+- Packed and Unpacked parsing allow for all repeated, as per version 2.3
+- Fix for leaving Builder a public ctor on internal classes for use with
+  generic "where T: new()" constraints.
+
+Other:
+- Reformatted all code and line-endings to C# defaults
+- Reworking of performance benchmarks to produce reliable results, option /v2
+
+===============================================================================
+RELEASE NOTES - Version 2.3.0.277
+===============================================================================
+
+Features:
+- Added cls_compliance option to generate attributes indicating 
+  non-CLS-compliance.
+- Added file_extension option to control the generated output file's extension.
+- Added umbrella_namespace option to place the umbrella class into a nested
+  namespace to address issues with proto files having the same name as a 
+  message it contains.
+- Added output_directory option to set the output path for the source file(s).
+- Added ignore_google_protobuf option to avoid generating code for includes 
+  from the google.protobuf package.
+- Added the LITE framework (Google.ProtoBuffersLite.dll) and the ability to
+  generate code with "option optimize_for = LITE_RUNTIME;".
+- Added ability to invoke protoc.exe from within ProtoGen.exe.
+- Upgraded to protoc.exe (2.3) compiler.
+
+Fixes:
+- Issue 9:	Class cannot be static and sealed error
+- Issue 12:	default value for enumerate fields must be filled out
+
+Other:
+- Rewrite of build using MSBbuild instead of NAnt
+- Moved to NUnit Version 2.2.8.0
+- Changed to using secure .snk for releases
+
+===============================================================================
+RELEASE NOTES - Version 0.9.1
+===============================================================================
+
+Fixes:
+- issue 10:	Incorrect encoding of packed fields when serialized
+
+===============================================================================
+RELEASE NOTES - Version 0.9.0
+===============================================================================
+
+- Initial release
+
+===============================================================================

+ 9 - 9
build/Build.bat

@@ -1,10 +1,10 @@
-@echo off
-SET BUILD_TARGET=%1
-SET BUILD_CONFIG=%2
-
-IF "%BUILD_TARGET%"=="" SET BUILD_TARGET=Rebuild
-IF "%BUILD_CONFIG%"=="" SET BUILD_CONFIG=Debug
-
-CMD.exe /Q /C "CD %~dp0 && %WINDIR%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe build.csproj %3 %4 %5 %6 /t:%BUILD_TARGET% /p:BuildConfiguration=%BUILD_CONFIG% /p:Platform="Any CPU" /p:BuildTools=4.0 /toolsversion:4.0"
-
+@echo off
+SET BUILD_TARGET=%1
+SET BUILD_CONFIG=%2
+
+IF "%BUILD_TARGET%"=="" SET BUILD_TARGET=Rebuild
+IF "%BUILD_CONFIG%"=="" SET BUILD_CONFIG=Debug
+
+CMD.exe /Q /C "CD %~dp0 && %WINDIR%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe build.csproj %3 %4 %5 %6 /t:%BUILD_TARGET% /p:BuildConfiguration=%BUILD_CONFIG% /p:Platform="Any CPU" /p:BuildTools=4.0 /toolsversion:4.0"
+
 pause

+ 41 - 41
build/BuildAll.bat

@@ -1,42 +1,42 @@
-@ECHO OFF
-
-SET PREV_WORKING_DIR=%CD%
-CD %~dp0
-
-REM -- 3.5 Debug build, ensure this continues to work
-%WINDIR%\Microsoft.NET\Framework\v3.5\MSBuild.exe build.csproj /t:Rebuild /p:BuildConfiguration=Debug /p:Platform="Any CPU" /p:BuildTools=3.5 /toolsversion:3.5"
-IF ERRORLEVEL 1 GOTO ERROR
-
-REM -- 4.0 Debug build
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild /p:BuildConfiguration=Debug /p:Platform="Any CPU"
-IF ERRORLEVEL 1 GOTO ERROR
-
-REM -- 4.0 Release build
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild /p:BuildConfiguration=Release /p:Platform="Any CPU"
-IF ERRORLEVEL 1 GOTO ERROR
-
-IF EXIST "%ProgramFiles%\MSBuild\Microsoft\Silverlight\v2.0\Microsoft.Silverlight.CSharp.targets" GOTO SILVERLIGHT
-IF EXIST "%ProgramFiles(x86)%\MSBuild\Microsoft\Silverlight\v2.0\Microsoft.Silverlight.CSharp.targets" GOTO SILVERLIGHT
-
-ECHO Unable to locate %ProgramFiles(x86)%\MSBuild\Microsoft\Silverlight\v2.0
-GOTO ERROR
-
-:SILVERLIGHT
-
-REM -- 4.0 Debug_Silverlight2 build
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild /p:BuildConfiguration=Debug_Silverlight2 /p:Platform="Any CPU"
-IF ERRORLEVEL 1 GOTO ERROR
-
-REM -- 4.0 Release_Silverlight2 build
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild /p:BuildConfiguration=Release_Silverlight2 /p:Platform="Any CPU"
-IF ERRORLEVEL 1 GOTO ERROR
-
-GOTO END
-
-:ERROR
-CD %PREV_WORKING_DIR%
-PAUSE
-
-:END
-CD %PREV_WORKING_DIR%
+@ECHO OFF
+
+SET PREV_WORKING_DIR=%CD%
+CD %~dp0
+
+REM -- 3.5 Debug build, ensure this continues to work
+%WINDIR%\Microsoft.NET\Framework\v3.5\MSBuild.exe build.csproj /t:Rebuild /p:BuildConfiguration=Debug /p:Platform="Any CPU" /p:BuildTools=3.5 /toolsversion:3.5"
+IF ERRORLEVEL 1 GOTO ERROR
+
+REM -- 4.0 Debug build
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild /p:BuildConfiguration=Debug /p:Platform="Any CPU"
+IF ERRORLEVEL 1 GOTO ERROR
+
+REM -- 4.0 Release build
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild /p:BuildConfiguration=Release /p:Platform="Any CPU"
+IF ERRORLEVEL 1 GOTO ERROR
+
+IF EXIST "%ProgramFiles%\MSBuild\Microsoft\Silverlight\v2.0\Microsoft.Silverlight.CSharp.targets" GOTO SILVERLIGHT
+IF EXIST "%ProgramFiles(x86)%\MSBuild\Microsoft\Silverlight\v2.0\Microsoft.Silverlight.CSharp.targets" GOTO SILVERLIGHT
+
+ECHO Unable to locate %ProgramFiles(x86)%\MSBuild\Microsoft\Silverlight\v2.0
+GOTO ERROR
+
+:SILVERLIGHT
+
+REM -- 4.0 Debug_Silverlight2 build
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild /p:BuildConfiguration=Debug_Silverlight2 /p:Platform="Any CPU"
+IF ERRORLEVEL 1 GOTO ERROR
+
+REM -- 4.0 Release_Silverlight2 build
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild /p:BuildConfiguration=Release_Silverlight2 /p:Platform="Any CPU"
+IF ERRORLEVEL 1 GOTO ERROR
+
+GOTO END
+
+:ERROR
+CD %PREV_WORKING_DIR%
+PAUSE
+
+:END
+CD %PREV_WORKING_DIR%
 SET PREV_WORKING_DIR=

+ 4 - 4
build/BuildSilverlight2.bat

@@ -1,5 +1,5 @@
-@echo off
-
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Build /p:BuildConfiguration=Debug_Silverlight2 /p:Platform="Any CPU"
-
+@echo off
+
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Build /p:BuildConfiguration=Debug_Silverlight2 /p:Platform="Any CPU"
+
 pause

+ 18 - 18
build/GenerateCompletePackage.bat

@@ -1,19 +1,19 @@
-@ECHO OFF
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:PrepareOutputDirectory
-IF ERRORLEVEL 1 GOTO END
-
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild;PreparePackageComponent /p:BuildConfiguration=Debug /p:Platform="Any CPU" %PROTOBUF_KEY_FILE%
-IF ERRORLEVEL 1 GOTO END
-
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild;PreparePackageComponent /p:BuildConfiguration=Debug_Silverlight2 /p:Platform="Any CPU" %PROTOBUF_KEY_FILE%
-IF ERRORLEVEL 1 GOTO END
-
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild;PreparePackageComponent /p:BuildConfiguration=Release /p:Platform="Any CPU" %PROTOBUF_KEY_FILE%
-IF ERRORLEVEL 1 GOTO END
-
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild;PreparePackageComponent /p:BuildConfiguration=Release_Silverlight2 /p:Platform="Any CPU" %PROTOBUF_KEY_FILE%
-IF ERRORLEVEL 1 GOTO END
-
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:GeneratePackage /p:PackageName=AllBinariesAndSource.zip /p:Platform="Any CPU"
-
+@ECHO OFF
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:PrepareOutputDirectory
+IF ERRORLEVEL 1 GOTO END
+
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild;PreparePackageComponent /p:BuildConfiguration=Debug /p:Platform="Any CPU" %PROTOBUF_KEY_FILE%
+IF ERRORLEVEL 1 GOTO END
+
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild;PreparePackageComponent /p:BuildConfiguration=Debug_Silverlight2 /p:Platform="Any CPU" %PROTOBUF_KEY_FILE%
+IF ERRORLEVEL 1 GOTO END
+
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild;PreparePackageComponent /p:BuildConfiguration=Release /p:Platform="Any CPU" %PROTOBUF_KEY_FILE%
+IF ERRORLEVEL 1 GOTO END
+
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild;PreparePackageComponent /p:BuildConfiguration=Release_Silverlight2 /p:Platform="Any CPU" %PROTOBUF_KEY_FILE%
+IF ERRORLEVEL 1 GOTO END
+
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:GeneratePackage /p:PackageName=AllBinariesAndSource.zip /p:Platform="Any CPU"
+
 :END

+ 12 - 12
build/GenerateReleasePackage.bat

@@ -1,13 +1,13 @@
-@ECHO OFF
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:PrepareOutputDirectory
-IF ERRORLEVEL 1 GOTO END
-
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild;PreparePackageComponent /p:BuildConfiguration=Release /p:Platform="Any CPU" %PROTOBUF_KEY_FILE%
-IF ERRORLEVEL 1 GOTO END
-
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild;PreparePackageComponent /p:BuildConfiguration=Release_Silverlight2 /p:Platform="Any CPU" %PROTOBUF_KEY_FILE%
-IF ERRORLEVEL 1 GOTO END
-
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:GeneratePackage /p:PackageName=ReleaseBinaries.zip /p:Platform="Any CPU"
-
+@ECHO OFF
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:PrepareOutputDirectory
+IF ERRORLEVEL 1 GOTO END
+
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild;PreparePackageComponent /p:BuildConfiguration=Release /p:Platform="Any CPU" %PROTOBUF_KEY_FILE%
+IF ERRORLEVEL 1 GOTO END
+
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:Rebuild;PreparePackageComponent /p:BuildConfiguration=Release_Silverlight2 /p:Platform="Any CPU" %PROTOBUF_KEY_FILE%
+IF ERRORLEVEL 1 GOTO END
+
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild build.csproj /m /t:GeneratePackage /p:PackageName=ReleaseBinaries.zip /p:Platform="Any CPU"
+
 :END

+ 4 - 4
build/RunBenchmarks.bat

@@ -1,5 +1,5 @@
-@echo off
-
-%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild %~dp0\build.csproj /m /t:RunBenchmarks /p:BuildConfiguration=Release /p:Platform="Any CPU"
-
+@echo off
+
+%WINDIR%\Microsoft.NET\Framework\v4.0.30319\msbuild %~dp0\build.csproj /m /t:RunBenchmarks /p:BuildConfiguration=Release /p:Platform="Any CPU"
+
 pause

+ 8 - 8
build/build35.bat

@@ -1,8 +1,8 @@
-@echo off
-SET BUILD_TARGET=%1
-SET BUILD_CONFIG=%2
-
-IF "%BUILD_TARGET%"=="" SET BUILD_TARGET=Rebuild
-IF "%BUILD_CONFIG%"=="" SET BUILD_CONFIG=Debug
-
-CMD.exe /Q /C "CD %~dp0 && %WINDIR%\Microsoft.NET\Framework\v3.5\MSBuild.exe build.csproj %3 %4 %5 %6 /t:%BUILD_TARGET% /p:BuildConfiguration=%BUILD_CONFIG% /p:Platform="Any CPU" /p:BuildTools=3.5 /toolsversion:3.5"
+@echo off
+SET BUILD_TARGET=%1
+SET BUILD_CONFIG=%2
+
+IF "%BUILD_TARGET%"=="" SET BUILD_TARGET=Rebuild
+IF "%BUILD_CONFIG%"=="" SET BUILD_CONFIG=Debug
+
+CMD.exe /Q /C "CD %~dp0 && %WINDIR%\Microsoft.NET\Framework\v3.5\MSBuild.exe build.csproj %3 %4 %5 %6 /t:%BUILD_TARGET% /p:BuildConfiguration=%BUILD_CONFIG% /p:Platform="Any CPU" /p:BuildTools=3.5 /toolsversion:3.5"

+ 31 - 31
license.txt

@@ -1,31 +1,31 @@
-Protocol Buffers - Google's data interchange format
-Copyright 2008-2010 Google Inc.  All rights reserved.
-http://github.com/jskeet/dotnet-protobufs/
-Original C++/Java/Python code:
-http://code.google.com/p/protobuf/
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-    * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+Protocol Buffers - Google's data interchange format
+Copyright 2008-2010 Google Inc.  All rights reserved.
+http://github.com/jskeet/dotnet-protobufs/
+Original C++/Java/Python code:
+http://code.google.com/p/protobuf/
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 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;

+ 44 - 0
protos/extest/unittest_issues.proto

@@ -86,3 +86,47 @@ message NumberField {
     optional int32 _01 = 1;
 }
 
+// Issue 28: Circular message dependencies result in null defaults for DefaultInstance
+
+message MyMessageAReferenceB {
+    required MyMessageBReferenceA value = 1;
+}
+
+message MyMessageBReferenceA {
+    required MyMessageAReferenceB value = 1;
+}
+
+// issue 19 - negative enum values
+
+enum NegativeEnum {
+    FiveBelow = -5;
+    MinusOne = -1;
+    Zero = 0;
+}
+
+message NegativeEnumMessage { 
+    optional NegativeEnum value = 1;
+    repeated NegativeEnum values = 2;
+    repeated NegativeEnum packed_values = 3 [packed=true];
+}
+
+// Issue 21: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=21
+// Decorate fields with [deprecated=true] as [System.Obsolete]
+
+message DeprecatedChild {
+}
+
+enum DeprecatedEnum {
+    one = 1;
+}
+
+message DeprecatedFieldsMessage {
+    optional int32 PrimitiveValue = 1 [deprecated = true];
+    repeated int32 PrimitiveArray = 2 [deprecated = true];
+
+    optional DeprecatedChild MessageValue = 3 [deprecated = true];
+    repeated DeprecatedChild MessageArray = 4 [deprecated = true];
+
+    optional DeprecatedEnum EnumValue = 5 [deprecated = true];
+    repeated DeprecatedEnum EnumArray = 6 [deprecated = true];
+}

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

+ 44 - 0
protos/npp.language.xml

@@ -0,0 +1,44 @@
+<NotepadPlus>
+<!--
+Defines syntax highlighting for Notepad++.
+1. Install Notepad++ from http://notepad-plus-plus.org
+2. Open Notepad++, from the View menu, select "User-Defined Dialog..."
+3. Click the "Import..." button and select this file
+4. Restart Notepad++
+5. Open and edit any *.proto file
+-->
+    <UserLang name="Proto Buffer" ext="proto">
+        <Settings>
+            <Global caseIgnored="no" />
+            <TreatAsSymbol comment="no" commentLine="yes" />
+            <Prefix words1="no" words2="no" words3="no" words4="yes" />
+        </Settings>
+        <KeywordLists>
+            <Keywords name="Delimiters">[00]00</Keywords>
+            <Keywords name="Folder+">{</Keywords>
+            <Keywords name="Folder-">}</Keywords>
+            <Keywords name="Operators">=</Keywords>
+            <Keywords name="Comment"> 1option 1package 1import 2; 0//</Keywords>
+            <Keywords name="Words1">message enum service extend</Keywords>
+            <Keywords name="Words2">required optional repeated extensions to rpc returns</Keywords>
+            <Keywords name="Words3">double float int32 int64 uint32 uint64 sint32 sint64 fixed32 fixed64 sfixed32 sfixed64 bool string bytes</Keywords>
+            <Keywords name="Words4"></Keywords>
+        </KeywordLists>
+        <Styles>
+            <WordsStyle name="DEFAULT" styleID="11" fgColor="000000" bgColor="FFFFFF" fontStyle="0" />
+            <WordsStyle name="FOLDEROPEN" styleID="12" fgColor="000000" bgColor="FFFFFF" fontStyle="1" />
+            <WordsStyle name="FOLDERCLOSE" styleID="13" fgColor="000000" bgColor="FFFFFF" fontStyle="1" />
+            <WordsStyle name="KEYWORD1" styleID="5" fgColor="0000FF" bgColor="FFFFFF" fontStyle="0" />
+            <WordsStyle name="KEYWORD2" styleID="6" fgColor="0080C0" bgColor="FFFFFF" fontStyle="0" />
+            <WordsStyle name="KEYWORD3" styleID="7" fgColor="0000FF" bgColor="FFFFFF" fontStyle="0" />
+            <WordsStyle name="KEYWORD4" styleID="8" fgColor="008040" bgColor="FFFFFF" fontStyle="0" />
+            <WordsStyle name="COMMENT" styleID="1" fgColor="008000" bgColor="FFFFFF" fontStyle="0" />
+            <WordsStyle name="COMMENT LINE" styleID="2" fgColor="949494" bgColor="FFFFFF" fontStyle="0" />
+            <WordsStyle name="NUMBER" styleID="4" fgColor="FF0000" bgColor="FFFFFF" fontStyle="0" />
+            <WordsStyle name="OPERATOR" styleID="10" fgColor="000000" bgColor="FFFFFF" fontStyle="0" />
+            <WordsStyle name="DELIMINER1" styleID="14" fgColor="800080" bgColor="FFFFFF" fontStyle="0" />
+            <WordsStyle name="DELIMINER2" styleID="15" fgColor="808080" bgColor="FFFFFF" fontStyle="0" />
+            <WordsStyle name="DELIMINER3" styleID="16" fgColor="000000" bgColor="FFFFFF" fontStyle="0" />
+        </Styles>
+    </UserLang>
+</NotepadPlus>

+ 0 - 40
readme.txt

@@ -1,40 +0,0 @@
-Welcome to the C# port of Google Protocol Buffers, written by Jon Skeet
-(skeet@pobox.com) based on the work of many talented people.
-
-For more information about this port, visit its homepage:
-http://protobuf-csharp-port.googlecode.com
-
-For more information about Protocol Buffers in general, visit the
-project page for the C++, Java and Python project:
-http://protobuf.googlecode.com
-
-
-Release 0.9.1
--------------
-
-Fix to release 0.9:
-
-- Include protos in binary download
-- Fix issue 10: incorrect encoding of packed fields when serialized
-  size wasn't fetched first
-
-
-Release 0.9
------------
-
-Due to popular demand, I have built a version of the binaries to put
-on the web site. Currently these are set at assembly version 0.9,
-and an assembly file version of 0.9. This should be seen as a mark
-of the readiness of the release process more than the stability of
-the code. As far as I'm aware, the code itself is perfectly fine: I
-certainly have plans for more features particularly around making
-code generation simpler, but you should feel confident about the
-parsing and serialization of messages produced with this version of
-the library. Of course, if you do find any problems, *please* report
-them at the web site.
-
-Currently the downloadable release is built with the snk file which
-is in the open source library. I am considering having a privately
-held key so that you can check that you're building against a
-"blessed" release - feedback on this (and any other aspect of the
-release process) is very welcome.

+ 169 - 48
src/AddressBook/AddressBookProtos.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -68,7 +68,8 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class Person : pb::GeneratedMessage<Person, Person.Builder> {
-    private static readonly Person defaultInstance = new Builder().BuildPartial();
+    private Person() { }
+    private static readonly Person defaultInstance = new Person().MakeReadOnly();
     private static readonly string[] _personFieldNames = new string[] { "email", "id", "name", "phone" };
     private static readonly uint[] _personFieldTags = new uint[] { 26, 16, 10, 34 };
     public static Person DefaultInstance {
@@ -76,7 +77,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
     }
     
     public override Person DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override Person ThisMessage {
@@ -108,7 +109,8 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
       [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
       public sealed partial class PhoneNumber : pb::GeneratedMessage<PhoneNumber, PhoneNumber.Builder> {
-        private static readonly PhoneNumber defaultInstance = new Builder().BuildPartial();
+        private PhoneNumber() { }
+        private static readonly PhoneNumber defaultInstance = new PhoneNumber().MakeReadOnly();
         private static readonly string[] _phoneNumberFieldNames = new string[] { "number", "type" };
         private static readonly uint[] _phoneNumberFieldTags = new uint[] { 10, 16 };
         public static PhoneNumber DefaultInstance {
@@ -116,7 +118,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
         }
         
         public override PhoneNumber DefaultInstanceForType {
-          get { return defaultInstance; }
+          get { return DefaultInstance; }
         }
         
         protected override PhoneNumber ThisMessage {
@@ -219,11 +221,15 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
         public static PhoneNumber ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
           return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
         }
+        private PhoneNumber MakeReadOnly() {
+          return this;
+        }
+        
         public static Builder CreateBuilder() { return new Builder(); }
         public override Builder ToBuilder() { return CreateBuilder(this); }
         public override Builder CreateBuilderForType() { return new Builder(); }
         public static Builder CreateBuilder(PhoneNumber prototype) {
-          return (Builder) new Builder().MergeFrom(prototype);
+          return new Builder(prototype);
         }
         
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -233,21 +239,48 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
           protected override Builder ThisBuilder {
             get { return this; }
           }
-          public Builder() {}
+          public Builder() {
+            result = DefaultInstance;
+            resultIsReadOnly = true;
+          }
+          internal Builder(PhoneNumber cloneFrom) {
+            result = cloneFrom;
+            resultIsReadOnly = true;
+          }
+          
+          private bool resultIsReadOnly;
+          private PhoneNumber result;
           
-          PhoneNumber result = new PhoneNumber();
+          private PhoneNumber PrepareBuilder() {
+            if (resultIsReadOnly) {
+              PhoneNumber original = result;
+              result = new PhoneNumber();
+              resultIsReadOnly = false;
+              MergeFrom(original);
+            }
+            return result;
+          }
+          
+          public override bool IsInitialized {
+            get { return result.IsInitialized; }
+          }
           
           protected override PhoneNumber MessageBeingBuilt {
-            get { return result; }
+            get { return PrepareBuilder(); }
           }
           
           public override Builder Clear() {
-            result = new PhoneNumber();
+            result = DefaultInstance;
+            resultIsReadOnly = true;
             return this;
           }
           
           public override Builder Clone() {
-            return new Builder().MergeFrom(result);
+            if (resultIsReadOnly) {
+              return new Builder(result);
+            } else {
+              return new Builder().MergeFrom(result);
+            }
           }
           
           public override pbd::MessageDescriptor DescriptorForType {
@@ -259,12 +292,11 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
           }
           
           public override PhoneNumber BuildPartial() {
-            if (result == null) {
-              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+            if (resultIsReadOnly) {
+              return result;
             }
-            PhoneNumber returnMe = result;
-            result = null;
-            return returnMe;
+            resultIsReadOnly = true;
+            return result.MakeReadOnly();
           }
           
           public override Builder MergeFrom(pb::IMessage other) {
@@ -278,6 +310,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
           
           public override Builder MergeFrom(PhoneNumber other) {
             if (other == global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.DefaultInstance) return this;
+            PrepareBuilder();
             if (other.HasNumber) {
               Number = other.Number;
             }
@@ -293,6 +326,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
           }
           
           public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+            PrepareBuilder();
             pb::UnknownFieldSet.Builder unknownFields = null;
             uint tag;
             string field_name;
@@ -361,11 +395,13 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
           }
           public Builder SetNumber(string value) {
             pb::ThrowHelper.ThrowIfNull(value, "value");
+            PrepareBuilder();
             result.hasNumber = true;
             result.number_ = value;
             return this;
           }
           public Builder ClearNumber() {
+            PrepareBuilder();
             result.hasNumber = false;
             result.number_ = "";
             return this;
@@ -379,11 +415,13 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
             set { SetType(value); }
           }
           public Builder SetType(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType value) {
+            PrepareBuilder();
             result.hasType = true;
             result.type_ = value;
             return this;
           }
           public Builder ClearType() {
+            PrepareBuilder();
             result.hasType = false;
             result.type_ = global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType.HOME;
             return this;
@@ -523,11 +561,16 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
     public static Person ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private Person MakeReadOnly() {
+      phone_.MakeReadOnly();
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(Person prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -537,21 +580,48 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(Person cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
       
-      Person result = new Person();
+      private bool resultIsReadOnly;
+      private Person result;
+      
+      private Person PrepareBuilder() {
+        if (resultIsReadOnly) {
+          Person original = result;
+          result = new Person();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override Person MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new Person();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -563,13 +633,11 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       }
       
       public override Person BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        result.phone_.MakeReadOnly();
-        Person returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -583,6 +651,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       
       public override Builder MergeFrom(Person other) {
         if (other == global::Google.ProtocolBuffers.Examples.AddressBook.Person.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasName) {
           Name = other.Name;
         }
@@ -593,7 +662,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
           Email = other.Email;
         }
         if (other.phone_.Count != 0) {
-          base.AddRange(other.phone_, result.phone_);
+          result.phone_.Add(other.phone_);
         }
         this.MergeUnknownFields(other.UnknownFields);
         return this;
@@ -604,6 +673,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -672,11 +742,13 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       }
       public Builder SetName(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasName = true;
         result.name_ = value;
         return this;
       }
       public Builder ClearName() {
+        PrepareBuilder();
         result.hasName = false;
         result.name_ = "";
         return this;
@@ -690,11 +762,13 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
         set { SetId(value); }
       }
       public Builder SetId(int value) {
+        PrepareBuilder();
         result.hasId = true;
         result.id_ = value;
         return this;
       }
       public Builder ClearId() {
+        PrepareBuilder();
         result.hasId = false;
         result.id_ = 0;
         return this;
@@ -709,18 +783,20 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       }
       public Builder SetEmail(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasEmail = true;
         result.email_ = value;
         return this;
       }
       public Builder ClearEmail() {
+        PrepareBuilder();
         result.hasEmail = false;
         result.email_ = "";
         return this;
       }
       
       public pbc::IPopsicleList<global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber> PhoneList {
-        get { return result.phone_; }
+        get { return PrepareBuilder().phone_; }
       }
       public int PhoneCount {
         get { return result.PhoneCount; }
@@ -730,29 +806,35 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       }
       public Builder SetPhone(int index, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.phone_[index] = value;
         return this;
       }
       public Builder SetPhone(int index, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.phone_[index] = builderForValue.Build();
         return this;
       }
       public Builder AddPhone(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.phone_.Add(value);
         return this;
       }
       public Builder AddPhone(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.phone_.Add(builderForValue.Build());
         return this;
       }
       public Builder AddRangePhone(scg::IEnumerable<global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber> values) {
-        base.AddRange(values, result.phone_);
+        PrepareBuilder();
+        result.phone_.Add(values);
         return this;
       }
       public Builder ClearPhone() {
+        PrepareBuilder();
         result.phone_.Clear();
         return this;
       }
@@ -766,7 +848,8 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class AddressBook : pb::GeneratedMessage<AddressBook, AddressBook.Builder> {
-    private static readonly AddressBook defaultInstance = new Builder().BuildPartial();
+    private AddressBook() { }
+    private static readonly AddressBook defaultInstance = new AddressBook().MakeReadOnly();
     private static readonly string[] _addressBookFieldNames = new string[] { "person" };
     private static readonly uint[] _addressBookFieldTags = new uint[] { 10 };
     public static AddressBook DefaultInstance {
@@ -774,7 +857,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
     }
     
     public override AddressBook DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override AddressBook ThisMessage {
@@ -865,11 +948,16 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
     public static AddressBook ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private AddressBook MakeReadOnly() {
+      person_.MakeReadOnly();
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(AddressBook prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -879,21 +967,48 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(AddressBook cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private AddressBook result;
       
-      AddressBook result = new AddressBook();
+      private AddressBook PrepareBuilder() {
+        if (resultIsReadOnly) {
+          AddressBook original = result;
+          result = new AddressBook();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override AddressBook MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new AddressBook();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -905,13 +1020,11 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       }
       
       public override AddressBook BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        result.person_.MakeReadOnly();
-        AddressBook returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -925,8 +1038,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       
       public override Builder MergeFrom(AddressBook other) {
         if (other == global::Google.ProtocolBuffers.Examples.AddressBook.AddressBook.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.person_.Count != 0) {
-          base.AddRange(other.person_, result.person_);
+          result.person_.Add(other.person_);
         }
         this.MergeUnknownFields(other.UnknownFields);
         return this;
@@ -937,6 +1051,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -985,7 +1100,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       
       
       public pbc::IPopsicleList<global::Google.ProtocolBuffers.Examples.AddressBook.Person> PersonList {
-        get { return result.person_; }
+        get { return PrepareBuilder().person_; }
       }
       public int PersonCount {
         get { return result.PersonCount; }
@@ -995,29 +1110,35 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       }
       public Builder SetPerson(int index, global::Google.ProtocolBuffers.Examples.AddressBook.Person value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.person_[index] = value;
         return this;
       }
       public Builder SetPerson(int index, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.person_[index] = builderForValue.Build();
         return this;
       }
       public Builder AddPerson(global::Google.ProtocolBuffers.Examples.AddressBook.Person value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.person_.Add(value);
         return this;
       }
       public Builder AddPerson(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.person_.Add(builderForValue.Build());
         return this;
       }
       public Builder AddRangePerson(scg::IEnumerable<global::Google.ProtocolBuffers.Examples.AddressBook.Person> values) {
-        base.AddRange(values, result.person_);
+        PrepareBuilder();
+        result.person_.Add(values);
         return this;
       }
       public Builder ClearPerson() {
+        PrepareBuilder();
         result.person_.Clear();
         return this;
       }

+ 6 - 6
src/ProtoGen.Test/DependencyResolutionTest.cs

@@ -52,7 +52,7 @@ namespace Google.ProtocolBuffers.ProtoGen
         {
             FileDescriptorProto first = new FileDescriptorProto.Builder {Name = "First"}.Build();
             FileDescriptorProto second = new FileDescriptorProto.Builder {Name = "Second"}.Build();
-            FileDescriptorSet set = new FileDescriptorSet {FileList = {first, second}};
+            FileDescriptorSet set = new FileDescriptorSet.Builder { FileList = { first, second } }.Build();
 
             IList<FileDescriptor> converted = Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
             Assert.AreEqual(2, converted.Count);
@@ -68,7 +68,7 @@ namespace Google.ProtocolBuffers.ProtoGen
             FileDescriptorProto first =
                 new FileDescriptorProto.Builder {Name = "First", DependencyList = {"Second"}}.Build();
             FileDescriptorProto second = new FileDescriptorProto.Builder {Name = "Second"}.Build();
-            FileDescriptorSet set = new FileDescriptorSet {FileList = {first, second}};
+            FileDescriptorSet set = new FileDescriptorSet.Builder { FileList = { first, second } }.Build();
             IList<FileDescriptor> converted = Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
             Assert.AreEqual(2, converted.Count);
             Assert.AreEqual("First", converted[0].Name);
@@ -84,7 +84,7 @@ namespace Google.ProtocolBuffers.ProtoGen
             FileDescriptorProto first = new FileDescriptorProto.Builder {Name = "First"}.Build();
             FileDescriptorProto second =
                 new FileDescriptorProto.Builder {Name = "Second", DependencyList = {"First"}}.Build();
-            FileDescriptorSet set = new FileDescriptorSet {FileList = {first, second}};
+            FileDescriptorSet set = new FileDescriptorSet.Builder { FileList = { first, second } }.Build();
             IList<FileDescriptor> converted = Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
             Assert.AreEqual(2, converted.Count);
             Assert.AreEqual("First", converted[0].Name);
@@ -101,7 +101,7 @@ namespace Google.ProtocolBuffers.ProtoGen
                 new FileDescriptorProto.Builder {Name = "First", DependencyList = {"Second"}}.Build();
             FileDescriptorProto second =
                 new FileDescriptorProto.Builder {Name = "Second", DependencyList = {"First"}}.Build();
-            FileDescriptorSet set = new FileDescriptorSet {FileList = {first, second}};
+            FileDescriptorSet set = new FileDescriptorSet.Builder { FileList = { first, second } }.Build();
             try
             {
                 Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
@@ -118,7 +118,7 @@ namespace Google.ProtocolBuffers.ProtoGen
         {
             FileDescriptorProto first =
                 new FileDescriptorProto.Builder {Name = "First", DependencyList = {"Second"}}.Build();
-            FileDescriptorSet set = new FileDescriptorSet {FileList = {first}};
+            FileDescriptorSet set = new FileDescriptorSet.Builder { FileList = { first } }.Build();
             try
             {
                 Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);
@@ -135,7 +135,7 @@ namespace Google.ProtocolBuffers.ProtoGen
         {
             FileDescriptorProto first =
                 new FileDescriptorProto.Builder {Name = "First", DependencyList = {"First"}}.Build();
-            FileDescriptorSet set = new FileDescriptorSet {FileList = {first}};
+            FileDescriptorSet set = new FileDescriptorSet.Builder { FileList = { first } }.Build();
             try
             {
                 Generator.ConvertDescriptors(CSharpFileOptions.DefaultInstance, set);

+ 8 - 3
src/ProtoGen/EnumFieldGenerator.cs

@@ -49,10 +49,11 @@ namespace Google.ProtocolBuffers.ProtoGen
         {
             writer.WriteLine("private bool has{0};", PropertyName);
             writer.WriteLine("private {0} {1}_ = {2};", TypeName, Name, DefaultValue);
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public bool Has{0} {{", PropertyName);
             writer.WriteLine("  get {{ return has{0}; }}", PropertyName);
             writer.WriteLine("}");
-            AddClsComplianceCheck(writer);
+            AddPublicMemberAttributes(writer);
             writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
             writer.WriteLine("  get {{ return {0}_; }}", Name);
             writer.WriteLine("}");
@@ -60,21 +61,25 @@ namespace Google.ProtocolBuffers.ProtoGen
 
         public void GenerateBuilderMembers(TextGenerator writer)
         {
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public bool Has{0} {{", PropertyName);
             writer.WriteLine(" get {{ return result.has{0}; }}", PropertyName);
             writer.WriteLine("}");
-            AddClsComplianceCheck(writer);
+            AddPublicMemberAttributes(writer);
             writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
             writer.WriteLine("  get {{ return result.{0}; }}", PropertyName);
             writer.WriteLine("  set {{ Set{0}(value); }}", PropertyName);
             writer.WriteLine("}");
-            AddClsComplianceCheck(writer);
+            AddPublicMemberAttributes(writer);
             writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.has{0} = true;", PropertyName);
             writer.WriteLine("  result.{0}_ = value;", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.has{0} = false;", PropertyName);
             writer.WriteLine("  result.{0}_ = {1};", Name, DefaultValue);
             writer.WriteLine("  return this;");

+ 19 - 0
src/ProtoGen/FieldGeneratorBase.cs

@@ -251,6 +251,12 @@ namespace Google.ProtocolBuffers.ProtoGen
             }
         }
 
+        protected void AddPublicMemberAttributes(TextGenerator writer)
+        {
+            AddDeprecatedFlag(writer);
+            AddClsComplianceCheck(writer);
+        }
+
         protected void AddClsComplianceCheck(TextGenerator writer)
         {
             if (!Descriptor.IsCLSCompliant && Descriptor.File.CSharpOptions.ClsCompliance)
@@ -259,6 +265,19 @@ namespace Google.ProtocolBuffers.ProtoGen
             }
         }
 
+        protected bool IsObsolete { get { return Descriptor.Options.Deprecated; } }
+
+        /// <summary>
+        /// Writes [global::System.ObsoleteAttribute()] if the member is obsolete
+        /// </summary>
+        protected void AddDeprecatedFlag(TextGenerator writer)
+        {
+            if (IsObsolete)
+            {
+                writer.WriteLine("[global::System.ObsoleteAttribute()]");
+            }
+        }
+
         /// <summary>
         /// For encodings with fixed sizes, returns that size in bytes.  Otherwise
         /// returns -1. TODO(jonskeet): Make this less ugly.

+ 15 - 3
src/ProtoGen/MessageFieldGenerator.cs

@@ -48,38 +48,48 @@ namespace Google.ProtocolBuffers.ProtoGen
         public void GenerateMembers(TextGenerator writer)
         {
             writer.WriteLine("private bool has{0};", PropertyName);
-            writer.WriteLine("private {0} {1}_ = {2};", TypeName, Name, DefaultValue);
+            writer.WriteLine("private {0} {1}_;", TypeName, Name);
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public bool Has{0} {{", PropertyName);
             writer.WriteLine("  get {{ return has{0}; }}", PropertyName);
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
-            writer.WriteLine("  get {{ return {0}_; }}", Name);
+            writer.WriteLine("  get {{ return {0}_ ?? {1}; }}", Name, DefaultValue);
             writer.WriteLine("}");
         }
 
         public void GenerateBuilderMembers(TextGenerator writer)
         {
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public bool Has{0} {{", PropertyName);
             writer.WriteLine(" get {{ return result.has{0}; }}", PropertyName);
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
             writer.WriteLine("  get {{ return result.{0}; }}", PropertyName);
             writer.WriteLine("  set {{ Set{0}(value); }}", PropertyName);
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
             AddNullCheck(writer);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.has{0} = true;", PropertyName);
             writer.WriteLine("  result.{0}_ = value;", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Set{0}({1}.Builder builderForValue) {{", PropertyName, TypeName);
             AddNullCheck(writer, "builderForValue");
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.has{0} = true;", PropertyName);
             writer.WriteLine("  result.{0}_ = builderForValue.Build();", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Merge{0}({1} value) {{", PropertyName, TypeName);
             AddNullCheck(writer);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  if (result.has{0} &&", PropertyName);
             writer.WriteLine("      result.{0}_ != {1}) {{", Name, DefaultValue);
             writer.WriteLine("      result.{0}_ = {1}.CreateBuilder(result.{0}_).MergeFrom(value).BuildPartial();", Name,
@@ -90,9 +100,11 @@ namespace Google.ProtocolBuffers.ProtoGen
             writer.WriteLine("  result.has{0} = true;", PropertyName);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.has{0} = false;", PropertyName);
-            writer.WriteLine("  result.{0}_ = {1};", Name, DefaultValue);
+            writer.WriteLine("  result.{0}_ = null;", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
         }

+ 66 - 19
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}\")]",
@@ -177,8 +181,9 @@ namespace Google.ProtocolBuffers.ProtoGen
                              Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated",
                              RuntimeSuffix);
             writer.Indent();
+            writer.WriteLine("private {0}() {{ }}", ClassName);
             // Must call BuildPartial() to make sure all lists are made read-only
-            writer.WriteLine("private static readonly {0} defaultInstance = new Builder().BuildPartial();", ClassName);
+            writer.WriteLine("private static readonly {0} defaultInstance = new {0}().MakeReadOnly();", ClassName);
 
             if (OptimizeSpeed)
             {
@@ -199,7 +204,7 @@ namespace Google.ProtocolBuffers.ProtoGen
             writer.WriteLine("}");
             writer.WriteLine();
             writer.WriteLine("public override {0} DefaultInstanceForType {{", ClassName);
-            writer.WriteLine("  get { return defaultInstance; }");
+            writer.WriteLine("  get { return DefaultInstance; }");
             writer.WriteLine("}");
             writer.WriteLine();
             writer.WriteLine("protected override {0} ThisMessage {{", ClassName);
@@ -547,13 +552,28 @@ namespace Google.ProtocolBuffers.ProtoGen
 
         private void GenerateBuilder(TextGenerator writer)
         {
+            writer.WriteLine("private {0} MakeReadOnly() {{", ClassName);
+            writer.Indent();
+            foreach (FieldDescriptor field in Descriptor.Fields)
+            {
+                CreateFieldGenerator(field).GenerateBuildingCode(writer);
+            }
+            writer.WriteLine("return this;");
+            writer.Outdent();
+            writer.WriteLine("}");
+            writer.WriteLine();
+
             writer.WriteLine("public static Builder CreateBuilder() { return new Builder(); }");
             writer.WriteLine("public override Builder ToBuilder() { return CreateBuilder(this); }");
             writer.WriteLine("public override Builder CreateBuilderForType() { return new Builder(); }");
             writer.WriteLine("public static Builder CreateBuilder({0} prototype) {{", ClassName);
-            writer.WriteLine("  return (Builder) new Builder().MergeFrom(prototype);");
+            writer.WriteLine("  return new Builder(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}\")]",
@@ -582,21 +602,52 @@ namespace Google.ProtocolBuffers.ProtoGen
 
         private void GenerateCommonBuilderMethods(TextGenerator writer)
         {
-            writer.WriteLine("public Builder() {{}}", ClassAccessLevel);
+            //default constructor
+            writer.WriteLine("public Builder() {");
+            //Durring static initialization of message, DefaultInstance is expected to return null.
+            writer.WriteLine("  result = DefaultInstance;");
+            writer.WriteLine("  resultIsReadOnly = true;");
+            writer.WriteLine("}");
+            //clone constructor
+            writer.WriteLine("internal Builder({0} cloneFrom) {{", ClassName);
+            writer.WriteLine("  result = cloneFrom;");
+            writer.WriteLine("  resultIsReadOnly = true;");
+            writer.WriteLine("}");
+            writer.WriteLine();
+            writer.WriteLine("private bool resultIsReadOnly;");
+            writer.WriteLine("private {0} result;", ClassName);
             writer.WriteLine();
-            writer.WriteLine("{0} result = new {0}();", ClassName);
+            writer.WriteLine("private {0} PrepareBuilder() {{", ClassName);
+            writer.WriteLine("  if (resultIsReadOnly) {");
+            writer.WriteLine("    {0} original = result;", ClassName);
+            writer.WriteLine("    result = new {0}();", ClassName);
+            writer.WriteLine("    resultIsReadOnly = false;");
+            writer.WriteLine("    MergeFrom(original);");
+            writer.WriteLine("  }");
+            writer.WriteLine("  return result;");
+            writer.WriteLine("}");
+            writer.WriteLine();
+            writer.WriteLine("public override bool IsInitialized {");
+            writer.WriteLine("  get { return result.IsInitialized; }");
+            writer.WriteLine("}");
             writer.WriteLine();
             writer.WriteLine("protected override {0} MessageBeingBuilt {{", ClassName);
-            writer.WriteLine("  get { return result; }");
+            writer.WriteLine("  get { return PrepareBuilder(); }");
             writer.WriteLine("}");
             writer.WriteLine();
+            //Not actually expecting that DefaultInstance would ever be null here; however, we will ensure it does not break
             writer.WriteLine("public override Builder Clear() {");
-            writer.WriteLine("  result = new {0}();", ClassName);
+            writer.WriteLine("  result = DefaultInstance;", ClassName);
+            writer.WriteLine("  resultIsReadOnly = true;");
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
             writer.WriteLine();
             writer.WriteLine("public override Builder Clone() {");
-            writer.WriteLine("  return new Builder().MergeFrom(result);");
+            writer.WriteLine("  if (resultIsReadOnly) {");
+            writer.WriteLine("    return new Builder(result);");
+            writer.WriteLine("  } else {");
+            writer.WriteLine("    return new Builder().MergeFrom(result);");
+            writer.WriteLine("  }");
             writer.WriteLine("}");
             writer.WriteLine();
             if (!UseLiteRuntime)
@@ -613,17 +664,11 @@ namespace Google.ProtocolBuffers.ProtoGen
 
             writer.WriteLine("public override {0} BuildPartial() {{", ClassName);
             writer.Indent();
-            writer.WriteLine("if (result == null) {");
-            writer.WriteLine(
-                "  throw new global::System.InvalidOperationException(\"build() has already been called on this Builder\");");
+            writer.WriteLine("if (resultIsReadOnly) {");
+            writer.WriteLine("  return result;");
             writer.WriteLine("}");
-            foreach (FieldDescriptor field in Descriptor.Fields)
-            {
-                CreateFieldGenerator(field).GenerateBuildingCode(writer);
-            }
-            writer.WriteLine("{0} returnMe = result;", ClassName);
-            writer.WriteLine("result = null;");
-            writer.WriteLine("return returnMe;");
+            writer.WriteLine("resultIsReadOnly = true;");
+            writer.WriteLine("return result.MakeReadOnly();");
             writer.Outdent();
             writer.WriteLine("}");
             writer.WriteLine();
@@ -644,6 +689,7 @@ namespace Google.ProtocolBuffers.ProtoGen
                 // fields are set so we can skip the merge.
                 writer.Indent();
                 writer.WriteLine("if (other == {0}.DefaultInstance) return this;", FullClassName);
+                writer.WriteLine("PrepareBuilder();");
                 foreach (FieldDescriptor field in Descriptor.Fields)
                 {
                     CreateFieldGenerator(field).GenerateMergingCode(writer);
@@ -676,6 +722,7 @@ namespace Google.ProtocolBuffers.ProtoGen
             writer.WriteLine(
                 "public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {");
             writer.Indent();
+            writer.WriteLine("PrepareBuilder();");
             if (!UseLiteRuntime)
             {
                 writer.WriteLine("pb::UnknownFieldSet.Builder unknownFields = null;");

+ 8 - 3
src/ProtoGen/PrimitiveFieldGenerator.cs

@@ -50,10 +50,11 @@ namespace Google.ProtocolBuffers.ProtoGen
         {
             writer.WriteLine("private bool has{0};", PropertyName);
             writer.WriteLine("private {0} {1}_{2};", TypeName, Name, HasDefaultValue ? " = " + DefaultValue : "");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public bool Has{0} {{", PropertyName);
             writer.WriteLine("  get {{ return has{0}; }}", PropertyName);
             writer.WriteLine("}");
-            AddClsComplianceCheck(writer);
+            AddPublicMemberAttributes(writer);
             writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
             writer.WriteLine("  get {{ return {0}_; }}", Name);
             writer.WriteLine("}");
@@ -61,22 +62,26 @@ namespace Google.ProtocolBuffers.ProtoGen
 
         public void GenerateBuilderMembers(TextGenerator writer)
         {
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public bool Has{0} {{", PropertyName);
             writer.WriteLine("  get {{ return result.has{0}; }}", PropertyName);
             writer.WriteLine("}");
-            AddClsComplianceCheck(writer);
+            AddPublicMemberAttributes(writer);
             writer.WriteLine("public {0} {1} {{", TypeName, PropertyName);
             writer.WriteLine("  get {{ return result.{0}; }}", PropertyName);
             writer.WriteLine("  set {{ Set{0}(value); }}", PropertyName);
             writer.WriteLine("}");
-            AddClsComplianceCheck(writer);
+            AddPublicMemberAttributes(writer);
             writer.WriteLine("public Builder Set{0}({1} value) {{", PropertyName, TypeName);
             AddNullCheck(writer);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.has{0} = true;", PropertyName);
             writer.WriteLine("  result.{0}_ = value;", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.has{0} = false;", PropertyName);
             writer.WriteLine("  result.{0}_ = {1};", Name, DefaultValue);
             writer.WriteLine("  return this;");

+ 18 - 4
src/ProtoGen/RepeatedEnumFieldGenerator.cs

@@ -52,15 +52,18 @@ namespace Google.ProtocolBuffers.ProtoGen
                 writer.WriteLine("private int {0}MemoizedSerializedSize;", Name);
             }
             writer.WriteLine("private pbc::PopsicleList<{0}> {1}_ = new pbc::PopsicleList<{0}>();", TypeName, Name);
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public scg::IList<{0}> {1}List {{", TypeName, PropertyName);
             writer.WriteLine("  get {{ return pbc::Lists.AsReadOnly({0}_); }}", Name);
             writer.WriteLine("}");
 
             // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public int {0}Count {{", PropertyName);
             writer.WriteLine("  get {{ return {0}_.Count; }}", Name);
             writer.WriteLine("}");
 
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
             writer.WriteLine("  return {0}_[index];", Name);
             writer.WriteLine("}");
@@ -70,28 +73,39 @@ namespace Google.ProtocolBuffers.ProtoGen
         {
             // Note:  We can return the original list here, because we make it unmodifiable when we build
             // We return it via IPopsicleList so that collection initializers work more pleasantly.
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public pbc::IPopsicleList<{0}> {1}List {{", TypeName, PropertyName);
-            writer.WriteLine("  get {{ return result.{0}_; }}", Name);
+            writer.WriteLine("  get {{ return PrepareBuilder().{0}_; }}", Name);
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public int {0}Count {{", PropertyName);
             writer.WriteLine("  get {{ return result.{0}Count; }}", PropertyName);
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
             writer.WriteLine("  return result.Get{0}(index);", PropertyName);
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.{0}_[index] = value;", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.{0}_.Add(value);", Name, TypeName);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{", PropertyName, TypeName);
-            writer.WriteLine("  base.AddRange(values, result.{0}_);", Name);
+            writer.WriteLine("  PrepareBuilder();");
+            writer.WriteLine("  result.{0}_.Add(values);", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.{0}_.Clear();", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
@@ -100,13 +114,13 @@ namespace Google.ProtocolBuffers.ProtoGen
         public void GenerateMergingCode(TextGenerator writer)
         {
             writer.WriteLine("if (other.{0}_.Count != 0) {{", Name);
-            writer.WriteLine("  base.AddRange(other.{0}_, result.{0}_);", Name);
+            writer.WriteLine("  result.{0}_.Add(other.{0}_);", Name);
             writer.WriteLine("}");
         }
 
         public void GenerateBuildingCode(TextGenerator writer)
         {
-            writer.WriteLine("result.{0}_.MakeReadOnly();", Name);
+            writer.WriteLine("{0}_.MakeReadOnly();", Name);
         }
 
         public void GenerateParsingCode(TextGenerator writer)

+ 22 - 4
src/ProtoGen/RepeatedMessageFieldGenerator.cs

@@ -48,15 +48,18 @@ namespace Google.ProtocolBuffers.ProtoGen
         public void GenerateMembers(TextGenerator writer)
         {
             writer.WriteLine("private pbc::PopsicleList<{0}> {1}_ = new pbc::PopsicleList<{0}>();", TypeName, Name);
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public scg::IList<{0}> {1}List {{", TypeName, PropertyName);
             writer.WriteLine("  get {{ return {0}_; }}", Name);
             writer.WriteLine("}");
 
             // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public int {0}Count {{", PropertyName);
             writer.WriteLine("  get {{ return {0}_.Count; }}", Name);
             writer.WriteLine("}");
 
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
             writer.WriteLine("  return {0}_[index];", Name);
             writer.WriteLine("}");
@@ -66,42 +69,57 @@ namespace Google.ProtocolBuffers.ProtoGen
         {
             // Note:  We can return the original list here, because we make it unmodifiable when we build
             // We return it via IPopsicleList so that collection initializers work more pleasantly.
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public pbc::IPopsicleList<{0}> {1}List {{", TypeName, PropertyName);
-            writer.WriteLine("  get {{ return result.{0}_; }}", Name);
+            writer.WriteLine("  get {{ return PrepareBuilder().{0}_; }}", Name);
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public int {0}Count {{", PropertyName);
             writer.WriteLine("  get {{ return result.{0}Count; }}", PropertyName);
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
             writer.WriteLine("  return result.Get{0}(index);", PropertyName);
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
             AddNullCheck(writer);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.{0}_[index] = value;", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
             // Extra overload for builder (just on messages)
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Set{0}(int index, {1}.Builder builderForValue) {{", PropertyName, TypeName);
             AddNullCheck(writer, "builderForValue");
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.{0}_[index] = builderForValue.Build();", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
             AddNullCheck(writer);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.{0}_.Add(value);", Name, TypeName);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
             // Extra overload for builder (just on messages)
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Add{0}({1}.Builder builderForValue) {{", PropertyName, TypeName);
             AddNullCheck(writer, "builderForValue");
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.{0}_.Add(builderForValue.Build());", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{", PropertyName, TypeName);
-            writer.WriteLine("  base.AddRange(values, result.{0}_);", Name);
+            writer.WriteLine("  PrepareBuilder();");
+            writer.WriteLine("  result.{0}_.Add(values);", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.{0}_.Clear();", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
@@ -110,13 +128,13 @@ namespace Google.ProtocolBuffers.ProtoGen
         public void GenerateMergingCode(TextGenerator writer)
         {
             writer.WriteLine("if (other.{0}_.Count != 0) {{", Name);
-            writer.WriteLine("  base.AddRange(other.{0}_, result.{0}_);", Name);
+            writer.WriteLine("  result.{0}_.Add(other.{0}_);", Name);
             writer.WriteLine("}");
         }
 
         public void GenerateBuildingCode(TextGenerator writer)
         {
-            writer.WriteLine("result.{0}_.MakeReadOnly();", Name);
+            writer.WriteLine("{0}_.MakeReadOnly();", Name);
         }
 
         public void GenerateParsingCode(TextGenerator writer)

+ 18 - 11
src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs

@@ -52,17 +52,18 @@ namespace Google.ProtocolBuffers.ProtoGen
                 writer.WriteLine("private int {0}MemoizedSerializedSize;", Name);
             }
             writer.WriteLine("private pbc::PopsicleList<{0}> {1}_ = new pbc::PopsicleList<{0}>();", TypeName, Name);
-            AddClsComplianceCheck(writer);
+            AddPublicMemberAttributes(writer);
             writer.WriteLine("public scg::IList<{0}> {1}List {{", TypeName, PropertyName);
             writer.WriteLine("  get {{ return pbc::Lists.AsReadOnly({0}_); }}", Name);
             writer.WriteLine("}");
 
             // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public int {0}Count {{", PropertyName);
             writer.WriteLine("  get {{ return {0}_.Count; }}", Name);
             writer.WriteLine("}");
 
-            AddClsComplianceCheck(writer);
+            AddPublicMemberAttributes(writer);
             writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
             writer.WriteLine("  return {0}_[index];", Name);
             writer.WriteLine("}");
@@ -72,35 +73,41 @@ namespace Google.ProtocolBuffers.ProtoGen
         {
             // Note:  We can return the original list here, because we make it unmodifiable when we build
             // We return it via IPopsicleList so that collection initializers work more pleasantly.
-            AddClsComplianceCheck(writer);
+            AddPublicMemberAttributes(writer);
             writer.WriteLine("public pbc::IPopsicleList<{0}> {1}List {{", TypeName, PropertyName);
-            writer.WriteLine("  get {{ return result.{0}_; }}", Name);
+            writer.WriteLine("  get {{ return PrepareBuilder().{0}_; }}", Name);
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public int {0}Count {{", PropertyName);
             writer.WriteLine("  get {{ return result.{0}Count; }}", PropertyName);
             writer.WriteLine("}");
-            AddClsComplianceCheck(writer);
+            AddPublicMemberAttributes(writer);
             writer.WriteLine("public {0} Get{1}(int index) {{", TypeName, PropertyName);
             writer.WriteLine("  return result.Get{0}(index);", PropertyName);
             writer.WriteLine("}");
-            AddClsComplianceCheck(writer);
+            AddPublicMemberAttributes(writer);
             writer.WriteLine("public Builder Set{0}(int index, {1} value) {{", PropertyName, TypeName);
             AddNullCheck(writer);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.{0}_[index] = value;", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
-            AddClsComplianceCheck(writer);
+            AddPublicMemberAttributes(writer);
             writer.WriteLine("public Builder Add{0}({1} value) {{", PropertyName, TypeName);
             AddNullCheck(writer);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.{0}_.Add(value);", Name, TypeName);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
-            AddClsComplianceCheck(writer);
+            AddPublicMemberAttributes(writer);
             writer.WriteLine("public Builder AddRange{0}(scg::IEnumerable<{1}> values) {{", PropertyName, TypeName);
-            writer.WriteLine("  base.AddRange(values, result.{0}_);", Name);
+            writer.WriteLine("  PrepareBuilder();");
+            writer.WriteLine("  result.{0}_.Add(values);", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
+            AddDeprecatedFlag(writer);
             writer.WriteLine("public Builder Clear{0}() {{", PropertyName);
+            writer.WriteLine("  PrepareBuilder();");
             writer.WriteLine("  result.{0}_.Clear();", Name);
             writer.WriteLine("  return this;");
             writer.WriteLine("}");
@@ -109,13 +116,13 @@ namespace Google.ProtocolBuffers.ProtoGen
         public void GenerateMergingCode(TextGenerator writer)
         {
             writer.WriteLine("if (other.{0}_.Count != 0) {{", Name);
-            writer.WriteLine("  base.AddRange(other.{0}_, result.{0}_);", Name);
+            writer.WriteLine("  result.{0}_.Add(other.{0}_);", Name);
             writer.WriteLine("}");
         }
 
         public void GenerateBuildingCode(TextGenerator writer)
         {
-            writer.WriteLine("result.{0}_.MakeReadOnly();", Name);
+            writer.WriteLine("{0}_.MakeReadOnly();", Name);
         }
 
         public void GenerateParsingCode(TextGenerator writer)

+ 2 - 2
src/ProtoGen/UmbrellaClassGenerator.cs

@@ -138,8 +138,8 @@ namespace Google.ProtocolBuffers.ProtoGen
 
         private void WriteIntroduction(TextGenerator writer)
         {
-            writer.WriteLine("// Generated by {0}.  DO NOT EDIT!", this.GetType().Assembly.FullName);
-            writer.WriteLine("#pragma warning disable 1591");
+            writer.WriteLine("// Generated by {0}.  DO NOT EDIT!", this.GetType().Assembly.FullName);
+            writer.WriteLine("#pragma warning disable 1591, 0612");
             writer.WriteLine("#region Designer generated code");
 
             writer.WriteLine();

+ 73 - 0
src/ProtocolBuffers.Test/CodedInputStreamTest.cs

@@ -35,6 +35,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using System.IO;
 using Google.ProtocolBuffers.TestProtos;
 using NUnit.Framework;
@@ -532,5 +533,77 @@ namespace Google.ProtocolBuffers
                 return base.Read(buffer, offset, Math.Min(count, blockSize));
             }
         }
+
+        enum TestNegEnum { None = 0, Value = -2 }
+
+        [Test]
+        public void TestNegativeEnum()
+        {
+            byte[] bytes = new byte[10] { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01 };
+            CodedInputStream input = CodedInputStream.CreateInstance(bytes);
+            object unk;
+            TestNegEnum val = TestNegEnum.None;
+
+            Assert.IsTrue(input.ReadEnum(ref val, out unk));
+            Assert.IsTrue(input.IsAtEnd);
+            Assert.AreEqual(TestNegEnum.Value, val);
+        }
+
+        [Test]
+        public void TestNegativeEnumPackedArray()
+        {
+            int arraySize = 1 + (10 * 5);
+            int msgSize = 1 + 1 + arraySize;
+            byte[] bytes = new byte[msgSize];
+            CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
+            output.WritePackedInt32Array(8, "", arraySize, new int[] { 0, -1, -2, -3, -4, -5 });
+
+            Assert.AreEqual(0, output.SpaceLeft);
+
+            CodedInputStream input = CodedInputStream.CreateInstance(bytes);
+            uint tag;
+            string name;
+            Assert.IsTrue(input.ReadTag(out tag, out name));
+
+            List<TestNegEnum> values = new List<TestNegEnum>();
+            ICollection<object> unk;
+            input.ReadEnumArray(tag, name, values, out unk);
+
+            Assert.AreEqual(2, values.Count);
+            Assert.AreEqual(TestNegEnum.None, values[0]);
+            Assert.AreEqual(TestNegEnum.Value, values[1]);
+
+            Assert.IsNotNull(unk);
+            Assert.AreEqual(4, unk.Count);
+        }
+
+        [Test]
+        public void TestNegativeEnumArray()
+        {
+            int arraySize = 1 + 1 + (11 * 5);
+            int msgSize = arraySize;
+            byte[] bytes = new byte[msgSize];
+            CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
+            output.WriteInt32Array(8, "", new int[] { 0, -1, -2, -3, -4, -5 });
+
+            Assert.AreEqual(0, output.SpaceLeft);
+
+            CodedInputStream input = CodedInputStream.CreateInstance(bytes);
+            uint tag;
+            string name;
+            Assert.IsTrue(input.ReadTag(out tag, out name));
+
+            List<TestNegEnum> values = new List<TestNegEnum>();
+            ICollection<object> unk;
+            input.ReadEnumArray(tag, name, values, out unk);
+
+            Assert.AreEqual(2, values.Count);
+            Assert.AreEqual(TestNegEnum.None, values[0]);
+            Assert.AreEqual(TestNegEnum.Value, values[1]);
+
+            Assert.IsNotNull(unk);
+            Assert.AreEqual(4, unk.Count);
+        }
+
     }
 }

+ 79 - 0
src/ProtocolBuffers.Test/CodedOutputStreamTest.cs

@@ -34,6 +34,8 @@
 
 #endregion
 
+using System;
+using System.Collections.Generic;
 using System.IO;
 using Google.ProtocolBuffers.TestProtos;
 using NUnit.Framework;
@@ -288,5 +290,82 @@ namespace Google.ProtocolBuffers
             Assert.AreEqual(-75123905439571256L,
                             CodedInputStream.DecodeZigZag64(CodedOutputStream.EncodeZigZag64(-75123905439571256L)));
         }
+
+        [Test]
+        public void TestNegativeEnumNoTag()
+        {
+            Assert.AreEqual(10, CodedOutputStream.ComputeInt32SizeNoTag(-2));
+            Assert.AreEqual(10, CodedOutputStream.ComputeEnumSizeNoTag(-2));
+
+            byte[] bytes = new byte[10];
+            CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
+            output.WriteEnumNoTag(-2);
+
+            Assert.AreEqual(0, output.SpaceLeft);
+            Assert.AreEqual("FE-FF-FF-FF-FF-FF-FF-FF-FF-01", BitConverter.ToString(bytes));
+        }
+
+        [Test]
+        public void TestNegativeEnumWithTag()
+        {
+            Assert.AreEqual(11, CodedOutputStream.ComputeInt32Size(8, -2));
+            Assert.AreEqual(11, CodedOutputStream.ComputeEnumSize(8, -2));
+
+            byte[] bytes = new byte[11];
+            CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
+            output.WriteEnum(8, "", -2, -2);
+
+            Assert.AreEqual(0, output.SpaceLeft);
+            //fyi, 0x40 == 0x08 << 3 + 0, field num + wire format shift
+            Assert.AreEqual("40-FE-FF-FF-FF-FF-FF-FF-FF-FF-01", BitConverter.ToString(bytes));
+        }
+
+        [Test]
+        public void TestNegativeEnumArrayPacked()
+        {
+            int arraySize = 1 + (10 * 5);
+            int msgSize = 1 + 1 + arraySize;
+            byte[] bytes = new byte[msgSize];
+            CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
+            output.WritePackedEnumArray(8, "", arraySize, new int[] { 0, -1, -2, -3, -4, -5 });
+
+            Assert.AreEqual(0, output.SpaceLeft);
+
+            CodedInputStream input = CodedInputStream.CreateInstance(bytes);
+            uint tag;
+            string name;
+            Assert.IsTrue(input.ReadTag(out tag, out name));
+
+            List<int> values = new List<int>();
+            input.ReadInt32Array(tag, name, values);
+
+            Assert.AreEqual(6, values.Count);
+            for (int i = 0; i > -6; i--)
+                Assert.AreEqual(i, values[Math.Abs(i)]);
+        }
+
+        [Test]
+        public void TestNegativeEnumArray()
+        {
+            int arraySize = 1 + 1 + (11 * 5);
+            int msgSize = arraySize;
+            byte[] bytes = new byte[msgSize];
+            CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
+            output.WriteEnumArray(8, "", new int[] { 0, -1, -2, -3, -4, -5 });
+
+            Assert.AreEqual(0, output.SpaceLeft);
+
+            CodedInputStream input = CodedInputStream.CreateInstance(bytes);
+            uint tag;
+            string name;
+            Assert.IsTrue(input.ReadTag(out tag, out name));
+
+            List<int> values = new List<int>();
+            input.ReadInt32Array(tag, name, values);
+
+            Assert.AreEqual(6, values.Count);
+            for (int i = 0; i > -6; i--)
+                Assert.AreEqual(i, values[Math.Abs(i)]);
+        }
     }
 }

+ 59 - 0
src/ProtocolBuffers.Test/Collections/PopsicleListTest.cs

@@ -35,6 +35,7 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
 using NUnit.Framework;
 
 internal delegate void Action();
@@ -94,6 +95,64 @@ namespace Google.ProtocolBuffers.Collections
             Assert.IsFalse(list.IsReadOnly);
         }
 
+        [Test]
+        public void DoesNotAddNullEnumerable()
+        {
+            PopsicleList<string> list = new PopsicleList<string>();
+            try
+            {
+                list.Add((IEnumerable<string>)null);
+            }
+            catch (ArgumentNullException)
+            { return; }
+
+            Assert.Fail("List should not allow nulls.");
+        }
+
+        [Test]
+        public void DoesNotAddRangeWithNull()
+        {
+            PopsicleList<string> list = new PopsicleList<string>();
+            try
+            {
+                list.Add(new[] { "a", "b", null });
+            }
+            catch (ArgumentNullException)
+            { return; }
+
+            Assert.Fail("List should not allow nulls.");
+        }
+
+        [Test]
+        public void DoesNotAddNull()
+        {
+            PopsicleList<string> list = new PopsicleList<string>();
+            try
+            {
+                list.Add((string)null);
+            }
+            catch (ArgumentNullException)
+            { return; }
+
+            Assert.Fail("List should not allow nulls.");
+        }
+
+        [Test]
+        public void DoesNotSetNull()
+        {
+            PopsicleList<string> list = new PopsicleList<string>();
+            list.Add("a");
+            try
+            {
+                list[0] = null;
+            }
+            catch (ArgumentNullException)
+            { return; }
+
+            Assert.Fail("List should not allow nulls.");
+        }
+
+
         private static void AssertNotSupported(Action action)
         {
             try

+ 102 - 0
src/ProtocolBuffers.Test/DeprecatedMemberTest.cs

@@ -0,0 +1,102 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+using NUnit.Framework;
+using UnitTest.Issues.TestProtos;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class DeprecatedMemberTest
+    {
+        private static void AssertIsDeprecated(ICustomAttributeProvider member)
+        {
+            Assert.IsNotNull(member);
+            Assert.IsTrue(member.IsDefined(typeof(ObsoleteAttribute), false), "Member not obsolete: " + member);
+        }
+
+        [Test]
+        public void TestDepreatedPrimitiveValue()
+        {
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetProperty("HasPrimitiveValue"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetProperty("PrimitiveValue"));
+
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetProperty("HasPrimitiveValue"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetProperty("PrimitiveValue"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("ClearPrimitiveValue"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("SetPrimitiveValue"));
+        }
+        [Test]
+        public void TestDepreatedPrimitiveArray()
+        {
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetProperty("PrimitiveArrayList"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetProperty("PrimitiveArrayCount"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetMethod("GetPrimitiveArray"));
+
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetProperty("PrimitiveArrayList"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetProperty("PrimitiveArrayCount"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("GetPrimitiveArray"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("SetPrimitiveArray"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("AddPrimitiveArray"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("AddRangePrimitiveArray"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("ClearPrimitiveArray"));
+        }
+        [Test]
+        public void TestDepreatedMessageValue()
+        {
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetProperty("HasMessageValue"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetProperty("MessageValue"));
+
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetProperty("HasMessageValue"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetProperty("MessageValue"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("MergeMessageValue"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("ClearMessageValue"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("SetMessageValue", new[] { typeof(DeprecatedChild) }));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("SetMessageValue", new[] { typeof(DeprecatedChild.Builder) }));
+        }
+        [Test]
+        public void TestDepreatedMessageArray()
+        {
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetProperty("MessageArrayList"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetProperty("MessageArrayCount"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetMethod("GetMessageArray"));
+
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetProperty("MessageArrayList"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetProperty("MessageArrayCount"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("GetMessageArray"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("SetMessageArray", new[] { typeof(int), typeof(DeprecatedChild) }));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("SetMessageArray", new[] { typeof(int), typeof(DeprecatedChild.Builder) }));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("AddMessageArray", new[] { typeof(DeprecatedChild) }));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("AddMessageArray", new[] { typeof(DeprecatedChild.Builder) }));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("AddRangeMessageArray"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("ClearMessageArray"));
+        }
+        [Test]
+        public void TestDepreatedEnumValue()
+        {
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetProperty("HasEnumValue"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetProperty("EnumValue"));
+
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetProperty("HasEnumValue"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetProperty("EnumValue"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("ClearEnumValue"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("SetEnumValue"));
+        }
+        [Test]
+        public void TestDepreatedEnumArray()
+        {
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetProperty("EnumArrayList"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetProperty("EnumArrayCount"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage).GetMethod("GetEnumArray"));
+
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetProperty("EnumArrayList"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetProperty("EnumArrayCount"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("GetEnumArray"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("SetEnumArray"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("AddEnumArray"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("AddRangeEnumArray"));
+            AssertIsDeprecated(typeof(DeprecatedFieldsMessage.Builder).GetMethod("ClearEnumArray"));
+        }
+    }
+}

+ 123 - 0
src/ProtocolBuffers.Test/GeneratedBuilderTest.cs

@@ -0,0 +1,123 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Google.ProtocolBuffers.TestProtos;
+using NUnit.Framework;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class GeneratedBuilderTest
+    {
+        class OneTimeEnumerator<T> : IEnumerable<T>
+        {
+            readonly T _item;
+            bool _enumerated;
+            public OneTimeEnumerator(T item)
+            {
+                _item = item;
+            }
+            public IEnumerator<T> GetEnumerator()
+            {
+                Assert.IsFalse(_enumerated, "The collection {0} has already been enumerated", GetType());
+                _enumerated = true;
+                yield return _item;
+            }
+            System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+            { return GetEnumerator(); }
+        }
+
+        [Test]
+        public void DoesNotEnumerateTwiceForMessageList()
+        {
+            TestAllTypes.Builder b = new TestAllTypes.Builder();
+            b.AddRangeRepeatedForeignMessage(
+                new OneTimeEnumerator<ForeignMessage>(
+                    ForeignMessage.DefaultInstance));
+        }
+        [Test]
+        public void DoesNotEnumerateTwiceForPrimitiveList()
+        {
+            TestAllTypes.Builder b = new TestAllTypes.Builder();
+            b.AddRangeRepeatedInt32(new OneTimeEnumerator<int>(1));
+        }
+        [Test]
+        public void DoesNotEnumerateTwiceForStringList()
+        {
+            TestAllTypes.Builder b = new TestAllTypes.Builder();
+            b.AddRangeRepeatedString(new OneTimeEnumerator<string>("test"));
+        }
+        [Test]
+        public void DoesNotEnumerateTwiceForEnumList()
+        {
+            TestAllTypes.Builder b = new TestAllTypes.Builder();
+            b.AddRangeRepeatedForeignEnum(new OneTimeEnumerator<ForeignEnum>(ForeignEnum.FOREIGN_BAR));
+        }
+
+        private static void AssertThrows<T>(System.Threading.ThreadStart method) where T : Exception
+        {
+            try
+            {
+                method();
+            }
+            catch (Exception error)
+            {
+                if (error is T)
+                    return;
+                throw;
+            }
+            Assert.Fail("Expected exception of type " + typeof(T));
+        }
+
+        [Test]
+        public void DoesNotAddNullToMessageListByAddRange()
+        {
+            TestAllTypes.Builder b = new TestAllTypes.Builder();
+            AssertThrows<ArgumentNullException>(
+                () => b.AddRangeRepeatedForeignMessage(new ForeignMessage[] { null })
+                    );
+        }
+        [Test]
+        public void DoesNotAddNullToMessageListByAdd()
+        {
+            TestAllTypes.Builder b = new TestAllTypes.Builder();
+            AssertThrows<ArgumentNullException>(
+                () => b.AddRepeatedForeignMessage((ForeignMessage)null)
+                    );
+        }
+        [Test]
+        public void DoesNotAddNullToMessageListBySet()
+        {
+            TestAllTypes.Builder b = new TestAllTypes.Builder();
+            b.AddRepeatedForeignMessage(ForeignMessage.DefaultInstance);
+            AssertThrows<ArgumentNullException>(
+                () => b.SetRepeatedForeignMessage(0, (ForeignMessage)null)
+                    );
+        }
+        [Test]
+        public void DoesNotAddNullToStringListByAddRange()
+        {
+            TestAllTypes.Builder b = new TestAllTypes.Builder();
+            AssertThrows<ArgumentNullException>(
+                () => b.AddRangeRepeatedString(new String[] { null })
+                    );
+        }
+        [Test]
+        public void DoesNotAddNullToStringListByAdd()
+        {
+            TestAllTypes.Builder b = new TestAllTypes.Builder();
+            AssertThrows<ArgumentNullException>(
+                () => b.AddRepeatedString(null)
+                    );
+        }
+        [Test]
+        public void DoesNotAddNullToStringListBySet()
+        {
+            TestAllTypes.Builder b = new TestAllTypes.Builder();
+            b.AddRepeatedString("one");
+            AssertThrows<ArgumentNullException>(
+                () => b.SetRepeatedString(0, null)
+                    );
+        }
+    }
+}

+ 0 - 16
src/ProtocolBuffers.Test/GeneratedMessageTest.cs

@@ -111,22 +111,6 @@ namespace Google.ProtocolBuffers
             }
         }
 
-        [Test]
-        public void DoubleBuildError()
-        {
-            TestAllTypes.Builder builder = new TestAllTypes.Builder();
-            builder.Build();
-            try
-            {
-                builder.Build();
-                Assert.Fail("Should have thrown exception.");
-            }
-            catch (InvalidOperationException)
-            {
-                // Success.
-            }
-        }
-
         [Test]
         public void DefaultInstance()
         {

+ 5 - 4
src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj

@@ -45,9 +45,7 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <DocumentationFile>bin\Debug\Google.ProtocolBuffers.Test.XML</DocumentationFile>
     <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <NoWarn>1591</NoWarn>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
     <DebugType>pdbonly</DebugType>
@@ -57,9 +55,7 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <DocumentationFile>bin\Release\Google.ProtocolBuffers.Test.XML</DocumentationFile>
     <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <NoWarn>1591</NoWarn>
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="nunit.framework, Version=2.2.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
@@ -94,10 +90,12 @@
     <Compile Include="Compatibility\XmlCompatibilityTests.cs" />
     <Compile Include="TestReaderForUrlEncoded.cs" />
     <Compile Include="CSharpOptionsTest.cs" />
+    <Compile Include="DeprecatedMemberTest.cs" />
     <Compile Include="DescriptorsTest.cs" />
     <Compile Include="Descriptors\MessageDescriptorTest.cs" />
     <Compile Include="DynamicMessageTest.cs" />
     <Compile Include="ExtendableMessageTest.cs" />
+    <Compile Include="GeneratedBuilderTest.cs" />
     <Compile Include="GeneratedMessageTest.cs" />
     <Compile Include="MessageStreamIteratorTest.cs" />
     <Compile Include="MessageStreamWriterTest.cs" />
@@ -106,7 +104,10 @@
     <Compile Include="NameHelpersTest.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="ReflectionTester.cs" />
+    <Compile Include="ReusableBuilderTest.cs" />
+    <Compile Include="SerializableTest.cs" />
     <Compile Include="ServiceTest.cs" />
+    <Compile Include="TestCornerCases.cs" />
     <Compile Include="TestMimeMessageFormats.cs" />
     <Compile Include="TestProtos\UnitTestCSharpOptionsProtoFile.cs" />
     <Compile Include="TestProtos\UnitTestCustomOptionsProtoFile.cs" />

+ 170 - 0
src/ProtocolBuffers.Test/ReusableBuilderTest.cs

@@ -0,0 +1,170 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Text;
+using Google.ProtocolBuffers.Collections;
+using NUnit.Framework;
+using Google.ProtocolBuffers.TestProtos;
+using Google.ProtocolBuffers.Serialization;
+using UnitTest.Issues.TestProtos;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class ReusableBuilderTest
+    {
+        [Test, Description("Issue 28: Circular message dependencies result in null defaults for DefaultInstance")]
+        public void EnsureStaticCicularReference()
+        {
+            MyMessageAReferenceB ab = MyMessageAReferenceB.DefaultInstance;
+            Assert.IsNotNull(ab);
+            Assert.IsNotNull(ab.Value);
+            MyMessageBReferenceA ba = MyMessageBReferenceA.DefaultInstance;
+            Assert.IsNotNull(ba);
+            Assert.IsNotNull(ba.Value);
+        }
+
+        [Test]
+        public void TestModifyDefaultInstance()
+        {
+            //verify that the default instance has correctly been marked as read-only
+            Assert.AreEqual(typeof(PopsicleList<bool>), TestAllTypes.DefaultInstance.RepeatedBoolList.GetType());
+            PopsicleList<bool> list = (PopsicleList<bool>)TestAllTypes.DefaultInstance.RepeatedBoolList;
+            Assert.IsTrue(list.IsReadOnly);
+        }
+
+        [Test]
+        public void TestUnmodifiedDefaultInstance()
+        {
+            //Simply calling ToBuilder().Build() no longer creates a copy of the message
+            TestAllTypes.Builder builder = TestAllTypes.DefaultInstance.ToBuilder();
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+        }
+
+        [Test]
+        public void BuildMultipleWithoutChange()
+        {
+            //Calling Build() or BuildPartial() does not require a copy of the message
+            TestAllTypes.Builder builder = TestAllTypes.DefaultInstance.ToBuilder();
+            builder.SetDefaultBool(true);
+
+            TestAllTypes first = builder.BuildPartial();
+            //Still the same instance?
+            Assert.IsTrue(ReferenceEquals(first, builder.Build()));
+            //Still the same instance?
+            Assert.IsTrue(ReferenceEquals(first, builder.BuildPartial().ToBuilder().Build()));
+        }
+
+        [Test]
+        public void MergeFromDefaultInstance()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.DefaultInstance.ToBuilder();
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+            builder.MergeFrom(TestAllTypes.DefaultInstance);
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+        }
+
+        [Test]
+        public void BuildNewBuilderIsDefaultInstance()
+        {
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance, new TestAllTypes.Builder().Build()));
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance, TestAllTypes.CreateBuilder().Build()));
+            //last test, if you clear a builder it reverts to default instance
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance,
+                TestAllTypes.CreateBuilder().SetOptionalBool(true).Build().ToBuilder().Clear().Build()));
+        }
+
+        [Test]
+        public void BuildModifyAndRebuild()
+        {
+            TestAllTypes.Builder b1 = new TestAllTypes.Builder();
+            b1.SetDefaultInt32(1);
+            b1.AddRepeatedInt32(2);
+            b1.SetOptionalForeignMessage(ForeignMessage.DefaultInstance);
+
+            TestAllTypes m1 = b1.Build();
+
+            b1.SetDefaultInt32(5);
+            b1.AddRepeatedInt32(6);
+            b1.SetOptionalForeignMessage(b1.OptionalForeignMessage.ToBuilder().SetC(7));
+
+            TestAllTypes m2 = b1.Build();
+            
+            Assert.AreEqual("{\"optional_foreign_message\":{},\"repeated_int32\":[2],\"default_int32\":1}", m1.ToJson());
+            Assert.AreEqual("{\"optional_foreign_message\":{\"c\":7},\"repeated_int32\":[2,6],\"default_int32\":5}", m2.ToJson());
+        }
+
+        [Test]
+        public void CloneOnChangePrimitive()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.DefaultInstance.ToBuilder();
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+            builder.SetDefaultBool(true);
+            Assert.IsFalse(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+        }
+
+        [Test]
+        public void CloneOnAddRepeatedBool()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.DefaultInstance.ToBuilder();
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+            builder.AddRepeatedBool(true);
+            Assert.IsFalse(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+        }
+
+        [Test]
+        public void CloneOnGetRepeatedBoolList()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.DefaultInstance.ToBuilder();
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+            GC.KeepAlive(builder.RepeatedBoolList);
+            Assert.IsFalse(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+        }
+
+        [Test]
+        public void CloneOnChangeMessage()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.DefaultInstance.ToBuilder();
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+            builder.SetOptionalForeignMessage(new ForeignMessage.Builder());
+            Assert.IsFalse(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+        }
+
+        [Test]
+        public void CloneOnClearMessage()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.DefaultInstance.ToBuilder();
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+            builder.ClearOptionalForeignMessage();
+            Assert.IsFalse(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+        }
+
+        [Test]
+        public void CloneOnGetRepeatedForeignMessageList()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.DefaultInstance.ToBuilder();
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+            GC.KeepAlive(builder.RepeatedForeignMessageList);
+            Assert.IsFalse(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+        }
+
+        [Test]
+        public void CloneOnChangeEnumValue()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.DefaultInstance.ToBuilder();
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+            builder.SetOptionalForeignEnum(ForeignEnum.FOREIGN_BAR);
+            Assert.IsFalse(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+        }
+
+        [Test]
+        public void CloneOnGetRepeatedForeignEnumList()
+        {
+            TestAllTypes.Builder builder = TestAllTypes.DefaultInstance.ToBuilder();
+            Assert.IsTrue(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+            GC.KeepAlive(builder.RepeatedForeignEnumList);
+            Assert.IsFalse(ReferenceEquals(TestAllTypes.DefaultInstance, builder.Build()));
+        }
+
+    }
+}

+ 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());
+        }
+    }
+}

+ 38 - 0
src/ProtocolBuffers.Test/TestCornerCases.cs

@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using NUnit.Framework;
+using UnitTest.Issues.TestProtos;
+
+namespace Google.ProtocolBuffers
+{
+    [TestFixture]
+    public class TestCornerCases
+    {
+        [Test]
+        public void TestRoundTripNegativeEnums()
+        {
+            NegativeEnumMessage msg = NegativeEnumMessage.CreateBuilder()
+                .SetValue(NegativeEnum.MinusOne) //11
+                .AddValues(NegativeEnum.Zero) //2
+                .AddValues(NegativeEnum.MinusOne) //11
+                .AddValues(NegativeEnum.FiveBelow) //11
+                //2
+                .AddPackedValues(NegativeEnum.Zero) //1
+                .AddPackedValues(NegativeEnum.MinusOne) //10
+                .AddPackedValues(NegativeEnum.FiveBelow) //10
+                .Build();
+
+            Assert.AreEqual(58, msg.SerializedSize);
+
+            byte[] bytes = new byte[58];
+            CodedOutputStream output = CodedOutputStream.CreateInstance(bytes);
+
+            msg.WriteTo(output);
+            Assert.AreEqual(0, output.SpaceLeft);
+
+            NegativeEnumMessage copy = NegativeEnumMessage.ParseFrom(bytes);
+            Assert.AreEqual(msg, copy);
+        }
+    }
+}

+ 53 - 14
src/ProtocolBuffers.Test/TestProtos/UnitTestCSharpOptionsProtoFile.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -60,7 +60,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class OptionsMessage : pb::GeneratedMessage<OptionsMessage, OptionsMessage.Builder> {
-    private static readonly OptionsMessage defaultInstance = new Builder().BuildPartial();
+    private OptionsMessage() { }
+    private static readonly OptionsMessage defaultInstance = new OptionsMessage().MakeReadOnly();
     private static readonly string[] _optionsMessageFieldNames = new string[] { "customized", "normal", "options_message" };
     private static readonly uint[] _optionsMessageFieldTags = new uint[] { 26, 10, 18 };
     public static OptionsMessage DefaultInstance {
@@ -68,7 +69,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override OptionsMessage DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override OptionsMessage ThisMessage {
@@ -186,11 +187,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static OptionsMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private OptionsMessage MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(OptionsMessage prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -200,21 +205,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(OptionsMessage cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private OptionsMessage result;
+      
+      private OptionsMessage PrepareBuilder() {
+        if (resultIsReadOnly) {
+          OptionsMessage original = result;
+          result = new OptionsMessage();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      OptionsMessage result = new OptionsMessage();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override OptionsMessage MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new OptionsMessage();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -226,12 +258,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override OptionsMessage BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        OptionsMessage returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -245,6 +276,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(OptionsMessage other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.OptionsMessage.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasNormal) {
           Normal = other.Normal;
         }
@@ -263,6 +295,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -327,11 +360,13 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetNormal(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasNormal = true;
         result.normal_ = value;
         return this;
       }
       public Builder ClearNormal() {
+        PrepareBuilder();
         result.hasNormal = false;
         result.normal_ = "";
         return this;
@@ -346,11 +381,13 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetOptionsMessage_(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasOptionsMessage_ = true;
         result.optionsMessage_ = value;
         return this;
       }
       public Builder ClearOptionsMessage_() {
+        PrepareBuilder();
         result.hasOptionsMessage_ = false;
         result.optionsMessage_ = "";
         return this;
@@ -365,11 +402,13 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetCustomName(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasCustomName = true;
         result.customized_ = value;
         return this;
       }
       public Builder ClearCustomName() {
+        PrepareBuilder();
         result.hasCustomName = false;
         result.customized_ = "";
         return this;

Різницю між файлами не показано, бо вона завелика
+ 371 - 105
src/ProtocolBuffers.Test/TestProtos/UnitTestCustomOptionsProtoFile.cs


+ 64 - 21
src/ProtocolBuffers.Test/TestProtos/UnitTestEmbedOptimizeForProtoFile.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -64,7 +64,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestEmbedOptimizedForSize : pb::GeneratedMessage<TestEmbedOptimizedForSize, TestEmbedOptimizedForSize.Builder> {
-    private static readonly TestEmbedOptimizedForSize defaultInstance = new Builder().BuildPartial();
+    private TestEmbedOptimizedForSize() { }
+    private static readonly TestEmbedOptimizedForSize defaultInstance = new TestEmbedOptimizedForSize().MakeReadOnly();
     private static readonly string[] _testEmbedOptimizedForSizeFieldNames = new string[] { "optional_message", "repeated_message" };
     private static readonly uint[] _testEmbedOptimizedForSizeFieldTags = new uint[] { 10, 18 };
     public static TestEmbedOptimizedForSize DefaultInstance {
@@ -72,7 +73,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override TestEmbedOptimizedForSize DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override TestEmbedOptimizedForSize ThisMessage {
@@ -89,12 +90,12 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public const int OptionalMessageFieldNumber = 1;
     private bool hasOptionalMessage;
-    private global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize optionalMessage_ = global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.DefaultInstance;
+    private global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize optionalMessage_;
     public bool HasOptionalMessage {
       get { return hasOptionalMessage; }
     }
     public global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize OptionalMessage {
-      get { return optionalMessage_; }
+      get { return optionalMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.DefaultInstance; }
     }
     
     public const int RepeatedMessageFieldNumber = 2;
@@ -182,11 +183,16 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static TestEmbedOptimizedForSize ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private TestEmbedOptimizedForSize MakeReadOnly() {
+      repeatedMessage_.MakeReadOnly();
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(TestEmbedOptimizedForSize prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -196,21 +202,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(TestEmbedOptimizedForSize cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private TestEmbedOptimizedForSize result;
+      
+      private TestEmbedOptimizedForSize PrepareBuilder() {
+        if (resultIsReadOnly) {
+          TestEmbedOptimizedForSize original = result;
+          result = new TestEmbedOptimizedForSize();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      TestEmbedOptimizedForSize result = new TestEmbedOptimizedForSize();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override TestEmbedOptimizedForSize MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new TestEmbedOptimizedForSize();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -222,13 +255,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override TestEmbedOptimizedForSize BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        result.repeatedMessage_.MakeReadOnly();
-        TestEmbedOptimizedForSize returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -242,11 +273,12 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(TestEmbedOptimizedForSize other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.TestEmbedOptimizedForSize.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasOptionalMessage) {
           MergeOptionalMessage(other.OptionalMessage);
         }
         if (other.repeatedMessage_.Count != 0) {
-          base.AddRange(other.repeatedMessage_, result.repeatedMessage_);
+          result.repeatedMessage_.Add(other.repeatedMessage_);
         }
         this.MergeUnknownFields(other.UnknownFields);
         return this;
@@ -257,6 +289,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -322,18 +355,21 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetOptionalMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasOptionalMessage = true;
         result.optionalMessage_ = value;
         return this;
       }
       public Builder SetOptionalMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.hasOptionalMessage = true;
         result.optionalMessage_ = builderForValue.Build();
         return this;
       }
       public Builder MergeOptionalMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         if (result.hasOptionalMessage &&
             result.optionalMessage_ != global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.DefaultInstance) {
             result.optionalMessage_ = global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.CreateBuilder(result.optionalMessage_).MergeFrom(value).BuildPartial();
@@ -344,13 +380,14 @@ namespace Google.ProtocolBuffers.TestProtos {
         return this;
       }
       public Builder ClearOptionalMessage() {
+        PrepareBuilder();
         result.hasOptionalMessage = false;
-        result.optionalMessage_ = global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.DefaultInstance;
+        result.optionalMessage_ = null;
         return this;
       }
       
       public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize> RepeatedMessageList {
-        get { return result.repeatedMessage_; }
+        get { return PrepareBuilder().repeatedMessage_; }
       }
       public int RepeatedMessageCount {
         get { return result.RepeatedMessageCount; }
@@ -360,29 +397,35 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetRepeatedMessage(int index, global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.repeatedMessage_[index] = value;
         return this;
       }
       public Builder SetRepeatedMessage(int index, global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.repeatedMessage_[index] = builderForValue.Build();
         return this;
       }
       public Builder AddRepeatedMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.repeatedMessage_.Add(value);
         return this;
       }
       public Builder AddRepeatedMessage(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.repeatedMessage_.Add(builderForValue.Build());
         return this;
       }
       public Builder AddRangeRepeatedMessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize> values) {
-        base.AddRange(values, result.repeatedMessage_);
+        PrepareBuilder();
+        result.repeatedMessage_.Add(values);
         return this;
       }
       public Builder ClearRepeatedMessage() {
+        PrepareBuilder();
         result.repeatedMessage_.Clear();
         return this;
       }

+ 1 - 1
src/ProtocolBuffers.Test/TestProtos/UnitTestEmptyProtoFile.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;

+ 2174 - 56
src/ProtocolBuffers.Test/TestProtos/UnitTestExtrasIssuesProtoFile.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -26,6 +26,16 @@ namespace UnitTest.Issues.TestProtos {
     internal static pb::FieldAccess.FieldAccessorTable<global::UnitTest.Issues.TestProtos.AB, global::UnitTest.Issues.TestProtos.AB.Builder> internal__static_unittest_issues_AB__FieldAccessorTable;
     internal static pbd::MessageDescriptor internal__static_unittest_issues_NumberField__Descriptor;
     internal static pb::FieldAccess.FieldAccessorTable<global::UnitTest.Issues.TestProtos.NumberField, global::UnitTest.Issues.TestProtos.NumberField.Builder> internal__static_unittest_issues_NumberField__FieldAccessorTable;
+    internal static pbd::MessageDescriptor internal__static_unittest_issues_MyMessageAReferenceB__Descriptor;
+    internal static pb::FieldAccess.FieldAccessorTable<global::UnitTest.Issues.TestProtos.MyMessageAReferenceB, global::UnitTest.Issues.TestProtos.MyMessageAReferenceB.Builder> internal__static_unittest_issues_MyMessageAReferenceB__FieldAccessorTable;
+    internal static pbd::MessageDescriptor internal__static_unittest_issues_MyMessageBReferenceA__Descriptor;
+    internal static pb::FieldAccess.FieldAccessorTable<global::UnitTest.Issues.TestProtos.MyMessageBReferenceA, global::UnitTest.Issues.TestProtos.MyMessageBReferenceA.Builder> internal__static_unittest_issues_MyMessageBReferenceA__FieldAccessorTable;
+    internal static pbd::MessageDescriptor internal__static_unittest_issues_NegativeEnumMessage__Descriptor;
+    internal static pb::FieldAccess.FieldAccessorTable<global::UnitTest.Issues.TestProtos.NegativeEnumMessage, global::UnitTest.Issues.TestProtos.NegativeEnumMessage.Builder> internal__static_unittest_issues_NegativeEnumMessage__FieldAccessorTable;
+    internal static pbd::MessageDescriptor internal__static_unittest_issues_DeprecatedChild__Descriptor;
+    internal static pb::FieldAccess.FieldAccessorTable<global::UnitTest.Issues.TestProtos.DeprecatedChild, global::UnitTest.Issues.TestProtos.DeprecatedChild.Builder> internal__static_unittest_issues_DeprecatedChild__FieldAccessorTable;
+    internal static pbd::MessageDescriptor internal__static_unittest_issues_DeprecatedFieldsMessage__Descriptor;
+    internal static pb::FieldAccess.FieldAccessorTable<global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage, global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage.Builder> internal__static_unittest_issues_DeprecatedFieldsMessage__FieldAccessorTable;
     #endregion
     #region Descriptor
     public static pbd::FileDescriptor Descriptor {
@@ -38,9 +48,26 @@ namespace UnitTest.Issues.TestProtos {
           "ChxleHRlc3QvdW5pdHRlc3RfaXNzdWVzLnByb3RvEg91bml0dGVzdF9pc3N1" + 
           "ZXMaJGdvb2dsZS9wcm90b2J1Zi9jc2hhcnBfb3B0aW9ucy5wcm90byIPCgFB" + 
           "EgoKAl9BGAEgASgFIg8KAUISCgoCQl8YASABKAUiEQoCQUISCwoDYV9iGAEg" + 
-          "ASgFIhoKC051bWJlckZpZWxkEgsKA18wMRgBIAEoBUJASAHCPjsKGlVuaXRU" + 
-          "ZXN0Lklzc3Vlcy5UZXN0UHJvdG9zEh1Vbml0VGVzdEV4dHJhc0lzc3Vlc1By" + 
-          "b3RvRmlsZQ==");
+          "ASgFIhoKC051bWJlckZpZWxkEgsKA18wMRgBIAEoBSJMChRNeU1lc3NhZ2VB" + 
+          "UmVmZXJlbmNlQhI0CgV2YWx1ZRgBIAIoCzIlLnVuaXR0ZXN0X2lzc3Vlcy5N" + 
+          "eU1lc3NhZ2VCUmVmZXJlbmNlQSJMChRNeU1lc3NhZ2VCUmVmZXJlbmNlQRI0" + 
+          "CgV2YWx1ZRgBIAIoCzIlLnVuaXR0ZXN0X2lzc3Vlcy5NeU1lc3NhZ2VBUmVm" + 
+          "ZXJlbmNlQiKsAQoTTmVnYXRpdmVFbnVtTWVzc2FnZRIsCgV2YWx1ZRgBIAEo" + 
+          "DjIdLnVuaXR0ZXN0X2lzc3Vlcy5OZWdhdGl2ZUVudW0SLQoGdmFsdWVzGAIg" + 
+          "AygOMh0udW5pdHRlc3RfaXNzdWVzLk5lZ2F0aXZlRW51bRI4Cg1wYWNrZWRf" + 
+          "dmFsdWVzGAMgAygOMh0udW5pdHRlc3RfaXNzdWVzLk5lZ2F0aXZlRW51bUIC" + 
+          "EAEiEQoPRGVwcmVjYXRlZENoaWxkIrkCChdEZXByZWNhdGVkRmllbGRzTWVz" + 
+          "c2FnZRIaCg5QcmltaXRpdmVWYWx1ZRgBIAEoBUICGAESGgoOUHJpbWl0aXZl" + 
+          "QXJyYXkYAiADKAVCAhgBEjoKDE1lc3NhZ2VWYWx1ZRgDIAEoCzIgLnVuaXR0" + 
+          "ZXN0X2lzc3Vlcy5EZXByZWNhdGVkQ2hpbGRCAhgBEjoKDE1lc3NhZ2VBcnJh" + 
+          "eRgEIAMoCzIgLnVuaXR0ZXN0X2lzc3Vlcy5EZXByZWNhdGVkQ2hpbGRCAhgB" + 
+          "EjYKCUVudW1WYWx1ZRgFIAEoDjIfLnVuaXR0ZXN0X2lzc3Vlcy5EZXByZWNh" + 
+          "dGVkRW51bUICGAESNgoJRW51bUFycmF5GAYgAygOMh8udW5pdHRlc3RfaXNz" + 
+          "dWVzLkRlcHJlY2F0ZWRFbnVtQgIYASpHCgxOZWdhdGl2ZUVudW0SFgoJRml2" + 
+          "ZUJlbG93EPv//////////wESFQoITWludXNPbmUQ////////////ARIICgRa" + 
+          "ZXJvEAAqGQoORGVwcmVjYXRlZEVudW0SBwoDb25lEAFCQEgBwj47ChpVbml0" + 
+          "VGVzdC5Jc3N1ZXMuVGVzdFByb3RvcxIdVW5pdFRlc3RFeHRyYXNJc3N1ZXNQ" + 
+          "cm90b0ZpbGU=");
       pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
         descriptor = root;
         internal__static_unittest_issues_A__Descriptor = Descriptor.MessageTypes[0];
@@ -59,6 +86,26 @@ namespace UnitTest.Issues.TestProtos {
         internal__static_unittest_issues_NumberField__FieldAccessorTable = 
             new pb::FieldAccess.FieldAccessorTable<global::UnitTest.Issues.TestProtos.NumberField, global::UnitTest.Issues.TestProtos.NumberField.Builder>(internal__static_unittest_issues_NumberField__Descriptor,
                 new string[] { "_01", });
+        internal__static_unittest_issues_MyMessageAReferenceB__Descriptor = Descriptor.MessageTypes[4];
+        internal__static_unittest_issues_MyMessageAReferenceB__FieldAccessorTable = 
+            new pb::FieldAccess.FieldAccessorTable<global::UnitTest.Issues.TestProtos.MyMessageAReferenceB, global::UnitTest.Issues.TestProtos.MyMessageAReferenceB.Builder>(internal__static_unittest_issues_MyMessageAReferenceB__Descriptor,
+                new string[] { "Value", });
+        internal__static_unittest_issues_MyMessageBReferenceA__Descriptor = Descriptor.MessageTypes[5];
+        internal__static_unittest_issues_MyMessageBReferenceA__FieldAccessorTable = 
+            new pb::FieldAccess.FieldAccessorTable<global::UnitTest.Issues.TestProtos.MyMessageBReferenceA, global::UnitTest.Issues.TestProtos.MyMessageBReferenceA.Builder>(internal__static_unittest_issues_MyMessageBReferenceA__Descriptor,
+                new string[] { "Value", });
+        internal__static_unittest_issues_NegativeEnumMessage__Descriptor = Descriptor.MessageTypes[6];
+        internal__static_unittest_issues_NegativeEnumMessage__FieldAccessorTable = 
+            new pb::FieldAccess.FieldAccessorTable<global::UnitTest.Issues.TestProtos.NegativeEnumMessage, global::UnitTest.Issues.TestProtos.NegativeEnumMessage.Builder>(internal__static_unittest_issues_NegativeEnumMessage__Descriptor,
+                new string[] { "Value", "Values", "PackedValues", });
+        internal__static_unittest_issues_DeprecatedChild__Descriptor = Descriptor.MessageTypes[7];
+        internal__static_unittest_issues_DeprecatedChild__FieldAccessorTable = 
+            new pb::FieldAccess.FieldAccessorTable<global::UnitTest.Issues.TestProtos.DeprecatedChild, global::UnitTest.Issues.TestProtos.DeprecatedChild.Builder>(internal__static_unittest_issues_DeprecatedChild__Descriptor,
+                new string[] { });
+        internal__static_unittest_issues_DeprecatedFieldsMessage__Descriptor = Descriptor.MessageTypes[8];
+        internal__static_unittest_issues_DeprecatedFieldsMessage__FieldAccessorTable = 
+            new pb::FieldAccess.FieldAccessorTable<global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage, global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage.Builder>(internal__static_unittest_issues_DeprecatedFieldsMessage__Descriptor,
+                new string[] { "PrimitiveValue", "PrimitiveArray", "MessageValue", "MessageArray", "EnumValue", "EnumArray", });
         pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
         RegisterAllExtensions(registry);
         global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.RegisterAllExtensions(registry);
@@ -72,12 +119,30 @@ namespace UnitTest.Issues.TestProtos {
     #endregion
     
   }
+  #region Enums
+  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+  public enum NegativeEnum {
+    FiveBelow = -5,
+    MinusOne = -1,
+    Zero = 0,
+  }
+  
+  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+  public enum DeprecatedEnum {
+    one = 1,
+  }
+  
+  #endregion
+  
   #region Messages
   [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class A : pb::GeneratedMessage<A, A.Builder> {
-    private static readonly A defaultInstance = new Builder().BuildPartial();
+    private A() { }
+    private static readonly A defaultInstance = new A().MakeReadOnly();
     private static readonly string[] _aFieldNames = new string[] { "_A" };
     private static readonly uint[] _aFieldTags = new uint[] { 8 };
     public static A DefaultInstance {
@@ -85,7 +150,7 @@ namespace UnitTest.Issues.TestProtos {
     }
     
     public override A DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override A ThisMessage {
@@ -171,11 +236,15 @@ namespace UnitTest.Issues.TestProtos {
     public static A ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private A MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(A prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -185,21 +254,48 @@ namespace UnitTest.Issues.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(A cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private A result;
+      
+      private A PrepareBuilder() {
+        if (resultIsReadOnly) {
+          A original = result;
+          result = new A();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      A result = new A();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override A MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new A();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -211,12 +307,11 @@ namespace UnitTest.Issues.TestProtos {
       }
       
       public override A BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        A returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -230,6 +325,7 @@ namespace UnitTest.Issues.TestProtos {
       
       public override Builder MergeFrom(A other) {
         if (other == global::UnitTest.Issues.TestProtos.A.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasA_) {
           A_ = other.A_;
         }
@@ -242,6 +338,7 @@ namespace UnitTest.Issues.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -297,11 +394,13 @@ namespace UnitTest.Issues.TestProtos {
         set { SetA_(value); }
       }
       public Builder SetA_(int value) {
+        PrepareBuilder();
         result.hasA_ = true;
         result.a_ = value;
         return this;
       }
       public Builder ClearA_() {
+        PrepareBuilder();
         result.hasA_ = false;
         result.a_ = 0;
         return this;
@@ -316,7 +415,8 @@ namespace UnitTest.Issues.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class B : pb::GeneratedMessage<B, B.Builder> {
-    private static readonly B defaultInstance = new Builder().BuildPartial();
+    private B() { }
+    private static readonly B defaultInstance = new B().MakeReadOnly();
     private static readonly string[] _bFieldNames = new string[] { "B_" };
     private static readonly uint[] _bFieldTags = new uint[] { 8 };
     public static B DefaultInstance {
@@ -324,7 +424,7 @@ namespace UnitTest.Issues.TestProtos {
     }
     
     public override B DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override B ThisMessage {
@@ -410,11 +510,15 @@ namespace UnitTest.Issues.TestProtos {
     public static B ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private B MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(B prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -424,21 +528,48 @@ namespace UnitTest.Issues.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(B cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private B result;
+      
+      private B PrepareBuilder() {
+        if (resultIsReadOnly) {
+          B original = result;
+          result = new B();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      B result = new B();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override B MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new B();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -450,12 +581,11 @@ namespace UnitTest.Issues.TestProtos {
       }
       
       public override B BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        B returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -469,6 +599,7 @@ namespace UnitTest.Issues.TestProtos {
       
       public override Builder MergeFrom(B other) {
         if (other == global::UnitTest.Issues.TestProtos.B.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasB_) {
           B_ = other.B_;
         }
@@ -481,6 +612,7 @@ namespace UnitTest.Issues.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -536,11 +668,13 @@ namespace UnitTest.Issues.TestProtos {
         set { SetB_(value); }
       }
       public Builder SetB_(int value) {
+        PrepareBuilder();
         result.hasB_ = true;
         result.b_ = value;
         return this;
       }
       public Builder ClearB_() {
+        PrepareBuilder();
         result.hasB_ = false;
         result.b_ = 0;
         return this;
@@ -555,7 +689,8 @@ namespace UnitTest.Issues.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class AB : pb::GeneratedMessage<AB, AB.Builder> {
-    private static readonly AB defaultInstance = new Builder().BuildPartial();
+    private AB() { }
+    private static readonly AB defaultInstance = new AB().MakeReadOnly();
     private static readonly string[] _aBFieldNames = new string[] { "a_b" };
     private static readonly uint[] _aBFieldTags = new uint[] { 8 };
     public static AB DefaultInstance {
@@ -563,7 +698,7 @@ namespace UnitTest.Issues.TestProtos {
     }
     
     public override AB DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override AB ThisMessage {
@@ -649,11 +784,15 @@ namespace UnitTest.Issues.TestProtos {
     public static AB ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private AB MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(AB prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -663,21 +802,48 @@ namespace UnitTest.Issues.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(AB cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private AB result;
+      
+      private AB PrepareBuilder() {
+        if (resultIsReadOnly) {
+          AB original = result;
+          result = new AB();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      AB result = new AB();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override AB MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new AB();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -689,12 +855,11 @@ namespace UnitTest.Issues.TestProtos {
       }
       
       public override AB BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        AB returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -708,6 +873,7 @@ namespace UnitTest.Issues.TestProtos {
       
       public override Builder MergeFrom(AB other) {
         if (other == global::UnitTest.Issues.TestProtos.AB.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasAB_) {
           AB_ = other.AB_;
         }
@@ -720,6 +886,7 @@ namespace UnitTest.Issues.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -775,11 +942,13 @@ namespace UnitTest.Issues.TestProtos {
         set { SetAB_(value); }
       }
       public Builder SetAB_(int value) {
+        PrepareBuilder();
         result.hasAB_ = true;
         result.aB_ = value;
         return this;
       }
       public Builder ClearAB_() {
+        PrepareBuilder();
         result.hasAB_ = false;
         result.aB_ = 0;
         return this;
@@ -794,7 +963,8 @@ namespace UnitTest.Issues.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class NumberField : pb::GeneratedMessage<NumberField, NumberField.Builder> {
-    private static readonly NumberField defaultInstance = new Builder().BuildPartial();
+    private NumberField() { }
+    private static readonly NumberField defaultInstance = new NumberField().MakeReadOnly();
     private static readonly string[] _numberFieldFieldNames = new string[] { "_01" };
     private static readonly uint[] _numberFieldFieldTags = new uint[] { 8 };
     public static NumberField DefaultInstance {
@@ -802,7 +972,7 @@ namespace UnitTest.Issues.TestProtos {
     }
     
     public override NumberField DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override NumberField ThisMessage {
@@ -890,11 +1060,15 @@ namespace UnitTest.Issues.TestProtos {
     public static NumberField ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private NumberField MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(NumberField prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -904,21 +1078,48 @@ namespace UnitTest.Issues.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(NumberField cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private NumberField result;
+      
+      private NumberField PrepareBuilder() {
+        if (resultIsReadOnly) {
+          NumberField original = result;
+          result = new NumberField();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      NumberField result = new NumberField();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override NumberField MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new NumberField();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -930,12 +1131,11 @@ namespace UnitTest.Issues.TestProtos {
       }
       
       public override NumberField BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        NumberField returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -949,6 +1149,7 @@ namespace UnitTest.Issues.TestProtos {
       
       public override Builder MergeFrom(NumberField other) {
         if (other == global::UnitTest.Issues.TestProtos.NumberField.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.Has_01) {
           _01 = other._01;
         }
@@ -961,6 +1162,7 @@ namespace UnitTest.Issues.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -1018,11 +1220,13 @@ namespace UnitTest.Issues.TestProtos {
       }
       [global::System.CLSCompliant(false)]
       public Builder Set_01(int value) {
+        PrepareBuilder();
         result.has_01 = true;
         result._01_ = value;
         return this;
       }
       public Builder Clear_01() {
+        PrepareBuilder();
         result.has_01 = false;
         result._01_ = 0;
         return this;
@@ -1033,6 +1237,1920 @@ namespace UnitTest.Issues.TestProtos {
     }
   }
   
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+  public sealed partial class MyMessageAReferenceB : pb::GeneratedMessage<MyMessageAReferenceB, MyMessageAReferenceB.Builder> {
+    private MyMessageAReferenceB() { }
+    private static readonly MyMessageAReferenceB defaultInstance = new MyMessageAReferenceB().MakeReadOnly();
+    private static readonly string[] _myMessageAReferenceBFieldNames = new string[] { "value" };
+    private static readonly uint[] _myMessageAReferenceBFieldTags = new uint[] { 10 };
+    public static MyMessageAReferenceB DefaultInstance {
+      get { return defaultInstance; }
+    }
+    
+    public override MyMessageAReferenceB DefaultInstanceForType {
+      get { return DefaultInstance; }
+    }
+    
+    protected override MyMessageAReferenceB ThisMessage {
+      get { return this; }
+    }
+    
+    public static pbd::MessageDescriptor Descriptor {
+      get { return global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.internal__static_unittest_issues_MyMessageAReferenceB__Descriptor; }
+    }
+    
+    protected override pb::FieldAccess.FieldAccessorTable<MyMessageAReferenceB, MyMessageAReferenceB.Builder> InternalFieldAccessors {
+      get { return global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.internal__static_unittest_issues_MyMessageAReferenceB__FieldAccessorTable; }
+    }
+    
+    public const int ValueFieldNumber = 1;
+    private bool hasValue;
+    private global::UnitTest.Issues.TestProtos.MyMessageBReferenceA value_;
+    public bool HasValue {
+      get { return hasValue; }
+    }
+    public global::UnitTest.Issues.TestProtos.MyMessageBReferenceA Value {
+      get { return value_ ?? global::UnitTest.Issues.TestProtos.MyMessageBReferenceA.DefaultInstance; }
+    }
+    
+    public override bool IsInitialized {
+      get {
+        if (!hasValue) return false;
+        if (!Value.IsInitialized) return false;
+        return true;
+      }
+    }
+    
+    public override void WriteTo(pb::ICodedOutputStream output) {
+      int size = SerializedSize;
+      string[] field_names = _myMessageAReferenceBFieldNames;
+      if (hasValue) {
+        output.WriteMessage(1, field_names[0], Value);
+      }
+      UnknownFields.WriteTo(output);
+    }
+    
+    private int memoizedSerializedSize = -1;
+    public override int SerializedSize {
+      get {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+        
+        size = 0;
+        if (hasValue) {
+          size += pb::CodedOutputStream.ComputeMessageSize(1, Value);
+        }
+        size += UnknownFields.SerializedSize;
+        memoizedSerializedSize = size;
+        return size;
+      }
+    }
+    
+    public static MyMessageAReferenceB ParseFrom(pb::ByteString data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static MyMessageAReferenceB ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static MyMessageAReferenceB ParseFrom(byte[] data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static MyMessageAReferenceB ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static MyMessageAReferenceB ParseFrom(global::System.IO.Stream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static MyMessageAReferenceB ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static MyMessageAReferenceB ParseDelimitedFrom(global::System.IO.Stream input) {
+      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+    }
+    public static MyMessageAReferenceB ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+    }
+    public static MyMessageAReferenceB ParseFrom(pb::ICodedInputStream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static MyMessageAReferenceB ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    private MyMessageAReferenceB MakeReadOnly() {
+      return this;
+    }
+    
+    public static Builder CreateBuilder() { return new Builder(); }
+    public override Builder ToBuilder() { return CreateBuilder(this); }
+    public override Builder CreateBuilderForType() { return new Builder(); }
+    public static Builder CreateBuilder(MyMessageAReferenceB prototype) {
+      return new Builder(prototype);
+    }
+    
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+    public sealed partial class Builder : pb::GeneratedBuilder<MyMessageAReferenceB, Builder> {
+      protected override Builder ThisBuilder {
+        get { return this; }
+      }
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(MyMessageAReferenceB cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private MyMessageAReferenceB result;
+      
+      private MyMessageAReferenceB PrepareBuilder() {
+        if (resultIsReadOnly) {
+          MyMessageAReferenceB original = result;
+          result = new MyMessageAReferenceB();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
+      
+      protected override MyMessageAReferenceB MessageBeingBuilt {
+        get { return PrepareBuilder(); }
+      }
+      
+      public override Builder Clear() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+        return this;
+      }
+      
+      public override Builder Clone() {
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
+      }
+      
+      public override pbd::MessageDescriptor DescriptorForType {
+        get { return global::UnitTest.Issues.TestProtos.MyMessageAReferenceB.Descriptor; }
+      }
+      
+      public override MyMessageAReferenceB DefaultInstanceForType {
+        get { return global::UnitTest.Issues.TestProtos.MyMessageAReferenceB.DefaultInstance; }
+      }
+      
+      public override MyMessageAReferenceB BuildPartial() {
+        if (resultIsReadOnly) {
+          return result;
+        }
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
+      }
+      
+      public override Builder MergeFrom(pb::IMessage other) {
+        if (other is MyMessageAReferenceB) {
+          return MergeFrom((MyMessageAReferenceB) other);
+        } else {
+          base.MergeFrom(other);
+          return this;
+        }
+      }
+      
+      public override Builder MergeFrom(MyMessageAReferenceB other) {
+        if (other == global::UnitTest.Issues.TestProtos.MyMessageAReferenceB.DefaultInstance) return this;
+        PrepareBuilder();
+        if (other.HasValue) {
+          MergeValue(other.Value);
+        }
+        this.MergeUnknownFields(other.UnknownFields);
+        return this;
+      }
+      
+      public override Builder MergeFrom(pb::ICodedInputStream input) {
+        return MergeFrom(input, pb::ExtensionRegistry.Empty);
+      }
+      
+      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
+        pb::UnknownFieldSet.Builder unknownFields = null;
+        uint tag;
+        string field_name;
+        while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_myMessageAReferenceBFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _myMessageAReferenceBFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
+          switch (tag) {
+            case 0: {
+              throw pb::InvalidProtocolBufferException.InvalidTag();
+            }
+            default: {
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
+                return this;
+              }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              break;
+            }
+            case 10: {
+              global::UnitTest.Issues.TestProtos.MyMessageBReferenceA.Builder subBuilder = global::UnitTest.Issues.TestProtos.MyMessageBReferenceA.CreateBuilder();
+              if (result.hasValue) {
+                subBuilder.MergeFrom(Value);
+              }
+              input.ReadMessage(subBuilder, extensionRegistry);
+              Value = subBuilder.BuildPartial();
+              break;
+            }
+          }
+        }
+        
+        if (unknownFields != null) {
+          this.UnknownFields = unknownFields.Build();
+        }
+        return this;
+      }
+      
+      
+      public bool HasValue {
+       get { return result.hasValue; }
+      }
+      public global::UnitTest.Issues.TestProtos.MyMessageBReferenceA Value {
+        get { return result.Value; }
+        set { SetValue(value); }
+      }
+      public Builder SetValue(global::UnitTest.Issues.TestProtos.MyMessageBReferenceA value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        result.hasValue = true;
+        result.value_ = value;
+        return this;
+      }
+      public Builder SetValue(global::UnitTest.Issues.TestProtos.MyMessageBReferenceA.Builder builderForValue) {
+        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
+        result.hasValue = true;
+        result.value_ = builderForValue.Build();
+        return this;
+      }
+      public Builder MergeValue(global::UnitTest.Issues.TestProtos.MyMessageBReferenceA value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        if (result.hasValue &&
+            result.value_ != global::UnitTest.Issues.TestProtos.MyMessageBReferenceA.DefaultInstance) {
+            result.value_ = global::UnitTest.Issues.TestProtos.MyMessageBReferenceA.CreateBuilder(result.value_).MergeFrom(value).BuildPartial();
+        } else {
+          result.value_ = value;
+        }
+        result.hasValue = true;
+        return this;
+      }
+      public Builder ClearValue() {
+        PrepareBuilder();
+        result.hasValue = false;
+        result.value_ = null;
+        return this;
+      }
+    }
+    static MyMessageAReferenceB() {
+      object.ReferenceEquals(global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.Descriptor, null);
+    }
+  }
+  
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+  public sealed partial class MyMessageBReferenceA : pb::GeneratedMessage<MyMessageBReferenceA, MyMessageBReferenceA.Builder> {
+    private MyMessageBReferenceA() { }
+    private static readonly MyMessageBReferenceA defaultInstance = new MyMessageBReferenceA().MakeReadOnly();
+    private static readonly string[] _myMessageBReferenceAFieldNames = new string[] { "value" };
+    private static readonly uint[] _myMessageBReferenceAFieldTags = new uint[] { 10 };
+    public static MyMessageBReferenceA DefaultInstance {
+      get { return defaultInstance; }
+    }
+    
+    public override MyMessageBReferenceA DefaultInstanceForType {
+      get { return DefaultInstance; }
+    }
+    
+    protected override MyMessageBReferenceA ThisMessage {
+      get { return this; }
+    }
+    
+    public static pbd::MessageDescriptor Descriptor {
+      get { return global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.internal__static_unittest_issues_MyMessageBReferenceA__Descriptor; }
+    }
+    
+    protected override pb::FieldAccess.FieldAccessorTable<MyMessageBReferenceA, MyMessageBReferenceA.Builder> InternalFieldAccessors {
+      get { return global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.internal__static_unittest_issues_MyMessageBReferenceA__FieldAccessorTable; }
+    }
+    
+    public const int ValueFieldNumber = 1;
+    private bool hasValue;
+    private global::UnitTest.Issues.TestProtos.MyMessageAReferenceB value_;
+    public bool HasValue {
+      get { return hasValue; }
+    }
+    public global::UnitTest.Issues.TestProtos.MyMessageAReferenceB Value {
+      get { return value_ ?? global::UnitTest.Issues.TestProtos.MyMessageAReferenceB.DefaultInstance; }
+    }
+    
+    public override bool IsInitialized {
+      get {
+        if (!hasValue) return false;
+        if (!Value.IsInitialized) return false;
+        return true;
+      }
+    }
+    
+    public override void WriteTo(pb::ICodedOutputStream output) {
+      int size = SerializedSize;
+      string[] field_names = _myMessageBReferenceAFieldNames;
+      if (hasValue) {
+        output.WriteMessage(1, field_names[0], Value);
+      }
+      UnknownFields.WriteTo(output);
+    }
+    
+    private int memoizedSerializedSize = -1;
+    public override int SerializedSize {
+      get {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+        
+        size = 0;
+        if (hasValue) {
+          size += pb::CodedOutputStream.ComputeMessageSize(1, Value);
+        }
+        size += UnknownFields.SerializedSize;
+        memoizedSerializedSize = size;
+        return size;
+      }
+    }
+    
+    public static MyMessageBReferenceA ParseFrom(pb::ByteString data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static MyMessageBReferenceA ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static MyMessageBReferenceA ParseFrom(byte[] data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static MyMessageBReferenceA ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static MyMessageBReferenceA ParseFrom(global::System.IO.Stream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static MyMessageBReferenceA ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static MyMessageBReferenceA ParseDelimitedFrom(global::System.IO.Stream input) {
+      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+    }
+    public static MyMessageBReferenceA ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+    }
+    public static MyMessageBReferenceA ParseFrom(pb::ICodedInputStream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static MyMessageBReferenceA ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    private MyMessageBReferenceA MakeReadOnly() {
+      return this;
+    }
+    
+    public static Builder CreateBuilder() { return new Builder(); }
+    public override Builder ToBuilder() { return CreateBuilder(this); }
+    public override Builder CreateBuilderForType() { return new Builder(); }
+    public static Builder CreateBuilder(MyMessageBReferenceA prototype) {
+      return new Builder(prototype);
+    }
+    
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+    public sealed partial class Builder : pb::GeneratedBuilder<MyMessageBReferenceA, Builder> {
+      protected override Builder ThisBuilder {
+        get { return this; }
+      }
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(MyMessageBReferenceA cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private MyMessageBReferenceA result;
+      
+      private MyMessageBReferenceA PrepareBuilder() {
+        if (resultIsReadOnly) {
+          MyMessageBReferenceA original = result;
+          result = new MyMessageBReferenceA();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
+      
+      protected override MyMessageBReferenceA MessageBeingBuilt {
+        get { return PrepareBuilder(); }
+      }
+      
+      public override Builder Clear() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+        return this;
+      }
+      
+      public override Builder Clone() {
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
+      }
+      
+      public override pbd::MessageDescriptor DescriptorForType {
+        get { return global::UnitTest.Issues.TestProtos.MyMessageBReferenceA.Descriptor; }
+      }
+      
+      public override MyMessageBReferenceA DefaultInstanceForType {
+        get { return global::UnitTest.Issues.TestProtos.MyMessageBReferenceA.DefaultInstance; }
+      }
+      
+      public override MyMessageBReferenceA BuildPartial() {
+        if (resultIsReadOnly) {
+          return result;
+        }
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
+      }
+      
+      public override Builder MergeFrom(pb::IMessage other) {
+        if (other is MyMessageBReferenceA) {
+          return MergeFrom((MyMessageBReferenceA) other);
+        } else {
+          base.MergeFrom(other);
+          return this;
+        }
+      }
+      
+      public override Builder MergeFrom(MyMessageBReferenceA other) {
+        if (other == global::UnitTest.Issues.TestProtos.MyMessageBReferenceA.DefaultInstance) return this;
+        PrepareBuilder();
+        if (other.HasValue) {
+          MergeValue(other.Value);
+        }
+        this.MergeUnknownFields(other.UnknownFields);
+        return this;
+      }
+      
+      public override Builder MergeFrom(pb::ICodedInputStream input) {
+        return MergeFrom(input, pb::ExtensionRegistry.Empty);
+      }
+      
+      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
+        pb::UnknownFieldSet.Builder unknownFields = null;
+        uint tag;
+        string field_name;
+        while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_myMessageBReferenceAFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _myMessageBReferenceAFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
+          switch (tag) {
+            case 0: {
+              throw pb::InvalidProtocolBufferException.InvalidTag();
+            }
+            default: {
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
+                return this;
+              }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              break;
+            }
+            case 10: {
+              global::UnitTest.Issues.TestProtos.MyMessageAReferenceB.Builder subBuilder = global::UnitTest.Issues.TestProtos.MyMessageAReferenceB.CreateBuilder();
+              if (result.hasValue) {
+                subBuilder.MergeFrom(Value);
+              }
+              input.ReadMessage(subBuilder, extensionRegistry);
+              Value = subBuilder.BuildPartial();
+              break;
+            }
+          }
+        }
+        
+        if (unknownFields != null) {
+          this.UnknownFields = unknownFields.Build();
+        }
+        return this;
+      }
+      
+      
+      public bool HasValue {
+       get { return result.hasValue; }
+      }
+      public global::UnitTest.Issues.TestProtos.MyMessageAReferenceB Value {
+        get { return result.Value; }
+        set { SetValue(value); }
+      }
+      public Builder SetValue(global::UnitTest.Issues.TestProtos.MyMessageAReferenceB value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        result.hasValue = true;
+        result.value_ = value;
+        return this;
+      }
+      public Builder SetValue(global::UnitTest.Issues.TestProtos.MyMessageAReferenceB.Builder builderForValue) {
+        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
+        result.hasValue = true;
+        result.value_ = builderForValue.Build();
+        return this;
+      }
+      public Builder MergeValue(global::UnitTest.Issues.TestProtos.MyMessageAReferenceB value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        if (result.hasValue &&
+            result.value_ != global::UnitTest.Issues.TestProtos.MyMessageAReferenceB.DefaultInstance) {
+            result.value_ = global::UnitTest.Issues.TestProtos.MyMessageAReferenceB.CreateBuilder(result.value_).MergeFrom(value).BuildPartial();
+        } else {
+          result.value_ = value;
+        }
+        result.hasValue = true;
+        return this;
+      }
+      public Builder ClearValue() {
+        PrepareBuilder();
+        result.hasValue = false;
+        result.value_ = null;
+        return this;
+      }
+    }
+    static MyMessageBReferenceA() {
+      object.ReferenceEquals(global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.Descriptor, null);
+    }
+  }
+  
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+  public sealed partial class NegativeEnumMessage : pb::GeneratedMessage<NegativeEnumMessage, NegativeEnumMessage.Builder> {
+    private NegativeEnumMessage() { }
+    private static readonly NegativeEnumMessage defaultInstance = new NegativeEnumMessage().MakeReadOnly();
+    private static readonly string[] _negativeEnumMessageFieldNames = new string[] { "packed_values", "value", "values" };
+    private static readonly uint[] _negativeEnumMessageFieldTags = new uint[] { 26, 8, 16 };
+    public static NegativeEnumMessage DefaultInstance {
+      get { return defaultInstance; }
+    }
+    
+    public override NegativeEnumMessage DefaultInstanceForType {
+      get { return DefaultInstance; }
+    }
+    
+    protected override NegativeEnumMessage ThisMessage {
+      get { return this; }
+    }
+    
+    public static pbd::MessageDescriptor Descriptor {
+      get { return global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.internal__static_unittest_issues_NegativeEnumMessage__Descriptor; }
+    }
+    
+    protected override pb::FieldAccess.FieldAccessorTable<NegativeEnumMessage, NegativeEnumMessage.Builder> InternalFieldAccessors {
+      get { return global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.internal__static_unittest_issues_NegativeEnumMessage__FieldAccessorTable; }
+    }
+    
+    public const int ValueFieldNumber = 1;
+    private bool hasValue;
+    private global::UnitTest.Issues.TestProtos.NegativeEnum value_ = global::UnitTest.Issues.TestProtos.NegativeEnum.FiveBelow;
+    public bool HasValue {
+      get { return hasValue; }
+    }
+    public global::UnitTest.Issues.TestProtos.NegativeEnum Value {
+      get { return value_; }
+    }
+    
+    public const int ValuesFieldNumber = 2;
+    private pbc::PopsicleList<global::UnitTest.Issues.TestProtos.NegativeEnum> values_ = new pbc::PopsicleList<global::UnitTest.Issues.TestProtos.NegativeEnum>();
+    public scg::IList<global::UnitTest.Issues.TestProtos.NegativeEnum> ValuesList {
+      get { return pbc::Lists.AsReadOnly(values_); }
+    }
+    public int ValuesCount {
+      get { return values_.Count; }
+    }
+    public global::UnitTest.Issues.TestProtos.NegativeEnum GetValues(int index) {
+      return values_[index];
+    }
+    
+    public const int PackedValuesFieldNumber = 3;
+    private int packedValuesMemoizedSerializedSize;
+    private pbc::PopsicleList<global::UnitTest.Issues.TestProtos.NegativeEnum> packedValues_ = new pbc::PopsicleList<global::UnitTest.Issues.TestProtos.NegativeEnum>();
+    public scg::IList<global::UnitTest.Issues.TestProtos.NegativeEnum> PackedValuesList {
+      get { return pbc::Lists.AsReadOnly(packedValues_); }
+    }
+    public int PackedValuesCount {
+      get { return packedValues_.Count; }
+    }
+    public global::UnitTest.Issues.TestProtos.NegativeEnum GetPackedValues(int index) {
+      return packedValues_[index];
+    }
+    
+    public override bool IsInitialized {
+      get {
+        return true;
+      }
+    }
+    
+    public override void WriteTo(pb::ICodedOutputStream output) {
+      int size = SerializedSize;
+      string[] field_names = _negativeEnumMessageFieldNames;
+      if (hasValue) {
+        output.WriteEnum(1, field_names[1], (int) Value, Value);
+      }
+      if (values_.Count > 0) {
+        output.WriteEnumArray(2, field_names[2], values_);
+      }
+      if (packedValues_.Count > 0) {
+        output.WritePackedEnumArray(3, field_names[0], packedValuesMemoizedSerializedSize, packedValues_);
+      }
+      UnknownFields.WriteTo(output);
+    }
+    
+    private int memoizedSerializedSize = -1;
+    public override int SerializedSize {
+      get {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+        
+        size = 0;
+        if (hasValue) {
+          size += pb::CodedOutputStream.ComputeEnumSize(1, (int) Value);
+        }
+        {
+          int dataSize = 0;
+          if (values_.Count > 0) {
+            foreach (global::UnitTest.Issues.TestProtos.NegativeEnum element in values_) {
+              dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);
+            }
+            size += dataSize;
+            size += 1 * values_.Count;
+          }
+        }
+        {
+          int dataSize = 0;
+          if (packedValues_.Count > 0) {
+            foreach (global::UnitTest.Issues.TestProtos.NegativeEnum element in packedValues_) {
+              dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);
+            }
+            size += dataSize;
+            size += 1;
+            size += pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);
+          }
+          packedValuesMemoizedSerializedSize = dataSize;
+        }
+        size += UnknownFields.SerializedSize;
+        memoizedSerializedSize = size;
+        return size;
+      }
+    }
+    
+    public static NegativeEnumMessage ParseFrom(pb::ByteString data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static NegativeEnumMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static NegativeEnumMessage ParseFrom(byte[] data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static NegativeEnumMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static NegativeEnumMessage ParseFrom(global::System.IO.Stream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static NegativeEnumMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static NegativeEnumMessage ParseDelimitedFrom(global::System.IO.Stream input) {
+      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+    }
+    public static NegativeEnumMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+    }
+    public static NegativeEnumMessage ParseFrom(pb::ICodedInputStream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static NegativeEnumMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    private NegativeEnumMessage MakeReadOnly() {
+      values_.MakeReadOnly();
+      packedValues_.MakeReadOnly();
+      return this;
+    }
+    
+    public static Builder CreateBuilder() { return new Builder(); }
+    public override Builder ToBuilder() { return CreateBuilder(this); }
+    public override Builder CreateBuilderForType() { return new Builder(); }
+    public static Builder CreateBuilder(NegativeEnumMessage prototype) {
+      return new Builder(prototype);
+    }
+    
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+    public sealed partial class Builder : pb::GeneratedBuilder<NegativeEnumMessage, Builder> {
+      protected override Builder ThisBuilder {
+        get { return this; }
+      }
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(NegativeEnumMessage cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private NegativeEnumMessage result;
+      
+      private NegativeEnumMessage PrepareBuilder() {
+        if (resultIsReadOnly) {
+          NegativeEnumMessage original = result;
+          result = new NegativeEnumMessage();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
+      
+      protected override NegativeEnumMessage MessageBeingBuilt {
+        get { return PrepareBuilder(); }
+      }
+      
+      public override Builder Clear() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+        return this;
+      }
+      
+      public override Builder Clone() {
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
+      }
+      
+      public override pbd::MessageDescriptor DescriptorForType {
+        get { return global::UnitTest.Issues.TestProtos.NegativeEnumMessage.Descriptor; }
+      }
+      
+      public override NegativeEnumMessage DefaultInstanceForType {
+        get { return global::UnitTest.Issues.TestProtos.NegativeEnumMessage.DefaultInstance; }
+      }
+      
+      public override NegativeEnumMessage BuildPartial() {
+        if (resultIsReadOnly) {
+          return result;
+        }
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
+      }
+      
+      public override Builder MergeFrom(pb::IMessage other) {
+        if (other is NegativeEnumMessage) {
+          return MergeFrom((NegativeEnumMessage) other);
+        } else {
+          base.MergeFrom(other);
+          return this;
+        }
+      }
+      
+      public override Builder MergeFrom(NegativeEnumMessage other) {
+        if (other == global::UnitTest.Issues.TestProtos.NegativeEnumMessage.DefaultInstance) return this;
+        PrepareBuilder();
+        if (other.HasValue) {
+          Value = other.Value;
+        }
+        if (other.values_.Count != 0) {
+          result.values_.Add(other.values_);
+        }
+        if (other.packedValues_.Count != 0) {
+          result.packedValues_.Add(other.packedValues_);
+        }
+        this.MergeUnknownFields(other.UnknownFields);
+        return this;
+      }
+      
+      public override Builder MergeFrom(pb::ICodedInputStream input) {
+        return MergeFrom(input, pb::ExtensionRegistry.Empty);
+      }
+      
+      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
+        pb::UnknownFieldSet.Builder unknownFields = null;
+        uint tag;
+        string field_name;
+        while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_negativeEnumMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _negativeEnumMessageFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
+          switch (tag) {
+            case 0: {
+              throw pb::InvalidProtocolBufferException.InvalidTag();
+            }
+            default: {
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
+                return this;
+              }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              break;
+            }
+            case 8: {
+              object unknown;
+              if(input.ReadEnum(ref result.value_, out unknown)) {
+                result.hasValue = true;
+              } else if(unknown is int) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
+                unknownFields.MergeVarintField(1, (ulong)(int)unknown);
+              }
+              break;
+            }
+            case 18:
+            case 16: {
+              scg::ICollection<object> unknownItems;
+              input.ReadEnumArray<global::UnitTest.Issues.TestProtos.NegativeEnum>(tag, field_name, result.values_, out unknownItems);
+              if (unknownItems != null) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
+                foreach (object rawValue in unknownItems)
+                  if (rawValue is int)
+                    unknownFields.MergeVarintField(2, (ulong)(int)rawValue);
+              }
+              break;
+            }
+            case 26:
+            case 24: {
+              scg::ICollection<object> unknownItems;
+              input.ReadEnumArray<global::UnitTest.Issues.TestProtos.NegativeEnum>(tag, field_name, result.packedValues_, out unknownItems);
+              if (unknownItems != null) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
+                foreach (object rawValue in unknownItems)
+                  if (rawValue is int)
+                    unknownFields.MergeVarintField(3, (ulong)(int)rawValue);
+              }
+              break;
+            }
+          }
+        }
+        
+        if (unknownFields != null) {
+          this.UnknownFields = unknownFields.Build();
+        }
+        return this;
+      }
+      
+      
+      public bool HasValue {
+       get { return result.hasValue; }
+      }
+      public global::UnitTest.Issues.TestProtos.NegativeEnum Value {
+        get { return result.Value; }
+        set { SetValue(value); }
+      }
+      public Builder SetValue(global::UnitTest.Issues.TestProtos.NegativeEnum value) {
+        PrepareBuilder();
+        result.hasValue = true;
+        result.value_ = value;
+        return this;
+      }
+      public Builder ClearValue() {
+        PrepareBuilder();
+        result.hasValue = false;
+        result.value_ = global::UnitTest.Issues.TestProtos.NegativeEnum.FiveBelow;
+        return this;
+      }
+      
+      public pbc::IPopsicleList<global::UnitTest.Issues.TestProtos.NegativeEnum> ValuesList {
+        get { return PrepareBuilder().values_; }
+      }
+      public int ValuesCount {
+        get { return result.ValuesCount; }
+      }
+      public global::UnitTest.Issues.TestProtos.NegativeEnum GetValues(int index) {
+        return result.GetValues(index);
+      }
+      public Builder SetValues(int index, global::UnitTest.Issues.TestProtos.NegativeEnum value) {
+        PrepareBuilder();
+        result.values_[index] = value;
+        return this;
+      }
+      public Builder AddValues(global::UnitTest.Issues.TestProtos.NegativeEnum value) {
+        PrepareBuilder();
+        result.values_.Add(value);
+        return this;
+      }
+      public Builder AddRangeValues(scg::IEnumerable<global::UnitTest.Issues.TestProtos.NegativeEnum> values) {
+        PrepareBuilder();
+        result.values_.Add(values);
+        return this;
+      }
+      public Builder ClearValues() {
+        PrepareBuilder();
+        result.values_.Clear();
+        return this;
+      }
+      
+      public pbc::IPopsicleList<global::UnitTest.Issues.TestProtos.NegativeEnum> PackedValuesList {
+        get { return PrepareBuilder().packedValues_; }
+      }
+      public int PackedValuesCount {
+        get { return result.PackedValuesCount; }
+      }
+      public global::UnitTest.Issues.TestProtos.NegativeEnum GetPackedValues(int index) {
+        return result.GetPackedValues(index);
+      }
+      public Builder SetPackedValues(int index, global::UnitTest.Issues.TestProtos.NegativeEnum value) {
+        PrepareBuilder();
+        result.packedValues_[index] = value;
+        return this;
+      }
+      public Builder AddPackedValues(global::UnitTest.Issues.TestProtos.NegativeEnum value) {
+        PrepareBuilder();
+        result.packedValues_.Add(value);
+        return this;
+      }
+      public Builder AddRangePackedValues(scg::IEnumerable<global::UnitTest.Issues.TestProtos.NegativeEnum> values) {
+        PrepareBuilder();
+        result.packedValues_.Add(values);
+        return this;
+      }
+      public Builder ClearPackedValues() {
+        PrepareBuilder();
+        result.packedValues_.Clear();
+        return this;
+      }
+    }
+    static NegativeEnumMessage() {
+      object.ReferenceEquals(global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.Descriptor, null);
+    }
+  }
+  
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+  public sealed partial class DeprecatedChild : pb::GeneratedMessage<DeprecatedChild, DeprecatedChild.Builder> {
+    private DeprecatedChild() { }
+    private static readonly DeprecatedChild defaultInstance = new DeprecatedChild().MakeReadOnly();
+    private static readonly string[] _deprecatedChildFieldNames = new string[] {  };
+    private static readonly uint[] _deprecatedChildFieldTags = new uint[] {  };
+    public static DeprecatedChild DefaultInstance {
+      get { return defaultInstance; }
+    }
+    
+    public override DeprecatedChild DefaultInstanceForType {
+      get { return DefaultInstance; }
+    }
+    
+    protected override DeprecatedChild ThisMessage {
+      get { return this; }
+    }
+    
+    public static pbd::MessageDescriptor Descriptor {
+      get { return global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.internal__static_unittest_issues_DeprecatedChild__Descriptor; }
+    }
+    
+    protected override pb::FieldAccess.FieldAccessorTable<DeprecatedChild, DeprecatedChild.Builder> InternalFieldAccessors {
+      get { return global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.internal__static_unittest_issues_DeprecatedChild__FieldAccessorTable; }
+    }
+    
+    public override bool IsInitialized {
+      get {
+        return true;
+      }
+    }
+    
+    public override void WriteTo(pb::ICodedOutputStream output) {
+      int size = SerializedSize;
+      string[] field_names = _deprecatedChildFieldNames;
+      UnknownFields.WriteTo(output);
+    }
+    
+    private int memoizedSerializedSize = -1;
+    public override int SerializedSize {
+      get {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+        
+        size = 0;
+        size += UnknownFields.SerializedSize;
+        memoizedSerializedSize = size;
+        return size;
+      }
+    }
+    
+    public static DeprecatedChild ParseFrom(pb::ByteString data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static DeprecatedChild ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static DeprecatedChild ParseFrom(byte[] data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static DeprecatedChild ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static DeprecatedChild ParseFrom(global::System.IO.Stream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static DeprecatedChild ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static DeprecatedChild ParseDelimitedFrom(global::System.IO.Stream input) {
+      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+    }
+    public static DeprecatedChild ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+    }
+    public static DeprecatedChild ParseFrom(pb::ICodedInputStream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static DeprecatedChild ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    private DeprecatedChild MakeReadOnly() {
+      return this;
+    }
+    
+    public static Builder CreateBuilder() { return new Builder(); }
+    public override Builder ToBuilder() { return CreateBuilder(this); }
+    public override Builder CreateBuilderForType() { return new Builder(); }
+    public static Builder CreateBuilder(DeprecatedChild prototype) {
+      return new Builder(prototype);
+    }
+    
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+    public sealed partial class Builder : pb::GeneratedBuilder<DeprecatedChild, Builder> {
+      protected override Builder ThisBuilder {
+        get { return this; }
+      }
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(DeprecatedChild cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private DeprecatedChild result;
+      
+      private DeprecatedChild PrepareBuilder() {
+        if (resultIsReadOnly) {
+          DeprecatedChild original = result;
+          result = new DeprecatedChild();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
+      
+      protected override DeprecatedChild MessageBeingBuilt {
+        get { return PrepareBuilder(); }
+      }
+      
+      public override Builder Clear() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+        return this;
+      }
+      
+      public override Builder Clone() {
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
+      }
+      
+      public override pbd::MessageDescriptor DescriptorForType {
+        get { return global::UnitTest.Issues.TestProtos.DeprecatedChild.Descriptor; }
+      }
+      
+      public override DeprecatedChild DefaultInstanceForType {
+        get { return global::UnitTest.Issues.TestProtos.DeprecatedChild.DefaultInstance; }
+      }
+      
+      public override DeprecatedChild BuildPartial() {
+        if (resultIsReadOnly) {
+          return result;
+        }
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
+      }
+      
+      public override Builder MergeFrom(pb::IMessage other) {
+        if (other is DeprecatedChild) {
+          return MergeFrom((DeprecatedChild) other);
+        } else {
+          base.MergeFrom(other);
+          return this;
+        }
+      }
+      
+      public override Builder MergeFrom(DeprecatedChild other) {
+        if (other == global::UnitTest.Issues.TestProtos.DeprecatedChild.DefaultInstance) return this;
+        PrepareBuilder();
+        this.MergeUnknownFields(other.UnknownFields);
+        return this;
+      }
+      
+      public override Builder MergeFrom(pb::ICodedInputStream input) {
+        return MergeFrom(input, pb::ExtensionRegistry.Empty);
+      }
+      
+      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
+        pb::UnknownFieldSet.Builder unknownFields = null;
+        uint tag;
+        string field_name;
+        while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_deprecatedChildFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _deprecatedChildFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
+          switch (tag) {
+            case 0: {
+              throw pb::InvalidProtocolBufferException.InvalidTag();
+            }
+            default: {
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
+                return this;
+              }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              break;
+            }
+          }
+        }
+        
+        if (unknownFields != null) {
+          this.UnknownFields = unknownFields.Build();
+        }
+        return this;
+      }
+      
+    }
+    static DeprecatedChild() {
+      object.ReferenceEquals(global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.Descriptor, null);
+    }
+  }
+  
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+  public sealed partial class DeprecatedFieldsMessage : pb::GeneratedMessage<DeprecatedFieldsMessage, DeprecatedFieldsMessage.Builder> {
+    private DeprecatedFieldsMessage() { }
+    private static readonly DeprecatedFieldsMessage defaultInstance = new DeprecatedFieldsMessage().MakeReadOnly();
+    private static readonly string[] _deprecatedFieldsMessageFieldNames = new string[] { "EnumArray", "EnumValue", "MessageArray", "MessageValue", "PrimitiveArray", "PrimitiveValue" };
+    private static readonly uint[] _deprecatedFieldsMessageFieldTags = new uint[] { 48, 40, 34, 26, 16, 8 };
+    public static DeprecatedFieldsMessage DefaultInstance {
+      get { return defaultInstance; }
+    }
+    
+    public override DeprecatedFieldsMessage DefaultInstanceForType {
+      get { return DefaultInstance; }
+    }
+    
+    protected override DeprecatedFieldsMessage ThisMessage {
+      get { return this; }
+    }
+    
+    public static pbd::MessageDescriptor Descriptor {
+      get { return global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.internal__static_unittest_issues_DeprecatedFieldsMessage__Descriptor; }
+    }
+    
+    protected override pb::FieldAccess.FieldAccessorTable<DeprecatedFieldsMessage, DeprecatedFieldsMessage.Builder> InternalFieldAccessors {
+      get { return global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.internal__static_unittest_issues_DeprecatedFieldsMessage__FieldAccessorTable; }
+    }
+    
+    public const int PrimitiveValueFieldNumber = 1;
+    private bool hasPrimitiveValue;
+    private int primitiveValue_;
+    [global::System.ObsoleteAttribute()]
+    public bool HasPrimitiveValue {
+      get { return hasPrimitiveValue; }
+    }
+    [global::System.ObsoleteAttribute()]
+    public int PrimitiveValue {
+      get { return primitiveValue_; }
+    }
+    
+    public const int PrimitiveArrayFieldNumber = 2;
+    private pbc::PopsicleList<int> primitiveArray_ = new pbc::PopsicleList<int>();
+    [global::System.ObsoleteAttribute()]
+    public scg::IList<int> PrimitiveArrayList {
+      get { return pbc::Lists.AsReadOnly(primitiveArray_); }
+    }
+    [global::System.ObsoleteAttribute()]
+    public int PrimitiveArrayCount {
+      get { return primitiveArray_.Count; }
+    }
+    [global::System.ObsoleteAttribute()]
+    public int GetPrimitiveArray(int index) {
+      return primitiveArray_[index];
+    }
+    
+    public const int MessageValueFieldNumber = 3;
+    private bool hasMessageValue;
+    private global::UnitTest.Issues.TestProtos.DeprecatedChild messageValue_;
+    [global::System.ObsoleteAttribute()]
+    public bool HasMessageValue {
+      get { return hasMessageValue; }
+    }
+    [global::System.ObsoleteAttribute()]
+    public global::UnitTest.Issues.TestProtos.DeprecatedChild MessageValue {
+      get { return messageValue_ ?? global::UnitTest.Issues.TestProtos.DeprecatedChild.DefaultInstance; }
+    }
+    
+    public const int MessageArrayFieldNumber = 4;
+    private pbc::PopsicleList<global::UnitTest.Issues.TestProtos.DeprecatedChild> messageArray_ = new pbc::PopsicleList<global::UnitTest.Issues.TestProtos.DeprecatedChild>();
+    [global::System.ObsoleteAttribute()]
+    public scg::IList<global::UnitTest.Issues.TestProtos.DeprecatedChild> MessageArrayList {
+      get { return messageArray_; }
+    }
+    [global::System.ObsoleteAttribute()]
+    public int MessageArrayCount {
+      get { return messageArray_.Count; }
+    }
+    [global::System.ObsoleteAttribute()]
+    public global::UnitTest.Issues.TestProtos.DeprecatedChild GetMessageArray(int index) {
+      return messageArray_[index];
+    }
+    
+    public const int EnumValueFieldNumber = 5;
+    private bool hasEnumValue;
+    private global::UnitTest.Issues.TestProtos.DeprecatedEnum enumValue_ = global::UnitTest.Issues.TestProtos.DeprecatedEnum.one;
+    [global::System.ObsoleteAttribute()]
+    public bool HasEnumValue {
+      get { return hasEnumValue; }
+    }
+    [global::System.ObsoleteAttribute()]
+    public global::UnitTest.Issues.TestProtos.DeprecatedEnum EnumValue {
+      get { return enumValue_; }
+    }
+    
+    public const int EnumArrayFieldNumber = 6;
+    private pbc::PopsicleList<global::UnitTest.Issues.TestProtos.DeprecatedEnum> enumArray_ = new pbc::PopsicleList<global::UnitTest.Issues.TestProtos.DeprecatedEnum>();
+    [global::System.ObsoleteAttribute()]
+    public scg::IList<global::UnitTest.Issues.TestProtos.DeprecatedEnum> EnumArrayList {
+      get { return pbc::Lists.AsReadOnly(enumArray_); }
+    }
+    [global::System.ObsoleteAttribute()]
+    public int EnumArrayCount {
+      get { return enumArray_.Count; }
+    }
+    [global::System.ObsoleteAttribute()]
+    public global::UnitTest.Issues.TestProtos.DeprecatedEnum GetEnumArray(int index) {
+      return enumArray_[index];
+    }
+    
+    public override bool IsInitialized {
+      get {
+        return true;
+      }
+    }
+    
+    public override void WriteTo(pb::ICodedOutputStream output) {
+      int size = SerializedSize;
+      string[] field_names = _deprecatedFieldsMessageFieldNames;
+      if (hasPrimitiveValue) {
+        output.WriteInt32(1, field_names[5], PrimitiveValue);
+      }
+      if (primitiveArray_.Count > 0) {
+        output.WriteInt32Array(2, field_names[4], primitiveArray_);
+      }
+      if (hasMessageValue) {
+        output.WriteMessage(3, field_names[3], MessageValue);
+      }
+      if (messageArray_.Count > 0) {
+        output.WriteMessageArray(4, field_names[2], messageArray_);
+      }
+      if (hasEnumValue) {
+        output.WriteEnum(5, field_names[1], (int) EnumValue, EnumValue);
+      }
+      if (enumArray_.Count > 0) {
+        output.WriteEnumArray(6, field_names[0], enumArray_);
+      }
+      UnknownFields.WriteTo(output);
+    }
+    
+    private int memoizedSerializedSize = -1;
+    public override int SerializedSize {
+      get {
+        int size = memoizedSerializedSize;
+        if (size != -1) return size;
+        
+        size = 0;
+        if (hasPrimitiveValue) {
+          size += pb::CodedOutputStream.ComputeInt32Size(1, PrimitiveValue);
+        }
+        {
+          int dataSize = 0;
+          foreach (int element in PrimitiveArrayList) {
+            dataSize += pb::CodedOutputStream.ComputeInt32SizeNoTag(element);
+          }
+          size += dataSize;
+          size += 1 * primitiveArray_.Count;
+        }
+        if (hasMessageValue) {
+          size += pb::CodedOutputStream.ComputeMessageSize(3, MessageValue);
+        }
+        foreach (global::UnitTest.Issues.TestProtos.DeprecatedChild element in MessageArrayList) {
+          size += pb::CodedOutputStream.ComputeMessageSize(4, element);
+        }
+        if (hasEnumValue) {
+          size += pb::CodedOutputStream.ComputeEnumSize(5, (int) EnumValue);
+        }
+        {
+          int dataSize = 0;
+          if (enumArray_.Count > 0) {
+            foreach (global::UnitTest.Issues.TestProtos.DeprecatedEnum element in enumArray_) {
+              dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);
+            }
+            size += dataSize;
+            size += 1 * enumArray_.Count;
+          }
+        }
+        size += UnknownFields.SerializedSize;
+        memoizedSerializedSize = size;
+        return size;
+      }
+    }
+    
+    public static DeprecatedFieldsMessage ParseFrom(pb::ByteString data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static DeprecatedFieldsMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static DeprecatedFieldsMessage ParseFrom(byte[] data) {
+      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
+    }
+    public static DeprecatedFieldsMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
+    }
+    public static DeprecatedFieldsMessage ParseFrom(global::System.IO.Stream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static DeprecatedFieldsMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    public static DeprecatedFieldsMessage ParseDelimitedFrom(global::System.IO.Stream input) {
+      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
+    }
+    public static DeprecatedFieldsMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
+      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
+    }
+    public static DeprecatedFieldsMessage ParseFrom(pb::ICodedInputStream input) {
+      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
+    }
+    public static DeprecatedFieldsMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
+    }
+    private DeprecatedFieldsMessage MakeReadOnly() {
+      primitiveArray_.MakeReadOnly();
+      messageArray_.MakeReadOnly();
+      enumArray_.MakeReadOnly();
+      return this;
+    }
+    
+    public static Builder CreateBuilder() { return new Builder(); }
+    public override Builder ToBuilder() { return CreateBuilder(this); }
+    public override Builder CreateBuilderForType() { return new Builder(); }
+    public static Builder CreateBuilder(DeprecatedFieldsMessage prototype) {
+      return new Builder(prototype);
+    }
+    
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
+    public sealed partial class Builder : pb::GeneratedBuilder<DeprecatedFieldsMessage, Builder> {
+      protected override Builder ThisBuilder {
+        get { return this; }
+      }
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(DeprecatedFieldsMessage cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private DeprecatedFieldsMessage result;
+      
+      private DeprecatedFieldsMessage PrepareBuilder() {
+        if (resultIsReadOnly) {
+          DeprecatedFieldsMessage original = result;
+          result = new DeprecatedFieldsMessage();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
+      
+      protected override DeprecatedFieldsMessage MessageBeingBuilt {
+        get { return PrepareBuilder(); }
+      }
+      
+      public override Builder Clear() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+        return this;
+      }
+      
+      public override Builder Clone() {
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
+      }
+      
+      public override pbd::MessageDescriptor DescriptorForType {
+        get { return global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage.Descriptor; }
+      }
+      
+      public override DeprecatedFieldsMessage DefaultInstanceForType {
+        get { return global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage.DefaultInstance; }
+      }
+      
+      public override DeprecatedFieldsMessage BuildPartial() {
+        if (resultIsReadOnly) {
+          return result;
+        }
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
+      }
+      
+      public override Builder MergeFrom(pb::IMessage other) {
+        if (other is DeprecatedFieldsMessage) {
+          return MergeFrom((DeprecatedFieldsMessage) other);
+        } else {
+          base.MergeFrom(other);
+          return this;
+        }
+      }
+      
+      public override Builder MergeFrom(DeprecatedFieldsMessage other) {
+        if (other == global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage.DefaultInstance) return this;
+        PrepareBuilder();
+        if (other.HasPrimitiveValue) {
+          PrimitiveValue = other.PrimitiveValue;
+        }
+        if (other.primitiveArray_.Count != 0) {
+          result.primitiveArray_.Add(other.primitiveArray_);
+        }
+        if (other.HasMessageValue) {
+          MergeMessageValue(other.MessageValue);
+        }
+        if (other.messageArray_.Count != 0) {
+          result.messageArray_.Add(other.messageArray_);
+        }
+        if (other.HasEnumValue) {
+          EnumValue = other.EnumValue;
+        }
+        if (other.enumArray_.Count != 0) {
+          result.enumArray_.Add(other.enumArray_);
+        }
+        this.MergeUnknownFields(other.UnknownFields);
+        return this;
+      }
+      
+      public override Builder MergeFrom(pb::ICodedInputStream input) {
+        return MergeFrom(input, pb::ExtensionRegistry.Empty);
+      }
+      
+      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
+        pb::UnknownFieldSet.Builder unknownFields = null;
+        uint tag;
+        string field_name;
+        while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_deprecatedFieldsMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _deprecatedFieldsMessageFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
+          switch (tag) {
+            case 0: {
+              throw pb::InvalidProtocolBufferException.InvalidTag();
+            }
+            default: {
+              if (pb::WireFormat.IsEndGroupTag(tag)) {
+                if (unknownFields != null) {
+                  this.UnknownFields = unknownFields.Build();
+                }
+                return this;
+              }
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              break;
+            }
+            case 8: {
+              result.hasPrimitiveValue = input.ReadInt32(ref result.primitiveValue_);
+              break;
+            }
+            case 18:
+            case 16: {
+              input.ReadInt32Array(tag, field_name, result.primitiveArray_);
+              break;
+            }
+            case 26: {
+              global::UnitTest.Issues.TestProtos.DeprecatedChild.Builder subBuilder = global::UnitTest.Issues.TestProtos.DeprecatedChild.CreateBuilder();
+              if (result.hasMessageValue) {
+                subBuilder.MergeFrom(MessageValue);
+              }
+              input.ReadMessage(subBuilder, extensionRegistry);
+              MessageValue = subBuilder.BuildPartial();
+              break;
+            }
+            case 34: {
+              input.ReadMessageArray(tag, field_name, result.messageArray_, global::UnitTest.Issues.TestProtos.DeprecatedChild.DefaultInstance, extensionRegistry);
+              break;
+            }
+            case 40: {
+              object unknown;
+              if(input.ReadEnum(ref result.enumValue_, out unknown)) {
+                result.hasEnumValue = true;
+              } else if(unknown is int) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
+                unknownFields.MergeVarintField(5, (ulong)(int)unknown);
+              }
+              break;
+            }
+            case 50:
+            case 48: {
+              scg::ICollection<object> unknownItems;
+              input.ReadEnumArray<global::UnitTest.Issues.TestProtos.DeprecatedEnum>(tag, field_name, result.enumArray_, out unknownItems);
+              if (unknownItems != null) {
+                if (unknownFields == null) {
+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                }
+                foreach (object rawValue in unknownItems)
+                  if (rawValue is int)
+                    unknownFields.MergeVarintField(6, (ulong)(int)rawValue);
+              }
+              break;
+            }
+          }
+        }
+        
+        if (unknownFields != null) {
+          this.UnknownFields = unknownFields.Build();
+        }
+        return this;
+      }
+      
+      
+      [global::System.ObsoleteAttribute()]
+      public bool HasPrimitiveValue {
+        get { return result.hasPrimitiveValue; }
+      }
+      [global::System.ObsoleteAttribute()]
+      public int PrimitiveValue {
+        get { return result.PrimitiveValue; }
+        set { SetPrimitiveValue(value); }
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder SetPrimitiveValue(int value) {
+        PrepareBuilder();
+        result.hasPrimitiveValue = true;
+        result.primitiveValue_ = value;
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder ClearPrimitiveValue() {
+        PrepareBuilder();
+        result.hasPrimitiveValue = false;
+        result.primitiveValue_ = 0;
+        return this;
+      }
+      
+      [global::System.ObsoleteAttribute()]
+      public pbc::IPopsicleList<int> PrimitiveArrayList {
+        get { return PrepareBuilder().primitiveArray_; }
+      }
+      [global::System.ObsoleteAttribute()]
+      public int PrimitiveArrayCount {
+        get { return result.PrimitiveArrayCount; }
+      }
+      [global::System.ObsoleteAttribute()]
+      public int GetPrimitiveArray(int index) {
+        return result.GetPrimitiveArray(index);
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder SetPrimitiveArray(int index, int value) {
+        PrepareBuilder();
+        result.primitiveArray_[index] = value;
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder AddPrimitiveArray(int value) {
+        PrepareBuilder();
+        result.primitiveArray_.Add(value);
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder AddRangePrimitiveArray(scg::IEnumerable<int> values) {
+        PrepareBuilder();
+        result.primitiveArray_.Add(values);
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder ClearPrimitiveArray() {
+        PrepareBuilder();
+        result.primitiveArray_.Clear();
+        return this;
+      }
+      
+      [global::System.ObsoleteAttribute()]
+      public bool HasMessageValue {
+       get { return result.hasMessageValue; }
+      }
+      [global::System.ObsoleteAttribute()]
+      public global::UnitTest.Issues.TestProtos.DeprecatedChild MessageValue {
+        get { return result.MessageValue; }
+        set { SetMessageValue(value); }
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder SetMessageValue(global::UnitTest.Issues.TestProtos.DeprecatedChild value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        result.hasMessageValue = true;
+        result.messageValue_ = value;
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder SetMessageValue(global::UnitTest.Issues.TestProtos.DeprecatedChild.Builder builderForValue) {
+        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
+        result.hasMessageValue = true;
+        result.messageValue_ = builderForValue.Build();
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder MergeMessageValue(global::UnitTest.Issues.TestProtos.DeprecatedChild value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        if (result.hasMessageValue &&
+            result.messageValue_ != global::UnitTest.Issues.TestProtos.DeprecatedChild.DefaultInstance) {
+            result.messageValue_ = global::UnitTest.Issues.TestProtos.DeprecatedChild.CreateBuilder(result.messageValue_).MergeFrom(value).BuildPartial();
+        } else {
+          result.messageValue_ = value;
+        }
+        result.hasMessageValue = true;
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder ClearMessageValue() {
+        PrepareBuilder();
+        result.hasMessageValue = false;
+        result.messageValue_ = null;
+        return this;
+      }
+      
+      [global::System.ObsoleteAttribute()]
+      public pbc::IPopsicleList<global::UnitTest.Issues.TestProtos.DeprecatedChild> MessageArrayList {
+        get { return PrepareBuilder().messageArray_; }
+      }
+      [global::System.ObsoleteAttribute()]
+      public int MessageArrayCount {
+        get { return result.MessageArrayCount; }
+      }
+      [global::System.ObsoleteAttribute()]
+      public global::UnitTest.Issues.TestProtos.DeprecatedChild GetMessageArray(int index) {
+        return result.GetMessageArray(index);
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder SetMessageArray(int index, global::UnitTest.Issues.TestProtos.DeprecatedChild value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        result.messageArray_[index] = value;
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder SetMessageArray(int index, global::UnitTest.Issues.TestProtos.DeprecatedChild.Builder builderForValue) {
+        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
+        result.messageArray_[index] = builderForValue.Build();
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder AddMessageArray(global::UnitTest.Issues.TestProtos.DeprecatedChild value) {
+        pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
+        result.messageArray_.Add(value);
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder AddMessageArray(global::UnitTest.Issues.TestProtos.DeprecatedChild.Builder builderForValue) {
+        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
+        result.messageArray_.Add(builderForValue.Build());
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder AddRangeMessageArray(scg::IEnumerable<global::UnitTest.Issues.TestProtos.DeprecatedChild> values) {
+        PrepareBuilder();
+        result.messageArray_.Add(values);
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder ClearMessageArray() {
+        PrepareBuilder();
+        result.messageArray_.Clear();
+        return this;
+      }
+      
+      [global::System.ObsoleteAttribute()]
+      public bool HasEnumValue {
+       get { return result.hasEnumValue; }
+      }
+      [global::System.ObsoleteAttribute()]
+      public global::UnitTest.Issues.TestProtos.DeprecatedEnum EnumValue {
+        get { return result.EnumValue; }
+        set { SetEnumValue(value); }
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder SetEnumValue(global::UnitTest.Issues.TestProtos.DeprecatedEnum value) {
+        PrepareBuilder();
+        result.hasEnumValue = true;
+        result.enumValue_ = value;
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder ClearEnumValue() {
+        PrepareBuilder();
+        result.hasEnumValue = false;
+        result.enumValue_ = global::UnitTest.Issues.TestProtos.DeprecatedEnum.one;
+        return this;
+      }
+      
+      [global::System.ObsoleteAttribute()]
+      public pbc::IPopsicleList<global::UnitTest.Issues.TestProtos.DeprecatedEnum> EnumArrayList {
+        get { return PrepareBuilder().enumArray_; }
+      }
+      [global::System.ObsoleteAttribute()]
+      public int EnumArrayCount {
+        get { return result.EnumArrayCount; }
+      }
+      [global::System.ObsoleteAttribute()]
+      public global::UnitTest.Issues.TestProtos.DeprecatedEnum GetEnumArray(int index) {
+        return result.GetEnumArray(index);
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder SetEnumArray(int index, global::UnitTest.Issues.TestProtos.DeprecatedEnum value) {
+        PrepareBuilder();
+        result.enumArray_[index] = value;
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder AddEnumArray(global::UnitTest.Issues.TestProtos.DeprecatedEnum value) {
+        PrepareBuilder();
+        result.enumArray_.Add(value);
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder AddRangeEnumArray(scg::IEnumerable<global::UnitTest.Issues.TestProtos.DeprecatedEnum> values) {
+        PrepareBuilder();
+        result.enumArray_.Add(values);
+        return this;
+      }
+      [global::System.ObsoleteAttribute()]
+      public Builder ClearEnumArray() {
+        PrepareBuilder();
+        result.enumArray_.Clear();
+        return this;
+      }
+    }
+    static DeprecatedFieldsMessage() {
+      object.ReferenceEquals(global::UnitTest.Issues.TestProtos.UnitTestExtrasIssuesProtoFile.Descriptor, null);
+    }
+  }
+  
   #endregion
   
 }

+ 1 - 1
src/ProtocolBuffers.Test/TestProtos/UnitTestGenericServices.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;

Різницю між файлами не показано, бо вона завелика
+ 203 - 33
src/ProtocolBuffers.Test/TestProtos/UnitTestGoogleSizeProtoFile.cs


Різницю між файлами не показано, бо вона завелика
+ 202 - 34
src/ProtocolBuffers.Test/TestProtos/UnitTestGoogleSpeedProtoFile.cs


+ 49 - 14
src/ProtocolBuffers.Test/TestProtos/UnitTestImportLiteProtoFile.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -43,7 +43,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class ImportMessageLite : pb::GeneratedMessageLite<ImportMessageLite, ImportMessageLite.Builder> {
-    private static readonly ImportMessageLite defaultInstance = new Builder().BuildPartial();
+    private ImportMessageLite() { }
+    private static readonly ImportMessageLite defaultInstance = new ImportMessageLite().MakeReadOnly();
     private static readonly string[] _importMessageLiteFieldNames = new string[] { "d" };
     private static readonly uint[] _importMessageLiteFieldTags = new uint[] { 8 };
     public static ImportMessageLite DefaultInstance {
@@ -51,7 +52,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override ImportMessageLite DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override ImportMessageLite ThisMessage {
@@ -146,11 +147,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static ImportMessageLite ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private ImportMessageLite MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(ImportMessageLite prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -160,21 +165,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(ImportMessageLite cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private ImportMessageLite result;
+      
+      private ImportMessageLite PrepareBuilder() {
+        if (resultIsReadOnly) {
+          ImportMessageLite original = result;
+          result = new ImportMessageLite();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      ImportMessageLite result = new ImportMessageLite();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override ImportMessageLite MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new ImportMessageLite();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override ImportMessageLite DefaultInstanceForType {
@@ -182,12 +214,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override ImportMessageLite BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        ImportMessageLite returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessageLite other) {
@@ -201,6 +232,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(ImportMessageLite other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.ImportMessageLite.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasD) {
           D = other.D;
         }
@@ -212,6 +244,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
@@ -254,11 +287,13 @@ namespace Google.ProtocolBuffers.TestProtos {
         set { SetD(value); }
       }
       public Builder SetD(int value) {
+        PrepareBuilder();
         result.hasD = true;
         result.d_ = value;
         return this;
       }
       public Builder ClearD() {
+        PrepareBuilder();
         result.hasD = false;
         result.d_ = 0;
         return this;

+ 49 - 14
src/ProtocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -71,7 +71,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class ImportMessage : pb::GeneratedMessage<ImportMessage, ImportMessage.Builder> {
-    private static readonly ImportMessage defaultInstance = new Builder().BuildPartial();
+    private ImportMessage() { }
+    private static readonly ImportMessage defaultInstance = new ImportMessage().MakeReadOnly();
     private static readonly string[] _importMessageFieldNames = new string[] { "d" };
     private static readonly uint[] _importMessageFieldTags = new uint[] { 8 };
     public static ImportMessage DefaultInstance {
@@ -79,7 +80,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override ImportMessage DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override ImportMessage ThisMessage {
@@ -165,11 +166,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static ImportMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private ImportMessage MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(ImportMessage prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -179,21 +184,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(ImportMessage cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private ImportMessage result;
+      
+      private ImportMessage PrepareBuilder() {
+        if (resultIsReadOnly) {
+          ImportMessage original = result;
+          result = new ImportMessage();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      ImportMessage result = new ImportMessage();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override ImportMessage MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new ImportMessage();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -205,12 +237,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override ImportMessage BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        ImportMessage returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -224,6 +255,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(ImportMessage other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.ImportMessage.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasD) {
           D = other.D;
         }
@@ -236,6 +268,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -291,11 +324,13 @@ namespace Google.ProtocolBuffers.TestProtos {
         set { SetD(value); }
       }
       public Builder SetD(int value) {
+        PrepareBuilder();
         result.hasD = true;
         result.d_ = value;
         return this;
       }
       public Builder ClearD() {
+        PrepareBuilder();
         result.hasD = false;
         result.d_ = 0;
         return this;

+ 302 - 86
src/ProtocolBuffers.Test/TestProtos/UnitTestMessageSetProtoFile.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -103,7 +103,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestMessageSet : pb::ExtendableMessage<TestMessageSet, TestMessageSet.Builder> {
-    private static readonly TestMessageSet defaultInstance = new Builder().BuildPartial();
+    private TestMessageSet() { }
+    private static readonly TestMessageSet defaultInstance = new TestMessageSet().MakeReadOnly();
     private static readonly string[] _testMessageSetFieldNames = new string[] {  };
     private static readonly uint[] _testMessageSetFieldTags = new uint[] {  };
     public static TestMessageSet DefaultInstance {
@@ -111,7 +112,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override TestMessageSet DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override TestMessageSet ThisMessage {
@@ -185,11 +186,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static TestMessageSet ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private TestMessageSet MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(TestMessageSet prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -199,21 +204,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(TestMessageSet cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
       
-      TestMessageSet result = new TestMessageSet();
+      private bool resultIsReadOnly;
+      private TestMessageSet result;
+      
+      private TestMessageSet PrepareBuilder() {
+        if (resultIsReadOnly) {
+          TestMessageSet original = result;
+          result = new TestMessageSet();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override TestMessageSet MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new TestMessageSet();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -225,12 +257,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override TestMessageSet BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        TestMessageSet returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -244,6 +275,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(TestMessageSet other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.TestMessageSet.DefaultInstance) return this;
+        PrepareBuilder();
           this.MergeExtensionFields(other);
         this.MergeUnknownFields(other.UnknownFields);
         return this;
@@ -254,6 +286,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -306,7 +339,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestMessageSetContainer : pb::GeneratedMessage<TestMessageSetContainer, TestMessageSetContainer.Builder> {
-    private static readonly TestMessageSetContainer defaultInstance = new Builder().BuildPartial();
+    private TestMessageSetContainer() { }
+    private static readonly TestMessageSetContainer defaultInstance = new TestMessageSetContainer().MakeReadOnly();
     private static readonly string[] _testMessageSetContainerFieldNames = new string[] { "message_set" };
     private static readonly uint[] _testMessageSetContainerFieldTags = new uint[] { 10 };
     public static TestMessageSetContainer DefaultInstance {
@@ -314,7 +348,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override TestMessageSetContainer DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override TestMessageSetContainer ThisMessage {
@@ -331,12 +365,12 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public const int MessageSetFieldNumber = 1;
     private bool hasMessageSet;
-    private global::Google.ProtocolBuffers.TestProtos.TestMessageSet messageSet_ = global::Google.ProtocolBuffers.TestProtos.TestMessageSet.DefaultInstance;
+    private global::Google.ProtocolBuffers.TestProtos.TestMessageSet messageSet_;
     public bool HasMessageSet {
       get { return hasMessageSet; }
     }
     public global::Google.ProtocolBuffers.TestProtos.TestMessageSet MessageSet {
-      get { return messageSet_; }
+      get { return messageSet_ ?? global::Google.ProtocolBuffers.TestProtos.TestMessageSet.DefaultInstance; }
     }
     
     public override bool IsInitialized {
@@ -400,11 +434,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static TestMessageSetContainer ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private TestMessageSetContainer MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(TestMessageSetContainer prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -414,21 +452,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(TestMessageSetContainer cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
       
-      TestMessageSetContainer result = new TestMessageSetContainer();
+      private bool resultIsReadOnly;
+      private TestMessageSetContainer result;
+      
+      private TestMessageSetContainer PrepareBuilder() {
+        if (resultIsReadOnly) {
+          TestMessageSetContainer original = result;
+          result = new TestMessageSetContainer();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override TestMessageSetContainer MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new TestMessageSetContainer();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -440,12 +505,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override TestMessageSetContainer BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        TestMessageSetContainer returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -459,6 +523,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(TestMessageSetContainer other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.TestMessageSetContainer.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasMessageSet) {
           MergeMessageSet(other.MessageSet);
         }
@@ -471,6 +536,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -532,18 +598,21 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetMessageSet(global::Google.ProtocolBuffers.TestProtos.TestMessageSet value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasMessageSet = true;
         result.messageSet_ = value;
         return this;
       }
       public Builder SetMessageSet(global::Google.ProtocolBuffers.TestProtos.TestMessageSet.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.hasMessageSet = true;
         result.messageSet_ = builderForValue.Build();
         return this;
       }
       public Builder MergeMessageSet(global::Google.ProtocolBuffers.TestProtos.TestMessageSet value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         if (result.hasMessageSet &&
             result.messageSet_ != global::Google.ProtocolBuffers.TestProtos.TestMessageSet.DefaultInstance) {
             result.messageSet_ = global::Google.ProtocolBuffers.TestProtos.TestMessageSet.CreateBuilder(result.messageSet_).MergeFrom(value).BuildPartial();
@@ -554,8 +623,9 @@ namespace Google.ProtocolBuffers.TestProtos {
         return this;
       }
       public Builder ClearMessageSet() {
+        PrepareBuilder();
         result.hasMessageSet = false;
-        result.messageSet_ = global::Google.ProtocolBuffers.TestProtos.TestMessageSet.DefaultInstance;
+        result.messageSet_ = null;
         return this;
       }
     }
@@ -568,7 +638,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestMessageSetExtension1 : pb::GeneratedMessage<TestMessageSetExtension1, TestMessageSetExtension1.Builder> {
-    private static readonly TestMessageSetExtension1 defaultInstance = new Builder().BuildPartial();
+    private TestMessageSetExtension1() { }
+    private static readonly TestMessageSetExtension1 defaultInstance = new TestMessageSetExtension1().MakeReadOnly();
     private static readonly string[] _testMessageSetExtension1FieldNames = new string[] { "i" };
     private static readonly uint[] _testMessageSetExtension1FieldTags = new uint[] { 120 };
     public static TestMessageSetExtension1 DefaultInstance {
@@ -576,7 +647,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override TestMessageSetExtension1 DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override TestMessageSetExtension1 ThisMessage {
@@ -664,11 +735,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static TestMessageSetExtension1 ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private TestMessageSetExtension1 MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(TestMessageSetExtension1 prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -678,21 +753,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(TestMessageSetExtension1 cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
       
-      TestMessageSetExtension1 result = new TestMessageSetExtension1();
+      private bool resultIsReadOnly;
+      private TestMessageSetExtension1 result;
+      
+      private TestMessageSetExtension1 PrepareBuilder() {
+        if (resultIsReadOnly) {
+          TestMessageSetExtension1 original = result;
+          result = new TestMessageSetExtension1();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override TestMessageSetExtension1 MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new TestMessageSetExtension1();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -704,12 +806,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override TestMessageSetExtension1 BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        TestMessageSetExtension1 returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -723,6 +824,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(TestMessageSetExtension1 other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.TestMessageSetExtension1.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasI) {
           I = other.I;
         }
@@ -735,6 +837,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -790,11 +893,13 @@ namespace Google.ProtocolBuffers.TestProtos {
         set { SetI(value); }
       }
       public Builder SetI(int value) {
+        PrepareBuilder();
         result.hasI = true;
         result.i_ = value;
         return this;
       }
       public Builder ClearI() {
+        PrepareBuilder();
         result.hasI = false;
         result.i_ = 0;
         return this;
@@ -809,7 +914,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestMessageSetExtension2 : pb::GeneratedMessage<TestMessageSetExtension2, TestMessageSetExtension2.Builder> {
-    private static readonly TestMessageSetExtension2 defaultInstance = new Builder().BuildPartial();
+    private TestMessageSetExtension2() { }
+    private static readonly TestMessageSetExtension2 defaultInstance = new TestMessageSetExtension2().MakeReadOnly();
     private static readonly string[] _testMessageSetExtension2FieldNames = new string[] { "str" };
     private static readonly uint[] _testMessageSetExtension2FieldTags = new uint[] { 202 };
     public static TestMessageSetExtension2 DefaultInstance {
@@ -817,7 +923,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override TestMessageSetExtension2 DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override TestMessageSetExtension2 ThisMessage {
@@ -905,11 +1011,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static TestMessageSetExtension2 ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private TestMessageSetExtension2 MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(TestMessageSetExtension2 prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -919,21 +1029,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(TestMessageSetExtension2 cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private TestMessageSetExtension2 result;
       
-      TestMessageSetExtension2 result = new TestMessageSetExtension2();
+      private TestMessageSetExtension2 PrepareBuilder() {
+        if (resultIsReadOnly) {
+          TestMessageSetExtension2 original = result;
+          result = new TestMessageSetExtension2();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override TestMessageSetExtension2 MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new TestMessageSetExtension2();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -945,12 +1082,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override TestMessageSetExtension2 BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        TestMessageSetExtension2 returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -964,6 +1100,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(TestMessageSetExtension2 other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.TestMessageSetExtension2.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasStr) {
           Str = other.Str;
         }
@@ -976,6 +1113,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -1032,11 +1170,13 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetStr(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasStr = true;
         result.str_ = value;
         return this;
       }
       public Builder ClearStr() {
+        PrepareBuilder();
         result.hasStr = false;
         result.str_ = "";
         return this;
@@ -1051,7 +1191,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class RawMessageSet : pb::GeneratedMessage<RawMessageSet, RawMessageSet.Builder> {
-    private static readonly RawMessageSet defaultInstance = new Builder().BuildPartial();
+    private RawMessageSet() { }
+    private static readonly RawMessageSet defaultInstance = new RawMessageSet().MakeReadOnly();
     private static readonly string[] _rawMessageSetFieldNames = new string[] { "item" };
     private static readonly uint[] _rawMessageSetFieldTags = new uint[] { 11 };
     public static RawMessageSet DefaultInstance {
@@ -1059,7 +1200,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override RawMessageSet DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override RawMessageSet ThisMessage {
@@ -1083,7 +1224,8 @@ namespace Google.ProtocolBuffers.TestProtos {
       [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
       [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
       public sealed partial class Item : pb::GeneratedMessage<Item, Item.Builder> {
-        private static readonly Item defaultInstance = new Builder().BuildPartial();
+        private Item() { }
+        private static readonly Item defaultInstance = new Item().MakeReadOnly();
         private static readonly string[] _itemFieldNames = new string[] { "message", "type_id" };
         private static readonly uint[] _itemFieldTags = new uint[] { 26, 16 };
         public static Item DefaultInstance {
@@ -1091,7 +1233,7 @@ namespace Google.ProtocolBuffers.TestProtos {
         }
         
         public override Item DefaultInstanceForType {
-          get { return defaultInstance; }
+          get { return DefaultInstance; }
         }
         
         protected override Item ThisMessage {
@@ -1195,11 +1337,15 @@ namespace Google.ProtocolBuffers.TestProtos {
         public static Item ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
           return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
         }
+        private Item MakeReadOnly() {
+          return this;
+        }
+        
         public static Builder CreateBuilder() { return new Builder(); }
         public override Builder ToBuilder() { return CreateBuilder(this); }
         public override Builder CreateBuilderForType() { return new Builder(); }
         public static Builder CreateBuilder(Item prototype) {
-          return (Builder) new Builder().MergeFrom(prototype);
+          return new Builder(prototype);
         }
         
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -1209,21 +1355,48 @@ namespace Google.ProtocolBuffers.TestProtos {
           protected override Builder ThisBuilder {
             get { return this; }
           }
-          public Builder() {}
+          public Builder() {
+            result = DefaultInstance;
+            resultIsReadOnly = true;
+          }
+          internal Builder(Item cloneFrom) {
+            result = cloneFrom;
+            resultIsReadOnly = true;
+          }
           
-          Item result = new Item();
+          private bool resultIsReadOnly;
+          private Item result;
+          
+          private Item PrepareBuilder() {
+            if (resultIsReadOnly) {
+              Item original = result;
+              result = new Item();
+              resultIsReadOnly = false;
+              MergeFrom(original);
+            }
+            return result;
+          }
+          
+          public override bool IsInitialized {
+            get { return result.IsInitialized; }
+          }
           
           protected override Item MessageBeingBuilt {
-            get { return result; }
+            get { return PrepareBuilder(); }
           }
           
           public override Builder Clear() {
-            result = new Item();
+            result = DefaultInstance;
+            resultIsReadOnly = true;
             return this;
           }
           
           public override Builder Clone() {
-            return new Builder().MergeFrom(result);
+            if (resultIsReadOnly) {
+              return new Builder(result);
+            } else {
+              return new Builder().MergeFrom(result);
+            }
           }
           
           public override pbd::MessageDescriptor DescriptorForType {
@@ -1235,12 +1408,11 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           
           public override Item BuildPartial() {
-            if (result == null) {
-              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+            if (resultIsReadOnly) {
+              return result;
             }
-            Item returnMe = result;
-            result = null;
-            return returnMe;
+            resultIsReadOnly = true;
+            return result.MakeReadOnly();
           }
           
           public override Builder MergeFrom(pb::IMessage other) {
@@ -1254,6 +1426,7 @@ namespace Google.ProtocolBuffers.TestProtos {
           
           public override Builder MergeFrom(Item other) {
             if (other == global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item.DefaultInstance) return this;
+            PrepareBuilder();
             if (other.HasTypeId) {
               TypeId = other.TypeId;
             }
@@ -1269,6 +1442,7 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           
           public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+            PrepareBuilder();
             pb::UnknownFieldSet.Builder unknownFields = null;
             uint tag;
             string field_name;
@@ -1328,11 +1502,13 @@ namespace Google.ProtocolBuffers.TestProtos {
             set { SetTypeId(value); }
           }
           public Builder SetTypeId(int value) {
+            PrepareBuilder();
             result.hasTypeId = true;
             result.typeId_ = value;
             return this;
           }
           public Builder ClearTypeId() {
+            PrepareBuilder();
             result.hasTypeId = false;
             result.typeId_ = 0;
             return this;
@@ -1347,11 +1523,13 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           public Builder SetMessage(pb::ByteString value) {
             pb::ThrowHelper.ThrowIfNull(value, "value");
+            PrepareBuilder();
             result.hasMessage = true;
             result.message_ = value;
             return this;
           }
           public Builder ClearMessage() {
+            PrepareBuilder();
             result.hasMessage = false;
             result.message_ = pb::ByteString.Empty;
             return this;
@@ -1438,11 +1616,16 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static RawMessageSet ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private RawMessageSet MakeReadOnly() {
+      item_.MakeReadOnly();
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(RawMessageSet prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -1452,21 +1635,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(RawMessageSet cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private RawMessageSet result;
       
-      RawMessageSet result = new RawMessageSet();
+      private RawMessageSet PrepareBuilder() {
+        if (resultIsReadOnly) {
+          RawMessageSet original = result;
+          result = new RawMessageSet();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override RawMessageSet MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new RawMessageSet();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -1478,13 +1688,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override RawMessageSet BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        result.item_.MakeReadOnly();
-        RawMessageSet returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -1498,8 +1706,9 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(RawMessageSet other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.RawMessageSet.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.item_.Count != 0) {
-          base.AddRange(other.item_, result.item_);
+          result.item_.Add(other.item_);
         }
         this.MergeUnknownFields(other.UnknownFields);
         return this;
@@ -1510,6 +1719,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -1558,7 +1768,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       
       public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item> ItemList {
-        get { return result.item_; }
+        get { return PrepareBuilder().item_; }
       }
       public int ItemCount {
         get { return result.ItemCount; }
@@ -1568,29 +1778,35 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetItem(int index, global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.item_[index] = value;
         return this;
       }
       public Builder SetItem(int index, global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.item_[index] = builderForValue.Build();
         return this;
       }
       public Builder AddItem(global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.item_.Add(value);
         return this;
       }
       public Builder AddItem(global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.item_.Add(builderForValue.Build());
         return this;
       }
       public Builder AddRangeItem(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item> values) {
-        base.AddRange(values, result.item_);
+        PrepareBuilder();
+        result.item_.Add(values);
         return this;
       }
       public Builder ClearItem() {
+        PrepareBuilder();
         result.item_.Clear();
         return this;
       }

+ 49 - 14
src/ProtocolBuffers.Test/TestProtos/UnitTestNoGenericServicesProtoFile.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -81,7 +81,8 @@ namespace Google.ProtocolBuffers.TestProtos.NoGenericService {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestMessage : pb::ExtendableMessage<TestMessage, TestMessage.Builder> {
-    private static readonly TestMessage defaultInstance = new Builder().BuildPartial();
+    private TestMessage() { }
+    private static readonly TestMessage defaultInstance = new TestMessage().MakeReadOnly();
     private static readonly string[] _testMessageFieldNames = new string[] { "a" };
     private static readonly uint[] _testMessageFieldTags = new uint[] { 8 };
     public static TestMessage DefaultInstance {
@@ -89,7 +90,7 @@ namespace Google.ProtocolBuffers.TestProtos.NoGenericService {
     }
     
     public override TestMessage DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override TestMessage ThisMessage {
@@ -179,11 +180,15 @@ namespace Google.ProtocolBuffers.TestProtos.NoGenericService {
     public static TestMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private TestMessage MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(TestMessage prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -193,21 +198,48 @@ namespace Google.ProtocolBuffers.TestProtos.NoGenericService {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(TestMessage cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private TestMessage result;
+      
+      private TestMessage PrepareBuilder() {
+        if (resultIsReadOnly) {
+          TestMessage original = result;
+          result = new TestMessage();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      TestMessage result = new TestMessage();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override TestMessage MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new TestMessage();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -219,12 +251,11 @@ namespace Google.ProtocolBuffers.TestProtos.NoGenericService {
       }
       
       public override TestMessage BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        TestMessage returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -238,6 +269,7 @@ namespace Google.ProtocolBuffers.TestProtos.NoGenericService {
       
       public override Builder MergeFrom(TestMessage other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.NoGenericService.TestMessage.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasA) {
           A = other.A;
         }
@@ -251,6 +283,7 @@ namespace Google.ProtocolBuffers.TestProtos.NoGenericService {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -306,11 +339,13 @@ namespace Google.ProtocolBuffers.TestProtos.NoGenericService {
         set { SetA(value); }
       }
       public Builder SetA(int value) {
+        PrepareBuilder();
         result.hasA = true;
         result.a_ = value;
         return this;
       }
       public Builder ClearA() {
+        PrepareBuilder();
         result.hasA = false;
         result.a_ = 0;
         return this;

+ 151 - 46
src/ProtocolBuffers.Test/TestProtos/UnitTestOptimizeForProtoFile.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -85,13 +85,14 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestOptimizedForSize : pb::ExtendableMessage<TestOptimizedForSize, TestOptimizedForSize.Builder> {
-    private static readonly TestOptimizedForSize defaultInstance = new Builder().BuildPartial();
+    private TestOptimizedForSize() { }
+    private static readonly TestOptimizedForSize defaultInstance = new TestOptimizedForSize().MakeReadOnly();
     public static TestOptimizedForSize DefaultInstance {
       get { return defaultInstance; }
     }
     
     public override TestOptimizedForSize DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override TestOptimizedForSize ThisMessage {
@@ -122,12 +123,12 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public const int MsgFieldNumber = 19;
     private bool hasMsg;
-    private global::Google.ProtocolBuffers.TestProtos.ForeignMessage msg_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance;
+    private global::Google.ProtocolBuffers.TestProtos.ForeignMessage msg_;
     public bool HasMsg {
       get { return hasMsg; }
     }
     public global::Google.ProtocolBuffers.TestProtos.ForeignMessage Msg {
-      get { return msg_; }
+      get { return msg_ ?? global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance; }
     }
     
     public static TestOptimizedForSize ParseFrom(pb::ByteString data) {
@@ -160,11 +161,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static TestOptimizedForSize ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private TestOptimizedForSize MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(TestOptimizedForSize prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -174,21 +179,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(TestOptimizedForSize cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private TestOptimizedForSize result;
+      
+      private TestOptimizedForSize PrepareBuilder() {
+        if (resultIsReadOnly) {
+          TestOptimizedForSize original = result;
+          result = new TestOptimizedForSize();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      TestOptimizedForSize result = new TestOptimizedForSize();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override TestOptimizedForSize MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new TestOptimizedForSize();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -200,12 +232,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override TestOptimizedForSize BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        TestOptimizedForSize returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       
@@ -217,11 +248,13 @@ namespace Google.ProtocolBuffers.TestProtos {
         set { SetI(value); }
       }
       public Builder SetI(int value) {
+        PrepareBuilder();
         result.hasI = true;
         result.i_ = value;
         return this;
       }
       public Builder ClearI() {
+        PrepareBuilder();
         result.hasI = false;
         result.i_ = 0;
         return this;
@@ -236,18 +269,21 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetMsg(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasMsg = true;
         result.msg_ = value;
         return this;
       }
       public Builder SetMsg(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.hasMsg = true;
         result.msg_ = builderForValue.Build();
         return this;
       }
       public Builder MergeMsg(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         if (result.hasMsg &&
             result.msg_ != global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance) {
             result.msg_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder(result.msg_).MergeFrom(value).BuildPartial();
@@ -258,8 +294,9 @@ namespace Google.ProtocolBuffers.TestProtos {
         return this;
       }
       public Builder ClearMsg() {
+        PrepareBuilder();
         result.hasMsg = false;
-        result.msg_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance;
+        result.msg_ = null;
         return this;
       }
     }
@@ -272,13 +309,14 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestRequiredOptimizedForSize : pb::GeneratedMessage<TestRequiredOptimizedForSize, TestRequiredOptimizedForSize.Builder> {
-    private static readonly TestRequiredOptimizedForSize defaultInstance = new Builder().BuildPartial();
+    private TestRequiredOptimizedForSize() { }
+    private static readonly TestRequiredOptimizedForSize defaultInstance = new TestRequiredOptimizedForSize().MakeReadOnly();
     public static TestRequiredOptimizedForSize DefaultInstance {
       get { return defaultInstance; }
     }
     
     public override TestRequiredOptimizedForSize DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override TestRequiredOptimizedForSize ThisMessage {
@@ -333,11 +371,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static TestRequiredOptimizedForSize ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private TestRequiredOptimizedForSize MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(TestRequiredOptimizedForSize prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -347,21 +389,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(TestRequiredOptimizedForSize cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private TestRequiredOptimizedForSize result;
+      
+      private TestRequiredOptimizedForSize PrepareBuilder() {
+        if (resultIsReadOnly) {
+          TestRequiredOptimizedForSize original = result;
+          result = new TestRequiredOptimizedForSize();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      TestRequiredOptimizedForSize result = new TestRequiredOptimizedForSize();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override TestRequiredOptimizedForSize MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new TestRequiredOptimizedForSize();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -373,12 +442,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override TestRequiredOptimizedForSize BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        TestRequiredOptimizedForSize returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       
@@ -390,11 +458,13 @@ namespace Google.ProtocolBuffers.TestProtos {
         set { SetX(value); }
       }
       public Builder SetX(int value) {
+        PrepareBuilder();
         result.hasX = true;
         result.x_ = value;
         return this;
       }
       public Builder ClearX() {
+        PrepareBuilder();
         result.hasX = false;
         result.x_ = 0;
         return this;
@@ -409,13 +479,14 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestOptionalOptimizedForSize : pb::GeneratedMessage<TestOptionalOptimizedForSize, TestOptionalOptimizedForSize.Builder> {
-    private static readonly TestOptionalOptimizedForSize defaultInstance = new Builder().BuildPartial();
+    private TestOptionalOptimizedForSize() { }
+    private static readonly TestOptionalOptimizedForSize defaultInstance = new TestOptionalOptimizedForSize().MakeReadOnly();
     public static TestOptionalOptimizedForSize DefaultInstance {
       get { return defaultInstance; }
     }
     
     public override TestOptionalOptimizedForSize DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override TestOptionalOptimizedForSize ThisMessage {
@@ -432,12 +503,12 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public const int OFieldNumber = 1;
     private bool hasO;
-    private global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize o_ = global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.DefaultInstance;
+    private global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize o_;
     public bool HasO {
       get { return hasO; }
     }
     public global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize O {
-      get { return o_; }
+      get { return o_ ?? global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.DefaultInstance; }
     }
     
     public static TestOptionalOptimizedForSize ParseFrom(pb::ByteString data) {
@@ -470,11 +541,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static TestOptionalOptimizedForSize ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private TestOptionalOptimizedForSize MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(TestOptionalOptimizedForSize prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -484,21 +559,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(TestOptionalOptimizedForSize cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private TestOptionalOptimizedForSize result;
       
-      TestOptionalOptimizedForSize result = new TestOptionalOptimizedForSize();
+      private TestOptionalOptimizedForSize PrepareBuilder() {
+        if (resultIsReadOnly) {
+          TestOptionalOptimizedForSize original = result;
+          result = new TestOptionalOptimizedForSize();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override TestOptionalOptimizedForSize MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new TestOptionalOptimizedForSize();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -510,12 +612,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override TestOptionalOptimizedForSize BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        TestOptionalOptimizedForSize returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       
@@ -528,18 +629,21 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetO(global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasO = true;
         result.o_ = value;
         return this;
       }
       public Builder SetO(global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.hasO = true;
         result.o_ = builderForValue.Build();
         return this;
       }
       public Builder MergeO(global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         if (result.hasO &&
             result.o_ != global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.DefaultInstance) {
             result.o_ = global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.CreateBuilder(result.o_).MergeFrom(value).BuildPartial();
@@ -550,8 +654,9 @@ namespace Google.ProtocolBuffers.TestProtos {
         return this;
       }
       public Builder ClearO() {
+        PrepareBuilder();
         result.hasO = false;
-        result.o_ = global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.DefaultInstance;
+        result.o_ = null;
         return this;
       }
     }

Різницю між файлами не показано, бо вона завелика
+ 286 - 111
src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs


+ 222 - 68
src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -83,7 +83,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class SearchRequest : pb::GeneratedMessage<SearchRequest, SearchRequest.Builder> {
-    private static readonly SearchRequest defaultInstance = new Builder().BuildPartial();
+    private SearchRequest() { }
+    private static readonly SearchRequest defaultInstance = new SearchRequest().MakeReadOnly();
     private static readonly string[] _searchRequestFieldNames = new string[] { "Criteria" };
     private static readonly uint[] _searchRequestFieldTags = new uint[] { 10 };
     public static SearchRequest DefaultInstance {
@@ -91,7 +92,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override SearchRequest DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override SearchRequest ThisMessage {
@@ -184,11 +185,16 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static SearchRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private SearchRequest MakeReadOnly() {
+      criteria_.MakeReadOnly();
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(SearchRequest prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -198,21 +204,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(SearchRequest cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
       
-      SearchRequest result = new SearchRequest();
+      private bool resultIsReadOnly;
+      private SearchRequest result;
+      
+      private SearchRequest PrepareBuilder() {
+        if (resultIsReadOnly) {
+          SearchRequest original = result;
+          result = new SearchRequest();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override SearchRequest MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new SearchRequest();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -224,13 +257,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override SearchRequest BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        result.criteria_.MakeReadOnly();
-        SearchRequest returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -244,8 +275,9 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(SearchRequest other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.SearchRequest.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.criteria_.Count != 0) {
-          base.AddRange(other.criteria_, result.criteria_);
+          result.criteria_.Add(other.criteria_);
         }
         this.MergeUnknownFields(other.UnknownFields);
         return this;
@@ -256,6 +288,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -304,7 +337,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       
       public pbc::IPopsicleList<string> CriteriaList {
-        get { return result.criteria_; }
+        get { return PrepareBuilder().criteria_; }
       }
       public int CriteriaCount {
         get { return result.CriteriaCount; }
@@ -314,19 +347,23 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetCriteria(int index, string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.criteria_[index] = value;
         return this;
       }
       public Builder AddCriteria(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.criteria_.Add(value);
         return this;
       }
       public Builder AddRangeCriteria(scg::IEnumerable<string> values) {
-        base.AddRange(values, result.criteria_);
+        PrepareBuilder();
+        result.criteria_.Add(values);
         return this;
       }
       public Builder ClearCriteria() {
+        PrepareBuilder();
         result.criteria_.Clear();
         return this;
       }
@@ -340,7 +377,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class SearchResponse : pb::GeneratedMessage<SearchResponse, SearchResponse.Builder> {
-    private static readonly SearchResponse defaultInstance = new Builder().BuildPartial();
+    private SearchResponse() { }
+    private static readonly SearchResponse defaultInstance = new SearchResponse().MakeReadOnly();
     private static readonly string[] _searchResponseFieldNames = new string[] { "results" };
     private static readonly uint[] _searchResponseFieldTags = new uint[] { 10 };
     public static SearchResponse DefaultInstance {
@@ -348,7 +386,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override SearchResponse DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override SearchResponse ThisMessage {
@@ -372,7 +410,8 @@ namespace Google.ProtocolBuffers.TestProtos {
       [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
       [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
       public sealed partial class ResultItem : pb::GeneratedMessage<ResultItem, ResultItem.Builder> {
-        private static readonly ResultItem defaultInstance = new Builder().BuildPartial();
+        private ResultItem() { }
+        private static readonly ResultItem defaultInstance = new ResultItem().MakeReadOnly();
         private static readonly string[] _resultItemFieldNames = new string[] { "name", "url" };
         private static readonly uint[] _resultItemFieldTags = new uint[] { 18, 10 };
         public static ResultItem DefaultInstance {
@@ -380,7 +419,7 @@ namespace Google.ProtocolBuffers.TestProtos {
         }
         
         public override ResultItem DefaultInstanceForType {
-          get { return defaultInstance; }
+          get { return DefaultInstance; }
         }
         
         protected override ResultItem ThisMessage {
@@ -483,11 +522,15 @@ namespace Google.ProtocolBuffers.TestProtos {
         public static ResultItem ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
           return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
         }
+        private ResultItem MakeReadOnly() {
+          return this;
+        }
+        
         public static Builder CreateBuilder() { return new Builder(); }
         public override Builder ToBuilder() { return CreateBuilder(this); }
         public override Builder CreateBuilderForType() { return new Builder(); }
         public static Builder CreateBuilder(ResultItem prototype) {
-          return (Builder) new Builder().MergeFrom(prototype);
+          return new Builder(prototype);
         }
         
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -497,21 +540,48 @@ namespace Google.ProtocolBuffers.TestProtos {
           protected override Builder ThisBuilder {
             get { return this; }
           }
-          public Builder() {}
+          public Builder() {
+            result = DefaultInstance;
+            resultIsReadOnly = true;
+          }
+          internal Builder(ResultItem cloneFrom) {
+            result = cloneFrom;
+            resultIsReadOnly = true;
+          }
           
-          ResultItem result = new ResultItem();
+          private bool resultIsReadOnly;
+          private ResultItem result;
+          
+          private ResultItem PrepareBuilder() {
+            if (resultIsReadOnly) {
+              ResultItem original = result;
+              result = new ResultItem();
+              resultIsReadOnly = false;
+              MergeFrom(original);
+            }
+            return result;
+          }
+          
+          public override bool IsInitialized {
+            get { return result.IsInitialized; }
+          }
           
           protected override ResultItem MessageBeingBuilt {
-            get { return result; }
+            get { return PrepareBuilder(); }
           }
           
           public override Builder Clear() {
-            result = new ResultItem();
+            result = DefaultInstance;
+            resultIsReadOnly = true;
             return this;
           }
           
           public override Builder Clone() {
-            return new Builder().MergeFrom(result);
+            if (resultIsReadOnly) {
+              return new Builder(result);
+            } else {
+              return new Builder().MergeFrom(result);
+            }
           }
           
           public override pbd::MessageDescriptor DescriptorForType {
@@ -523,12 +593,11 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           
           public override ResultItem BuildPartial() {
-            if (result == null) {
-              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+            if (resultIsReadOnly) {
+              return result;
             }
-            ResultItem returnMe = result;
-            result = null;
-            return returnMe;
+            resultIsReadOnly = true;
+            return result.MakeReadOnly();
           }
           
           public override Builder MergeFrom(pb::IMessage other) {
@@ -542,6 +611,7 @@ namespace Google.ProtocolBuffers.TestProtos {
           
           public override Builder MergeFrom(ResultItem other) {
             if (other == global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem.DefaultInstance) return this;
+            PrepareBuilder();
             if (other.HasUrl) {
               Url = other.Url;
             }
@@ -557,6 +627,7 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           
           public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+            PrepareBuilder();
             pb::UnknownFieldSet.Builder unknownFields = null;
             uint tag;
             string field_name;
@@ -617,11 +688,13 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           public Builder SetUrl(string value) {
             pb::ThrowHelper.ThrowIfNull(value, "value");
+            PrepareBuilder();
             result.hasUrl = true;
             result.url_ = value;
             return this;
           }
           public Builder ClearUrl() {
+            PrepareBuilder();
             result.hasUrl = false;
             result.url_ = "";
             return this;
@@ -636,11 +709,13 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           public Builder SetName(string value) {
             pb::ThrowHelper.ThrowIfNull(value, "value");
+            PrepareBuilder();
             result.hasName = true;
             result.name_ = value;
             return this;
           }
           public Builder ClearName() {
+            PrepareBuilder();
             result.hasName = false;
             result.name_ = "";
             return this;
@@ -730,11 +805,16 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static SearchResponse ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private SearchResponse MakeReadOnly() {
+      results_.MakeReadOnly();
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(SearchResponse prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -744,21 +824,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(SearchResponse cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private SearchResponse result;
+      
+      private SearchResponse PrepareBuilder() {
+        if (resultIsReadOnly) {
+          SearchResponse original = result;
+          result = new SearchResponse();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      SearchResponse result = new SearchResponse();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override SearchResponse MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new SearchResponse();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -770,13 +877,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override SearchResponse BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        result.results_.MakeReadOnly();
-        SearchResponse returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -790,8 +895,9 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(SearchResponse other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.SearchResponse.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.results_.Count != 0) {
-          base.AddRange(other.results_, result.results_);
+          result.results_.Add(other.results_);
         }
         this.MergeUnknownFields(other.UnknownFields);
         return this;
@@ -802,6 +908,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -850,7 +957,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       
       public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem> ResultsList {
-        get { return result.results_; }
+        get { return PrepareBuilder().results_; }
       }
       public int ResultsCount {
         get { return result.ResultsCount; }
@@ -860,29 +967,35 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetResults(int index, global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.results_[index] = value;
         return this;
       }
       public Builder SetResults(int index, global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.results_[index] = builderForValue.Build();
         return this;
       }
       public Builder AddResults(global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.results_.Add(value);
         return this;
       }
       public Builder AddResults(global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.results_.Add(builderForValue.Build());
         return this;
       }
       public Builder AddRangeResults(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem> values) {
-        base.AddRange(values, result.results_);
+        PrepareBuilder();
+        result.results_.Add(values);
         return this;
       }
       public Builder ClearResults() {
+        PrepareBuilder();
         result.results_.Clear();
         return this;
       }
@@ -896,7 +1009,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class RefineSearchRequest : pb::GeneratedMessage<RefineSearchRequest, RefineSearchRequest.Builder> {
-    private static readonly RefineSearchRequest defaultInstance = new Builder().BuildPartial();
+    private RefineSearchRequest() { }
+    private static readonly RefineSearchRequest defaultInstance = new RefineSearchRequest().MakeReadOnly();
     private static readonly string[] _refineSearchRequestFieldNames = new string[] { "Criteria", "previous_results" };
     private static readonly uint[] _refineSearchRequestFieldTags = new uint[] { 10, 18 };
     public static RefineSearchRequest DefaultInstance {
@@ -904,7 +1018,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override RefineSearchRequest DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override RefineSearchRequest ThisMessage {
@@ -933,12 +1047,12 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public const int PreviousResultsFieldNumber = 2;
     private bool hasPreviousResults;
-    private global::Google.ProtocolBuffers.TestProtos.SearchResponse previousResults_ = global::Google.ProtocolBuffers.TestProtos.SearchResponse.DefaultInstance;
+    private global::Google.ProtocolBuffers.TestProtos.SearchResponse previousResults_;
     public bool HasPreviousResults {
       get { return hasPreviousResults; }
     }
     public global::Google.ProtocolBuffers.TestProtos.SearchResponse PreviousResults {
-      get { return previousResults_; }
+      get { return previousResults_ ?? global::Google.ProtocolBuffers.TestProtos.SearchResponse.DefaultInstance; }
     }
     
     public override bool IsInitialized {
@@ -1015,11 +1129,16 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static RefineSearchRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private RefineSearchRequest MakeReadOnly() {
+      criteria_.MakeReadOnly();
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(RefineSearchRequest prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -1029,21 +1148,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(RefineSearchRequest cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private RefineSearchRequest result;
+      
+      private RefineSearchRequest PrepareBuilder() {
+        if (resultIsReadOnly) {
+          RefineSearchRequest original = result;
+          result = new RefineSearchRequest();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      RefineSearchRequest result = new RefineSearchRequest();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override RefineSearchRequest MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new RefineSearchRequest();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -1055,13 +1201,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override RefineSearchRequest BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        result.criteria_.MakeReadOnly();
-        RefineSearchRequest returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -1075,8 +1219,9 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(RefineSearchRequest other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.RefineSearchRequest.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.criteria_.Count != 0) {
-          base.AddRange(other.criteria_, result.criteria_);
+          result.criteria_.Add(other.criteria_);
         }
         if (other.HasPreviousResults) {
           MergePreviousResults(other.PreviousResults);
@@ -1090,6 +1235,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -1147,7 +1293,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       
       public pbc::IPopsicleList<string> CriteriaList {
-        get { return result.criteria_; }
+        get { return PrepareBuilder().criteria_; }
       }
       public int CriteriaCount {
         get { return result.CriteriaCount; }
@@ -1157,19 +1303,23 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetCriteria(int index, string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.criteria_[index] = value;
         return this;
       }
       public Builder AddCriteria(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.criteria_.Add(value);
         return this;
       }
       public Builder AddRangeCriteria(scg::IEnumerable<string> values) {
-        base.AddRange(values, result.criteria_);
+        PrepareBuilder();
+        result.criteria_.Add(values);
         return this;
       }
       public Builder ClearCriteria() {
+        PrepareBuilder();
         result.criteria_.Clear();
         return this;
       }
@@ -1183,18 +1333,21 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetPreviousResults(global::Google.ProtocolBuffers.TestProtos.SearchResponse value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasPreviousResults = true;
         result.previousResults_ = value;
         return this;
       }
       public Builder SetPreviousResults(global::Google.ProtocolBuffers.TestProtos.SearchResponse.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.hasPreviousResults = true;
         result.previousResults_ = builderForValue.Build();
         return this;
       }
       public Builder MergePreviousResults(global::Google.ProtocolBuffers.TestProtos.SearchResponse value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         if (result.hasPreviousResults &&
             result.previousResults_ != global::Google.ProtocolBuffers.TestProtos.SearchResponse.DefaultInstance) {
             result.previousResults_ = global::Google.ProtocolBuffers.TestProtos.SearchResponse.CreateBuilder(result.previousResults_).MergeFrom(value).BuildPartial();
@@ -1205,8 +1358,9 @@ namespace Google.ProtocolBuffers.TestProtos {
         return this;
       }
       public Builder ClearPreviousResults() {
+        PrepareBuilder();
         result.hasPreviousResults = false;
-        result.previousResults_ = global::Google.ProtocolBuffers.TestProtos.SearchResponse.DefaultInstance;
+        result.previousResults_ = null;
         return this;
       }
     }

Різницю між файлами не показано, бо вона завелика
+ 303 - 94
src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs


+ 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>
     {

+ 2 - 2
src/ProtocolBuffers/CodedOutputStream.ComputeSize.cs

@@ -202,7 +202,7 @@ namespace Google.ProtocolBuffers
         /// </summary>
         public static int ComputeEnumSize(int fieldNumber, int value)
         {
-            return ComputeTagSize(fieldNumber) + ComputeRawVarint32Size((uint) value);
+            return ComputeTagSize(fieldNumber) + ComputeEnumSizeNoTag(value);
         }
 
         /// <summary>
@@ -391,7 +391,7 @@ namespace Google.ProtocolBuffers
         /// </summary>
         public static int ComputeEnumSizeNoTag(int value)
         {
-            return ComputeRawVarint32Size((uint) value);
+            return ComputeInt32SizeNoTag(value);
         }
 
         /// <summary>

+ 2 - 2
src/ProtocolBuffers/CodedOutputStream.cs

@@ -388,7 +388,7 @@ namespace Google.ProtocolBuffers
         public void WriteEnum(int fieldNumber, string fieldName, int value, object rawValue)
         {
             WriteTag(fieldNumber, WireFormat.WireType.Varint);
-            WriteRawVarint32((uint) value);
+            WriteInt32NoTag(value);
         }
 
         public void WriteSFixed32(int fieldNumber, string fieldName, int value)
@@ -663,7 +663,7 @@ namespace Google.ProtocolBuffers
 
         public void WriteEnumNoTag(int value)
         {
-            WriteRawVarint32((uint) value);
+            WriteInt32NoTag(value);
         }
 
         public void WriteSFixed32NoTag(int value)

+ 33 - 5
src/ProtocolBuffers/Collections/PopsicleList.cs

@@ -42,6 +42,7 @@ namespace Google.ProtocolBuffers.Collections
     /// </summary>
     public sealed class PopsicleList<T> : IPopsicleList<T>, ICastArray
     {
+        private static readonly bool CheckForNull = default(T) == null;
         private static readonly T[] EmptySet = new T[0];
 
         private List<T> items;
@@ -65,6 +66,10 @@ namespace Google.ProtocolBuffers.Collections
         public void Insert(int index, T item)
         {
             ValidateModification();
+            if (CheckForNull)
+            {
+                ThrowHelper.ThrowIfNull(item);
+            }
             items.Insert(index, item);
         }
 
@@ -87,6 +92,10 @@ namespace Google.ProtocolBuffers.Collections
             set
             {
                 ValidateModification();
+                if (CheckForNull)
+                {
+                    ThrowHelper.ThrowIfNull(value);
+                }
                 items[index] = value;
             }
         }
@@ -94,6 +103,10 @@ namespace Google.ProtocolBuffers.Collections
         public void Add(T item)
         {
             ValidateModification();
+            if (CheckForNull)
+            {
+                ThrowHelper.ThrowIfNull(item);
+            }
             items.Add(item);
         }
 
@@ -145,15 +158,30 @@ namespace Google.ProtocolBuffers.Collections
 
         public void Add(IEnumerable<T> collection)
         {
-            if (readOnly)
+            ValidateModification();
+            ThrowHelper.ThrowIfNull(collection);
+
+            if (!CheckForNull || collection is PopsicleList<T>)
             {
-                throw new NotSupportedException("List is read-only");
+                items.AddRange(collection);
             }
-            if (items == null)
+            else
             {
-                items = new List<T>();
+                // Assumption, it's ok to enumerate collections more than once.
+                if (collection is ICollection<T>)
+                {
+                    ThrowHelper.ThrowIfAnyNull(collection);
+                    items.AddRange(collection);
+                }
+                else
+                {
+                    foreach (T item in collection)
+                    {
+                        ThrowHelper.ThrowIfNull(item);
+                        items.Add(item);
+                    }
+                }
             }
-            items.AddRange(collection);
         }
 
         private void ValidateModification()

+ 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

+ 297 - 89
src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -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,
@@ -125,15 +126,16 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [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 CSharpFileOptions() { }
+    private static readonly CSharpFileOptions defaultInstance = new CSharpFileOptions().MakeReadOnly();
+    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; }
     }
     
     public override CSharpFileOptions DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override CSharpFileOptions ThisMessage {
@@ -228,6 +230,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 +300,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 +375,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);
         }
@@ -411,11 +429,15 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
     public static CSharpFileOptions ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private CSharpFileOptions MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(CSharpFileOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -425,21 +447,48 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(CSharpFileOptions cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private CSharpFileOptions result;
+      
+      private CSharpFileOptions PrepareBuilder() {
+        if (resultIsReadOnly) {
+          CSharpFileOptions original = result;
+          result = new CSharpFileOptions();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      CSharpFileOptions result = new CSharpFileOptions();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override CSharpFileOptions MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new CSharpFileOptions();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -451,12 +500,11 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       
       public override CSharpFileOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        CSharpFileOptions returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -470,6 +518,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       
       public override Builder MergeFrom(CSharpFileOptions other) {
         if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpFileOptions.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasNamespace) {
           Namespace = other.Namespace;
         }
@@ -494,6 +543,9 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         if (other.HasClsCompliance) {
           ClsCompliance = other.ClsCompliance;
         }
+        if (other.HasAddSerializable) {
+          AddSerializable = other.AddSerializable;
+        }
         if (other.HasFileExtension) {
           FileExtension = other.FileExtension;
         }
@@ -518,6 +570,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -583,6 +636,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;
@@ -630,11 +687,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       public Builder SetNamespace(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasNamespace = true;
         result.namespace_ = value;
         return this;
       }
       public Builder ClearNamespace() {
+        PrepareBuilder();
         result.hasNamespace = false;
         result.namespace_ = "";
         return this;
@@ -649,11 +708,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       public Builder SetUmbrellaClassname(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasUmbrellaClassname = true;
         result.umbrellaClassname_ = value;
         return this;
       }
       public Builder ClearUmbrellaClassname() {
+        PrepareBuilder();
         result.hasUmbrellaClassname = false;
         result.umbrellaClassname_ = "";
         return this;
@@ -667,11 +728,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         set { SetPublicClasses(value); }
       }
       public Builder SetPublicClasses(bool value) {
+        PrepareBuilder();
         result.hasPublicClasses = true;
         result.publicClasses_ = value;
         return this;
       }
       public Builder ClearPublicClasses() {
+        PrepareBuilder();
         result.hasPublicClasses = false;
         result.publicClasses_ = true;
         return this;
@@ -685,11 +748,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         set { SetMultipleFiles(value); }
       }
       public Builder SetMultipleFiles(bool value) {
+        PrepareBuilder();
         result.hasMultipleFiles = true;
         result.multipleFiles_ = value;
         return this;
       }
       public Builder ClearMultipleFiles() {
+        PrepareBuilder();
         result.hasMultipleFiles = false;
         result.multipleFiles_ = false;
         return this;
@@ -703,11 +768,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         set { SetNestClasses(value); }
       }
       public Builder SetNestClasses(bool value) {
+        PrepareBuilder();
         result.hasNestClasses = true;
         result.nestClasses_ = value;
         return this;
       }
       public Builder ClearNestClasses() {
+        PrepareBuilder();
         result.hasNestClasses = false;
         result.nestClasses_ = false;
         return this;
@@ -721,11 +788,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         set { SetCodeContracts(value); }
       }
       public Builder SetCodeContracts(bool value) {
+        PrepareBuilder();
         result.hasCodeContracts = true;
         result.codeContracts_ = value;
         return this;
       }
       public Builder ClearCodeContracts() {
+        PrepareBuilder();
         result.hasCodeContracts = false;
         result.codeContracts_ = false;
         return this;
@@ -739,11 +808,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         set { SetExpandNamespaceDirectories(value); }
       }
       public Builder SetExpandNamespaceDirectories(bool value) {
+        PrepareBuilder();
         result.hasExpandNamespaceDirectories = true;
         result.expandNamespaceDirectories_ = value;
         return this;
       }
       public Builder ClearExpandNamespaceDirectories() {
+        PrepareBuilder();
         result.hasExpandNamespaceDirectories = false;
         result.expandNamespaceDirectories_ = false;
         return this;
@@ -757,16 +828,38 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         set { SetClsCompliance(value); }
       }
       public Builder SetClsCompliance(bool value) {
+        PrepareBuilder();
         result.hasClsCompliance = true;
         result.clsCompliance_ = value;
         return this;
       }
       public Builder ClearClsCompliance() {
+        PrepareBuilder();
         result.hasClsCompliance = false;
         result.clsCompliance_ = true;
         return this;
       }
       
+      public bool HasAddSerializable {
+        get { return result.hasAddSerializable; }
+      }
+      public bool AddSerializable {
+        get { return result.AddSerializable; }
+        set { SetAddSerializable(value); }
+      }
+      public Builder SetAddSerializable(bool value) {
+        PrepareBuilder();
+        result.hasAddSerializable = true;
+        result.addSerializable_ = value;
+        return this;
+      }
+      public Builder ClearAddSerializable() {
+        PrepareBuilder();
+        result.hasAddSerializable = false;
+        result.addSerializable_ = false;
+        return this;
+      }
+      
       public bool HasFileExtension {
         get { return result.hasFileExtension; }
       }
@@ -776,11 +869,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       public Builder SetFileExtension(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasFileExtension = true;
         result.fileExtension_ = value;
         return this;
       }
       public Builder ClearFileExtension() {
+        PrepareBuilder();
         result.hasFileExtension = false;
         result.fileExtension_ = ".cs";
         return this;
@@ -795,11 +890,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       public Builder SetUmbrellaNamespace(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasUmbrellaNamespace = true;
         result.umbrellaNamespace_ = value;
         return this;
       }
       public Builder ClearUmbrellaNamespace() {
+        PrepareBuilder();
         result.hasUmbrellaNamespace = false;
         result.umbrellaNamespace_ = "";
         return this;
@@ -814,11 +911,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       public Builder SetOutputDirectory(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasOutputDirectory = true;
         result.outputDirectory_ = value;
         return this;
       }
       public Builder ClearOutputDirectory() {
+        PrepareBuilder();
         result.hasOutputDirectory = false;
         result.outputDirectory_ = ".";
         return this;
@@ -832,11 +931,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         set { SetIgnoreGoogleProtobuf(value); }
       }
       public Builder SetIgnoreGoogleProtobuf(bool value) {
+        PrepareBuilder();
         result.hasIgnoreGoogleProtobuf = true;
         result.ignoreGoogleProtobuf_ = value;
         return this;
       }
       public Builder ClearIgnoreGoogleProtobuf() {
+        PrepareBuilder();
         result.hasIgnoreGoogleProtobuf = false;
         result.ignoreGoogleProtobuf_ = false;
         return this;
@@ -850,11 +951,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         set { SetServiceGeneratorType(value); }
       }
       public Builder SetServiceGeneratorType(global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType value) {
+        PrepareBuilder();
         result.hasServiceGeneratorType = true;
         result.serviceGeneratorType_ = value;
         return this;
       }
       public Builder ClearServiceGeneratorType() {
+        PrepareBuilder();
         result.hasServiceGeneratorType = false;
         result.serviceGeneratorType_ = global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType.NONE;
         return this;
@@ -869,7 +972,8 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class CSharpFieldOptions : pb::GeneratedMessage<CSharpFieldOptions, CSharpFieldOptions.Builder> {
-    private static readonly CSharpFieldOptions defaultInstance = new Builder().BuildPartial();
+    private CSharpFieldOptions() { }
+    private static readonly CSharpFieldOptions defaultInstance = new CSharpFieldOptions().MakeReadOnly();
     private static readonly string[] _cSharpFieldOptionsFieldNames = new string[] { "property_name" };
     private static readonly uint[] _cSharpFieldOptionsFieldTags = new uint[] { 10 };
     public static CSharpFieldOptions DefaultInstance {
@@ -877,7 +981,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
     }
     
     public override CSharpFieldOptions DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override CSharpFieldOptions ThisMessage {
@@ -963,11 +1067,15 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
     public static CSharpFieldOptions ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private CSharpFieldOptions MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(CSharpFieldOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -977,21 +1085,48 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(CSharpFieldOptions cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
       
-      CSharpFieldOptions result = new CSharpFieldOptions();
+      private bool resultIsReadOnly;
+      private CSharpFieldOptions result;
+      
+      private CSharpFieldOptions PrepareBuilder() {
+        if (resultIsReadOnly) {
+          CSharpFieldOptions original = result;
+          result = new CSharpFieldOptions();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override CSharpFieldOptions MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new CSharpFieldOptions();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -1003,12 +1138,11 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       
       public override CSharpFieldOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        CSharpFieldOptions returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -1022,6 +1156,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       
       public override Builder MergeFrom(CSharpFieldOptions other) {
         if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpFieldOptions.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasPropertyName) {
           PropertyName = other.PropertyName;
         }
@@ -1034,6 +1169,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -1090,11 +1226,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       public Builder SetPropertyName(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasPropertyName = true;
         result.propertyName_ = value;
         return this;
       }
       public Builder ClearPropertyName() {
+        PrepareBuilder();
         result.hasPropertyName = false;
         result.propertyName_ = "";
         return this;
@@ -1109,7 +1247,8 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class CSharpServiceOptions : pb::GeneratedMessage<CSharpServiceOptions, CSharpServiceOptions.Builder> {
-    private static readonly CSharpServiceOptions defaultInstance = new Builder().BuildPartial();
+    private CSharpServiceOptions() { }
+    private static readonly CSharpServiceOptions defaultInstance = new CSharpServiceOptions().MakeReadOnly();
     private static readonly string[] _cSharpServiceOptionsFieldNames = new string[] { "interface_id" };
     private static readonly uint[] _cSharpServiceOptionsFieldTags = new uint[] { 10 };
     public static CSharpServiceOptions DefaultInstance {
@@ -1117,7 +1256,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
     }
     
     public override CSharpServiceOptions DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override CSharpServiceOptions ThisMessage {
@@ -1203,11 +1342,15 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
     public static CSharpServiceOptions ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private CSharpServiceOptions MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(CSharpServiceOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -1217,21 +1360,48 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(CSharpServiceOptions cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
       
-      CSharpServiceOptions result = new CSharpServiceOptions();
+      private bool resultIsReadOnly;
+      private CSharpServiceOptions result;
+      
+      private CSharpServiceOptions PrepareBuilder() {
+        if (resultIsReadOnly) {
+          CSharpServiceOptions original = result;
+          result = new CSharpServiceOptions();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override CSharpServiceOptions MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new CSharpServiceOptions();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -1243,12 +1413,11 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       
       public override CSharpServiceOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        CSharpServiceOptions returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -1262,6 +1431,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       
       public override Builder MergeFrom(CSharpServiceOptions other) {
         if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceOptions.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasInterfaceId) {
           InterfaceId = other.InterfaceId;
         }
@@ -1274,6 +1444,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -1330,11 +1501,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       public Builder SetInterfaceId(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasInterfaceId = true;
         result.interfaceId_ = value;
         return this;
       }
       public Builder ClearInterfaceId() {
+        PrepareBuilder();
         result.hasInterfaceId = false;
         result.interfaceId_ = "";
         return this;
@@ -1349,7 +1522,8 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class CSharpMethodOptions : pb::GeneratedMessage<CSharpMethodOptions, CSharpMethodOptions.Builder> {
-    private static readonly CSharpMethodOptions defaultInstance = new Builder().BuildPartial();
+    private CSharpMethodOptions() { }
+    private static readonly CSharpMethodOptions defaultInstance = new CSharpMethodOptions().MakeReadOnly();
     private static readonly string[] _cSharpMethodOptionsFieldNames = new string[] { "dispatch_id" };
     private static readonly uint[] _cSharpMethodOptionsFieldTags = new uint[] { 8 };
     public static CSharpMethodOptions DefaultInstance {
@@ -1357,7 +1531,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
     }
     
     public override CSharpMethodOptions DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override CSharpMethodOptions ThisMessage {
@@ -1443,11 +1617,15 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
     public static CSharpMethodOptions ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private CSharpMethodOptions MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(CSharpMethodOptions prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -1457,21 +1635,48 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(CSharpMethodOptions cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
       
-      CSharpMethodOptions result = new CSharpMethodOptions();
+      private bool resultIsReadOnly;
+      private CSharpMethodOptions result;
+      
+      private CSharpMethodOptions PrepareBuilder() {
+        if (resultIsReadOnly) {
+          CSharpMethodOptions original = result;
+          result = new CSharpMethodOptions();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override CSharpMethodOptions MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new CSharpMethodOptions();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -1483,12 +1688,11 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       
       public override CSharpMethodOptions BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        CSharpMethodOptions returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -1502,6 +1706,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       
       public override Builder MergeFrom(CSharpMethodOptions other) {
         if (other == global::Google.ProtocolBuffers.DescriptorProtos.CSharpMethodOptions.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasDispatchId) {
           DispatchId = other.DispatchId;
         }
@@ -1514,6 +1719,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -1569,11 +1775,13 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         set { SetDispatchId(value); }
       }
       public Builder SetDispatchId(int value) {
+        PrepareBuilder();
         result.hasDispatchId = true;
         result.dispatchId_ = value;
         return this;
       }
       public Builder ClearDispatchId() {
+        PrepareBuilder();
         result.hasDispatchId = false;
         result.dispatchId_ = 0;
         return this;

Різницю між файлами не показано, бо вона завелика
+ 281 - 95
src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs


+ 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>
     {

+ 4 - 35
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()
     {
@@ -58,12 +58,7 @@ namespace Google.ProtocolBuffers
 
         protected internal FieldAccessorTable<TMessage, TBuilder> InternalFieldAccessors
         {
-            get { return MessageBeingBuilt.FieldAccessorsFromBuilder; }
-        }
-
-        public override bool IsInitialized
-        {
-            get { return MessageBeingBuilt.IsInitialized; }
+            get { return DefaultInstanceForType.FieldAccessorsFromBuilder; }
         }
 
         public override IDictionary<FieldDescriptor, object> AllFields
@@ -84,32 +79,6 @@ namespace Google.ProtocolBuffers
             set { InternalFieldAccessors[field].SetValue(ThisBuilder, value); }
         }
 
-        /// <summary>
-        /// Adds all of the specified values to the given collection.
-        /// </summary>
-        /// <exception cref="ArgumentNullException">Any element of the list is null</exception>
-        protected void AddRange<T>(IEnumerable<T> source, IList<T> destination)
-        {
-            ThrowHelper.ThrowIfNull(source);
-            // We only need to check this for nullable types.
-            if (default(T) == null)
-            {
-                ThrowHelper.ThrowIfAnyNull(source);
-            }
-            List<T> list = destination as List<T>;
-            if (list != null)
-            {
-                list.AddRange(source);
-            }
-            else
-            {
-                foreach (T element in source)
-                {
-                    destination.Add(element);
-                }
-            }
-        }
-
         /// <summary>
         /// Called by derived classes to parse an unknown field.
         /// </summary>
@@ -123,7 +92,7 @@ namespace Google.ProtocolBuffers
 
         public override MessageDescriptor DescriptorForType
         {
-            get { return MessageBeingBuilt.DescriptorForType; }
+            get { return DefaultInstanceForType.DescriptorForType; }
         }
 
         public override int GetRepeatedFieldCount(FieldDescriptor field)
@@ -230,7 +199,7 @@ namespace Google.ProtocolBuffers
         public override TMessage Build()
         {
             // If the message is null, we'll throw a more appropriate exception in BuildPartial.
-            if (MessageBeingBuilt != null && !IsInitialized)
+            if (!IsInitialized)
             {
                 throw new UninitializedMessageException(MessageBeingBuilt);
             }

+ 2 - 33
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>
     {
@@ -61,37 +61,6 @@ namespace Google.ProtocolBuffers
 
         public abstract TBuilder MergeFrom(TMessage other);
 
-        public override bool IsInitialized
-        {
-            get { return MessageBeingBuilt.IsInitialized; }
-        }
-
-        /// <summary>
-        /// Adds all of the specified values to the given collection.
-        /// </summary>
-        /// <exception cref="ArgumentNullException">Any element of the list is null</exception>
-        protected void AddRange<T>(IEnumerable<T> source, IList<T> destination)
-        {
-            ThrowHelper.ThrowIfNull(source);
-            // We only need to check this for nullable types.
-            if (default(T) == null)
-            {
-                ThrowHelper.ThrowIfAnyNull(source);
-            }
-            List<T> list = destination as List<T>;
-            if (list != null)
-            {
-                list.AddRange(source);
-            }
-            else
-            {
-                foreach (T element in source)
-                {
-                    destination.Add(element);
-                }
-            }
-        }
-
         /// <summary>
         /// Called by derived classes to parse an unknown field.
         /// </summary>
@@ -122,7 +91,7 @@ namespace Google.ProtocolBuffers
         public override TMessage Build()
         {
             // If the message is null, we'll throw a more appropriate exception in BuildPartial.
-            if (MessageBeingBuilt != null && !IsInitialized)
+            if (!IsInitialized)
             {
                 throw new UninitializedMessageException(MessageBeingBuilt);
             }

+ 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 - 1
src/ProtocolBuffers/IRpcController.cs

@@ -105,7 +105,7 @@ namespace Google.ProtocolBuffers
         /// well give up on replying to it. This method must be called on the server
         /// side only. The server should still call the final "done" callback.
         /// </summary>
-        bool isCanceled();
+        bool IsCanceled();
 
         /// <summary>
         /// Requests that the given callback be called when the RPC is canceled.

+ 26 - 2
src/ProtocolBuffers/IRpcDispatch.cs

@@ -34,18 +34,42 @@
 
 #endregion
 
+using System;
+
 namespace Google.ProtocolBuffers
 {
     /// <summary>
-    /// 
+    /// Provides an entry-point for transport listeners to call a specified method on a service
     /// </summary>
-    public interface IRpcServerStub
+    public interface IRpcServerStub : IDisposable
     {
+        /// <summary>
+        /// Calls the method identified by methodName and returns the message
+        /// </summary>
+        /// <param name="methodName">The method name on the service descriptor (case-sensitive)</param>
+        /// <param name="input">The ICodedInputStream to deserialize the call parameter from</param>
+        /// <param name="registry">The extension registry to use when deserializing the call parameter</param>
+        /// <returns>The message that was returned from the service's method</returns>
         IMessageLite CallMethod(string methodName, ICodedInputStream input, ExtensionRegistry registry);
     }
 
+    /// <summary>
+    /// Used to forward an invocation of a service method to a transport sender implementation
+    /// </summary>
     public interface IRpcDispatch
     {
+        /// <summary>
+        /// Calls the service member on the endpoint connected.  This is generally done by serializing
+        /// the message, sending the bytes over a transport, and then deserializing the call parameter
+        /// to invoke the service's actual implementation via IRpcServerStub.  Once the call has
+        /// completed the result message is serialized and returned to the originating endpoint.
+        /// </summary>
+        /// <typeparam name="TMessage">The type of the response message</typeparam>
+        /// <typeparam name="TBuilder">The type of of the response builder</typeparam>
+        /// <param name="method">The name of the method on the service</param>
+        /// <param name="request">The message instance provided to the service call</param>
+        /// <param name="response">The builder used to deserialize the response</param>
+        /// <returns>The resulting message of the service call</returns>
         TMessage CallMethod<TMessage, TBuilder>(string method, IMessageLite request,
                                                 IBuilderLite<TMessage, TBuilder> response)
             where TMessage : IMessageLite<TMessage, TBuilder>

+ 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());
+        }
+    }
+}

Різницю між файлами не показано, бо вона завелика
+ 327 - 93
src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasFullProtoFile.cs


+ 295 - 78
src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -55,11 +55,13 @@ 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")]
   public sealed partial class TestRequiredLite : pb::GeneratedMessageLite<TestRequiredLite, TestRequiredLite.Builder> {
-    private static readonly TestRequiredLite defaultInstance = new Builder().BuildPartial();
+    private TestRequiredLite() { }
+    private static readonly TestRequiredLite defaultInstance = new TestRequiredLite().MakeReadOnly();
     private static readonly string[] _testRequiredLiteFieldNames = new string[] { "d", "en" };
     private static readonly uint[] _testRequiredLiteFieldTags = new uint[] { 8, 16 };
     public static TestRequiredLite DefaultInstance {
@@ -67,7 +69,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override TestRequiredLite DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override TestRequiredLite ThisMessage {
@@ -183,13 +185,18 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static TestRequiredLite ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private TestRequiredLite MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(TestRequiredLite prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
+    [global::System.SerializableAttribute()]
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
     [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
@@ -197,21 +204,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(TestRequiredLite cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private TestRequiredLite result;
+      
+      private TestRequiredLite PrepareBuilder() {
+        if (resultIsReadOnly) {
+          TestRequiredLite original = result;
+          result = new TestRequiredLite();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      TestRequiredLite result = new TestRequiredLite();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override TestRequiredLite MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new TestRequiredLite();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override TestRequiredLite DefaultInstanceForType {
@@ -219,12 +253,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override TestRequiredLite BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        TestRequiredLite returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessageLite other) {
@@ -238,6 +271,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(TestRequiredLite other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.TestRequiredLite.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasD) {
           D = other.D;
         }
@@ -252,6 +286,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
@@ -302,11 +337,13 @@ namespace Google.ProtocolBuffers.TestProtos {
         set { SetD(value); }
       }
       public Builder SetD(int value) {
+        PrepareBuilder();
         result.hasD = true;
         result.d_ = value;
         return this;
       }
       public Builder ClearD() {
+        PrepareBuilder();
         result.hasD = false;
         result.d_ = 0;
         return this;
@@ -320,11 +357,13 @@ namespace Google.ProtocolBuffers.TestProtos {
         set { SetEn(value); }
       }
       public Builder SetEn(global::Google.ProtocolBuffers.TestProtos.ExtraEnum value) {
+        PrepareBuilder();
         result.hasEn = true;
         result.en_ = value;
         return this;
       }
       public Builder ClearEn() {
+        PrepareBuilder();
         result.hasEn = false;
         result.en_ = global::Google.ProtocolBuffers.TestProtos.ExtraEnum.DEFAULT;
         return this;
@@ -335,11 +374,13 @@ 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")]
   public sealed partial class TestInteropPersonLite : pb::ExtendableMessageLite<TestInteropPersonLite, TestInteropPersonLite.Builder> {
-    private static readonly TestInteropPersonLite defaultInstance = new Builder().BuildPartial();
+    private TestInteropPersonLite() { }
+    private static readonly TestInteropPersonLite defaultInstance = new TestInteropPersonLite().MakeReadOnly();
     private static readonly string[] _testInteropPersonLiteFieldNames = new string[] { "addresses", "codes", "email", "id", "name", "phone" };
     private static readonly uint[] _testInteropPersonLiteFieldTags = new uint[] { 43, 82, 26, 16, 10, 34 };
     public static TestInteropPersonLite DefaultInstance {
@@ -347,7 +388,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override TestInteropPersonLite DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override TestInteropPersonLite ThisMessage {
@@ -367,11 +408,13 @@ 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")]
       public sealed partial class PhoneNumber : pb::GeneratedMessageLite<PhoneNumber, PhoneNumber.Builder> {
-        private static readonly PhoneNumber defaultInstance = new Builder().BuildPartial();
+        private PhoneNumber() { }
+        private static readonly PhoneNumber defaultInstance = new PhoneNumber().MakeReadOnly();
         private static readonly string[] _phoneNumberFieldNames = new string[] { "number", "type" };
         private static readonly uint[] _phoneNumberFieldTags = new uint[] { 10, 16 };
         public static PhoneNumber DefaultInstance {
@@ -379,7 +422,7 @@ namespace Google.ProtocolBuffers.TestProtos {
         }
         
         public override PhoneNumber DefaultInstanceForType {
-          get { return defaultInstance; }
+          get { return DefaultInstance; }
         }
         
         protected override PhoneNumber ThisMessage {
@@ -494,13 +537,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         public static PhoneNumber ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
           return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
         }
+        private PhoneNumber MakeReadOnly() {
+          return this;
+        }
+        
         public static Builder CreateBuilder() { return new Builder(); }
         public override Builder ToBuilder() { return CreateBuilder(this); }
         public override Builder CreateBuilderForType() { return new Builder(); }
         public static Builder CreateBuilder(PhoneNumber prototype) {
-          return (Builder) new Builder().MergeFrom(prototype);
+          return new Builder(prototype);
         }
         
+        [global::System.SerializableAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
         [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
         [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
@@ -508,21 +556,48 @@ namespace Google.ProtocolBuffers.TestProtos {
           protected override Builder ThisBuilder {
             get { return this; }
           }
-          public Builder() {}
+          public Builder() {
+            result = DefaultInstance;
+            resultIsReadOnly = true;
+          }
+          internal Builder(PhoneNumber cloneFrom) {
+            result = cloneFrom;
+            resultIsReadOnly = true;
+          }
+          
+          private bool resultIsReadOnly;
+          private PhoneNumber result;
+          
+          private PhoneNumber PrepareBuilder() {
+            if (resultIsReadOnly) {
+              PhoneNumber original = result;
+              result = new PhoneNumber();
+              resultIsReadOnly = false;
+              MergeFrom(original);
+            }
+            return result;
+          }
           
-          PhoneNumber result = new PhoneNumber();
+          public override bool IsInitialized {
+            get { return result.IsInitialized; }
+          }
           
           protected override PhoneNumber MessageBeingBuilt {
-            get { return result; }
+            get { return PrepareBuilder(); }
           }
           
           public override Builder Clear() {
-            result = new PhoneNumber();
+            result = DefaultInstance;
+            resultIsReadOnly = true;
             return this;
           }
           
           public override Builder Clone() {
-            return new Builder().MergeFrom(result);
+            if (resultIsReadOnly) {
+              return new Builder(result);
+            } else {
+              return new Builder().MergeFrom(result);
+            }
           }
           
           public override PhoneNumber DefaultInstanceForType {
@@ -530,12 +605,11 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           
           public override PhoneNumber BuildPartial() {
-            if (result == null) {
-              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+            if (resultIsReadOnly) {
+              return result;
             }
-            PhoneNumber returnMe = result;
-            result = null;
-            return returnMe;
+            resultIsReadOnly = true;
+            return result.MakeReadOnly();
           }
           
           public override Builder MergeFrom(pb::IMessageLite other) {
@@ -549,6 +623,7 @@ namespace Google.ProtocolBuffers.TestProtos {
           
           public override Builder MergeFrom(PhoneNumber other) {
             if (other == global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.DefaultInstance) return this;
+            PrepareBuilder();
             if (other.HasNumber) {
               Number = other.Number;
             }
@@ -563,6 +638,7 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           
           public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+            PrepareBuilder();
             uint tag;
             string field_name;
             while (input.ReadTag(out tag, out field_name)) {
@@ -614,11 +690,13 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           public Builder SetNumber(string value) {
             pb::ThrowHelper.ThrowIfNull(value, "value");
+            PrepareBuilder();
             result.hasNumber = true;
             result.number_ = value;
             return this;
           }
           public Builder ClearNumber() {
+            PrepareBuilder();
             result.hasNumber = false;
             result.number_ = "";
             return this;
@@ -632,11 +710,13 @@ namespace Google.ProtocolBuffers.TestProtos {
             set { SetType(value); }
           }
           public Builder SetType(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType value) {
+            PrepareBuilder();
             result.hasType = true;
             result.type_ = value;
             return this;
           }
           public Builder ClearType() {
+            PrepareBuilder();
             result.hasType = false;
             result.type_ = global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType.HOME;
             return this;
@@ -647,11 +727,13 @@ 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")]
       public sealed partial class Addresses : pb::GeneratedMessageLite<Addresses, Addresses.Builder> {
-        private static readonly Addresses defaultInstance = new Builder().BuildPartial();
+        private Addresses() { }
+        private static readonly Addresses defaultInstance = new Addresses().MakeReadOnly();
         private static readonly string[] _addressesFieldNames = new string[] { "address", "address2", "city", "state", "zip" };
         private static readonly uint[] _addressesFieldTags = new uint[] { 10, 18, 26, 34, 45 };
         public static Addresses DefaultInstance {
@@ -659,7 +741,7 @@ namespace Google.ProtocolBuffers.TestProtos {
         }
         
         public override Addresses DefaultInstanceForType {
-          get { return defaultInstance; }
+          get { return DefaultInstance; }
         }
         
         protected override Addresses ThisMessage {
@@ -835,13 +917,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         public static Addresses ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
           return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
         }
+        private Addresses MakeReadOnly() {
+          return this;
+        }
+        
         public static Builder CreateBuilder() { return new Builder(); }
         public override Builder ToBuilder() { return CreateBuilder(this); }
         public override Builder CreateBuilderForType() { return new Builder(); }
         public static Builder CreateBuilder(Addresses prototype) {
-          return (Builder) new Builder().MergeFrom(prototype);
+          return new Builder(prototype);
         }
         
+        [global::System.SerializableAttribute()]
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
         [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
         [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
@@ -849,21 +936,48 @@ namespace Google.ProtocolBuffers.TestProtos {
           protected override Builder ThisBuilder {
             get { return this; }
           }
-          public Builder() {}
+          public Builder() {
+            result = DefaultInstance;
+            resultIsReadOnly = true;
+          }
+          internal Builder(Addresses cloneFrom) {
+            result = cloneFrom;
+            resultIsReadOnly = true;
+          }
+          
+          private bool resultIsReadOnly;
+          private Addresses result;
+          
+          private Addresses PrepareBuilder() {
+            if (resultIsReadOnly) {
+              Addresses original = result;
+              result = new Addresses();
+              resultIsReadOnly = false;
+              MergeFrom(original);
+            }
+            return result;
+          }
           
-          Addresses result = new Addresses();
+          public override bool IsInitialized {
+            get { return result.IsInitialized; }
+          }
           
           protected override Addresses MessageBeingBuilt {
-            get { return result; }
+            get { return PrepareBuilder(); }
           }
           
           public override Builder Clear() {
-            result = new Addresses();
+            result = DefaultInstance;
+            resultIsReadOnly = true;
             return this;
           }
           
           public override Builder Clone() {
-            return new Builder().MergeFrom(result);
+            if (resultIsReadOnly) {
+              return new Builder(result);
+            } else {
+              return new Builder().MergeFrom(result);
+            }
           }
           
           public override Addresses DefaultInstanceForType {
@@ -871,12 +985,11 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           
           public override Addresses BuildPartial() {
-            if (result == null) {
-              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+            if (resultIsReadOnly) {
+              return result;
             }
-            Addresses returnMe = result;
-            result = null;
-            return returnMe;
+            resultIsReadOnly = true;
+            return result.MakeReadOnly();
           }
           
           public override Builder MergeFrom(pb::IMessageLite other) {
@@ -890,6 +1003,7 @@ namespace Google.ProtocolBuffers.TestProtos {
           
           public override Builder MergeFrom(Addresses other) {
             if (other == global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.DefaultInstance) return this;
+            PrepareBuilder();
             if (other.HasAddress) {
               Address = other.Address;
             }
@@ -913,6 +1027,7 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           
           public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+            PrepareBuilder();
             uint tag;
             string field_name;
             while (input.ReadTag(out tag, out field_name)) {
@@ -972,11 +1087,13 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           public Builder SetAddress(string value) {
             pb::ThrowHelper.ThrowIfNull(value, "value");
+            PrepareBuilder();
             result.hasAddress = true;
             result.address_ = value;
             return this;
           }
           public Builder ClearAddress() {
+            PrepareBuilder();
             result.hasAddress = false;
             result.address_ = "";
             return this;
@@ -991,11 +1108,13 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           public Builder SetAddress2(string value) {
             pb::ThrowHelper.ThrowIfNull(value, "value");
+            PrepareBuilder();
             result.hasAddress2 = true;
             result.address2_ = value;
             return this;
           }
           public Builder ClearAddress2() {
+            PrepareBuilder();
             result.hasAddress2 = false;
             result.address2_ = "";
             return this;
@@ -1010,11 +1129,13 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           public Builder SetCity(string value) {
             pb::ThrowHelper.ThrowIfNull(value, "value");
+            PrepareBuilder();
             result.hasCity = true;
             result.city_ = value;
             return this;
           }
           public Builder ClearCity() {
+            PrepareBuilder();
             result.hasCity = false;
             result.city_ = "";
             return this;
@@ -1029,11 +1150,13 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           public Builder SetState(string value) {
             pb::ThrowHelper.ThrowIfNull(value, "value");
+            PrepareBuilder();
             result.hasState = true;
             result.state_ = value;
             return this;
           }
           public Builder ClearState() {
+            PrepareBuilder();
             result.hasState = false;
             result.state_ = "";
             return this;
@@ -1049,11 +1172,13 @@ namespace Google.ProtocolBuffers.TestProtos {
           }
           [global::System.CLSCompliant(false)]
           public Builder SetZip(uint value) {
+            PrepareBuilder();
             result.hasZip = true;
             result.zip_ = value;
             return this;
           }
           public Builder ClearZip() {
+            PrepareBuilder();
             result.hasZip = false;
             result.zip_ = 0;
             return this;
@@ -1286,13 +1411,21 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static TestInteropPersonLite ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private TestInteropPersonLite MakeReadOnly() {
+      codes_.MakeReadOnly();
+      phone_.MakeReadOnly();
+      addresses_.MakeReadOnly();
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(TestInteropPersonLite prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
+    [global::System.SerializableAttribute()]
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
     [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
@@ -1300,21 +1433,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(TestInteropPersonLite cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
       
-      TestInteropPersonLite result = new TestInteropPersonLite();
+      private bool resultIsReadOnly;
+      private TestInteropPersonLite result;
+      
+      private TestInteropPersonLite PrepareBuilder() {
+        if (resultIsReadOnly) {
+          TestInteropPersonLite original = result;
+          result = new TestInteropPersonLite();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override TestInteropPersonLite MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new TestInteropPersonLite();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override TestInteropPersonLite DefaultInstanceForType {
@@ -1322,15 +1482,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override TestInteropPersonLite BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        result.codes_.MakeReadOnly();
-        result.phone_.MakeReadOnly();
-        result.addresses_.MakeReadOnly();
-        TestInteropPersonLite returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessageLite other) {
@@ -1344,6 +1500,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(TestInteropPersonLite other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasName) {
           Name = other.Name;
         }
@@ -1354,13 +1511,13 @@ namespace Google.ProtocolBuffers.TestProtos {
           Email = other.Email;
         }
         if (other.codes_.Count != 0) {
-          base.AddRange(other.codes_, result.codes_);
+          result.codes_.Add(other.codes_);
         }
         if (other.phone_.Count != 0) {
-          base.AddRange(other.phone_, result.phone_);
+          result.phone_.Add(other.phone_);
         }
         if (other.addresses_.Count != 0) {
-          base.AddRange(other.addresses_, result.addresses_);
+          result.addresses_.Add(other.addresses_);
         }
           this.MergeExtensionFields(other);
         return this;
@@ -1371,6 +1528,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
@@ -1435,11 +1593,13 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetName(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasName = true;
         result.name_ = value;
         return this;
       }
       public Builder ClearName() {
+        PrepareBuilder();
         result.hasName = false;
         result.name_ = "";
         return this;
@@ -1453,11 +1613,13 @@ namespace Google.ProtocolBuffers.TestProtos {
         set { SetId(value); }
       }
       public Builder SetId(int value) {
+        PrepareBuilder();
         result.hasId = true;
         result.id_ = value;
         return this;
       }
       public Builder ClearId() {
+        PrepareBuilder();
         result.hasId = false;
         result.id_ = 0;
         return this;
@@ -1472,18 +1634,20 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetEmail(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasEmail = true;
         result.email_ = value;
         return this;
       }
       public Builder ClearEmail() {
+        PrepareBuilder();
         result.hasEmail = false;
         result.email_ = "";
         return this;
       }
       
       public pbc::IPopsicleList<int> CodesList {
-        get { return result.codes_; }
+        get { return PrepareBuilder().codes_; }
       }
       public int CodesCount {
         get { return result.CodesCount; }
@@ -1492,24 +1656,28 @@ namespace Google.ProtocolBuffers.TestProtos {
         return result.GetCodes(index);
       }
       public Builder SetCodes(int index, int value) {
+        PrepareBuilder();
         result.codes_[index] = value;
         return this;
       }
       public Builder AddCodes(int value) {
+        PrepareBuilder();
         result.codes_.Add(value);
         return this;
       }
       public Builder AddRangeCodes(scg::IEnumerable<int> values) {
-        base.AddRange(values, result.codes_);
+        PrepareBuilder();
+        result.codes_.Add(values);
         return this;
       }
       public Builder ClearCodes() {
+        PrepareBuilder();
         result.codes_.Clear();
         return this;
       }
       
       public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber> PhoneList {
-        get { return result.phone_; }
+        get { return PrepareBuilder().phone_; }
       }
       public int PhoneCount {
         get { return result.PhoneCount; }
@@ -1519,35 +1687,41 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetPhone(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.phone_[index] = value;
         return this;
       }
       public Builder SetPhone(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.phone_[index] = builderForValue.Build();
         return this;
       }
       public Builder AddPhone(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.phone_.Add(value);
         return this;
       }
       public Builder AddPhone(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.phone_.Add(builderForValue.Build());
         return this;
       }
       public Builder AddRangePhone(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber> values) {
-        base.AddRange(values, result.phone_);
+        PrepareBuilder();
+        result.phone_.Add(values);
         return this;
       }
       public Builder ClearPhone() {
+        PrepareBuilder();
         result.phone_.Clear();
         return this;
       }
       
       public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses> AddressesList {
-        get { return result.addresses_; }
+        get { return PrepareBuilder().addresses_; }
       }
       public int AddressesCount {
         get { return result.AddressesCount; }
@@ -1557,29 +1731,35 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetAddresses(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.addresses_[index] = value;
         return this;
       }
       public Builder SetAddresses(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.addresses_[index] = builderForValue.Build();
         return this;
       }
       public Builder AddAddresses(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.addresses_.Add(value);
         return this;
       }
       public Builder AddAddresses(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.addresses_.Add(builderForValue.Build());
         return this;
       }
       public Builder AddRangeAddresses(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses> values) {
-        base.AddRange(values, result.addresses_);
+        PrepareBuilder();
+        result.addresses_.Add(values);
         return this;
       }
       public Builder ClearAddresses() {
+        PrepareBuilder();
         result.addresses_.Clear();
         return this;
       }
@@ -1589,11 +1769,13 @@ 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")]
   public sealed partial class TestInteropEmployeeIdLite : pb::GeneratedMessageLite<TestInteropEmployeeIdLite, TestInteropEmployeeIdLite.Builder> {
-    private static readonly TestInteropEmployeeIdLite defaultInstance = new Builder().BuildPartial();
+    private TestInteropEmployeeIdLite() { }
+    private static readonly TestInteropEmployeeIdLite defaultInstance = new TestInteropEmployeeIdLite().MakeReadOnly();
     private static readonly string[] _testInteropEmployeeIdLiteFieldNames = new string[] { "number" };
     private static readonly uint[] _testInteropEmployeeIdLiteFieldTags = new uint[] { 10 };
     public static TestInteropEmployeeIdLite DefaultInstance {
@@ -1601,7 +1783,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override TestInteropEmployeeIdLite DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override TestInteropEmployeeIdLite ThisMessage {
@@ -1697,13 +1879,18 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static TestInteropEmployeeIdLite ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private TestInteropEmployeeIdLite MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(TestInteropEmployeeIdLite prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
+    [global::System.SerializableAttribute()]
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
     [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
@@ -1711,21 +1898,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(TestInteropEmployeeIdLite cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
       
-      TestInteropEmployeeIdLite result = new TestInteropEmployeeIdLite();
+      private bool resultIsReadOnly;
+      private TestInteropEmployeeIdLite result;
+      
+      private TestInteropEmployeeIdLite PrepareBuilder() {
+        if (resultIsReadOnly) {
+          TestInteropEmployeeIdLite original = result;
+          result = new TestInteropEmployeeIdLite();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
+      
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override TestInteropEmployeeIdLite MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new TestInteropEmployeeIdLite();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override TestInteropEmployeeIdLite DefaultInstanceForType {
@@ -1733,12 +1947,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override TestInteropEmployeeIdLite BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        TestInteropEmployeeIdLite returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessageLite other) {
@@ -1752,6 +1965,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(TestInteropEmployeeIdLite other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeIdLite.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasNumber) {
           Number = other.Number;
         }
@@ -1763,6 +1977,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
@@ -1806,11 +2021,13 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetNumber(string value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasNumber = true;
         result.number_ = value;
         return this;
       }
       public Builder ClearNumber() {
+        PrepareBuilder();
         result.hasNumber = false;
         result.number_ = "";
         return this;

+ 49 - 14
src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportLiteProtoFile.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -43,7 +43,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class ImportMessageLite : pb::GeneratedMessageLite<ImportMessageLite, ImportMessageLite.Builder> {
-    private static readonly ImportMessageLite defaultInstance = new Builder().BuildPartial();
+    private ImportMessageLite() { }
+    private static readonly ImportMessageLite defaultInstance = new ImportMessageLite().MakeReadOnly();
     private static readonly string[] _importMessageLiteFieldNames = new string[] { "d" };
     private static readonly uint[] _importMessageLiteFieldTags = new uint[] { 8 };
     public static ImportMessageLite DefaultInstance {
@@ -51,7 +52,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override ImportMessageLite DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override ImportMessageLite ThisMessage {
@@ -146,11 +147,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static ImportMessageLite ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private ImportMessageLite MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(ImportMessageLite prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -160,21 +165,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(ImportMessageLite cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private ImportMessageLite result;
+      
+      private ImportMessageLite PrepareBuilder() {
+        if (resultIsReadOnly) {
+          ImportMessageLite original = result;
+          result = new ImportMessageLite();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      ImportMessageLite result = new ImportMessageLite();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override ImportMessageLite MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new ImportMessageLite();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override ImportMessageLite DefaultInstanceForType {
@@ -182,12 +214,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override ImportMessageLite BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        ImportMessageLite returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessageLite other) {
@@ -201,6 +232,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(ImportMessageLite other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.ImportMessageLite.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasD) {
           D = other.D;
         }
@@ -212,6 +244,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
@@ -254,11 +287,13 @@ namespace Google.ProtocolBuffers.TestProtos {
         set { SetD(value); }
       }
       public Builder SetD(int value) {
+        PrepareBuilder();
         result.hasD = true;
         result.d_ = value;
         return this;
       }
       public Builder ClearD() {
+        PrepareBuilder();
         result.hasD = false;
         result.d_ = 0;
         return this;

+ 49 - 14
src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportProtoFile.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -71,7 +71,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class ImportMessage : pb::GeneratedMessage<ImportMessage, ImportMessage.Builder> {
-    private static readonly ImportMessage defaultInstance = new Builder().BuildPartial();
+    private ImportMessage() { }
+    private static readonly ImportMessage defaultInstance = new ImportMessage().MakeReadOnly();
     private static readonly string[] _importMessageFieldNames = new string[] { "d" };
     private static readonly uint[] _importMessageFieldTags = new uint[] { 8 };
     public static ImportMessage DefaultInstance {
@@ -79,7 +80,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override ImportMessage DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override ImportMessage ThisMessage {
@@ -165,11 +166,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static ImportMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private ImportMessage MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(ImportMessage prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -179,21 +184,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(ImportMessage cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private ImportMessage result;
+      
+      private ImportMessage PrepareBuilder() {
+        if (resultIsReadOnly) {
+          ImportMessage original = result;
+          result = new ImportMessage();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      ImportMessage result = new ImportMessage();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override ImportMessage MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new ImportMessage();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override pbd::MessageDescriptor DescriptorForType {
@@ -205,12 +237,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override ImportMessage BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        ImportMessage returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessage other) {
@@ -224,6 +255,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(ImportMessage other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.ImportMessage.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasD) {
           D = other.D;
         }
@@ -236,6 +268,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         pb::UnknownFieldSet.Builder unknownFields = null;
         uint tag;
         string field_name;
@@ -291,11 +324,13 @@ namespace Google.ProtocolBuffers.TestProtos {
         set { SetD(value); }
       }
       public Builder SetD(int value) {
+        PrepareBuilder();
         result.hasD = true;
         result.d_ = value;
         return this;
       }
       public Builder ClearD() {
+        PrepareBuilder();
         result.hasD = false;
         result.d_ = 0;
         return this;

+ 54 - 17
src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteImportNonLiteProtoFile.cs

@@ -1,5 +1,5 @@
 // Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!
-#pragma warning disable 1591
+#pragma warning disable 1591, 0612
 #region Designer generated code
 
 using pb = global::Google.ProtocolBuffers;
@@ -32,7 +32,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestLiteImportsNonlite : pb::GeneratedMessageLite<TestLiteImportsNonlite, TestLiteImportsNonlite.Builder> {
-    private static readonly TestLiteImportsNonlite defaultInstance = new Builder().BuildPartial();
+    private TestLiteImportsNonlite() { }
+    private static readonly TestLiteImportsNonlite defaultInstance = new TestLiteImportsNonlite().MakeReadOnly();
     private static readonly string[] _testLiteImportsNonliteFieldNames = new string[] { "message" };
     private static readonly uint[] _testLiteImportsNonliteFieldTags = new uint[] { 10 };
     public static TestLiteImportsNonlite DefaultInstance {
@@ -40,7 +41,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     }
     
     public override TestLiteImportsNonlite DefaultInstanceForType {
-      get { return defaultInstance; }
+      get { return DefaultInstance; }
     }
     
     protected override TestLiteImportsNonlite ThisMessage {
@@ -49,12 +50,12 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public const int MessageFieldNumber = 1;
     private bool hasMessage;
-    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes message_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance;
+    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes message_;
     public bool HasMessage {
       get { return hasMessage; }
     }
     public global::Google.ProtocolBuffers.TestProtos.TestAllTypes Message {
-      get { return message_; }
+      get { return message_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
     }
     
     public override bool IsInitialized {
@@ -135,11 +136,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     public static TestLiteImportsNonlite ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
       return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
     }
+    private TestLiteImportsNonlite MakeReadOnly() {
+      return this;
+    }
+    
     public static Builder CreateBuilder() { return new Builder(); }
     public override Builder ToBuilder() { return CreateBuilder(this); }
     public override Builder CreateBuilderForType() { return new Builder(); }
     public static Builder CreateBuilder(TestLiteImportsNonlite prototype) {
-      return (Builder) new Builder().MergeFrom(prototype);
+      return new Builder(prototype);
     }
     
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
@@ -149,21 +154,48 @@ namespace Google.ProtocolBuffers.TestProtos {
       protected override Builder ThisBuilder {
         get { return this; }
       }
-      public Builder() {}
+      public Builder() {
+        result = DefaultInstance;
+        resultIsReadOnly = true;
+      }
+      internal Builder(TestLiteImportsNonlite cloneFrom) {
+        result = cloneFrom;
+        resultIsReadOnly = true;
+      }
+      
+      private bool resultIsReadOnly;
+      private TestLiteImportsNonlite result;
+      
+      private TestLiteImportsNonlite PrepareBuilder() {
+        if (resultIsReadOnly) {
+          TestLiteImportsNonlite original = result;
+          result = new TestLiteImportsNonlite();
+          resultIsReadOnly = false;
+          MergeFrom(original);
+        }
+        return result;
+      }
       
-      TestLiteImportsNonlite result = new TestLiteImportsNonlite();
+      public override bool IsInitialized {
+        get { return result.IsInitialized; }
+      }
       
       protected override TestLiteImportsNonlite MessageBeingBuilt {
-        get { return result; }
+        get { return PrepareBuilder(); }
       }
       
       public override Builder Clear() {
-        result = new TestLiteImportsNonlite();
+        result = DefaultInstance;
+        resultIsReadOnly = true;
         return this;
       }
       
       public override Builder Clone() {
-        return new Builder().MergeFrom(result);
+        if (resultIsReadOnly) {
+          return new Builder(result);
+        } else {
+          return new Builder().MergeFrom(result);
+        }
       }
       
       public override TestLiteImportsNonlite DefaultInstanceForType {
@@ -171,12 +203,11 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override TestLiteImportsNonlite BuildPartial() {
-        if (result == null) {
-          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
+        if (resultIsReadOnly) {
+          return result;
         }
-        TestLiteImportsNonlite returnMe = result;
-        result = null;
-        return returnMe;
+        resultIsReadOnly = true;
+        return result.MakeReadOnly();
       }
       
       public override Builder MergeFrom(pb::IMessageLite other) {
@@ -190,6 +221,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       
       public override Builder MergeFrom(TestLiteImportsNonlite other) {
         if (other == global::Google.ProtocolBuffers.TestProtos.TestLiteImportsNonlite.DefaultInstance) return this;
+        PrepareBuilder();
         if (other.HasMessage) {
           MergeMessage(other.Message);
         }
@@ -201,6 +233,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       
       public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
+        PrepareBuilder();
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
@@ -249,18 +282,21 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
       public Builder SetMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         result.hasMessage = true;
         result.message_ = value;
         return this;
       }
       public Builder SetMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
         pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
+        PrepareBuilder();
         result.hasMessage = true;
         result.message_ = builderForValue.Build();
         return this;
       }
       public Builder MergeMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
         pb::ThrowHelper.ThrowIfNull(value, "value");
+        PrepareBuilder();
         if (result.hasMessage &&
             result.message_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) {
             result.message_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder(result.message_).MergeFrom(value).BuildPartial();
@@ -271,8 +307,9 @@ namespace Google.ProtocolBuffers.TestProtos {
         return this;
       }
       public Builder ClearMessage() {
+        PrepareBuilder();
         result.hasMessage = false;
-        result.message_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance;
+        result.message_ = null;
         return this;
       }
     }

Різницю між файлами не показано, бо вона завелика
+ 286 - 111
src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteProtoFile.cs


Різницю між файлами не показано, бо вона завелика
+ 286 - 111
src/ProtocolBuffersLite.Test/TestProtos/UnitTestProtoFile.cs


+ 0 - 16
todo.txt

@@ -1,16 +0,0 @@
-Current task list (not in order)
-
-- Remove multifile support
-- Docs
-- Clean up protogen code
-- Avoid using reflection for messages which don't need it (is this
-  possible?)
-- Bring service generation into line with Java
-- Build protoc as a dll and use directly from protogen
-- Check copyright is everywhere
-- Work out how to unit test Silverlight code
-- Reformat code
-- Change generated format
-- Add regions to copyright
-- Build and publish binaries
-- Work out why the Compact Framework 3.5 build fails under VS2010

Деякі файли не було показано, через те що забагато файлів було змінено