Bladeren bron

First stab at new proto3-only code generator

Jon Skeet 10 jaren geleden
bovenliggende
commit
f52426827e
26 gewijzigde bestanden met toevoegingen van 295 en 2095 verwijderingen
  1. 1 5
      src/Makefile.am
  2. 1 1
      src/google/protobuf/compiler/csharp/csharp_enum.cc
  3. 13 36
      src/google/protobuf/compiler/csharp/csharp_enum_field.cc
  4. 0 184
      src/google/protobuf/compiler/csharp/csharp_extension.cc
  5. 0 78
      src/google/protobuf/compiler/csharp/csharp_extension.h
  6. 4 33
      src/google/protobuf/compiler/csharp/csharp_field_base.cc
  7. 0 5
      src/google/protobuf/compiler/csharp/csharp_field_base.h
  8. 153 702
      src/google/protobuf/compiler/csharp/csharp_message.cc
  9. 1 13
      src/google/protobuf/compiler/csharp/csharp_message.h
  10. 30 201
      src/google/protobuf/compiler/csharp/csharp_message_field.cc
  11. 0 6
      src/google/protobuf/compiler/csharp/csharp_message_field.h
  12. 40 137
      src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
  13. 3 6
      src/google/protobuf/compiler/csharp/csharp_primitive_field.h
  14. 15 116
      src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
  15. 2 4
      src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h
  16. 14 106
      src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc
  17. 0 4
      src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h
  18. 14 105
      src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
  19. 0 4
      src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
  20. 0 8
      src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc
  21. 0 17
      src/google/protobuf/compiler/csharp/csharp_source_generator_base.h
  22. 4 84
      src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc
  23. 0 7
      src/google/protobuf/compiler/csharp/csharp_umbrella_class.h
  24. 0 136
      src/google/protobuf/compiler/csharp/csharp_writer.cc
  25. 0 93
      src/google/protobuf/compiler/csharp/csharp_writer.h
  26. 0 4
      vsprojects/libprotoc.vcproj

+ 1 - 5
src/Makefile.am

@@ -369,8 +369,6 @@ libprotoc_la_SOURCES =                                         \
   google/protobuf/compiler/csharp/csharp_enum.h                \
   google/protobuf/compiler/csharp/csharp_enum_field.cc         \
   google/protobuf/compiler/csharp/csharp_enum_field.h          \
-  google/protobuf/compiler/csharp/csharp_extension.cc          \
-  google/protobuf/compiler/csharp/csharp_extension.h           \
   google/protobuf/compiler/csharp/csharp_field_base.cc         \
   google/protobuf/compiler/csharp/csharp_field_base.h          \
   google/protobuf/compiler/csharp/csharp_generator.cc          \
@@ -391,9 +389,7 @@ libprotoc_la_SOURCES =                                         \
   google/protobuf/compiler/csharp/csharp_source_generator_base.cc \
   google/protobuf/compiler/csharp/csharp_source_generator_base.h \
   google/protobuf/compiler/csharp/csharp_umbrella_class.cc     \
-  google/protobuf/compiler/csharp/csharp_umbrella_class.h      \
-  google/protobuf/compiler/csharp/csharp_writer.cc             \
-  google/protobuf/compiler/csharp/csharp_writer.h
+  google/protobuf/compiler/csharp/csharp_umbrella_class.h
 
 bin_PROGRAMS = protoc
 protoc_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la

+ 1 - 1
src/google/protobuf/compiler/csharp/csharp_enum.cc

@@ -58,7 +58,7 @@ EnumGenerator::~EnumGenerator() {
 
 void EnumGenerator::Generate(io::Printer* printer) {
   WriteGeneratedCodeAttributes(printer);
-  printer->Print("$access_level$ enum $name$ {\n",
+  printer->Print("$access_level$ enum $name$ : long {\n",
                  "access_level", class_access_level(),
                  "name", descriptor_->name());
   printer->Indent();

+ 13 - 36
src/google/protobuf/compiler/csharp/csharp_enum_field.cc

@@ -55,36 +55,22 @@ EnumFieldGenerator::~EnumFieldGenerator() {
 
 void EnumFieldGenerator::GenerateParsingCode(io::Printer* printer) {
   printer->Print(variables_,
-                 "object unknown;\n"
-                 "if(input.ReadEnum(ref result.$name$_, out unknown)) {\n");
-  if (SupportFieldPresence(descriptor_->file())) {
-    printer->Print(variables_,
-                   "  result.has$property_name$ = true;\n");
-  }
-  printer->Print("} else if(unknown is int) {\n");
-  if (!use_lite_runtime()) {
-    printer->Print(variables_,
-                   "  if (unknownFields == null) {\n"  // First unknown field - create builder now
-                   "    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);\n"
-                   "  }\n"
-                   "  unknownFields.MergeVarintField($number$, (ulong)(int)unknown);\n");
-  }
-  printer->Print("}\n");
+    "input.ReadEnum(ref $name$_);\n");
 }
 
 void EnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
   printer->Print(variables_,
-                 "if ($has_property_check$) {\n"
-                 "  output.WriteEnum($number$, field_names[$field_ordinal$], (int) $property_name$, $property_name$);\n"
-                 "}\n");
+    "if ($has_property_check$) {\n"
+    "  output.WriteEnum($number$, fieldNames[$field_ordinal$], (long) $property_name$, $property_name$);\n"
+    "}\n");
 }
 
 void EnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
   printer->Print(
-      variables_,
-      "if ($has_property_check$) {\n"
-      "  size += pb::CodedOutputStream.ComputeEnumSize($number$, (int) $property_name$);\n"
-      "}\n");
+    variables_,
+    "if ($has_property_check$) {\n"
+    "  size += pb::CodedOutputStream.ComputeEnumSize($number$, (long) $property_name$);\n"
+    "}\n");
 }
 
 EnumOneofFieldGenerator::EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
@@ -96,30 +82,21 @@ EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {
 }
 
 void EnumOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+  // TODO(jonskeet): What about if we read the default value?
   printer->Print(
     variables_,
-    "object unknown;\n"
     "$type_name$ enumValue = $default_value$;\n"
-    "if(input.ReadEnum(ref enumValue, out unknown)) {\n"
+    "if(input.ReadEnum(ref enumValue)) {\n"
     "  result.$oneof_name$_ = enumValue;\n"
     "  result.$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n"
-    "} else if(unknown is int) {\n");
-  if (!use_lite_runtime()) {
-    printer->Print(
-      variables_,
-      "  if (unknownFields == null) {\n"  // First unknown field - create builder now
-      "    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);\n"
-      "  }\n"
-      "  unknownFields.MergeVarintField($number$, (ulong)(int)unknown);\n");
-  }
-  printer->Print("}\n");
+    "}\n");
 }
 
 void EnumOneofFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  output.WriteEnum($number$, field_names[$field_ordinal$], (int) $property_name$, $property_name$);\n"
+    "  output.WriteEnum($number$, fieldNames[$field_ordinal$], (long) $property_name$, $property_name$);\n"
     "}\n");
 }
 
@@ -127,7 +104,7 @@ void EnumOneofFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  size += pb::CodedOutputStream.ComputeEnumSize($number$, (int) $property_name$);\n"
+    "  size += pb::CodedOutputStream.ComputeEnumSize($number$, (long) $property_name$);\n"
     "}\n");
 }
 

+ 0 - 184
src/google/protobuf/compiler/csharp/csharp_extension.cc

@@ -1,184 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <sstream>
-
-#include <google/protobuf/compiler/code_generator.h>
-#include <google/protobuf/compiler/plugin.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/io/printer.h>
-#include <google/protobuf/io/zero_copy_stream.h>
-
-#include <google/protobuf/compiler/csharp/csharp_extension.h>
-#include <google/protobuf/compiler/csharp/csharp_helpers.h>
-#include <google/protobuf/compiler/csharp/csharp_field_base.h>
-
-using google::protobuf::internal::scoped_ptr;
-
-namespace google {
-namespace protobuf {
-namespace compiler {
-namespace csharp {
-
-ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor)
-    : FieldGeneratorBase(descriptor, 0) {
-  if (descriptor_->extension_scope()) {
-    variables_["scope"] = GetClassName(descriptor_->extension_scope());
-  } else {
-    variables_["scope"] = GetFullUmbrellaClassName(descriptor_->file());
-  }
-  variables_["extends"] = GetClassName(descriptor_->containing_type());
-  variables_["capitalized_type_name"] = capitalized_type_name();
-  variables_["full_name"] = descriptor_->full_name();
-  variables_["access_level"] = class_access_level();
-  variables_["index"] = SimpleItoa(descriptor_->index());
-  variables_["property_name"] = property_name();
-  variables_["type_name"] = type_name();
-  if (use_lite_runtime()) {
-    variables_["generated_extension"] = descriptor_->is_repeated() ?
-      "GeneratedRepeatExtensionLite" : "GeneratedExtensionLite";
-  } else {
-    variables_["generated_extension"] = descriptor_->is_repeated() ?
-      "GeneratedRepeatExtension" : "GeneratedExtension";
-  }
-}
-
-ExtensionGenerator::~ExtensionGenerator() {
-}
-
-void ExtensionGenerator::Generate(io::Printer* printer) {
-  printer->Print(
-    "public const int $constant_name$ = $number$;\n",
-    "constant_name", GetFieldConstantName(descriptor_),
-    "number", SimpleItoa(descriptor_->number()));
-
-  if (use_lite_runtime()) {
-    // TODO(jtattermusch): include the following check
-    //if (Descriptor.MappedType == MappedType.Message && Descriptor.MessageType.Options.MessageSetWireFormat)
-    //{
-    //    throw new ArgumentException(
-    //        "option message_set_wire_format = true; is not supported in Lite runtime extensions.");
-    //}
-
-    printer->Print(
-      variables_,
-      "$access_level$ static pb::$generated_extension$<$extends$, $type_name$> $property_name$;\n");
-  } else if (descriptor_->is_repeated()) {
-    printer->Print(
-      variables_,
-      "$access_level$ static pb::GeneratedExtensionBase<scg::IList<$type_name$>> $property_name$;\n");
-  } else {
-    printer->Print(
-      variables_,
-      "$access_level$ static pb::GeneratedExtensionBase<$type_name$> $property_name$;\n");
-  }
-}
-
-void ExtensionGenerator::GenerateStaticVariableInitializers(io::Printer* printer) {
-  if (use_lite_runtime()) {
-    printer->Print(
-      variables_,
-      "$scope$.$property_name$ = \n");
-    printer->Indent();
-    printer->Print(
-      variables_,
-      "new pb::$generated_extension$<$extends$, $type_name$>(\n");
-    printer->Indent();
-    printer->Print(
-      variables_,
-      "\"$full_name$\",\n"
-      "$extends$.DefaultInstance,\n");
-    if (!descriptor_->is_repeated()) {
-      std::string default_val;
-      if (descriptor_->has_default_value()) {
-        default_val = default_value();
-      } else {
-        default_val = is_nullable_type() ? "null" : ("default(" + type_name() + ")");
-      }
-      printer->Print("$default_val$,\n", "default_val", default_val);
-    }
-    printer->Print(
-      "$message_val$,\n",
-      "message_val",
-      (GetCSharpType(descriptor_->type()) == CSHARPTYPE_MESSAGE) ?
-	  type_name() + ".DefaultInstance" : "null");
-    printer->Print(
-      "$enum_val$,\n",
-      "enum_val",
-      (GetCSharpType(descriptor_->type()) == CSHARPTYPE_ENUM) ?
-	  "new EnumLiteMap<" + type_name() + ">()" : "null");
-    printer->Print(
-      variables_,
-      "$scope$.$property_name$FieldNumber,\n"
-      "pbd::FieldType.$capitalized_type_name$");
-    if (descriptor_->is_repeated()) {
-      printer->Print(
-        ",\n"
-        "$is_packed$",
-        "is_packed", descriptor_->is_packed() ? "true" : "false");
-    }
-    printer->Outdent();
-    printer->Print(");\n");
-    printer->Outdent();
-  }
-  else if (descriptor_->is_repeated())
-  {
-    printer->Print(
-      variables_,
-      "$scope$.$property_name$ = pb::GeneratedRepeatExtension<$type_name$>.CreateInstance($scope$.Descriptor.Extensions[$index$]);\n");
-  }
-  else
-  {
-    printer->Print(
-      variables_,
-      "$scope$.$property_name$ = pb::GeneratedSingleExtension<$type_name$>.CreateInstance($scope$.Descriptor.Extensions[$index$]);\n");
-  }
-}
-
-void ExtensionGenerator::GenerateExtensionRegistrationCode(io::Printer* printer) {
-  printer->Print(
-    variables_,
-    "registry.Add($scope$.$property_name$);\n");
-}
-
-void ExtensionGenerator::WriteHash(io::Printer* printer) {
-}
-
-void ExtensionGenerator::WriteEquals(io::Printer* printer) {
-}
-
-void ExtensionGenerator::WriteToString(io::Printer* printer) {
-}
-
-}  // namespace csharp
-}  // namespace compiler
-}  // namespace protobuf
-}  // namespace google

+ 0 - 78
src/google/protobuf/compiler/csharp/csharp_extension.h

@@ -1,78 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_EXTENSION_H__
-#define GOOGLE_PROTOBUF_COMPILER_CSHARP_EXTENSION_H__
-
-#include <string>
-
-#include <google/protobuf/compiler/code_generator.h>
-#include <google/protobuf/compiler/csharp/csharp_field_base.h>
-
-namespace google {
-namespace protobuf {
-namespace compiler {
-namespace csharp {
-
-class ExtensionGenerator : public FieldGeneratorBase {
- public:
-  ExtensionGenerator(const FieldDescriptor* descriptor);
-  ~ExtensionGenerator();
-
-  void GenerateStaticVariableInitializers(io::Printer* printer);
-  void GenerateExtensionRegistrationCode(io::Printer* printer);
-  void Generate(io::Printer* printer);
-
-  virtual void WriteHash(io::Printer* printer);
-  virtual void WriteEquals(io::Printer* printer);
-  virtual void WriteToString(io::Printer* printer);
-
-  virtual void GenerateMembers(io::Printer* printer) {};
-  virtual void GenerateBuilderMembers(io::Printer* printer) {};
-  virtual void GenerateMergingCode(io::Printer* printer) {};
-  virtual void GenerateBuildingCode(io::Printer* printer) {};
-  virtual void GenerateParsingCode(io::Printer* printer) {};
-  virtual void GenerateSerializationCode(io::Printer* printer) {};
-  virtual void GenerateSerializedSizeCode(io::Printer* printer) {};
-
- private:
-  std::string scope_;
-  std::string extends_;
-
-  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
-};
-
-}  // namespace csharp
-}  // namespace compiler
-}  // namespace protobuf
-}  // namespace google
-
-#endif  // GOOGLE_PROTOBUF_COMPILER_CSHARP_EXTENSION_H__
-

+ 4 - 33
src/google/protobuf/compiler/csharp/csharp_field_base.cc

@@ -263,37 +263,13 @@ bool AllPrintableAscii(const std::string& text) {
 }
 
 std::string FieldGeneratorBase::GetStringDefaultValueInternal() {
-  if (!descriptor_->has_default_value()) {
-    return "\"\"";
-  }
-  if (AllPrintableAscii(descriptor_->default_value_string())) {
-    // All chars are ASCII and printable.  In this case we only
-    // need to escape quotes and backslashes.
-    std::string temp = descriptor_->default_value_string();
-    temp = StringReplace(temp, "\\", "\\\\", true);
-    temp = StringReplace(temp, "'", "\\'", true);
-    temp = StringReplace(temp, "\"", "\\\"", true);
-    return "\"" + temp + "\"";
-  }
-  if (use_lite_runtime()) {
-    return "pb::ByteString.FromBase64(\""
-        + StringToBase64(descriptor_->default_value_string())
-        + "\").ToStringUtf8()";
-  }
-  return "(string) " + GetClassName(descriptor_->containing_type())
-      + ".Descriptor.Fields[" + SimpleItoa(descriptor_->index())
-      + "].DefaultValue";
+  // No other default values needed for proto3...
+  return "\"\"";
 }
 
 std::string FieldGeneratorBase::GetBytesDefaultValueInternal() {
-  if (!descriptor_->has_default_value()) {
-    return "pb::ByteString.Empty";
-  }
-  if (use_lite_runtime()) {
-    return "pb::ByteString.FromBase64(\"" + StringToBase64(descriptor_->default_value_string()) + "\")";
-  }
-  return "(pb::ByteString) "+ GetClassName(descriptor_->containing_type()) +
-      ".Descriptor.Fields[" + SimpleItoa(descriptor_->index()) + "].DefaultValue";
+  // No other default values needed for proto3...
+  return "pb::ByteString.Empty";
 }
 
 std::string FieldGeneratorBase::default_value() {
@@ -365,11 +341,6 @@ std::string FieldGeneratorBase::number() {
   return SimpleItoa(descriptor_->number());
 }
 
-std::string FieldGeneratorBase::message_or_group() {
-  return
-      (descriptor_->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message";
-}
-
 std::string FieldGeneratorBase::capitalized_type_name() {
   switch (descriptor_->type()) {
     case FieldDescriptor::TYPE_ENUM:

+ 0 - 5
src/google/protobuf/compiler/csharp/csharp_field_base.h

@@ -42,17 +42,13 @@ namespace protobuf {
 namespace compiler {
 namespace csharp {
 
-class Writer;
-
 class FieldGeneratorBase : public SourceGeneratorBase {
  public:
   FieldGeneratorBase(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~FieldGeneratorBase();
 
   virtual void GenerateMembers(io::Printer* printer) = 0;
-  virtual void GenerateBuilderMembers(io::Printer* printer) = 0;
   virtual void GenerateMergingCode(io::Printer* printer) = 0;
-  virtual void GenerateBuildingCode(io::Printer* printer) = 0;
   virtual void GenerateParsingCode(io::Printer* printer) = 0;
   virtual void GenerateSerializationCode(io::Printer* printer) = 0;
   virtual void GenerateSerializedSizeCode(io::Printer* printer) = 0;
@@ -82,7 +78,6 @@ class FieldGeneratorBase : public SourceGeneratorBase {
   bool is_nullable_type();
   std::string default_value();
   std::string number();
-  std::string message_or_group();
   std::string capitalized_type_name();
   std::string field_ordinal();
 

+ 153 - 702
src/google/protobuf/compiler/csharp/csharp_message.cc

@@ -43,7 +43,6 @@
 #include <google/protobuf/wire_format_lite.h>
 
 #include <google/protobuf/compiler/csharp/csharp_enum.h>
-#include <google/protobuf/compiler/csharp/csharp_extension.h>
 #include <google/protobuf/compiler/csharp/csharp_message.h>
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
 #include <google/protobuf/compiler/csharp/csharp_field_base.h>
@@ -106,7 +105,7 @@ std::string GetUniqueFileScopeIdentifier(const Descriptor* descriptor) {
 }
 
 void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
-  // Because descriptor.proto (Google.ProtocolBuffers.DescriptorProtos) is
+  // Because descriptor.proto (Google.Protobuf.DescriptorProtos) is
   // used in the construction of descriptors, we have a tricky bootstrapping
   // problem.  To help control static initialization order, we make sure all
   // descriptors and other static data that depends on them are members of
@@ -115,14 +114,12 @@ void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
 
   std::string identifier = GetUniqueFileScopeIdentifier(descriptor_);
 
-  if (!use_lite_runtime()) {
-    // The descriptor for this type.
-    printer->Print(
-        "internal static pbd::MessageDescriptor internal__$identifier$__Descriptor;\n"
-        "internal static pb::FieldAccess.FieldAccessorTable<$full_class_name$, $full_class_name$.Builder> internal__$identifier$__FieldAccessorTable;\n",
-	"identifier", GetUniqueFileScopeIdentifier(descriptor_),
-	"full_class_name", full_class_name());
-  }
+  // The descriptor for this type.
+  printer->Print(
+      "internal static pbd::MessageDescriptor internal__$identifier$__Descriptor;\n"
+      "internal static pb::FieldAccess.FieldAccessorTable<$full_class_name$> internal__$identifier$__FieldAccessorTable;\n",
+      "identifier", GetUniqueFileScopeIdentifier(descriptor_),
+      "full_class_name", full_class_name());
 
   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
     MessageGenerator messageGenerator(descriptor_->nested_type(i));
@@ -139,139 +136,106 @@ void MessageGenerator::GenerateStaticVariableInitializers(io::Printer* printer)
     vars["parent"] = GetUniqueFileScopeIdentifier(
 	descriptor_->containing_type());
   }
-  if (!use_lite_runtime()) {
-    printer->Print(vars, "internal__$identifier$__Descriptor = ");
+  printer->Print(vars, "internal__$identifier$__Descriptor = ");
 
-    if (!descriptor_->containing_type()) {
-      printer->Print(vars, "Descriptor.MessageTypes[$index$];\n");
-    } else {
-      printer->Print(vars, "internal__$parent$__Descriptor.NestedTypes[$index$];\n");
-    }
+  if (!descriptor_->containing_type()) {
+    printer->Print(vars, "Descriptor.MessageTypes[$index$];\n");
+  } else {
+    printer->Print(vars, "internal__$parent$__Descriptor.NestedTypes[$index$];\n");
+  }
 
-    printer->Print(
-      vars,
-      "internal__$identifier$__FieldAccessorTable = \n"
-      "    new pb::FieldAccess.FieldAccessorTable<$full_class_name$, $full_class_name$.Builder>(internal__$identifier$__Descriptor,\n");
-    printer->Print("        new string[] { ");
-    for (int i = 0; i < descriptor_->field_count(); i++) {
-      printer->Print("\"$property_name$\", ",
-                     "property_name", GetPropertyName(descriptor_->field(i)));
-    }
-    for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-      printer->Print("\"$oneof_name$\", ",
-                     "oneof_name",
-                     UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
-    }
-    printer->Print("});\n");
+  printer->Print(
+    vars,
+    "internal__$identifier$__FieldAccessorTable = \n"
+    "    new pb::FieldAccess.FieldAccessorTable<$full_class_name$>(internal__$identifier$__Descriptor,\n");
+  printer->Print("        new string[] { ");
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    printer->Print("\"$property_name$\", ",
+                   "property_name", GetPropertyName(descriptor_->field(i)));
+  }
+  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+    printer->Print("\"$oneof_name$\", ",
+                   "oneof_name",
+                   UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
   }
+  printer->Print("});\n");
 
   // Generate static member initializers for all nested types.
   for (int i = 0; i < descriptor_->nested_type_count(); i++) {
     MessageGenerator messageGenerator(descriptor_->nested_type(i));
     messageGenerator.GenerateStaticVariableInitializers(printer);
   }
-
-  for (int i = 0; i < descriptor_->extension_count(); i++) {
-    ExtensionGenerator extensionGenerator(descriptor_->extension(i));
-    extensionGenerator.GenerateStaticVariableInitializers(printer);
-  }
 }
 
 void MessageGenerator::Generate(io::Printer* printer) {
   map<string, string> vars;
   vars["class_name"] = class_name();
   vars["access_level"] = class_access_level();
-  vars["extendable_or_generated"] = descriptor_->extension_range_count() > 0 ?
-    "Extendable" : "Generated";
-  vars["suffix"] = runtime_suffix();
   vars["umbrella_class_name"] = GetFullUmbrellaClassName(descriptor_->file());
   vars["identifier"] = GetUniqueFileScopeIdentifier(descriptor_);
 
   printer->Print(
-      "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n");
+    "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n");
   WriteGeneratedCodeAttributes(printer);
   printer->Print(
     vars,
-    "$access_level$ sealed partial class $class_name$ : pb::$extendable_or_generated$Message$suffix$<$class_name$, $class_name$.Builder> {\n");
+    "$access_level$ sealed partial class $class_name$ : pb::IMessage<$class_name$> {\n");
   printer->Indent();
-  printer->Print(
-    vars,
-    "private $class_name$() { }\n"  // Private ctor.
-    // Must call MakeReadOnly() to make sure all lists are made read-only
-    "private static readonly $class_name$ defaultInstance = new $class_name$().MakeReadOnly();\n");
 
-  if (optimize_speed()) {
-    printer->Print(
-      "private static readonly string[] _$name$FieldNames = "
-      "new string[] { $slash$$field_names$$slash$ };\n",
-      "name", UnderscoresToCamelCase(class_name(), false),
-      "field_names", JoinStrings(field_names(), "\", \""),
+  // All static fields and properties
+  printer->Print(
+    "private static readonly string[] _fieldNames = "
+    "new string[] { $slash$$field_names$$slash$ };\n",
+    "field_names", JoinStrings(field_names(), "\", \""),
       "slash", field_names().size() > 0 ? "\"" : "");
-    std::vector<std::string> tags;
-    for (int i = 0; i < field_names().size(); i++) {
-      uint32 tag = internal::WireFormat::MakeTag(
-          descriptor_->FindFieldByName(field_names()[i]));
-      tags.push_back(SimpleItoa(tag));
-    }
-    printer->Print(
-      "private static readonly uint[] _$name$FieldTags = new uint[] { $tags$ };\n",
-      "name", UnderscoresToCamelCase(class_name(), false),
-      "tags", JoinStrings(tags, ", "));
+  std::vector<std::string> tags;
+  for (int i = 0; i < field_names().size(); i++) {
+    uint32 tag = internal::WireFormat::MakeTag(
+        descriptor_->FindFieldByName(field_names()[i]));
+    tags.push_back(SimpleItoa(tag));
   }
+  printer->Print(
+    "private static readonly uint[] _fieldTags = new uint[] { $tags$ };\n",
+    "tags", JoinStrings(tags, ", "));
+
   printer->Print(
     vars,
-    "public static $class_name$ DefaultInstance {\n"
-    "  get { return defaultInstance; }\n"
+    "public static pbd::MessageDescriptor Descriptor {\n"
+    "  get { return $umbrella_class_name$.internal__$identifier$__Descriptor; }\n"
     "}\n"
     "\n"
-    "public override $class_name$ DefaultInstanceForType {\n"
-    "  get { return DefaultInstance; }\n"
+    "protected override pb::FieldAccess.FieldAccessorTable<$class_name$> InternalFieldAccessors {\n"
+    "  get { return $umbrella_class_name$.internal__$identifier$__FieldAccessorTable; }\n"
     "}\n"
-    "\n"
-    "protected override $class_name$ ThisMessage {\n"
-    "  get { return this; }\n"
-    "}\n\n");
+    "\n");
 
-  if (!use_lite_runtime()) {
-    printer->Print(
-      vars,
-      "public static pbd::MessageDescriptor Descriptor {\n"
-      "  get { return $umbrella_class_name$.internal__$identifier$__Descriptor; }\n"
-      "}\n"
-      "\n"
-      "protected override pb::FieldAccess.FieldAccessorTable<$class_name$, $class_name$.Builder> InternalFieldAccessors {\n"
-      "  get { return $umbrella_class_name$.internal__$identifier$__FieldAccessorTable; }\n"
-      "}\n"
-      "\n");
-  }
+  // Constructors
+  printer->Print(
+    vars,
+    "public $class_name$() { }\n");  // Public parameterless ctor.
 
-  // Extensions don't need to go in an extra nested type
-  for (int i = 0; i < descriptor_->extension_count(); i++) {
-    ExtensionGenerator extensionGenerator(descriptor_->extension(i));
-    extensionGenerator.Generate(printer);
-  }
+  printer->Print(
+    vars,
+    "public $class_name$($class_name$ other) {\n"
+    "  MergeWith(other);\n"
+    "}\n");  // Merge ctor.
 
-  if (descriptor_->enum_type_count() + descriptor_->nested_type_count() > 0) {
-    printer->Print("#region Nested types\n"
-		   "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n");
-    WriteGeneratedCodeAttributes(printer);
-    printer->Print("public static partial class Types {\n");
-    printer->Indent();
-    for (int i = 0; i < descriptor_->enum_type_count(); i++) {
-      EnumGenerator enumGenerator(descriptor_->enum_type(i));
-      enumGenerator.Generate(printer);
-    }
-    for (int i = 0; i < descriptor_->nested_type_count(); i++) {
-      MessageGenerator messageGenerator(descriptor_->nested_type(i));
-      messageGenerator.Generate(printer);
-    }
-    printer->Outdent();
-    printer->Print("}\n"
-                   "#endregion\n"
-                   "\n");
+  // Fields/properties
+  for (int i = 0; i < descriptor_->field_count(); i++) {
+    const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
+
+    // Rats: we lose the debug comment here :(
+    printer->Print(
+      "public const int $field_constant_name$ = $index$;\n",
+      "field_constant_name", GetFieldConstantName(fieldDescriptor),
+      "index", SimpleItoa(fieldDescriptor->number()));
+    scoped_ptr<FieldGeneratorBase> generator(
+        CreateFieldGeneratorInternal(fieldDescriptor));
+    generator->GenerateMembers(printer);
+    printer->Print("\n");
   }
 
-  // oneof
+  // oneof properties
   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
     vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
     vars["property_name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true);
@@ -280,13 +244,13 @@ void MessageGenerator::Generate(io::Printer* printer) {
       "private object $name$_;\n"
       "public enum $property_name$OneofCase {\n");
     printer->Indent();
+    printer->Print("None = 0,\n");
     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
       printer->Print("$field_property_name$ = $index$,\n",
                      "field_property_name", GetPropertyName(field),
                      "index", SimpleItoa(field->number()));
     }
-    printer->Print("None = 0,\n");
     printer->Outdent();
     printer->Print("}\n");
     printer->Print(
@@ -294,243 +258,78 @@ void MessageGenerator::Generate(io::Printer* printer) {
       "private $property_name$OneofCase $name$Case_ = $property_name$OneofCase.None;\n"
       "public $property_name$OneofCase $property_name$Case {\n"
       "  get { return $name$Case_; }\n"
+      "}\n\n"
+      "private Clear$property_name$() {;\n"
+      "  $name$Case_ = $property_name$OneofCase.None;"
+      "  $name$_ = null;"
       "}\n\n");
   }
 
-  // Fields
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
+  // TODO(jonskeet): Map properties
 
-    // Rats: we lose the debug comment here :(
-    printer->Print(
-      "public const int $field_constant_name$ = $index$;\n",
-      "field_constant_name", GetFieldConstantName(fieldDescriptor),
-      "index", SimpleItoa(fieldDescriptor->number()));
-    scoped_ptr<FieldGeneratorBase> generator(
-        CreateFieldGeneratorInternal(fieldDescriptor));
-    generator->GenerateMembers(printer);
-    printer->Print("\n");
-  }
+  // Standard methods
+  GenerateMessageSerializationMethods(printer);
+  GenerateMergingMethods(printer);
 
-  if (optimize_speed()) {
-    if (SupportFieldPresence(descriptor_->file())) {
-      GenerateIsInitialized(printer);
+  // Nested messages and enums
+  if (descriptor_->enum_type_count() + descriptor_->nested_type_count() > 0) {
+    printer->Print("#region Nested types\n"
+		   "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n");
+    WriteGeneratedCodeAttributes(printer);
+    printer->Print("public static partial class Types {\n");
+    printer->Indent();
+    for (int i = 0; i < descriptor_->enum_type_count(); i++) {
+      EnumGenerator enumGenerator(descriptor_->enum_type(i));
+      enumGenerator.Generate(printer);
     }
-    GenerateMessageSerializationMethods(printer);
-  }
-  if (use_lite_runtime()) {
-    GenerateLiteRuntimeMethods(printer);
-  }
-
-  GenerateParseFromMethods(printer);
-  GenerateBuilder(printer);
-
-  // Force the static initialization code for the file to run, since it may
-  // initialize static variables declared in this class.
-  printer->Print(vars, "static $class_name$() {\n");
-  // We call object.ReferenceEquals() just to make it a valid statement on its own.
-  // Another option would be GetType(), but that causes problems in DescriptorProtoFile,
-  // where the bootstrapping is somewhat recursive - type initializers call
-  // each other, effectively. We temporarily see Descriptor as null.
-  printer->Print(
-    vars,
-    "  object.ReferenceEquals($umbrella_class_name$.Descriptor, null);\n"
-    "}\n");
-
-  printer->Outdent();
-  printer->Print("}\n");
-  printer->Print("\n");
-
-}
-
-void MessageGenerator::GenerateLiteRuntimeMethods(io::Printer* printer) {
-  map<string, string> vars;
-  vars["class_name"] = class_name();
-
-  bool callbase = descriptor_->extension_range_count() > 0;
-  printer->Print("#region Lite runtime methods\n"
-                 "public override int GetHashCode() {\n");
-  printer->Indent();
-  printer->Print("int hash = GetType().GetHashCode();\n");
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* field = descriptor_->field(i);
-    if (field->containing_oneof() == NULL) {
-      scoped_ptr<FieldGeneratorBase> generator(
-          CreateFieldGeneratorInternal(field));
-      generator->WriteHash(printer);
+    for (int i = 0; i < descriptor_->nested_type_count(); i++) {
+      MessageGenerator messageGenerator(descriptor_->nested_type(i));
+      messageGenerator.Generate(printer);
     }
-  }
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    string name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
-    string property_name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true);
-    printer->Print(
-      "if ($name$Case_ != $property_name$OneofCase.None) {\n"
-      "  hash ^= $name$_.GetHashCode();\n"
-      "}\n",
-      "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false),
-      "property_name",
-      UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
-  }
-  if (callbase) {
-    printer->Print("hash ^= base.GetHashCode();\n");
-  }
-  printer->Print("return hash;\n");
-  printer->Outdent();
-  printer->Print("}\n");
-  printer->Print("\n");
-
-  printer->Print("public override bool Equals(object obj) {\n");
-  printer->Indent();
-  printer->Print(
-    vars,
-    "$class_name$ other = obj as $class_name$;\n"
-    "if (other == null) return false;\n");
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    scoped_ptr<FieldGeneratorBase> generator(
-        CreateFieldGeneratorInternal(descriptor_->field(i)));
-    generator->WriteEquals(printer);
-  }
-  if (callbase) {
-    printer->Print("if (!base.Equals(other)) return false;\n");
-  }
-  printer->Print("return true;\n");
-  printer->Outdent();
-  printer->Print("}\n");
-  printer->Print("\n");
-
-  printer->Print(
-    "public override void PrintTo(global::System.IO.TextWriter writer) {\n");
-  printer->Indent();
-
-  for (int i = 0; i < fields_by_number().size(); i++) {
-    scoped_ptr<FieldGeneratorBase> generator(
-        CreateFieldGeneratorInternal(fields_by_number()[i]));
-    generator->WriteToString(printer);
+    printer->Outdent();
+    printer->Print("}\n"
+                   "#endregion\n"
+                   "\n");
   }
 
-  if (callbase) {
-    printer->Print("base.PrintTo(writer);\n");
-  }
   printer->Outdent();
   printer->Print("}\n");
-  printer->Print("#endregion\n");
   printer->Print("\n");
-}
 
-bool CompareExtensionRangesStart(const Descriptor::ExtensionRange* r1,
-                                 const Descriptor::ExtensionRange* r2) {
-  return r1->start < r2->start;
 }
 
 void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer) {
-  std::vector<const Descriptor::ExtensionRange*> extension_ranges_sorted;
-  for (int i = 0; i < descriptor_->extension_range_count(); i++) {
-    extension_ranges_sorted.push_back(descriptor_->extension_range(i));
-  }
-  std::sort(extension_ranges_sorted.begin(), extension_ranges_sorted.end(),
-            CompareExtensionRangesStart);
-
   printer->Print(
-      "public override void WriteTo(pb::ICodedOutputStream output) {\n");
+      "public void WriteTo(pb::ICodedOutputStream output) {\n");
   printer->Indent();
-  // Make sure we've computed the serialized length, so that packed fields are generated correctly.
-  printer->Print("CalcSerializedSize();\n"
-		 "string[] field_names = _$class_name$FieldNames;\n",
-                 "class_name", UnderscoresToCamelCase(class_name(), false));
-  if (descriptor_->extension_range_count()) {
-    printer->Print(
-      "pb::ExtendableMessage$runtime_suffix$<$class_name$, $class_name$.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);\n",
-      "class_name", class_name(),
-      "runtime_suffix", runtime_suffix());
-  }
-
-  // Merge the fields and the extension ranges, both sorted by field number.
-  for (int i = 0, j = 0;
-      i < fields_by_number().size() || j < extension_ranges_sorted.size();) {
-    if (i == fields_by_number().size()) {
-      GenerateSerializeOneExtensionRange(printer, extension_ranges_sorted[j++]);
-    } else if (j == extension_ranges_sorted.size()) {
-      GenerateSerializeOneField(printer, fields_by_number()[i++]);
-    } else if (fields_by_number()[i]->number()
-        < extension_ranges_sorted[j]->start) {
-      GenerateSerializeOneField(printer, fields_by_number()[i++]);
-    } else {
-      GenerateSerializeOneExtensionRange(printer, extension_ranges_sorted[j++]);
-    }
-  }
+  printer->Print("string[] fieldNames = _fieldNames;\n");
 
-  if (!use_lite_runtime()) {
-    if (descriptor_->options().message_set_wire_format())
-    {
-      printer->Print("UnknownFields.WriteAsMessageSetTo(output);\n");
-    } else {
-      printer->Print("UnknownFields.WriteTo(output);\n");
-    }
+  // Serialize all the fields
+  for (int i = 0; i < fields_by_number().size(); i++) {
+    scoped_ptr<FieldGeneratorBase> generator(
+      CreateFieldGeneratorInternal(fields_by_number()[i]));
+    generator->GenerateSerializationCode(printer);
   }
 
+  // TODO(jonskeet): Memoize size of frozen messages?
   printer->Outdent();
   printer->Print(
     "}\n"
     "\n"
-    "private int memoizedSerializedSize = -1;\n"
-    "public override int SerializedSize {\n");
+    "public int CalculateSerializedSize() {\n");
   printer->Indent();
-  printer->Print("get {\n");
-  printer->Indent();
-  printer->Print(
-    "int size = memoizedSerializedSize;\n"
-    "if (size != -1) return size;\n"
-    "return CalcSerializedSize();\n");
-  printer->Outdent();
-  printer->Print("}\n");
-  printer->Outdent();
-  printer->Print("}\n");
-  printer->Print("\n");
-
-  printer->Print("private int CalcSerializedSize() {\n");
-  printer->Indent();
-  printer->Print(
-    "int size = memoizedSerializedSize;\n"
-    "if (size != -1) return size;\n"
-    "\n"
-    "size = 0;\n");
+  printer->Print("int size = 0;\n");
   for (int i = 0; i < descriptor_->field_count(); i++) {
     scoped_ptr<FieldGeneratorBase> generator(
         CreateFieldGeneratorInternal(descriptor_->field(i)));
     generator->GenerateSerializedSizeCode(printer);
   }
-  if (descriptor_->extension_range_count() > 0) {
-    printer->Print("size += ExtensionsSerializedSize;\n");
-  }
-
-  if (!use_lite_runtime()) {
-    if (descriptor_->options().message_set_wire_format()) {
-      printer->Print("size += UnknownFields.SerializedSizeAsMessageSet;\n");
-    } else {
-      printer->Print("size += UnknownFields.SerializedSize;\n");
-    }
-  }
-  printer->Print(
-    "memoizedSerializedSize = size;\n"
-    "return size;\n");
+  printer->Print("return size;\n");
   printer->Outdent();
   printer->Print("}\n");
 }
 
-void MessageGenerator::GenerateSerializeOneField(
-    io::Printer* printer, const FieldDescriptor* fieldDescriptor) {
-  scoped_ptr<FieldGeneratorBase> generator(
-      CreateFieldGeneratorInternal(fieldDescriptor));
-  generator->GenerateSerializationCode(printer);
-}
-
-void MessageGenerator::GenerateSerializeOneExtensionRange(
-    io::Printer* printer, const Descriptor::ExtensionRange* extensionRange) {
-  printer->Print("extensionWriter.WriteUntil($range_end$, output);\n",
-		 "range_end", SimpleItoa(extensionRange->end));
-}
-
-void MessageGenerator::GenerateParseFromMethods(io::Printer* printer) {
+void MessageGenerator::GenerateMergingMethods(io::Printer* printer) {
   // Note:  These are separate from GenerateMessageSerializationMethods()
   //   because they need to be generated even for messages that are optimized
   //   for code size.
@@ -539,339 +338,72 @@ void MessageGenerator::GenerateParseFromMethods(io::Printer* printer) {
 
   printer->Print(
     vars,
-    "public static $class_name$ ParseFrom(pb::ByteString data) {\n"
-    "  return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();\n"
-    "}\n"
-    "public static $class_name$ ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {\n"
-    "  return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();\n"
-    "}\n"
-    "public static $class_name$ ParseFrom(byte[] data) {\n"
-    "  return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();\n"
-    "}\n"
-    "public static $class_name$ ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {\n"
-    "  return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();\n"
-    "}\n"
-    "public static $class_name$ ParseFrom(global::System.IO.Stream input) {\n"
-    "  return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();\n"
-    "}\n"
-    "public static $class_name$ ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {\n"
-    "  return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();\n"
-    "}\n"
-    "public static $class_name$ ParseDelimitedFrom(global::System.IO.Stream input) {\n"
-    "  return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();\n"
-    "}\n"
-    "public static $class_name$ ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {\n"
-    "  return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();\n"
-    "}\n"
-    "public static $class_name$ ParseFrom(pb::ICodedInputStream input) {\n"
-    "  return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();\n"
-    "}\n"
-    "public static $class_name$ ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {\n"
-    "  return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();\n"
-    "}\n");
-}
-
-void MessageGenerator::GenerateBuilder(io::Printer* printer) {
-  map<string, string> vars;
-  vars["class_name"] = class_name();
-  vars["access_level"] = class_access_level();
-  vars["extendable_or_generated"] = descriptor_->extension_range_count() > 0 ?
-    "Extendable" : "Generated";
-  vars["suffix"] = runtime_suffix();
-
-  printer->Print(vars, "private $class_name$ MakeReadOnly() {\n");
-  printer->Indent();
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    scoped_ptr<FieldGeneratorBase> generator(
-        CreateFieldGeneratorInternal(descriptor_->field(i)));
-    generator->GenerateBuildingCode(printer);
-  }
-  printer->Print("return this;\n");
-  printer->Outdent();
-  printer->Print("}\n\n");
-
-  printer->Print(
-    vars,
-    "public static Builder CreateBuilder() { return new Builder(); }\n"
-    "public override Builder ToBuilder() { return CreateBuilder(this); }\n"
-    "public override Builder CreateBuilderForType() { return new Builder(); }\n"
-    "public static Builder CreateBuilder($class_name$ prototype) {\n"
-    "  return new Builder(prototype);\n"
-    "}\n"
-    "\n"
-    "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n");
-  WriteGeneratedCodeAttributes(printer);
-  printer->Print(
-    vars,
-    "$access_level$ sealed partial class Builder : pb::$extendable_or_generated$Builder$suffix$<$class_name$, Builder> {\n");
+    "public void MergeWith($class_name$ other) {\n");
   printer->Indent();
   printer->Print(
-    "protected override Builder ThisBuilder {\n"
-    "  get { return this; }\n"
+    "if (other == null) {\n"
+    "  return;\n"
     "}\n");
-  GenerateCommonBuilderMethods(printer);
-  if (optimize_speed()) {
-    GenerateBuilderParsingMethods(printer);
-  }
+  // TODO(jonskeet): Maps?
+  // Merge non-oneof fields
   for (int i = 0; i < descriptor_->field_count(); i++) {
-    scoped_ptr<FieldGeneratorBase> generator(
-        CreateFieldGeneratorInternal(descriptor_->field(i)));
-    printer->Print("\n");
-    // No field comment :(
-    generator->GenerateBuilderMembers(printer);
-  }
-
-  // oneof
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
-    printer->Print("\n");
-    string name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
-    string property_name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true);
-    printer->Print(
-      "public $property_name$OneofCase $property_name$Case {\n"
-      "  get { return result.$name$Case_; }\n"
-      "}\n"
-      "public Builder Clear$property_name$() {\n"
-      "  PrepareBuilder();\n"
-      "  result.$name$_ = null;\n"
-      "  result.$name$Case_ = $property_name$OneofCase.None;\n"
-      "  return this;\n"
-      "}\n",
-      "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false),
-      "property_name",
-      UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
-  }
-
-  printer->Outdent();
-  printer->Print("}\n");
-}
-
-void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
-  map<string, string> vars;
-  vars["class_name"] = class_name();
-  vars["full_class_name"] = full_class_name();
-  vars["suffix"] = runtime_suffix();
-
-  printer->Print(
-    vars,
-    //default constructor
-    "public Builder() {\n"
-    //Durring static initialization of message, DefaultInstance is expected to return null.
-    "  result = DefaultInstance;\n"
-    "  resultIsReadOnly = true;\n"
-    "}\n"
-    //clone constructor
-    "internal Builder($class_name$ cloneFrom) {\n"
-    "  result = cloneFrom;\n"
-    "  resultIsReadOnly = true;\n"
-    "}\n"
-    "\n"
-    "private bool resultIsReadOnly;\n"
-    "private $class_name$ result;\n"
-    "\n"
-    "private $class_name$ PrepareBuilder() {\n"
-    "  if (resultIsReadOnly) {\n"
-    "    $class_name$ original = result;\n"
-    "    result = new $class_name$();\n"
-    "    resultIsReadOnly = false;\n"
-    "    MergeFrom(original);\n"
-    "  }\n"
-    "  return result;\n"
-    "}\n"
-    "\n"
-    "public override bool IsInitialized {\n"
-    "  get { return result.IsInitialized; }\n"
-    "}\n"
-    "\n"
-    "protected override $class_name$ MessageBeingBuilt {\n"
-    "  get { return PrepareBuilder(); }\n"
-    "}\n"
-    "\n");
-  //Not actually expecting that DefaultInstance would ever be null here; however, we will ensure it does not break
-  printer->Print(
-    "public override Builder Clear() {\n"
-    "  result = DefaultInstance;\n"
-    "  resultIsReadOnly = true;\n"
-    "  return this;\n"
-    "}\n"
-    "\n"
-    "public override Builder Clone() {\n"
-    "  if (resultIsReadOnly) {\n"
-    "    return new Builder(result);\n"
-    "  } else {\n"
-    "    return new Builder().MergeFrom(result);\n"
-    "  }\n"
-    "}\n"
-    "\n");
-  if (!use_lite_runtime()) {
-    printer->Print(
-      vars,
-      "public override pbd::MessageDescriptor DescriptorForType {\n"
-      "  get { return $full_class_name$.Descriptor; }\n"
-      "}\n\n");
+    if (!descriptor_->field(i)->containing_oneof()) {      
+      scoped_ptr<FieldGeneratorBase> generator(
+          CreateFieldGeneratorInternal(descriptor_->field(i)));
+      generator->GenerateMergingCode(printer);
+    }
   }
-  printer->Print(
-    vars,
-    "public override $class_name$ DefaultInstanceForType {\n"
-    "  get { return $full_class_name$.DefaultInstance; }\n"
-    "}\n\n");
-
-  printer->Print(
-    vars,
-    "public override $class_name$ BuildPartial() {\n"
-    "  if (resultIsReadOnly) {\n"
-    "    return result;\n"
-    "  }\n"
-    "  resultIsReadOnly = true;\n"
-    "  return result.MakeReadOnly();\n"
-    "}\n\n");
-
-  if (optimize_speed()) {
-    printer->Print(
-      vars,
-      "public override Builder MergeFrom(pb::IMessage$suffix$ other) {\n"
-      "  if (other is $class_name$) {\n"
-      "    return MergeFrom(($class_name$) other);\n"
-      "  } else {\n"
-      "    base.MergeFrom(other);\n"
-      "    return this;\n"
-      "  }\n"
-      "}\n\n");
-
-    printer->Print(vars,"public override Builder MergeFrom($class_name$ other) {\n");
-    // Optimization:  If other is the default instance, we know none of its
-    // fields are set so we can skip the merge.
+  // Merge oneof fields
+  for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
+    vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
+    vars["property_name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true);
+    printer->Print(vars, "switch (other.$property_name$Case) {\n");
     printer->Indent();
-    printer->Print(
-      vars,
-      "if (other == $full_class_name$.DefaultInstance) return this;\n"
-      "PrepareBuilder();\n");
-    for (int i = 0; i < descriptor_->field_count(); i++) {
-      if (!descriptor_->field(i)->containing_oneof()) {
-	scoped_ptr<FieldGeneratorBase> generator(
-	  CreateFieldGeneratorInternal(descriptor_->field(i)));
-	generator->GenerateMergingCode(printer);
-      }
-     }
-
-    // Merge oneof fields
-    for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
-      vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
-      vars["property_name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true);
-      printer->Print(vars, "switch (other.$property_name$Case) {\n");
-      printer->Indent();
-      for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
-        const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
-	vars["field_property_name"] = GetPropertyName(field);
-	printer->Print(
-          vars,
-          "case $property_name$OneofCase.$field_property_name$: {\n");
-	if (field->type() == FieldDescriptor::TYPE_GROUP ||
-	    field->type() == FieldDescriptor::TYPE_MESSAGE) {
-	  printer->Print(
-            vars,
-            "  Merge$field_property_name$(other.$field_property_name$);\n");
-	} else {
-	  printer->Print(
-            vars,
-            "  Set$field_property_name$(other.$field_property_name$);\n");
-	}
-        printer->Print("  break;\n");
-	printer->Print("}\n");
-      }
-      printer->Print(vars, "case $property_name$OneofCase.None: { break; }\n");
-      printer->Outdent();
-      printer->Print("}\n");
-    }
-
-    // if message type has extensions
-    if (descriptor_->extension_range_count() > 0) {
-      printer->Print("  this.MergeExtensionFields(other);\n");
-    }
-    if (!use_lite_runtime()) {
-      printer->Print("this.MergeUnknownFields(other.UnknownFields);\n");
+    for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+      const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+      vars["field_property_name"] = GetPropertyName(field);
+      printer->Print(
+        vars,
+        "case $property_name$OneofCase.$field_property_name$:\n"
+        "  $field_property_name$ = other.$field_property_name$;\n"
+        "  break;\n");
     }
-    printer->Print("return this;\n");
     printer->Outdent();
     printer->Print("}\n\n");
   }
-
-}
-
-void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
-  printer->Print(
-    "public override Builder MergeFrom(pb::ICodedInputStream input) {\n"
-    "  return MergeFrom(input, pb::ExtensionRegistry.Empty);\n"
-    "}\n\n");
-
-  printer->Print(
-    "public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {\n");
+  printer->Outdent();
+  printer->Print("}\n\n");
+  printer->Print("public void MergeFrom(pb::ICodedInputStream input) {\n");
   printer->Indent();
-  printer->Print("PrepareBuilder();\n");
-  if (!use_lite_runtime()) {
-    printer->Print("pb::UnknownFieldSet.Builder unknownFields = null;\n");
-  }
   printer->Print(
     "uint tag;\n"
-    "string field_name;\n"
-    "while (input.ReadTag(out tag, out field_name)) {\n");
+    "string fieldName;\n"
+    "while (input.ReadTag(out tag, out fieldName)) {\n"
+    "  if (tag == 0 && fieldName != null) {");
   printer->Indent();
-  printer->Print("if(tag == 0 && field_name != null) {\n");
   printer->Indent();
-  //if you change from StringComparer.Ordinal, the array sort in FieldNames { get; } must also change
-  printer->Print(
-    "int field_ordinal = global::System.Array.BinarySearch(_$camel_class_name$FieldNames, field_name, global::System.StringComparer.Ordinal);\n"
-    "if(field_ordinal >= 0)\n"
-    "  tag = _$camel_class_name$FieldTags[field_ordinal];\n"
-    "else {\n",
-    "camel_class_name", UnderscoresToCamelCase(class_name(), false));
-  if (!use_lite_runtime()) {
-    printer->Print(
-      "  if (unknownFields == null) {\n"  // First unknown field - create builder now
-      "    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);\n"
-      "  }\n");
-  }
   printer->Print(
-    "  ParseUnknownField(input, $prefix$extensionRegistry, tag, field_name);\n",
-    "prefix", use_lite_runtime() ? "" : "unknownFields, ");
-  printer->Print("  continue;\n");
-  printer->Print("}\n");
-  printer->Outdent();
-  printer->Print("}\n");
-
-  printer->Print("switch (tag) {\n");
+    "int fieldOrdinal = global::System.Array.BinarySearch(_fieldNames, fieldName, global::System.String.String.Ordinal);\n"
+    "if (fieldOrdinal >= 0) {\n"
+    "  tag = _fieldTags[fieldOrdinal];\n"
+    "}\n"
+    "switch(tag) {\n");
   printer->Indent();
   printer->Print(
     "case 0: {\n"  // 0 signals EOF / limit reached
     "  throw pb::InvalidProtocolBufferException.InvalidTag();\n"
     "}\n"
-    "default: {\n"
-    "  if (pb::WireFormat.IsEndGroupTag(tag)) {\n");
-  if (!use_lite_runtime()) {
-    printer->Print(
-      "    if (unknownFields != null) {\n"
-      "      this.UnknownFields = unknownFields.Build();\n"
-      "    }\n");
-  }
-  printer->Print(
-    "    return this;\n"  // it's an endgroup tag
-    "  }\n");
-  if (!use_lite_runtime()) {
-    printer->Print(
-      "  if (unknownFields == null) {\n"  // First unknown field - create builder now
-      "    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);\n"
-      "  }\n");
-  }
-  printer->Print(
-      "  ParseUnknownField(input, $prefix$extensionRegistry, tag, field_name);\n",
-      "prefix", use_lite_runtime() ? "" : "unknownFields, ");
-  printer->Print("  break;\n");
-  printer->Print("}\n");
-
+    "default:\n"
+    "  if (pb::WireFormat.IsEndGroupTag(tag)) {\n"
+    "    return;\n"
+    "  }\n"
+    "  break;"); // Note: we're ignoring unknown fields here.
   for (int i = 0; i < fields_by_number().size(); i++) {
     const FieldDescriptor* field = fields_by_number()[i];
     internal::WireFormatLite::WireType wt =
         internal::WireFormat::WireTypeForFieldType(field->type());
     uint32 tag = internal::WireFormatLite::MakeTag(field->number(), wt);
+    // TODO(jonskeet): Understand what this is trying to do
     if (field->is_repeated()
         && (wt == internal::WireFormatLite::WIRETYPE_VARINT
             || wt == internal::WireFormatLite::WIRETYPE_FIXED32
@@ -894,95 +426,14 @@ void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
     printer->Outdent();
     printer->Print("}\n");
   }
-
-  printer->Outdent();
-  printer->Print("}\n");
   printer->Outdent();
-  printer->Print("}\n");
-  printer->Print("\n");
-  if (!use_lite_runtime()) {
-    printer->Print(
-      "if (unknownFields != null) {\n"
-      "  this.UnknownFields = unknownFields.Build();\n"
-      "}\n");
-  }
-  printer->Print("return this;\n");
+  printer->Print("}\n"); // switch
   printer->Outdent();
-  printer->Print("}\n\n");
-}
-
-void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
-  printer->Print("public override bool IsInitialized {\n");
-  printer->Indent();
-  printer->Print("get {\n");
-  printer->Indent();
-
-  // Check that all required fields in this message are set.
-  // TODO(kenton):  We can optimize this when we switch to putting all the
-  // "has" fields into a single bitfield.
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    if (descriptor_->field(i)->is_required()) {
-      printer->Print("if (!has$property_name$) return false;\n",
-		     "property_name", GetPropertyName(descriptor_->field(i)));
-    }
-  }
-
-  // Now check that all embedded messages are initialized.
-  for (int i = 0; i < descriptor_->field_count(); i++) {
-    const FieldDescriptor* field = descriptor_->field(i);
-
-      if (field->type() != FieldDescriptor::TYPE_MESSAGE ||
-          !HasRequiredFields(field->message_type()))
-      {
-          continue;
-      }
-      // TODO(jtattermusch): shouldn't we use GetPropertyName here?
-      string propertyName = UnderscoresToPascalCase(GetFieldName(field));
-      if (field->is_repeated())
-      {
-        printer->Print(
-          "foreach ($class_name$ element in $property_name$List) {\n"
-          "  if (!element.IsInitialized) return false;\n"
-          "}\n",
-          "class_name", GetClassName(field->message_type()),
-          "property_name", propertyName);
-      }
-      else if (field->is_optional())
-      {
-        printer->Print(
-          "if (Has$property_name$) {\n"
-          "  if (!$property_name$.IsInitialized) return false;\n"
-          "}\n",
-          "property_name", propertyName);
-      }
-      else
-      {
-        printer->Print(
-          "if (!$property_name$.IsInitialized) return false;\n",
-          "property_name", propertyName);
-      }
-  }
-
-  if (descriptor_->extension_range_count() > 0) {
-    printer->Print("if (!ExtensionsAreInitialized) return false;\n");
-  }
-  printer->Print("return true;\n");
+  printer->Print("}\n"); // if
   printer->Outdent();
-  printer->Print("}\n");
+  printer->Print("}\n"); // while
   printer->Outdent();
-  printer->Print("}\n");
-  printer->Print("\n");
-}
-
-void MessageGenerator::GenerateExtensionRegistrationCode(io::Printer* printer) {
-  for (int i = 0; i < descriptor_->extension_count(); i++) {
-    ExtensionGenerator extensionGenerator(descriptor_->extension(i));
-    extensionGenerator.GenerateExtensionRegistrationCode(printer);
-  }
-  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
-    MessageGenerator messageGenerator(descriptor_->nested_type(i));
-    messageGenerator.GenerateExtensionRegistrationCode(printer);
-  }
+  printer->Print("}\n\n"); // method
 }
 
 int MessageGenerator::GetFieldOrdinal(const FieldDescriptor* descriptor) {

+ 1 - 13
src/google/protobuf/compiler/csharp/csharp_message.h

@@ -43,7 +43,6 @@ namespace protobuf {
 namespace compiler {
 namespace csharp {
 
-class Writer;
 class FieldGeneratorBase;
 
 class MessageGenerator : public SourceGeneratorBase {
@@ -53,7 +52,6 @@ class MessageGenerator : public SourceGeneratorBase {
 
   void GenerateStaticVariables(io::Printer* printer);
   void GenerateStaticVariableInitializers(io::Printer* printer);
-  void GenerateExtensionRegistrationCode(io::Printer* printer);
   void Generate(io::Printer* printer);
 
  private:
@@ -61,17 +59,8 @@ class MessageGenerator : public SourceGeneratorBase {
   std::vector<std::string> field_names_;
   std::vector<const FieldDescriptor*> fields_by_number_;
 
-  void GenerateLiteRuntimeMethods(io::Printer* printer);
   void GenerateMessageSerializationMethods(io::Printer* printer);
-  void GenerateSerializeOneField(io::Printer* printer,
-                                 const FieldDescriptor* fieldDescriptor);
-  void GenerateSerializeOneExtensionRange(
-      io::Printer* printer, const Descriptor::ExtensionRange* extendsionRange);
-  void GenerateParseFromMethods(io::Printer* printer);
-  void GenerateBuilder(io::Printer* printer);
-  void GenerateCommonBuilderMethods(io::Printer* printer);
-  void GenerateBuilderParsingMethods(io::Printer* printer);
-  void GenerateIsInitialized(io::Printer* printer);
+  void GenerateMergingMethods(io::Printer* printer);
 
   int GetFieldOrdinal(const FieldDescriptor* descriptor);
   FieldGeneratorBase* CreateFieldGeneratorInternal(
@@ -95,4 +84,3 @@ class MessageGenerator : public SourceGeneratorBase {
 }  // namespace google
 
 #endif  // GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__
-

+ 30 - 201
src/google/protobuf/compiler/csharp/csharp_message_field.cc

@@ -49,8 +49,8 @@ namespace csharp {
 MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
                                              int fieldOrdinal)
     : FieldGeneratorBase(descriptor, fieldOrdinal) {
-  variables_["has_property_check"] = "has" + property_name();
-  variables_["message_or_group"] = message_or_group();
+  variables_["has_property_check"] = property_name() + "_ != null";
+  variables_["has_not_property_check"] = property_name() + "_ == null";
 }
 
 MessageFieldGenerator::~MessageFieldGenerator() {
@@ -60,125 +60,42 @@ MessageFieldGenerator::~MessageFieldGenerator() {
 void MessageFieldGenerator::GenerateMembers(io::Printer* printer) {
   printer->Print(
     variables_,
-    "private bool has$property_name$;\n"
     "private $type_name$ $name$_;\n");
   AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public bool Has$property_name$ {\n"
-    "  get { return has$property_name$; }\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
   printer->Print(
     variables_,
     "public $type_name$ $property_name$ {\n"
-    "  get { return $name$_ ?? $default_value$; }\n"
-    "}\n");
-}
-
-void MessageFieldGenerator::GenerateBuilderMembers(io::Printer* printer) {
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public bool Has$property_name$ {\n"
-    " get { return result.has$property_name$; }\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public $type_name$ $property_name$ {\n"
-    "  get { return result.$property_name$; }\n"
-    "  set { Set$property_name$(value); }\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Set$property_name$($type_name$ value) {\n");
-  AddNullCheck(printer);
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  result.has$property_name$ = true;\n"
-    "  result.$name$_ = value;\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Set$property_name$($type_name$.Builder builderForValue) {\n");
-  AddNullCheck(printer, "builderForValue");
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  result.has$property_name$ = true;\n"
-    "  result.$name$_ = builderForValue.Build();\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Merge$property_name$($type_name$ value) {\n");
-  AddNullCheck(printer);
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  if (result.has$property_name$ &&\n"
-    "      result.$name$_ != $default_value$) {\n"
-    "      result.$name$_ = $type_name$.CreateBuilder(result.$name$_).MergeFrom(value).BuildPartial();\n"
-    "  } else {\n"
-    "    result.$name$_ = value;\n"
-    "  }\n"
-    "  result.has$property_name$ = true;\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Clear$property_name$() {\n"
-    "  PrepareBuilder();\n"
-    "  result.has$property_name$ = false;\n"
-    "  result.$name$_ = null;\n"
-    "  return this;\n"
+    "  get { return $name$_; }\n"
+    "  set { return $name$_ = value; }\n"
     "}\n");
 }
 
 void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) {
   printer->Print(
     variables_,
-    "if (other.Has$property_name$) {\n"
-    "  Merge$property_name$(other.$property_name$);\n"
+    "if (other.$has_property_check$) {\n"
+    "  if ($has_not_property_check) {\n"
+    "    $name$_ = new $type_name$();\n"
+    "  }\n"
+    "  $property_name$.MergeWith(other.$property_name);\n"
     "}\n");
 }
 
-void MessageFieldGenerator::GenerateBuildingCode(io::Printer* printer) {
-  // Nothing to do for singular fields
-}
-
 void MessageFieldGenerator::GenerateParsingCode(io::Printer* printer) {
   printer->Print(
     variables_,
-    "$type_name$.Builder subBuilder = $type_name$.CreateBuilder();\n"
-    "if (result.has$property_name$) {\n"
-    "  subBuilder.MergeFrom($property_name$);\n"
-    "}\n");
-
-  if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
-    printer->Print(
-      variables_,
-      "input.ReadGroup($number$, subBuilder, extensionRegistry);\n");
-  } else {
-    printer->Print("input.ReadMessage(subBuilder, extensionRegistry);\n");
-  }
-  printer->Print(
-    variables_,
-    "$property_name$ = subBuilder.BuildPartial();\n");
+    "if ($has_not_property_check) {\n"
+    "  $name$_ = new $type_name$();\n"
+    "}\n"
+    "input.ReadMessage($name$_);\n"); // No need to support TYPE_GROUP...
 }
 
 void MessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+  // TODO(jonskeet): Why are we using array access instead of a literal here?
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  output.Write$message_or_group$($number$, field_names[$field_ordinal$], $property_name$);\n"
+    "  output.WriteMessage($number$, fieldNames[$field_ordinal$], $property_name$);\n"
     "}\n");
 }
 
@@ -186,19 +103,19 @@ void MessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  size += pb::CodedOutputStream.Compute$message_or_group$Size($number$, $property_name$);\n"
+    "  size += pb::CodedOutputStream.ComputeMessageSize($number$, $property_name$);\n"
     "}\n");
 }
 
 void MessageFieldGenerator::WriteHash(io::Printer* printer) {
   printer->Print(
     variables_,
-    "if (has$property_name$) hash ^= $name$_.GetHashCode();\n");
+    "if ($has_property_check$) hash ^= $name$_.GetHashCode();\n");
 }
 void MessageFieldGenerator::WriteEquals(io::Printer* printer) {
   printer->Print(
     variables_,
-    "if (has$property_name$ != other.has$property_name$ || (has$property_name$ && !$name$_.Equals(other.$name$_))) return false;\n");
+    "if (!object.Equals($property_name$_, other.$property_name$_)) return false;\n");
 }
 void MessageFieldGenerator::WriteToString(io::Printer* printer) {
   variables_["field_name"] = GetFieldName(descriptor_);
@@ -218,118 +135,30 @@ MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {
 }
 
 void MessageOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
-  if (SupportFieldPresence(descriptor_->file())) {
-    AddDeprecatedFlag(printer);
-    printer->Print(
-      variables_,
-      "public bool Has$property_name$ {\n"
-      "  get { return $has_property_check$; }\n"
-      "}\n");
-  }
   AddDeprecatedFlag(printer);
   printer->Print(
     variables_,
     "public $type_name$ $property_name$ {\n"
-    "  get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : $default_value$; }\n"
-    "}\n");
-}
-
-void MessageOneofFieldGenerator::GenerateBuilderMembers(io::Printer* printer) {
-  if (SupportFieldPresence(descriptor_->file())) {
-    AddDeprecatedFlag(printer);
-    printer->Print(
-      variables_,
-      "public bool Has$property_name$ {\n"
-      "  get { return result.$has_property_check$; }\n"
-      "}\n");
-  }
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public $type_name$ $property_name$ {\n"
-    "  get { return result.$has_property_check$ ? ($type_name$) result.$oneof_name$_ : $default_value$; }\n"
-    "  set { Set$property_name$(value); }\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Set$property_name$($type_name$ value) {\n");
-  AddNullCheck(printer);
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  result.$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n"
-    "  result.$oneof_name$_ = value;\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Set$property_name$($type_name$.Builder builderForValue) {\n");
-  AddNullCheck(printer, "builderForValue");
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  result.$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n"
-    "  result.$oneof_name$_ = builderForValue.Build();\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Merge$property_name$($type_name$ value) {\n");
-  AddNullCheck(printer);
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  if (result.$has_property_check$ &&\n"
-    "      result.$property_name$ != $default_value$) {\n"
-    "    result.$oneof_name$_ = $type_name$.CreateBuilder(result.$property_name$).MergeFrom(value).BuildPartial();\n"
-    "  } else {\n"
-    "    result.$oneof_name$_ = value;\n"
-    "  }\n"
-    "  result.$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Clear$property_name$() {\n"
-    "  if (result.$has_property_check$) {\n"
-    "    PrepareBuilder();\n"
-    "    result.$oneof_name$Case_ = $oneof_property_name$OneofCase.None;\n"
-    "    result.$oneof_name$_ = null;\n"
-    "  }\n"
-    "  return this;\n"
+    "  get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : null; }\n"
+    "  set { \n"
+    "    $name$_ = value;"
+    "    $oneof_name$Case_ = value == null ? $oneof_property_name$Case.None : $oneof_property_name$Case.$property_name$; }\n"
+    "  } \n"
     "}\n");
 }
 
 void MessageOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+  // TODO(jonskeet): We may be able to do better than this
   printer->Print(
     variables_,
-    "$type_name$.Builder subBuilder = $type_name$.CreateBuilder();\n"
-    "if (result.$has_property_check$) {\n"
-    "  subBuilder.MergeFrom($property_name$);\n"
-    "}\n");
-
-  if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
-    printer->Print(
-      variables_,
-      "input.ReadGroup($number$, subBuilder, extensionRegistry);\n");
-  } else {
-    printer->Print("input.ReadMessage(subBuilder, extensionRegistry);\n");
-  }
-  printer->Print(
-    variables_,
-    "result.$oneof_name$_ = subBuilder.BuildPartial();\n"
-    "result.$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n");
+    "$type_name$ subBuilder = new type_name$();\n"
+    "if ($has_property_check$) {\n"
+    "  subBuilder.MergeWith($property_name$);\n"
+    "}\n"
+    "input.ReadMessage(subBuilder);\n" // No support of TYPE_GROUP
+    "$oneof_property_name$ = subBuilder;\n");
 }
 
-void MessageOneofFieldGenerator::WriteEquals(io::Printer* printer) {
-  printer->Print(
-    variables_,
-    "if (!$property_name$.Equals(other.$property_name$)) return false;\n");
-}
 void MessageOneofFieldGenerator::WriteToString(io::Printer* printer) {
   printer->Print(
     variables_,

+ 0 - 6
src/google/protobuf/compiler/csharp/csharp_message_field.h

@@ -41,17 +41,13 @@ namespace protobuf {
 namespace compiler {
 namespace csharp {
 
-class Writer;
-
 class MessageFieldGenerator : public FieldGeneratorBase {
  public:
   MessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~MessageFieldGenerator();
 
   virtual void GenerateMembers(io::Printer* printer);
-  virtual void GenerateBuilderMembers(io::Printer* printer);
   virtual void GenerateMergingCode(io::Printer* printer);
-  virtual void GenerateBuildingCode(io::Printer* printer);
   virtual void GenerateParsingCode(io::Printer* printer);
   virtual void GenerateSerializationCode(io::Printer* printer);
   virtual void GenerateSerializedSizeCode(io::Printer* printer);
@@ -70,8 +66,6 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator {
   ~MessageOneofFieldGenerator();
 
   virtual void GenerateMembers(io::Printer* printer);
-  virtual void GenerateBuilderMembers(io::Printer* printer);
-  virtual void WriteEquals(io::Printer* printer);
   virtual void WriteToString(io::Printer* printer);
   virtual void GenerateParsingCode(io::Printer* printer);
 

+ 40 - 137
src/google/protobuf/compiler/csharp/csharp_primitive_field.cc

@@ -49,82 +49,37 @@ namespace csharp {
 PrimitiveFieldGenerator::PrimitiveFieldGenerator(
     const FieldDescriptor* descriptor, int fieldOrdinal)
     : FieldGeneratorBase(descriptor, fieldOrdinal) {
+  // TODO(jonskeet): Make this cleaner...
+  is_value_type = descriptor->type() != FieldDescriptor::TYPE_STRING
+      && descriptor->type() != FieldDescriptor::TYPE_BYTES;
 }
 
 PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {
-
 }
 
 void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) {
-  if (SupportFieldPresence(descriptor_->file())) {
-    printer->Print(variables_, "private bool has$property_name$;\n");
-  }
+  // TODO(jonskeet): Work out whether we want to prevent the fields from ever being
+  // null, or whether we just handle it, in the cases of bytes and string.
+  // (Basically, should null-handling code be in the getter or the setter?)
   printer->Print(
     variables_,
     "private $type_name$ $name_def_message$;\n");
   AddDeprecatedFlag(printer);
-  if (SupportFieldPresence(descriptor_->file())) {
-    printer->Print(
-      variables_,
-      "public bool Has$property_name$ {\n"
-      "  get { return has$property_name$; }\n"
-      "}\n");
-  }
-  AddPublicMemberAttributes(printer);
   printer->Print(
     variables_,
     "public $type_name$ $property_name$ {\n"
-    "  get { return $name$_; }\n"
-    "}\n");
-}
-
-void PrimitiveFieldGenerator::GenerateBuilderMembers(io::Printer* printer) {
-  AddDeprecatedFlag(printer);
-  if (SupportFieldPresence(descriptor_->file())) {
-    printer->Print(
-      variables_,
-      "public bool Has$property_name$ {\n"
-      "  get { return result.has$property_name$; }\n"
-      "}\n");
-  }
-  AddPublicMemberAttributes(printer);
-  printer->Print(
-    variables_,
-    "public $type_name$ $property_name$ {\n"
-    "  get { return result.$property_name$; }\n"
-    "  set { Set$property_name$(value); }\n"
-    "}\n");
-  AddPublicMemberAttributes(printer);
-  printer->Print(
-    variables_,
-    "public Builder Set$property_name$($type_name$ value) {\n");
-  AddNullCheck(printer);
-  printer->Print("  PrepareBuilder();\n");
-  if (SupportFieldPresence(descriptor_->file())) {
+    "  get { return $name$_; }\n");
+  if (is_value_type) {
     printer->Print(
       variables_,
-      "  result.has$property_name$ = true;\n");
-  }
-  printer->Print(
-    variables_,
-    "  result.$name$_ = value;\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Clear$property_name$() {\n"
-    "  PrepareBuilder();\n");
-  if (SupportFieldPresence(descriptor_->file())) {
+      "  set { $name$_ = value; }\n");
+
+  } else {
     printer->Print(
       variables_,
-      "  result.has$property_name$ = false;\n");
+      "  set { $name$_ = value ?? $default_value$; }\n");
   }
-  printer->Print(
-    variables_,
-    "  result.$name$_ = $default_value$;\n"
-    "  return this;\n"
-    "}\n");
+  printer->Print("}\n\n");
 }
 
 void PrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) {
@@ -135,27 +90,17 @@ void PrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) {
     "}\n");
 }
 
-void PrimitiveFieldGenerator::GenerateBuildingCode(io::Printer* printer) {
-  // Nothing to do here for primitive types
-}
-
 void PrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer) {
-  if (SupportFieldPresence(descriptor_->file())) {
-    printer->Print(
-      variables_,
-      "result.has$property_name$ = input.Read$capitalized_type_name$(ref result.$name$_);\n");
-  } else {
-    printer->Print(
-      variables_,
-      "input.Read$capitalized_type_name$(ref result.$name$_);\n");
-  }
+  printer->Print(
+    variables_,
+    "input.Read$capitalized_type_name$(ref result.$name$_);\n");
 }
 
 void PrimitiveFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  output.Write$capitalized_type_name$($number$, field_names[$field_ordinal$], $property_name$);\n"
+    "  output.Write$capitalized_type_name$($number$, fieldNames[$field_ordinal$], $property_name$);\n"
     "}\n");
 }
 
@@ -171,24 +116,18 @@ void PrimitiveFieldGenerator::WriteHash(io::Printer* printer) {
   printer->Print(
     variables_,
     "if ($has_property_check$) {\n"
-    "  hash ^= $name$_.GetHashCode();\n"
+    "  hash ^= $property_name$.GetHashCode();\n"
     "}\n");
 }
 void PrimitiveFieldGenerator::WriteEquals(io::Printer* printer) {
-  if (SupportFieldPresence(descriptor_->file())) {
-    printer->Print(
-      variables_,
-      "if (has$property_name$ != other.has$property_name$ || (has$property_name$ && !$name$_.Equals(other.$name$_))) return false;\n");
-  } else {
-    printer->Print(
-      variables_,
-      "if (!$name$_.Equals(other.$name$_)) return false;\n");
-  }
+  printer->Print(
+    variables_,
+    "if ($property_name$ != other.$property_name$) return false;\n");
 }
 void PrimitiveFieldGenerator::WriteToString(io::Printer* printer) {
   printer->Print(
     variables_,
-    "PrintField(\"$descriptor_name$\", $has_property_check$, $name$_, writer);\n");
+    "PrintField(\"$descriptor_name$\", $has_property_check$, $property_name$, writer);\n");
 }
 
 PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator(
@@ -201,79 +140,43 @@ PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {
 }
 
 void PrimitiveOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
+  // TODO(jonskeet): What should foo.OneofIntField = 0; do? Clear the oneof?
+  // Currently foo.OneOfStringField = null will clear the oneof, but foo.OneOfStringField = "" won't. Ick.
   AddDeprecatedFlag(printer);
-  if (SupportFieldPresence(descriptor_->file())) {
-    printer->Print(
-      variables_,
-      "public bool Has$property_name$ {\n"
-      "  get { return $has_property_check$; }\n"
-      "}\n");
-  }
-  AddPublicMemberAttributes(printer);
   printer->Print(
     variables_,
     "public $type_name$ $property_name$ {\n"
     "  get { return $has_property_check$ ? ($type_name$) $oneof_name$_ : $default_value$; }\n"
-    "}\n");
-}
-
-void PrimitiveOneofFieldGenerator::GenerateBuilderMembers(io::Printer* printer) {
-  AddDeprecatedFlag(printer);
-  if (SupportFieldPresence(descriptor_->file())) {
+    "  set {");
+    if (is_value_type) {
+      printer->Print(
+        variables_,
+        "  $oneof_name$_ = value;\n"
+        "  $oneof_name$Case_ = $oneof_property_name$Case.$property_name$;\n");
+    } else {
+      printer->Print(
+        variables_,
+        "  $oneof_name$_ = value ?? $default_value$;\n"
+        "  $oneof_name$Case_ = value == null ? $oneof_property_name$Case.None : $oneof_property_name$Case.$property_name$;\n");
+    }
     printer->Print(
-      variables_,
-      "public bool Has$property_name$ {\n"
-      "  get { return result.$has_property_check$; }\n"
+      "  }\n"
       "}\n");
-  }
-  AddPublicMemberAttributes(printer);
-  printer->Print(
-    variables_,
-    "public $type_name$ $property_name$ {\n"
-    "  get { return result.$has_property_check$ ? ($type_name$) result.$oneof_name$_ : $default_value$; }\n"
-    "  set { Set$property_name$(value); }\n"
-    "}\n");
-  AddPublicMemberAttributes(printer);
-  printer->Print(
-    variables_,
-    "public Builder Set$property_name$($type_name$ value) {\n");
-  AddNullCheck(printer);
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  result.$oneof_name$_ = value;\n"
-    "  result.$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Clear$property_name$() {\n"
-    "  PrepareBuilder();\n"
-    "  if (result.$has_property_check$) {\n"
-    "    result.$oneof_name$Case_ = $oneof_property_name$OneofCase.None;\n"
-    "  }\n"
-    "  return this;\n"
-    "}\n");
 }
 
-void PrimitiveOneofFieldGenerator::WriteEquals(io::Printer* printer) {
-  printer->Print(
-    variables_,
-    "if (!$property_name$.Equals(other.$property_name$)) return false;\n");
-}
 void PrimitiveOneofFieldGenerator::WriteToString(io::Printer* printer) {
   printer->Print(variables_,
     "PrintField(\"$descriptor_name$\", $has_property_check$, $oneof_name$_, writer);\n");
 }
 
 void PrimitiveOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+  // TODO(jonskeet): What if the value we read is the default value for the type?
   printer->Print(
     variables_,
     "$type_name$ value = $default_value$;\n"
     "if (input.Read$capitalized_type_name$(ref value)) {\n"
-    "  result.$oneof_name$_ = value;\n"
-    "  result.$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n"
+    "  $oneof_name$_ = value;\n"
+    "  $oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n"
     "}\n");
 }
 

+ 3 - 6
src/google/protobuf/compiler/csharp/csharp_primitive_field.h

@@ -41,17 +41,13 @@ namespace protobuf {
 namespace compiler {
 namespace csharp {
 
-class Writer;
-
 class PrimitiveFieldGenerator : public FieldGeneratorBase {
  public:
   PrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~PrimitiveFieldGenerator();
 
   virtual void GenerateMembers(io::Printer* printer);
-  virtual void GenerateBuilderMembers(io::Printer* printer);
   virtual void GenerateMergingCode(io::Printer* printer);
-  virtual void GenerateBuildingCode(io::Printer* printer);
   virtual void GenerateParsingCode(io::Printer* printer);
   virtual void GenerateSerializationCode(io::Printer* printer);
   virtual void GenerateSerializedSizeCode(io::Printer* printer);
@@ -60,6 +56,9 @@ class PrimitiveFieldGenerator : public FieldGeneratorBase {
   virtual void WriteEquals(io::Printer* printer);
   virtual void WriteToString(io::Printer* printer);
 
+ protected:
+  bool is_value_type;
+
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
 };
@@ -70,8 +69,6 @@ class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
   ~PrimitiveOneofFieldGenerator();
 
   virtual void GenerateMembers(io::Printer* printer);
-  virtual void GenerateBuilderMembers(io::Printer* printer);
-  virtual void WriteEquals(io::Printer* printer);
   virtual void WriteToString(io::Printer* printer);
   virtual void GenerateParsingCode(io::Printer* printer);
 

+ 15 - 116
src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc

@@ -56,141 +56,46 @@ RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {
 }
 
 void RepeatedEnumFieldGenerator::GenerateMembers(io::Printer* printer) {
-  if (descriptor_->is_packed() && optimize_speed()) {
-    printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n");
-  }
-  printer->Print(variables_,
-    "private pbc::PopsicleList<$type_name$> $name$_ = new pbc::PopsicleList<$type_name$>();\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public scg::IList<$type_name$> $property_name$List {\n"
-    "  get { return pbc::Lists.AsReadOnly($name$_); }\n"
-    "}\n");
-
-  // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public int $property_name$Count {\n"
-    "  get { return $name$_.Count; }\n"
-    "}\n");
-
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public $type_name$ Get$property_name$(int index) {\n"
-    "  return $name$_[index];\n"
-    "}\n");
-}
-
-void RepeatedEnumFieldGenerator::GenerateBuilderMembers(io::Printer* printer) {
-  // 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(printer);
-  printer->Print(
-    variables_,
-    "public pbc::IPopsicleList<$type_name$> $property_name$List {\n"
-    "  get { return PrepareBuilder().$name$_; }\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public int $property_name$Count {\n"
-    "  get { return result.$property_name$Count; }\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public $type_name$ Get$property_name$(int index) {\n"
-    "  return result.Get$property_name$(index);\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Set$property_name$(int index, $type_name$ value) {\n");
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  result.$name$_[index] = value;\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
   printer->Print(variables_,
-    "public Builder Add$property_name$($type_name$ value) {\n");
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  result.$name$_.Add(value);\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder AddRange$property_name$(scg::IEnumerable<$type_name$> values) {\n"
-    "  PrepareBuilder();\n"
-    "  result.$name$_.Add(values);\n"
-    "  return this;\n"
-    "}\n");
+    "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n");
   AddDeprecatedFlag(printer);
   printer->Print(
     variables_,
-    "public Builder Clear$property_name$() {\n"
-    "  PrepareBuilder();\n"
-    "  result.$name$_.Clear();\n"
-    "  return this;\n"
+    "public pbc::RepeatedField<$type_name$> $property_name$ {\n"
+    "  get { return $name$_; }\n"
     "}\n");
 }
 
 void RepeatedEnumFieldGenerator::GenerateMergingCode(io::Printer* printer) {
   printer->Print(
     variables_,
-    "if (other.$name$_.Count != 0) {\n"
-    "  result.$name$_.Add(other.$name$_);\n"
-    "}\n");
-}
-
-void RepeatedEnumFieldGenerator::GenerateBuildingCode(io::Printer* printer) {
-  printer->Print(variables_, "$name$_.MakeReadOnly();\n");
+    "$name$_.Add(other.$name$_);\n");
 }
 
 void RepeatedEnumFieldGenerator::GenerateParsingCode(io::Printer* printer) {
   printer->Print(
     variables_,
-    "scg::ICollection<object> unknownItems;\n"
-    "input.ReadEnumArray<$type_name$>(tag, field_name, result.$name$_, out unknownItems);\n");
-  if (!use_lite_runtime()) {
-    printer->Print(
-      variables_,
-      "if (unknownItems != null) {\n"
-      "  if (unknownFields == null) {\n"
-      "    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);\n"
-      "  }\n"
-      "  foreach (object rawValue in unknownItems)\n"
-      "    if (rawValue is int)\n"
-      "      unknownFields.MergeVarintField($number$, (ulong)(int)rawValue);\n"
-      "}\n");
-  }
+    "input.ReadEnumArray<$type_name$>(tag, fieldName, result.$name$_);\n");
 }
 
 void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
-  printer->Print(variables_, "if ($name$_.Count > 0) {\n");
-  printer->Indent();
+  // TODO(jonskeet): Originally, this checked for Count > 0 first.
+  // The Write* call should make that cheap though - no need to generate it every time.
   if (descriptor_->is_packed()) {
     printer->Print(
       variables_,
-      "output.WritePackedEnumArray($number$, field_names[$field_ordinal$], $name$MemoizedSerializedSize, $name$_);\n");
+      "output.WritePackedEnumArray($number$, fieldNames[$field_ordinal$], $name$_);\n");
   } else {
     printer->Print(variables_,
-      "output.WriteEnumArray($number$, field_names[$field_ordinal$], $name$_);\n");
+      "output.WriteEnumArray($number$, fieldNames[$field_ordinal$], $name$_);\n");
   }
-  printer->Outdent();
   printer->Print("}\n");
 }
 
 void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
   printer->Print("{\n");
   printer->Indent();
+  // TODO(jonskeet): Move all this code into CodedOutputStream? It's a lot to repeat everywhere...
   printer->Print(
     variables_,
     "int dataSize = 0;\n"
@@ -199,7 +104,7 @@ void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer
   printer->Print(
     variables_,
     "foreach ($type_name$ element in $name$_) {\n"
-    "  dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);\n"
+    "  dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((long) element);\n"
     "}\n"
     "size += dataSize;\n");
   int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type());
@@ -215,11 +120,6 @@ void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer
   }
   printer->Outdent();
   printer->Print("}\n");
-  // cache the data size for packed fields.
-  if (descriptor_->is_packed()) {
-    printer->Print(variables_,
-      "$name$MemoizedSerializedSize = dataSize;\n");
-  }
   printer->Outdent();
   printer->Print("}\n");
 }
@@ -227,16 +127,15 @@ void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer
 void RepeatedEnumFieldGenerator::WriteHash(io::Printer* printer) {
   printer->Print(
     variables_,
-    "foreach($type_name$ i in $name$_)\n"
-    "  hash ^= i.GetHashCode();\n");
+    "foreach($type_name$ i in $name$_) {\n"
+    "  hash ^= i.GetHashCode();\n"
+    "}\n");
 }
 
 void RepeatedEnumFieldGenerator::WriteEquals(io::Printer* printer) {
   printer->Print(
     variables_,
-    "if($name$_.Count != other.$name$_.Count) return false;\n"
-    "for(int ix=0; ix < $name$_.Count; ix++)\n"
-    "  if(!$name$_[ix].Equals(other.$name$_[ix])) return false;\n");
+    "if(!$name$_.Equals(other.$name$)) return false;\n");
 }
 
 void RepeatedEnumFieldGenerator::WriteToString(io::Printer* printer) {

+ 2 - 4
src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h

@@ -41,17 +41,15 @@ namespace protobuf {
 namespace compiler {
 namespace csharp {
 
-class Writer;
-
+// TODO(jonskeet): Refactor repeated field support; all the implementations are *really* similar. We
+// should probably have a RepeatedFieldGeneratorBase.
 class RepeatedEnumFieldGenerator : public FieldGeneratorBase {
  public:
   RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~RepeatedEnumFieldGenerator();
 
   virtual void GenerateMembers(io::Printer* printer);
-  virtual void GenerateBuilderMembers(io::Printer* printer);
   virtual void GenerateMergingCode(io::Printer* printer);
-  virtual void GenerateBuildingCode(io::Printer* printer);
   virtual void GenerateParsingCode(io::Printer* printer);
   virtual void GenerateSerializationCode(io::Printer* printer);
   virtual void GenerateSerializedSizeCode(io::Printer* printer);

+ 14 - 106
src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc

@@ -48,7 +48,6 @@ namespace csharp {
 RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
     const FieldDescriptor* descriptor, int fieldOrdinal)
     : FieldGeneratorBase(descriptor, fieldOrdinal) {
-  variables_["message_or_group"] = message_or_group();
 }
 
 RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {
@@ -58,11 +57,11 @@ RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {
 void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) {
   printer->Print(
     variables_,
-    "private pbc::PopsicleList<$type_name$> $name$_ = new pbc::PopsicleList<$type_name$>();\n");
+    "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n");
   AddDeprecatedFlag(printer);
   printer->Print(
     variables_,
-    "public scg::IList<$type_name$> $property_name$List {\n"
+    "public pbc::RepeatedField<$type_name$> $property_name$ {\n"
     "  get { return $name$_; }\n"
     "}\n");
 
@@ -82,137 +81,46 @@ void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) {
     "}\n");
 }
 
-void RepeatedMessageFieldGenerator::GenerateBuilderMembers(io::Printer* printer) {
-  // 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(printer);
-  printer->Print(
-    variables_,
-    "public pbc::IPopsicleList<$type_name$> $property_name$List {\n"
-    "  get { return PrepareBuilder().$name$_; }\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public int $property_name$Count {\n"
-    "  get { return result.$property_name$Count; }\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public $type_name$ Get$property_name$(int index) {\n"
-    "  return result.Get$property_name$(index);\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Set$property_name$(int index, $type_name$ value) {\n");
-  AddNullCheck(printer);
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  result.$name$_[index] = value;\n"
-    "  return this;\n"
-    "}\n");
-  // Extra overload for builder (just on messages)
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Set$property_name$(int index, $type_name$.Builder builderForValue) {\n");
-  AddNullCheck(printer, "builderForValue");
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  result.$name$_[index] = builderForValue.Build();\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Add$property_name$($type_name$ value) {\n");
-  AddNullCheck(printer);
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  result.$name$_.Add(value);\n"
-    "  return this;\n"
-    "}\n");
-  // Extra overload for builder (just on messages)
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Add$property_name$($type_name$.Builder builderForValue) {\n");
-  AddNullCheck(printer, "builderForValue");
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  result.$name$_.Add(builderForValue.Build());\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder AddRange$property_name$(scg::IEnumerable<$type_name$> values) {\n"
-    "  PrepareBuilder();\n"
-    "  result.$name$_.Add(values);\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Clear$property_name$() {\n"
-    "  PrepareBuilder();\n"
-    "  result.$name$_.Clear();\n"
-    "  return this;\n"
-    "}\n");
-}
-
 void RepeatedMessageFieldGenerator::GenerateMergingCode(io::Printer* printer) {
   printer->Print(
     variables_,
-    "if (other.$name$_.Count != 0) {\n"
-    "  result.$name$_.Add(other.$name$_);\n"
-    "}\n");
-}
-
-void RepeatedMessageFieldGenerator::GenerateBuildingCode(io::Printer* printer) {
-  printer->Print(variables_, "$name$_.MakeReadOnly();\n");
+    "$name$_.Add(other.$name$_);\n");
 }
 
 void RepeatedMessageFieldGenerator::GenerateParsingCode(io::Printer* printer) {
   printer->Print(
     variables_,
-    "input.Read$message_or_group$Array(tag, field_name, result.$name$_, $type_name$.DefaultInstance, extensionRegistry);\n");
+    "input.ReadMessageArray(tag, fieldName, $name$_);\n");
 }
 
 void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+  // TODO(jonskeet): Originally, this checked for Count > 0 first.
+  // The Write* call should make that cheap though - no need to generate it every time.
   printer->Print(
     variables_,
-    "if ($name$_.Count > 0) {\n"
-    "  output.Write$message_or_group$Array($number$, field_names[$field_ordinal$], $name$_);\n"
-    "}\n");
+    "output.WriteMessageArray($number$, fieldNames[$field_ordinal$], $name$_);\n");
 }
 
 void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+  // TODO(jonskeet): Put this into CodedOutputStream.
   printer->Print(
     variables_,
-    "foreach ($type_name$ element in $property_name$List) {\n"
-    "  size += pb::CodedOutputStream.Compute$message_or_group$Size($number$, element);\n"
+    "foreach ($type_name$ element in $property_name$) {\n"
+    "  size += pb::CodedOutputStream.ComputeMessageSize($number$, element);\n"
     "}\n");
 }
 
 void RepeatedMessageFieldGenerator::WriteHash(io::Printer* printer) {
   printer->Print(
     variables_,
-    "foreach($type_name$ i in $name$_)\n"
-    "  hash ^= i.GetHashCode();\n");
+    "foreach($type_name$ i in $name$_) {\n"
+    "  hash ^= i.GetHashCode();\n"
+    "}\n");
 }
 void RepeatedMessageFieldGenerator::WriteEquals(io::Printer* printer) {
   printer->Print(
     variables_,
-    "if($name$_.Count != other.$name$_.Count) return false;\n"
-    "for(int ix=0; ix < $name$_.Count; ix++)\n"
-    "  if(!$name$_[ix].Equals(other.$name$_[ix])) return false;\n");
+    "if(!$name$_.Equals(other.$name$)) return false;\n");
 }
 void RepeatedMessageFieldGenerator::WriteToString(io::Printer* printer) {
   variables_["field_name"] = GetFieldName(descriptor_);

+ 0 - 4
src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h

@@ -41,17 +41,13 @@ namespace protobuf {
 namespace compiler {
 namespace csharp {
 
-class Writer;
-
 class RepeatedMessageFieldGenerator : public FieldGeneratorBase {
  public:
   RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~RepeatedMessageFieldGenerator();
 
   virtual void GenerateMembers(io::Printer* printer);
-  virtual void GenerateBuilderMembers(io::Printer* printer);
   virtual void GenerateMergingCode(io::Printer* printer);
-  virtual void GenerateBuildingCode(io::Printer* printer);
   virtual void GenerateParsingCode(io::Printer* printer);
   virtual void GenerateSerializationCode(io::Printer* printer);
   virtual void GenerateSerializedSizeCode(io::Printer* printer);

+ 14 - 105
src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc

@@ -56,129 +56,43 @@ RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {
 }
 
 void RepeatedPrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) {
-  if (descriptor_->is_packed() && optimize_speed()) {
-    printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n");
-  }
   printer->Print(variables_,
-    "private pbc::PopsicleList<$type_name$> $name$_ = new pbc::PopsicleList<$type_name$>();\n");
-  AddPublicMemberAttributes(printer);
-  printer->Print(
-    variables_,
-    "public scg::IList<$type_name$> $property_name$List {\n"
-    "  get { return pbc::Lists.AsReadOnly($name$_); }\n"
-    "}\n");
-
-  // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
+    "private readonly pbc::RepeatedField<$type_name$> $name$_ = new pbc::RepeatedField<$type_name$>();\n");
   AddDeprecatedFlag(printer);
   printer->Print(
     variables_,
-    "public int $property_name$Count {\n"
-    "  get { return $name$_.Count; }\n"
-    "}\n");
-
-  AddPublicMemberAttributes(printer);
-  printer->Print(
-    variables_,
-    "public $type_name$ Get$property_name$(int index) {\n"
-    "  return $name$_[index];\n"
-    "}\n");
-}
-
-void RepeatedPrimitiveFieldGenerator::GenerateBuilderMembers(io::Printer* printer) {
-  // 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.
-  AddPublicMemberAttributes(printer);
-  printer->Print(
-    variables_,
-    "public pbc::IPopsicleList<$type_name$> $property_name$List {\n"
-    "  get { return PrepareBuilder().$name$_; }\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public int $property_name$Count {\n"
-    "  get { return result.$property_name$Count; }\n"
-    "}\n");
-  AddPublicMemberAttributes(printer);
-  printer->Print(
-    variables_,
-    "public $type_name$ Get$property_name$(int index) {\n"
-    "  return result.Get$property_name$(index);\n"
-    "}\n");
-  AddPublicMemberAttributes(printer);
-  printer->Print(
-    variables_,
-    "public Builder Set$property_name$(int index, $type_name$ value) {\n");
-  AddNullCheck(printer);
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  result.$name$_[index] = value;\n"
-    "  return this;\n"
-    "}\n");
-  AddPublicMemberAttributes(printer);
-  printer->Print(
-    variables_,
-    "public Builder Add$property_name$($type_name$ value) {\n");
-  AddNullCheck(printer);
-  printer->Print(
-    variables_,
-    "  PrepareBuilder();\n"
-    "  result.$name$_.Add(value);\n"
-    "  return this;\n"
-    "}\n");
-  AddPublicMemberAttributes(printer);
-  printer->Print(
-    variables_,
-    "public Builder AddRange$property_name$(scg::IEnumerable<$type_name$> values) {\n"
-    "  PrepareBuilder();\n"
-    "  result.$name$_.Add(values);\n"
-    "  return this;\n"
-    "}\n");
-  AddDeprecatedFlag(printer);
-  printer->Print(
-    variables_,
-    "public Builder Clear$property_name$() {\n"
-    "  PrepareBuilder();\n"
-    "  result.$name$_.Clear();\n"
-    "  return this;\n"
+    "public pbc::RepeatedField<$type_name$> $property_name$ {\n"
+    "  get { return $name$_; }\n"
     "}\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) {
   printer->Print(
     variables_,
-    "if (other.$name$_.Count != 0) {\n"
-    "  result.$name$_.Add(other.$name$_);\n"
-    "}\n");
-}
-
-void RepeatedPrimitiveFieldGenerator::GenerateBuildingCode(io::Printer* printer) {
-  printer->Print(variables_, "$name$_.MakeReadOnly();\n");
+    "$name$_.Add(other.$name$_);\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer) {
   printer->Print(variables_,
-    "input.Read$capitalized_type_name$Array(tag, field_name, result.$name$_);\n");
+    "input.Read$capitalized_type_name$Array(tag, fieldName, $name$_);\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(
     io::Printer* printer) {
-  printer->Print(variables_, "if ($name$_.Count > 0) {\n");
-  printer->Indent();
+  // TODO(jonskeet): Originally, this checked for Count > 0 first.
+  // The Write* call should make that cheap though - no need to generate it every time.
   if (descriptor_->is_packed()) {
     printer->Print(variables_,
-      "output.WritePacked$capitalized_type_name$Array($number$, field_names[$field_ordinal$], $name$MemoizedSerializedSize, $name$_);\n");
+      "output.WritePacked$capitalized_type_name$Array($number$, fieldNames[$field_ordinal$], $name$_);\n");
   } else {
     printer->Print(variables_,
-      "output.Write$capitalized_type_name$Array($number$, field_names[$field_ordinal$], $name$_);\n");
+      "output.Write$capitalized_type_name$Array($number$, fieldNames[$field_ordinal$], $name$_);\n");
   }
-  printer->Outdent();
-  printer->Print("}\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(
     io::Printer* printer) {
+  // TODO(jonskeet): Get rid of most of this - move it into the runtime.
   printer->Print("{\n");
   printer->Indent();
   printer->Print("int dataSize = 0;\n");
@@ -207,10 +121,6 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(
       "size += $tag_size$ * $name$_.Count;\n",
       "tag_size", SimpleItoa(tagSize), "name", name());
   }
-  // cache the data size for packed fields.
-  if (descriptor_->is_packed()) {
-    printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n");
-  }
   printer->Outdent();
   printer->Print("}\n");
 }
@@ -218,15 +128,14 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(
 void RepeatedPrimitiveFieldGenerator::WriteHash(io::Printer* printer) {
   printer->Print(
     variables_,
-    "foreach($type_name$ i in $name$_)\n"
-    "  hash ^= i.GetHashCode();\n");
+    "foreach($type_name$ i in $name$_)\n {"
+    "  hash ^= i.GetHashCode();\n"
+    "}\n");
 }
 void RepeatedPrimitiveFieldGenerator::WriteEquals(io::Printer* printer) {
   printer->Print(
     variables_,
-    "if($name$_.Count != other.$name$_.Count) return false;\n"
-    "for(int ix=0; ix < $name$_.Count; ix++)\n"
-    "  if(!$name$_[ix].Equals(other.$name$_[ix])) return false;\n");
+    "if(!$name$_.Equals(other.$name$)) return false;\n");
 }
 void RepeatedPrimitiveFieldGenerator::WriteToString(io::Printer* printer) {
   printer->Print(variables_,

+ 0 - 4
src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h

@@ -41,17 +41,13 @@ namespace protobuf {
 namespace compiler {
 namespace csharp {
 
-class Writer;
-
 class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase {
  public:
   RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~RepeatedPrimitiveFieldGenerator();
 
   virtual void GenerateMembers(io::Printer* printer);
-  virtual void GenerateBuilderMembers(io::Printer* printer);
   virtual void GenerateMergingCode(io::Printer* printer);
-  virtual void GenerateBuildingCode(io::Printer* printer);
   virtual void GenerateParsingCode(io::Printer* printer);
   virtual void GenerateSerializationCode(io::Printer* printer);
   virtual void GenerateSerializedSizeCode(io::Printer* printer);

+ 0 - 8
src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc

@@ -47,14 +47,6 @@ namespace csharp {
 
 SourceGeneratorBase::SourceGeneratorBase(const FileDescriptor* descriptor)
     : descriptor_(descriptor) {
-  optimizeSize_ = (descriptor->options().optimize_for()
-      == FileOptions::CODE_SIZE);
-  optimizeSpeed_ = (descriptor->options().optimize_for() == FileOptions::SPEED);
-  useLiteRuntime_ = (descriptor->options().optimize_for()
-      == FileOptions::LITE_RUNTIME);
-
-  optimizeSpeed_ |= useLiteRuntime_;
-  runtimeSuffix_ = useLiteRuntime_ ? "Lite" : "";
 }
 
 SourceGeneratorBase::~SourceGeneratorBase() {

+ 0 - 17
src/google/protobuf/compiler/csharp/csharp_source_generator_base.h

@@ -47,27 +47,10 @@ class SourceGeneratorBase {
 
   std::string class_access_level();
 
-  bool optimize_size() {
-    return optimizeSize_;
-  }
-  bool optimize_speed() {
-    return optimizeSpeed_;
-  }
-  bool use_lite_runtime() {
-    return useLiteRuntime_;
-  }
-  std::string runtime_suffix() {
-    return runtimeSuffix_;
-  }
-
   void WriteGeneratedCodeAttributes(io::Printer* printer);
 
  private:
   const FileDescriptor* descriptor_;
-  bool optimizeSize_;
-  bool optimizeSpeed_;
-  bool useLiteRuntime_;
-  std::string runtimeSuffix_;
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceGeneratorBase);
 };

+ 4 - 84
src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc

@@ -39,7 +39,6 @@
 
 #include <google/protobuf/compiler/csharp/csharp_umbrella_class.h>
 #include <google/protobuf/compiler/csharp/csharp_enum.h>
-#include <google/protobuf/compiler/csharp/csharp_extension.h>
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
 #include <google/protobuf/compiler/csharp/csharp_message.h>
 
@@ -61,18 +60,6 @@ UmbrellaClassGenerator::~UmbrellaClassGenerator() {
 
 void UmbrellaClassGenerator::Generate(io::Printer* printer) {
   WriteIntroduction(printer);
-  WriteExtensionRegistration(printer);
-
-  // write children: Extensions
-  if (file_->extension_count() > 0) {
-    printer->Print("#region Extensions\n");
-    for (int i = 0; i < file_->extension_count(); i++) {
-      ExtensionGenerator extensionGenerator(file_->extension(i));
-      extensionGenerator.Generate(printer);
-    }
-    printer->Print("#endregion\n");
-    printer->Print("\n");
-  }
 
   printer->Print("#region Static variables\n");
   for (int i = 0; i < file_->message_type_count(); i++) {
@@ -80,11 +67,7 @@ void UmbrellaClassGenerator::Generate(io::Printer* printer) {
     messageGenerator.GenerateStaticVariables(printer);
   }
   printer->Print("#endregion\n");
-  if (!use_lite_runtime()) {
-    WriteDescriptor(printer);
-  } else {
-    WriteLiteExtensions(printer);
-  }
+  WriteDescriptor(printer);
   // Close the class declaration.
   printer->Outdent();
   printer->Print("}\n");
@@ -134,9 +117,9 @@ void UmbrellaClassGenerator::WriteIntroduction(io::Printer* printer) {
     "#pragma warning disable 1591, 0612, 3021\n"
     "#region Designer generated code\n"
     "\n"
-    "using pb = global::Google.ProtocolBuffers;\n"
-    "using pbc = global::Google.ProtocolBuffers.Collections;\n"
-    "using pbd = global::Google.ProtocolBuffers.Descriptors;\n"
+    "using pb = global::Google.Protobuf;\n"
+    "using pbc = global::Google.Protobuf.Collections;\n"
+    "using pbd = global::Google.Protobuf.Descriptors;\n"
     "using scg = global::System.Collections.Generic;\n",
     "file_name", file_->name());
 
@@ -165,24 +148,6 @@ void UmbrellaClassGenerator::WriteIntroduction(io::Printer* printer) {
   printer->Indent();
 }
 
-void UmbrellaClassGenerator::WriteExtensionRegistration(io::Printer* printer) {
-  printer->Print(
-    "#region Extension registration\n"
-    "public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {\n");
-  printer->Indent();
-  for (int i = 0; i < file_->extension_count(); i++) {
-    ExtensionGenerator extensionGenerator(file_->extension(i));
-    extensionGenerator.GenerateExtensionRegistrationCode(printer);
-  }
-  for (int i = 0; i < file_->message_type_count(); i++) {
-    MessageGenerator messageGenerator(file_->message_type(i));
-    messageGenerator.GenerateExtensionRegistrationCode(printer);
-  }
-  printer->Outdent();
-  printer->Print("}\n");
-  printer->Print("#endregion\n");
-}
-
 void UmbrellaClassGenerator::WriteDescriptor(io::Printer* printer) {
   printer->Print(
     "#region Descriptor\n"
@@ -219,25 +184,7 @@ void UmbrellaClassGenerator::WriteDescriptor(io::Printer* printer) {
     MessageGenerator messageGenerator(file_->message_type(i));
     messageGenerator.GenerateStaticVariableInitializers(printer);
   }
-  for (int i = 0; i < file_->extension_count(); i++) {
-    ExtensionGenerator extensionGenerator(file_->extension(i));
-    extensionGenerator.GenerateStaticVariableInitializers(printer);
-  }
 
-  if (uses_extensions()) {
-    // Must construct an ExtensionRegistry containing all possible extensions
-    // and return it.
-    printer->Print(
-        "pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();\n");
-    printer->Print("RegisterAllExtensions(registry);\n");
-    for (int i = 0; i < file_->dependency_count(); i++) {
-      printer->Print("$dependency$.RegisterAllExtensions(registry);\n",
-		     "dependency", GetFullUmbrellaClassName(file_->dependency(i)));
-    }
-    printer->Print("return registry;\n");
-  } else {
-    printer->Print("return null;\n");
-  }
   printer->Outdent();
   printer->Print("};\n");
 
@@ -258,33 +205,6 @@ void UmbrellaClassGenerator::WriteDescriptor(io::Printer* printer) {
   printer->Print("#endregion\n\n");
 }
 
-void UmbrellaClassGenerator::WriteLiteExtensions(io::Printer* printer) {
-  printer->Print(
-    "#region Extensions\n"
-    "internal static readonly object Descriptor;\n"
-    "static $umbrella_class_name$() {\n",
-    "umbrella_class_name", umbrellaClassname_);
-  printer->Indent();
-  printer->Print("Descriptor = null;\n");
-  for (int i = 0; i < file_->message_type_count(); i++) {
-    MessageGenerator messageGenerator(file_->message_type(i));
-    messageGenerator.GenerateStaticVariableInitializers(printer);
-  }
-  for (int i = 0; i < file_->extension_count(); i++) {
-    ExtensionGenerator extensionGenerator(file_->extension(i));
-    extensionGenerator.GenerateStaticVariableInitializers(printer);
-  }
-  printer->Outdent();
-  printer->Print("}\n");
-  printer->Print("#endregion\n\n");
-}
-
-bool UmbrellaClassGenerator::uses_extensions() {
-  // TODO(jtattermusch): implement recursive descent that looks for extensions.
-  // For now, we conservatively assume that extensions are used.
-  return true;
-}
-
 }  // namespace csharp
 }  // namespace compiler
 }  // namespace protobuf

+ 0 - 7
src/google/protobuf/compiler/csharp/csharp_umbrella_class.h

@@ -41,8 +41,6 @@ namespace protobuf {
 namespace compiler {
 namespace csharp {
 
-class Writer;
-
 class UmbrellaClassGenerator : public SourceGeneratorBase {
  public:
   UmbrellaClassGenerator(const FileDescriptor* file);
@@ -58,11 +56,7 @@ class UmbrellaClassGenerator : public SourceGeneratorBase {
   std::string umbrellaNamespace_;
 
   void WriteIntroduction(io::Printer* printer);
-  void WriteExtensionRegistration(io::Printer* printer);
   void WriteDescriptor(io::Printer* printer);
-  void WriteLiteExtensions(io::Printer* printer);
-
-  bool uses_extensions();
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UmbrellaClassGenerator);
 };
@@ -73,4 +67,3 @@ class UmbrellaClassGenerator : public SourceGeneratorBase {
 }  // namespace google
 
 #endif  // GOOGLE_PROTOBUF_COMPILER_CSHARP_UMBRELLA_CLASS_H__
-

+ 0 - 136
src/google/protobuf/compiler/csharp/csharp_writer.cc

@@ -1,136 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: kenton@google.com (Kenton Varda)
-//  Based on original Protocol Buffers design by
-//  Sanjay Ghemawat, Jeff Dean, and others.
-
-#include <algorithm>
-#include <google/protobuf/stubs/hash.h>
-#include <limits>
-#include <vector>
-
-#include <google/protobuf/compiler/csharp/csharp_writer.h>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/io/printer.h>
-#include <google/protobuf/wire_format.h>
-#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/stubs/substitute.h>
-
-#include <google/protobuf/compiler/csharp/csharp_field_base.h>
-#include <google/protobuf/compiler/csharp/csharp_enum_field.h>
-#include <google/protobuf/compiler/csharp/csharp_message_field.h>
-#include <google/protobuf/compiler/csharp/csharp_primitive_field.h>
-#include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h>
-#include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h>
-#include <google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h>
-
-namespace google {
-namespace protobuf {
-namespace compiler {
-namespace csharp {
-
-Writer::Writer(google::protobuf::io::Printer* printer)
-    : printer_(printer),
-      newline_("\n") {
-  // TODO(jtattermusch): make newline customizable.
-}
-
-Writer::~Writer() {
-}
-
-void Writer::Indent() {
-  printer_->Indent();
-}
-
-void Writer::Outdent() {
-  printer_->Outdent();
-}
-
-void Writer::Write(const char* text) {
-  printer_->Print(text);
-}
-
-void Writer::Write(const char* text, const string& value0) {
-  printer_->Print(text, "0", value0);
-}
-
-void Writer::Write(const char* text, const string& value0,
-                   const string& value1) {
-  printer_->Print(text, "0", value0, "1", value1);
-}
-
-void Writer::Write(const char* text, const string& value0, const string& value1,
-                   const string& value2) {
-  printer_->Print(text, "0", value0, "1", value1, "2", value2);
-}
-
-void Writer::Write(const char* text, const string& value0, const string& value1,
-                   const string& value2, const string& value3) {
-  printer_->Print(text, "0", value0, "1", value1, "2", value2, "3", value3);
-}
-
-void Writer::WriteLine() {
-  printer_->Print(newline_);
-}
-
-void Writer::WriteLine(const char* text) {
-  Write(text);
-  WriteLine();
-}
-
-void Writer::WriteLine(const char* text, const string& value0) {
-  Write(text, value0);
-  WriteLine();
-}
-
-void Writer::WriteLine(const char* text, const string& value0,
-                       const string& value1) {
-  Write(text, value0, value1);
-  WriteLine();
-}
-
-void Writer::WriteLine(const char* text, const string& value0,
-                       const string& value1, const string& value2) {
-  Write(text, value0, value1, value2);
-  WriteLine();
-}
-
-void Writer::WriteLine(const char* text, const string& value0,
-                       const string& value1, const string& value2,
-                       const string& value3) {
-  Write(text, value0, value1, value2, value3);
-  WriteLine();
-}
-
-}  // namespace java
-}  // namespace compiler
-}  // namespace protobuf
-}  // namespace google

+ 0 - 93
src/google/protobuf/compiler/csharp/csharp_writer.h

@@ -1,93 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Author: kenton@google.com (Kenton Varda)
-//  Based on original Protocol Buffers design by
-//  Sanjay Ghemawat, Jeff Dean, and others.
-
-#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_WRITER_H__
-#define GOOGLE_PROTOBUF_COMPILER_CSHARP_WRITER_H__
-
-#include <string>
-#include <google/protobuf/descriptor.pb.h>
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/compiler/code_generator.h>
-#include <google/protobuf/io/printer.h>
-
-namespace google {
-namespace protobuf {
-namespace compiler {
-namespace csharp {
-
-// Simple wrapper around Printer that supports customizable line endings
-// and number-based variables (e.g. $0$).
-class Writer {
- public:
-  Writer(io::Printer* printer);
-  ~Writer();
-
-  void Indent();
-  void Outdent();
-
-  void Write(const char* text);
-
-  void Write(const char* text, const string& value0);
-
-  void Write(const char* text, const string& value0, const string& value1);
-
-  void Write(const char* text, const string& value0, const string& value1,
-             const string& value2);
-
-  void Write(const char* text, const string& value0, const string& value1,
-             const string& value2, const string& value3);
-
-  void WriteLine();
-
-  void WriteLine(const char* text);
-
-  void WriteLine(const char* text, const string& value0);
-
-  void WriteLine(const char* text, const string& value0, const string& value1);
-
-  void WriteLine(const char* text, const string& value0, const string& value1,
-                 const string& value2);
-
-  void WriteLine(const char* text, const string& value0, const string& value1,
-                 const string& value2, const string& value3);
- private:
-  io::Printer* printer_;
-  const char* newline_;
-};
-
-}  // namespace csharp
-}  // namespace compiler
-}  // namespace protobuf
-}  // namespace google
-#endif  // GOOGLE_PROTOBUF_COMPILER_CSHARP_WRITER_H__

+ 0 - 4
vsprojects/libprotoc.vcproj

@@ -169,7 +169,6 @@
       <File RelativePath="..\src\google\protobuf\compiler\cpp\cpp_string_field.h"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_enum.h"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_enum_field.h"></File>
-      <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_extension.h"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_field_base.h"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_generator.h"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_helpers.h"></File>
@@ -181,7 +180,6 @@
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_repeated_primitive_field.h"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_source_generator_base.h"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_umbrella_class.h"></File>
-      <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_writer.h"></File>
       <File RelativePath="..\src\google\protobuf\compiler\java\java_context.h"></File>
       <File RelativePath="..\src\google\protobuf\compiler\java\java_enum.h"></File>
       <File RelativePath="..\src\google\protobuf\compiler\java\java_enum_field.h"></File>
@@ -269,7 +267,6 @@
       <File RelativePath="..\src\google\protobuf\compiler\cpp\cpp_string_field.cc"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_enum.cc"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_enum_field.cc"></File>
-      <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_extension.cc"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_field_base.cc"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_generator.cc"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_helpers.cc"></File>
@@ -281,7 +278,6 @@
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_repeated_primitive_field.cc"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_source_generator_base.cc"></File>
       <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_umbrella_class.cc"></File>
-      <File RelativePath="..\src\google\protobuf\compiler\csharp\csharp_writer.cc"></File>
       <File RelativePath="..\src\google\protobuf\compiler\java\java_context.cc"></File>
       <File RelativePath="..\src\google\protobuf\compiler\java\java_doc_comment.cc"></File>
       <File RelativePath="..\src\google\protobuf\compiler\java\java_enum.cc"></File>