Эх сурвалжийг харах

Migrate writer to io::Printer for C#

Jie Luo 10 жил өмнө
parent
commit
90da3514cd
28 өөрчлөгдсөн 1803 нэмэгдсэн , 1595 устгасан
  1. 7 7
      csharp/src/ProtocolBuffers.Test/TestProtos/Unittest.cs
  2. 7 7
      csharp/src/ProtocolBuffersLite.Test/TestProtos/Unittest.cs
  3. 1 1
      csharp/src/ProtocolBuffersLite.Test/TestProtos/UnittestLite.cs
  4. 12 13
      src/google/protobuf/compiler/csharp/csharp_enum.cc
  5. 1 3
      src/google/protobuf/compiler/csharp/csharp_enum.h
  6. 52 55
      src/google/protobuf/compiler/csharp/csharp_enum_field.cc
  7. 6 8
      src/google/protobuf/compiler/csharp/csharp_enum_field.h
  8. 78 60
      src/google/protobuf/compiler/csharp/csharp_extension.cc
  9. 13 15
      src/google/protobuf/compiler/csharp/csharp_extension.h
  10. 45 9
      src/google/protobuf/compiler/csharp/csharp_field_base.cc
  11. 18 15
      src/google/protobuf/compiler/csharp/csharp_field_base.h
  12. 3 5
      src/google/protobuf/compiler/csharp/csharp_generator.cc
  13. 516 493
      src/google/protobuf/compiler/csharp/csharp_message.cc
  14. 13 13
      src/google/protobuf/compiler/csharp/csharp_message.h
  15. 232 187
      src/google/protobuf/compiler/csharp/csharp_message_field.cc
  16. 16 19
      src/google/protobuf/compiler/csharp/csharp_message_field.h
  17. 171 142
      src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
  18. 16 19
      src/google/protobuf/compiler/csharp/csharp_primitive_field.h
  19. 151 127
      src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
  20. 10 10
      src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h
  21. 143 117
      src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc
  22. 10 10
      src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h
  23. 138 118
      src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
  24. 10 10
      src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
  25. 1 2
      src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc
  26. 1 3
      src/google/protobuf/compiler/csharp/csharp_source_generator_base.h
  27. 127 122
      src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc
  28. 5 5
      src/google/protobuf/compiler/csharp/csharp_umbrella_class.h

+ 7 - 7
csharp/src/ProtocolBuffers.Test/TestProtos/Unittest.cs

@@ -6432,7 +6432,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasOneofNestedMessage {
-       get { return result.oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage; }
+        get { return result.oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage OneofNestedMessage {
         get { return result.oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage ? (global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage) result.oneofField_ : global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance; }
@@ -22008,7 +22008,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasFooMessage {
-       get { return result.fooCase_ == FooOneofCase.FooMessage; }
+        get { return result.fooCase_ == FooOneofCase.FooMessage; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestAllTypes FooMessage {
         get { return result.fooCase_ == FooOneofCase.FooMessage ? (global::Google.ProtocolBuffers.TestProtos.TestAllTypes) result.foo_ : global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
@@ -22050,7 +22050,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasFooGroup {
-       get { return result.fooCase_ == FooOneofCase.FooGroup; }
+        get { return result.fooCase_ == FooOneofCase.FooGroup; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup FooGroup {
         get { return result.fooCase_ == FooOneofCase.FooGroup ? (global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup) result.foo_ : global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup.DefaultInstance; }
@@ -24405,7 +24405,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasFooMessage {
-       get { return result.fooCase_ == FooOneofCase.FooMessage; }
+        get { return result.fooCase_ == FooOneofCase.FooMessage; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage FooMessage {
         get { return result.fooCase_ == FooOneofCase.FooMessage ? (global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage) result.foo_ : global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.DefaultInstance; }
@@ -24447,7 +24447,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasFooGroup {
-       get { return result.fooCase_ == FooOneofCase.FooGroup; }
+        get { return result.fooCase_ == FooOneofCase.FooGroup; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup FooGroup {
         get { return result.fooCase_ == FooOneofCase.FooGroup ? (global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup) result.foo_ : global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup.DefaultInstance; }
@@ -24489,7 +24489,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasFooLazyMessage {
-       get { return result.fooCase_ == FooOneofCase.FooLazyMessage; }
+        get { return result.fooCase_ == FooOneofCase.FooLazyMessage; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage FooLazyMessage {
         get { return result.fooCase_ == FooOneofCase.FooLazyMessage ? (global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage) result.foo_ : global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.DefaultInstance; }
@@ -25377,7 +25377,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasFooMessage {
-       get { return result.fooCase_ == FooOneofCase.FooMessage; }
+        get { return result.fooCase_ == FooOneofCase.FooMessage; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage FooMessage {
         get { return result.fooCase_ == FooOneofCase.FooMessage ? (global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage) result.foo_ : global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage.DefaultInstance; }

+ 7 - 7
csharp/src/ProtocolBuffersLite.Test/TestProtos/Unittest.cs

@@ -6432,7 +6432,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasOneofNestedMessage {
-       get { return result.oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage; }
+        get { return result.oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage OneofNestedMessage {
         get { return result.oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage ? (global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage) result.oneofField_ : global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance; }
@@ -22008,7 +22008,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasFooMessage {
-       get { return result.fooCase_ == FooOneofCase.FooMessage; }
+        get { return result.fooCase_ == FooOneofCase.FooMessage; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestAllTypes FooMessage {
         get { return result.fooCase_ == FooOneofCase.FooMessage ? (global::Google.ProtocolBuffers.TestProtos.TestAllTypes) result.foo_ : global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
@@ -22050,7 +22050,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasFooGroup {
-       get { return result.fooCase_ == FooOneofCase.FooGroup; }
+        get { return result.fooCase_ == FooOneofCase.FooGroup; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup FooGroup {
         get { return result.fooCase_ == FooOneofCase.FooGroup ? (global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup) result.foo_ : global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup.DefaultInstance; }
@@ -24405,7 +24405,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasFooMessage {
-       get { return result.fooCase_ == FooOneofCase.FooMessage; }
+        get { return result.fooCase_ == FooOneofCase.FooMessage; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage FooMessage {
         get { return result.fooCase_ == FooOneofCase.FooMessage ? (global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage) result.foo_ : global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.DefaultInstance; }
@@ -24447,7 +24447,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasFooGroup {
-       get { return result.fooCase_ == FooOneofCase.FooGroup; }
+        get { return result.fooCase_ == FooOneofCase.FooGroup; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup FooGroup {
         get { return result.fooCase_ == FooOneofCase.FooGroup ? (global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup) result.foo_ : global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup.DefaultInstance; }
@@ -24489,7 +24489,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasFooLazyMessage {
-       get { return result.fooCase_ == FooOneofCase.FooLazyMessage; }
+        get { return result.fooCase_ == FooOneofCase.FooLazyMessage; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage FooLazyMessage {
         get { return result.fooCase_ == FooOneofCase.FooLazyMessage ? (global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage) result.foo_ : global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.DefaultInstance; }
@@ -25377,7 +25377,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasFooMessage {
-       get { return result.fooCase_ == FooOneofCase.FooMessage; }
+        get { return result.fooCase_ == FooOneofCase.FooMessage; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage FooMessage {
         get { return result.fooCase_ == FooOneofCase.FooMessage ? (global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage) result.foo_ : global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage.DefaultInstance; }

+ 1 - 1
csharp/src/ProtocolBuffersLite.Test/TestProtos/UnittestLite.cs

@@ -6440,7 +6440,7 @@ namespace Google.ProtocolBuffers.TestProtos {
       }
 
       public bool HasOneofNestedMessage {
-       get { return result.oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage; }
+        get { return result.oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage; }
       }
       public global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.NestedMessage OneofNestedMessage {
         get { return result.oneofFieldCase_ == OneofFieldOneofCase.OneofNestedMessage ? (global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.NestedMessage) result.oneofField_ : global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.NestedMessage.DefaultInstance; }

+ 12 - 13
src/google/protobuf/compiler/csharp/csharp_enum.cc

@@ -40,7 +40,6 @@
 
 #include <google/protobuf/compiler/csharp/csharp_enum.h>
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
-#include <google/protobuf/compiler/csharp/csharp_writer.h>
 
 using google::protobuf::internal::scoped_ptr;
 
@@ -57,20 +56,20 @@ EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) :
 EnumGenerator::~EnumGenerator() {
 }
 
-void EnumGenerator::Generate(Writer* writer) {
-  WriteGeneratedCodeAttributes(writer);
-  writer->WriteLine("$0$ enum $1$ {",
-                    class_access_level(),
-                    descriptor_->name());
-  writer->Indent();
+void EnumGenerator::Generate(io::Printer* printer) {
+  WriteGeneratedCodeAttributes(printer);
+  printer->Print("$access_level$ enum $name$ {\n",
+                 "access_level", class_access_level(),
+                 "name", descriptor_->name());
+  printer->Indent();
   for (int i = 0; i < descriptor_->value_count(); i++) {
-      writer->WriteLine("$0$ = $1$,",
-                       descriptor_->value(i)->name(),
-                       SimpleItoa(descriptor_->value(i)->number()));
+    printer->Print("$name$ = $number$,\n",
+                   "name", descriptor_->value(i)->name(),
+                   "number", SimpleItoa(descriptor_->value(i)->number()));
   }
-  writer->Outdent();
-  writer->WriteLine("}");
-  writer->WriteLine();
+  printer->Outdent();
+  printer->Print("}\n");
+  printer->Print("\n");
 }
 
 }  // namespace csharp

+ 1 - 3
src/google/protobuf/compiler/csharp/csharp_enum.h

@@ -41,14 +41,12 @@ namespace protobuf {
 namespace compiler {
 namespace csharp {
 
-class Writer;
-
 class EnumGenerator : public SourceGeneratorBase {
  public:
   EnumGenerator(const EnumDescriptor* descriptor);
   ~EnumGenerator();
 
-  void Generate(Writer* writer);
+  void Generate(io::Printer* printer);
 
  private:
   const EnumDescriptor* descriptor_;

+ 52 - 55
src/google/protobuf/compiler/csharp/csharp_enum_field.cc

@@ -39,7 +39,6 @@
 
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
 #include <google/protobuf/compiler/csharp/csharp_enum_field.h>
-#include <google/protobuf/compiler/csharp/csharp_writer.h>
 
 namespace google {
 namespace protobuf {
@@ -54,39 +53,38 @@ EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor,
 EnumFieldGenerator::~EnumFieldGenerator() {
 }
 
-void EnumFieldGenerator::GenerateParsingCode(Writer* writer) {
-  writer->WriteLine("object unknown;");
-  writer->WriteLine("if(input.ReadEnum(ref result.$0$_, out unknown)) {", name());
+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())) {
-    writer->WriteLine("  result.has$0$ = true;", property_name());
+    printer->Print(variables_,
+                   "  result.has$property_name$ = true;\n");
   }
-  writer->WriteLine("} else if(unknown is int) {");
+  printer->Print("} else if(unknown is int) {\n");
   if (!use_lite_runtime()) {
-    writer->WriteLine("  if (unknownFields == null) {");  // First unknown field - create builder now
-    writer->WriteLine(
-        "    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
-    writer->WriteLine("  }");
-    writer->WriteLine(
-        "  unknownFields.MergeVarintField($0$, (ulong)(int)unknown);",
-        number());
+    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");
   }
-  writer->WriteLine("}");
+  printer->Print("}\n");
 }
 
-void EnumFieldGenerator::GenerateSerializationCode(Writer* writer) {
-  writer->WriteLine("if ($0$) {", has_property_check);
-  writer->WriteLine(
-      "  output.WriteEnum($0$, field_names[$2$], (int) $1$, $1$);", number(),
-      property_name(), field_ordinal());
-  writer->WriteLine("}");
+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");
 }
 
-void EnumFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
-  writer->WriteLine("if ($0$) {", has_property_check);
-  writer->WriteLine(
-      "  size += pb::CodedOutputStream.ComputeEnumSize($0$, (int) $1$);",
-      number(), property_name());
-  writer->WriteLine("}");
+void EnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+  printer->Print(
+      variables_,
+      "if ($has_property_check$) {\n"
+      "  size += pb::CodedOutputStream.ComputeEnumSize($number$, (int) $property_name$);\n"
+      "}\n");
 }
 
 EnumOneofFieldGenerator::EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
@@ -97,41 +95,40 @@ EnumOneofFieldGenerator::EnumOneofFieldGenerator(const FieldDescriptor* descript
 EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {
 }
 
-void EnumOneofFieldGenerator::GenerateParsingCode(Writer* writer) {
-  writer->WriteLine("object unknown;");
-  writer->WriteLine("$0$ enumValue = $1$;", type_name(), default_value());
-  writer->WriteLine("if(input.ReadEnum(ref enumValue, out unknown)) {",
-                    name());
-  writer->WriteLine("  result.$0$_ = enumValue;", oneof_name());
-  writer->WriteLine("  result.$0$Case_ = $1$OneofCase.$2$;",
-		    oneof_name(), oneof_property_name(), property_name());
-  writer->WriteLine("} else if(unknown is int) {");
+void EnumOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "object unknown;\n"
+    "$type_name$ enumValue = $default_value$;\n"
+    "if(input.ReadEnum(ref enumValue, out unknown)) {\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()) {
-    writer->WriteLine("  if (unknownFields == null) {");  // First unknown field - create builder now
-    writer->WriteLine(
-        "    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
-    writer->WriteLine("  }");
-    writer->WriteLine(
-        "  unknownFields.MergeVarintField($0$, (ulong)(int)unknown);",
-        number());
+    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");
   }
-  writer->WriteLine("}");
+  printer->Print("}\n");
 }
 
-void EnumOneofFieldGenerator::GenerateSerializationCode(Writer* writer) {
-  writer->WriteLine("if ($0$) {", has_property_check);
-  writer->WriteLine(
-      "  output.WriteEnum($0$, field_names[$2$], (int) $1$, $1$);", number(),
-      property_name(), field_ordinal());
-  writer->WriteLine("}");
+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"
+    "}\n");
 }
 
-void EnumOneofFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
-  writer->WriteLine("if ($0$) {", has_property_check);
-  writer->WriteLine(
-      "  size += pb::CodedOutputStream.ComputeEnumSize($0$, (int) $1$);",
-      number(), property_name());
-  writer->WriteLine("}");
+void EnumOneofFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "if ($has_property_check$) {\n"
+    "  size += pb::CodedOutputStream.ComputeEnumSize($number$, (int) $property_name$);\n"
+    "}\n");
 }
 
 }  // namespace csharp

+ 6 - 8
src/google/protobuf/compiler/csharp/csharp_enum_field.h

@@ -41,16 +41,14 @@ namespace protobuf {
 namespace compiler {
 namespace csharp {
 
-class Writer;
-
 class EnumFieldGenerator : public PrimitiveFieldGenerator {
  public:
   EnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~EnumFieldGenerator();
 
-  virtual void GenerateParsingCode(Writer* writer);
-  virtual void GenerateSerializationCode(Writer* writer);
-  virtual void GenerateSerializedSizeCode(Writer* writer);
+  virtual void GenerateParsingCode(io::Printer* printer);
+  virtual void GenerateSerializationCode(io::Printer* printer);
+  virtual void GenerateSerializedSizeCode(io::Printer* printer);
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
@@ -61,9 +59,9 @@ class EnumOneofFieldGenerator : public PrimitiveOneofFieldGenerator {
   EnumOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~EnumOneofFieldGenerator();
 
-  virtual void GenerateParsingCode(Writer* writer);
-  virtual void GenerateSerializationCode(Writer* writer);
-  virtual void GenerateSerializedSizeCode(Writer* writer);
+  virtual void GenerateParsingCode(io::Printer* printer);
+  virtual void GenerateSerializationCode(io::Printer* printer);
+  virtual void GenerateSerializedSizeCode(io::Printer* printer);
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumOneofFieldGenerator);

+ 78 - 60
src/google/protobuf/compiler/csharp/csharp_extension.cc

@@ -39,7 +39,6 @@
 
 #include <google/protobuf/compiler/csharp/csharp_extension.h>
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
-#include <google/protobuf/compiler/csharp/csharp_writer.h>
 #include <google/protobuf/compiler/csharp/csharp_field_base.h>
 
 using google::protobuf::internal::scoped_ptr;
@@ -52,20 +51,34 @@ namespace csharp {
 ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor)
     : FieldGeneratorBase(descriptor, 0) {
   if (descriptor_->extension_scope()) {
-    scope_ = GetClassName(descriptor_->extension_scope());
+    variables_["scope"] = GetClassName(descriptor_->extension_scope());
   } else {
-    scope_ = GetFullUmbrellaClassName(descriptor_->file());
+    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";
   }
-  extends_ = GetClassName(descriptor_->containing_type());
 }
 
 ExtensionGenerator::~ExtensionGenerator() {
 }
 
-void ExtensionGenerator::Generate(Writer* writer) {
-  writer->WriteLine("public const int $0$ = $1$;",
-                    GetFieldConstantName(descriptor_),
-                    SimpleItoa(descriptor_->number()));
+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
@@ -75,36 +88,34 @@ void ExtensionGenerator::Generate(Writer* writer) {
     //        "option message_set_wire_format = true; is not supported in Lite runtime extensions.");
     //}
 
-    writer->Write("$0$ ", class_access_level());
-    writer->WriteLine(
-        "static pb::$3$<$0$, $1$> $2$;",
-        extends_,
-        type_name(),
-        property_name(),
-        descriptor_->is_repeated() ?
-            "GeneratedRepeatExtensionLite" : "GeneratedExtensionLite");
+    printer->Print(
+      variables_,
+      "$access_level$ static pb::$generated_extension$<$extends$, $type_name$> $property_name$;\n");
   } else if (descriptor_->is_repeated()) {
-    writer->WriteLine(
-        "$0$ static pb::GeneratedExtensionBase<scg::IList<$1$>> $2$;",
-        class_access_level(), type_name(), property_name());
+    printer->Print(
+      variables_,
+      "$access_level$ static pb::GeneratedExtensionBase<scg::IList<$type_name$>> $property_name$;\n");
   } else {
-    writer->WriteLine("$0$ static pb::GeneratedExtensionBase<$1$> $2$;",
-                      class_access_level(), type_name(), property_name());
+    printer->Print(
+      variables_,
+      "$access_level$ static pb::GeneratedExtensionBase<$type_name$> $property_name$;\n");
   }
 }
 
-void ExtensionGenerator::GenerateStaticVariableInitializers(Writer* writer) {
+void ExtensionGenerator::GenerateStaticVariableInitializers(io::Printer* printer) {
   if (use_lite_runtime()) {
-    writer->WriteLine("$0$.$1$ = ", scope_, property_name());
-    writer->Indent();
-    writer->WriteLine(
-        "new pb::$0$<$1$, $2$>(",
-        descriptor_->is_repeated() ?
-            "GeneratedRepeatExtensionLite" : "GeneratedExtensionLite",
-        extends_, type_name());
-    writer->Indent();
-    writer->WriteLine("\"$0$\",", descriptor_->full_name());
-    writer->WriteLine("$0$.DefaultInstance,", extends_);
+    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()) {
@@ -112,52 +123,59 @@ void ExtensionGenerator::GenerateStaticVariableInitializers(Writer* writer) {
       } else {
         default_val = is_nullable_type() ? "null" : ("default(" + type_name() + ")");
       }
-      writer->WriteLine("$0$,", default_val);
+      printer->Print("$default_val$,\n", "default_val", default_val);
     }
-    writer->WriteLine(
-        "$0$,",
-        (GetCSharpType(descriptor_->type()) == CSHARPTYPE_MESSAGE) ?
-            type_name() + ".DefaultInstance" : "null");
-    writer->WriteLine(
-        "$0$,",
-        (GetCSharpType(descriptor_->type()) == CSHARPTYPE_ENUM) ?
-            "new EnumLiteMap<" + type_name() + ">()" : "null");
-    writer->WriteLine("$0$.$1$FieldNumber,", scope_,
-                      GetPropertyName(descriptor_));
-    writer->Write("pbd::FieldType.$0$", capitalized_type_name());
+    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()) {
-      writer->WriteLine(",");
-      writer->Write(descriptor_->is_packed() ? "true" : "false");
+      printer->Print(
+        ",\n"
+        "$is_packed$",
+        "is_packed", descriptor_->is_packed() ? "true" : "false");
     }
-    writer->Outdent();
-    writer->WriteLine(");");
-    writer->Outdent();
+    printer->Outdent();
+    printer->Print(");\n");
+    printer->Outdent();
   }
   else if (descriptor_->is_repeated())
   {
-     writer->WriteLine(
-         "$0$.$1$ = pb::GeneratedRepeatExtension<$2$>.CreateInstance($0$.Descriptor.Extensions[$3$]);",
-         scope_, property_name(), type_name(), SimpleItoa(descriptor_->index()));
+    printer->Print(
+      variables_,
+      "$scope$.$property_name$ = pb::GeneratedRepeatExtension<$type_name$>.CreateInstance($scope$.Descriptor.Extensions[$index$]);\n");
   }
   else
   {
-     writer->WriteLine(
-         "$0$.$1$ = pb::GeneratedSingleExtension<$2$>.CreateInstance($0$.Descriptor.Extensions[$3$]);",
-         scope_, property_name(), type_name(), SimpleItoa(descriptor_->index()));
+    printer->Print(
+      variables_,
+      "$scope$.$property_name$ = pb::GeneratedSingleExtension<$type_name$>.CreateInstance($scope$.Descriptor.Extensions[$index$]);\n");
   }
 }
 
-void ExtensionGenerator::GenerateExtensionRegistrationCode(Writer* writer) {
-  writer->WriteLine("registry.Add($0$.$1$);", scope_, property_name());
+void ExtensionGenerator::GenerateExtensionRegistrationCode(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "registry.Add($scope$.$property_name$);\n");
 }
 
-void ExtensionGenerator::WriteHash(Writer* writer) {
+void ExtensionGenerator::WriteHash(io::Printer* printer) {
 }
 
-void ExtensionGenerator::WriteEquals(Writer* writer) {
+void ExtensionGenerator::WriteEquals(io::Printer* printer) {
 }
 
-void ExtensionGenerator::WriteToString(Writer* writer) {
+void ExtensionGenerator::WriteToString(io::Printer* printer) {
 }
 
 }  // namespace csharp

+ 13 - 15
src/google/protobuf/compiler/csharp/csharp_extension.h

@@ -41,28 +41,26 @@ namespace protobuf {
 namespace compiler {
 namespace csharp {
 
-class Writer;
-
 class ExtensionGenerator : public FieldGeneratorBase {
  public:
   ExtensionGenerator(const FieldDescriptor* descriptor);
   ~ExtensionGenerator();
 
-  void GenerateStaticVariableInitializers(Writer* writer);
-  void GenerateExtensionRegistrationCode(Writer* writer);
-  void Generate(Writer* writer);
+  void GenerateStaticVariableInitializers(io::Printer* printer);
+  void GenerateExtensionRegistrationCode(io::Printer* printer);
+  void Generate(io::Printer* printer);
 
-  virtual void WriteHash(Writer* writer);
-  virtual void WriteEquals(Writer* writer);
-  virtual void WriteToString(Writer* writer);
+  virtual void WriteHash(io::Printer* printer);
+  virtual void WriteEquals(io::Printer* printer);
+  virtual void WriteToString(io::Printer* printer);
 
-  virtual void GenerateMembers(Writer* writer) {};
-  virtual void GenerateBuilderMembers(Writer* writer) {};
-  virtual void GenerateMergingCode(Writer* writer) {};
-  virtual void GenerateBuildingCode(Writer* writer) {};
-  virtual void GenerateParsingCode(Writer* writer) {};
-  virtual void GenerateSerializationCode(Writer* writer) {};
-  virtual void GenerateSerializedSizeCode(Writer* writer) {};
+  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_;

+ 45 - 9
src/google/protobuf/compiler/csharp/csharp_field_base.cc

@@ -41,7 +41,6 @@
 
 #include <google/protobuf/compiler/csharp/csharp_field_base.h>
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
-#include <google/protobuf/compiler/csharp/csharp_writer.h>
 
 using google::protobuf::internal::scoped_ptr;
 
@@ -50,35 +49,72 @@ namespace protobuf {
 namespace compiler {
 namespace csharp {
 
+void FieldGeneratorBase::SetCommonFieldVariables(
+    map<string, string>* variables) {
+  (*variables)["property_name"] = property_name();
+  (*variables)["type_name"] = type_name();
+  (*variables)["name"] = name();
+  (*variables)["descriptor_name"] = descriptor_->name();
+  (*variables)["default_value"] = default_value();
+  if (has_default_value()) {
+    (*variables)["name_def_message"] =
+      (*variables)["name"] + "_ = " + (*variables)["default_value"];
+  } else {
+    (*variables)["name_def_message"] = (*variables)["name"] + "_";
+  }
+  (*variables)["capitalized_type_name"] = capitalized_type_name();
+  (*variables)["number"] = number();
+  (*variables)["field_ordinal"] = field_ordinal();
+  if (SupportFieldPresence(descriptor_->file())) {
+    (*variables)["has_property_check"] = "has" + (*variables)["property_name"];
+    (*variables)["other_has_property_check"] = "other.Has" + (*variables)["property_name"];
+  } else {
+    (*variables)["has_property_check"] =
+      (*variables)["property_name"] + " != " + (*variables)["default_value"];
+    (*variables)["other_has_property_check"] = "other." +
+      (*variables)["property_name"] + " != " + (*variables)["default_value"];
+  }
+}
+
+void FieldGeneratorBase::SetCommonOneofFieldVariables(
+    map<string, string>* variables) {
+  (*variables)["oneof_name"] = oneof_name();
+  (*variables)["has_property_check"] = oneof_name() + "Case_ == " + oneof_property_name() +
+    "OneofCase." + property_name();
+  (*variables)["oneof_property_name"] = oneof_property_name();
+}
+
 FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* descriptor,
                                        int fieldOrdinal)
     : SourceGeneratorBase(descriptor->file()),
       descriptor_(descriptor),
       fieldOrdinal_(fieldOrdinal) {
+  SetCommonFieldVariables(&variables_);
 }
 
 FieldGeneratorBase::~FieldGeneratorBase() {
 }
 
-void FieldGeneratorBase::AddDeprecatedFlag(Writer* writer) {
+void FieldGeneratorBase::AddDeprecatedFlag(io::Printer* printer) {
   if (descriptor_->options().deprecated())
   {
-    writer->WriteLine("[global::System.ObsoleteAttribute()]");
+    printer->Print("[global::System.ObsoleteAttribute()]\n");
   }
 }
 
-void FieldGeneratorBase::AddNullCheck(Writer* writer) {
-  AddNullCheck(writer, "value");
+void FieldGeneratorBase::AddNullCheck(io::Printer* printer) {
+  AddNullCheck(printer, "value");
 }
 
-void FieldGeneratorBase::AddNullCheck(Writer* writer, const std::string& name) {
+void FieldGeneratorBase::AddNullCheck(io::Printer* printer, const std::string& name) {
   if (is_nullable_type()) {
-    writer->WriteLine("  pb::ThrowHelper.ThrowIfNull($0$, \"$0$\");", name);
+    printer->Print("  pb::ThrowHelper.ThrowIfNull($name$, \"$name$\");\n",
+                   "name", name);
   }
 }
 
-void FieldGeneratorBase::AddPublicMemberAttributes(Writer* writer) {
-  AddDeprecatedFlag(writer);
+void FieldGeneratorBase::AddPublicMemberAttributes(io::Printer* printer) {
+  AddDeprecatedFlag(printer);
 }
 
 std::string FieldGeneratorBase::oneof_property_name() {

+ 18 - 15
src/google/protobuf/compiler/csharp/csharp_field_base.h

@@ -49,27 +49,29 @@ class FieldGeneratorBase : public SourceGeneratorBase {
   FieldGeneratorBase(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~FieldGeneratorBase();
 
-  virtual void GenerateMembers(Writer* writer) = 0;
-  virtual void GenerateBuilderMembers(Writer* writer) = 0;
-  virtual void GenerateMergingCode(Writer* writer) = 0;
-  virtual void GenerateBuildingCode(Writer* writer) = 0;
-  virtual void GenerateParsingCode(Writer* writer) = 0;
-  virtual void GenerateSerializationCode(Writer* writer) = 0;
-  virtual void GenerateSerializedSizeCode(Writer* writer) = 0;
-
-  virtual void WriteHash(Writer* writer) = 0;
-  virtual void WriteEquals(Writer* writer) = 0;
-  virtual void WriteToString(Writer* writer) = 0;
+  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;
+
+  virtual void WriteHash(io::Printer* printer) = 0;
+  virtual void WriteEquals(io::Printer* printer) = 0;
+  virtual void WriteToString(io::Printer* printer) = 0;
 
  protected:
   const FieldDescriptor* descriptor_;
   const int fieldOrdinal_;
+  map<string, string> variables_;
 
-  void AddDeprecatedFlag(Writer* writer);
-  void AddNullCheck(Writer* writer);
-  void AddNullCheck(Writer* writer, const std::string& name);
+  void AddDeprecatedFlag(io::Printer* printer);
+  void AddNullCheck(io::Printer* printer);
+  void AddNullCheck(io::Printer* printer, const std::string& name);
 
-  void AddPublicMemberAttributes(Writer* writer);
+  void AddPublicMemberAttributes(io::Printer* printer);
+  void SetCommonOneofFieldVariables(map<string, string>* variables);
 
   std::string oneof_property_name();
   std::string oneof_name();
@@ -85,6 +87,7 @@ class FieldGeneratorBase : public SourceGeneratorBase {
   std::string field_ordinal();
 
  private:
+  void SetCommonFieldVariables(map<string, string>* variables);
   std::string GetStringDefaultValueInternal();
   std::string GetBytesDefaultValueInternal();
 

+ 3 - 5
src/google/protobuf/compiler/csharp/csharp_generator.cc

@@ -40,7 +40,6 @@
 #include <google/protobuf/compiler/csharp/csharp_generator.h>
 #include <google/protobuf/compiler/csharp/csharp_umbrella_class.h>
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
-#include <google/protobuf/compiler/csharp/csharp_writer.h>
 
 using google::protobuf::internal::scoped_ptr;
 
@@ -55,9 +54,9 @@ std::string GetOutputFile(const google::protobuf::FileDescriptor* file, const st
 }
 
 void GenerateFile(const google::protobuf::FileDescriptor* file,
-                  Writer* writer) {
+                  io::Printer* printer) {
   UmbrellaClassGenerator umbrellaGenerator(file);
-  umbrellaGenerator.Generate(writer);
+  umbrellaGenerator.Generate(printer);
 }
 
 bool Generator::Generate(
@@ -83,9 +82,8 @@ bool Generator::Generate(
   scoped_ptr<io::ZeroCopyOutputStream> output(
       generator_context->Open(filename));
   io::Printer printer(output.get(), '$');
-  Writer writer(&printer);
 
-  GenerateFile(file, &writer);
+  GenerateFile(file, &printer);
 
   return true;
 }

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 516 - 493
src/google/protobuf/compiler/csharp/csharp_message.cc


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

@@ -51,27 +51,27 @@ class MessageGenerator : public SourceGeneratorBase {
   MessageGenerator(const Descriptor* descriptor);
   ~MessageGenerator();
 
-  void GenerateStaticVariables(Writer* printer);
-  void GenerateStaticVariableInitializers(Writer* printer);
-  void GenerateExtensionRegistrationCode(Writer* printer);
-  void Generate(Writer* printer);
+  void GenerateStaticVariables(io::Printer* printer);
+  void GenerateStaticVariableInitializers(io::Printer* printer);
+  void GenerateExtensionRegistrationCode(io::Printer* printer);
+  void Generate(io::Printer* printer);
 
  private:
   const Descriptor* descriptor_;
   std::vector<std::string> field_names_;
   std::vector<const FieldDescriptor*> fields_by_number_;
 
-  void GenerateLiteRuntimeMethods(Writer* writer);
-  void GenerateMessageSerializationMethods(Writer* writer);
-  void GenerateSerializeOneField(Writer* writer,
+  void GenerateLiteRuntimeMethods(io::Printer* printer);
+  void GenerateMessageSerializationMethods(io::Printer* printer);
+  void GenerateSerializeOneField(io::Printer* printer,
                                  const FieldDescriptor* fieldDescriptor);
   void GenerateSerializeOneExtensionRange(
-      Writer* writer, const Descriptor::ExtensionRange* extendsionRange);
-  void GenerateParseFromMethods(Writer* writer);
-  void GenerateBuilder(Writer* writer);
-  void GenerateCommonBuilderMethods(Writer* writer);
-  void GenerateBuilderParsingMethods(Writer* writer);
-  void GenerateIsInitialized(Writer* writer);
+      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);
 
   int GetFieldOrdinal(const FieldDescriptor* descriptor);
   FieldGeneratorBase* CreateFieldGeneratorInternal(

+ 232 - 187
src/google/protobuf/compiler/csharp/csharp_message_field.cc

@@ -40,7 +40,6 @@
 
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
 #include <google/protobuf/compiler/csharp/csharp_message_field.h>
-#include <google/protobuf/compiler/csharp/csharp_writer.h>
 
 namespace google {
 namespace protobuf {
@@ -50,245 +49,291 @@ namespace csharp {
 MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
                                              int fieldOrdinal)
     : FieldGeneratorBase(descriptor, fieldOrdinal) {
-  has_property_check = "has" + property_name();
+  variables_["has_property_check"] = "has" + property_name();
+  variables_["message_or_group"] = message_or_group();
 }
 
 MessageFieldGenerator::~MessageFieldGenerator() {
 
 }
 
-void MessageFieldGenerator::GenerateMembers(Writer* writer) {
-  writer->WriteLine("private bool has$0$;", property_name());
-  writer->WriteLine("private $0$ $1$_;", type_name(), name());
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public bool Has$0$ {", property_name());
-  writer->WriteLine("  get { return has$0$; }", property_name());
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
-  writer->WriteLine("  get { return $0$_ ?? $1$; }", name(), default_value());
-  writer->WriteLine("}");
+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(Writer* writer) {
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public bool Has$0$ {", property_name());
-  writer->WriteLine(" get { return result.has$0$; }", property_name());
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
-  writer->WriteLine("  get { return result.$0$; }", property_name());
-  writer->WriteLine("  set { Set$0$(value); }", property_name());
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Set$0$($1$ value) {", property_name(),
-                    type_name());
-  AddNullCheck(writer);
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.has$0$ = true;", property_name());
-  writer->WriteLine("  result.$0$_ = value;", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Set$0$($1$.Builder builderForValue) {",
-                    property_name(), type_name());
-  AddNullCheck(writer, "builderForValue");
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.has$0$ = true;", property_name());
-  writer->WriteLine("  result.$0$_ = builderForValue.Build();", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Merge$0$($1$ value) {", property_name(),
-                    type_name());
-  AddNullCheck(writer);
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  if (result.has$0$ &&", property_name());
-  writer->WriteLine("      result.$0$_ != $1$) {", name(), default_value());
-  writer->WriteLine(
-      "      result.$0$_ = $1$.CreateBuilder(result.$0$_).MergeFrom(value).BuildPartial();",
-      name(), type_name());
-  writer->WriteLine("  } else {");
-  writer->WriteLine("    result.$0$_ = value;", name());
-  writer->WriteLine("  }");
-  writer->WriteLine("  result.has$0$ = true;", property_name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Clear$0$() {", property_name());
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.has$0$ = false;", property_name());
-  writer->WriteLine("  result.$0$_ = null;", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
+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"
+    "}\n");
 }
 
-void MessageFieldGenerator::GenerateMergingCode(Writer* writer) {
-  writer->WriteLine("if (other.Has$0$) {", property_name());
-  writer->WriteLine("  Merge$0$(other.$0$);", property_name());
-  writer->WriteLine("}");
+void MessageFieldGenerator::GenerateMergingCode(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "if (other.Has$property_name$) {\n"
+    "  Merge$property_name$(other.$property_name$);\n"
+    "}\n");
 }
 
-void MessageFieldGenerator::GenerateBuildingCode(Writer* writer) {
+void MessageFieldGenerator::GenerateBuildingCode(io::Printer* printer) {
   // Nothing to do for singular fields
 }
 
-void MessageFieldGenerator::GenerateParsingCode(Writer* writer) {
-  writer->WriteLine("$0$.Builder subBuilder = $0$.CreateBuilder();",
-                    type_name());
-  writer->WriteLine("if (result.has$0$) {", property_name());
-  writer->WriteLine("  subBuilder.MergeFrom($0$);", property_name());
-  writer->WriteLine("}");
+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) {
-    writer->WriteLine("input.ReadGroup($0$, subBuilder, extensionRegistry);",
-                      number());
+    printer->Print(
+      variables_,
+      "input.ReadGroup($number$, subBuilder, extensionRegistry);\n");
   } else {
-    writer->WriteLine("input.ReadMessage(subBuilder, extensionRegistry);");
+    printer->Print("input.ReadMessage(subBuilder, extensionRegistry);\n");
   }
-  writer->WriteLine("$0$ = subBuilder.BuildPartial();", property_name());
+  printer->Print(
+    variables_,
+    "$property_name$ = subBuilder.BuildPartial();\n");
 }
 
-void MessageFieldGenerator::GenerateSerializationCode(Writer* writer) {
-  writer->WriteLine("if ($0$) {", has_property_check);
-  writer->WriteLine("  output.Write$0$($1$, field_names[$3$], $2$);",
-                    message_or_group(), number(), property_name(),
-                    field_ordinal());
-  writer->WriteLine("}");
+void MessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "if ($has_property_check$) {\n"
+    "  output.Write$message_or_group$($number$, field_names[$field_ordinal$], $property_name$);\n"
+    "}\n");
 }
 
-void MessageFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
-  writer->WriteLine("if ($0$) {", has_property_check);
-  writer->WriteLine("  size += pb::CodedOutputStream.Compute$0$Size($1$, $2$);",
-                    message_or_group(), number(), property_name());
-  writer->WriteLine("}");
+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"
+    "}\n");
 }
 
-void MessageFieldGenerator::WriteHash(Writer* writer) {
-  writer->WriteLine("if (has$0$) hash ^= $1$_.GetHashCode();", property_name(),
-                    name());
+void MessageFieldGenerator::WriteHash(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "if (has$property_name$) hash ^= $name$_.GetHashCode();\n");
 }
-void MessageFieldGenerator::WriteEquals(Writer* writer) {
-  writer->WriteLine(
-      "if (has$0$ != other.has$0$ || (has$0$ && !$1$_.Equals(other.$1$_))) return false;",
-      property_name(), name());
+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");
 }
-void MessageFieldGenerator::WriteToString(Writer* writer) {
-  writer->WriteLine("PrintField(\"$2$\", has$0$, $1$_, writer);",
-                    property_name(), name(), GetFieldName(descriptor_));
+void MessageFieldGenerator::WriteToString(io::Printer* printer) {
+  variables_["field_name"] = GetFieldName(descriptor_);
+  printer->Print(
+    variables_,
+    "PrintField(\"$field_name$\", has$property_name$, $name$_, writer);\n");
 }
 
 MessageOneofFieldGenerator::MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
 						       int fieldOrdinal)
     : MessageFieldGenerator(descriptor, fieldOrdinal) {
-  has_property_check = oneof_name() + "Case_ == " + oneof_property_name() +
-    "OneofCase." + property_name();
+  SetCommonOneofFieldVariables(&variables_);
 }
 
 MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {
 
 }
 
-void MessageOneofFieldGenerator::GenerateMembers(Writer* writer) {
+void MessageOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
   if (SupportFieldPresence(descriptor_->file())) {
-    AddDeprecatedFlag(writer);
-    writer->WriteLine("public bool Has$0$ {", property_name());
-    writer->WriteLine("  get { return $0$; }", has_property_check);
-    writer->WriteLine("}");
+    AddDeprecatedFlag(printer);
+    printer->Print(
+      variables_,
+      "public bool Has$property_name$ {\n"
+      "  get { return $has_property_check$; }\n"
+      "}\n");
   }
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
-  writer->WriteLine("  get { return $0$ ? ($1$) $2$_ : $3$; }",
-		    has_property_check, type_name(), oneof_name(), default_value());
-  writer->WriteLine("}");
+  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(Writer* writer) {
+void MessageOneofFieldGenerator::GenerateBuilderMembers(io::Printer* printer) {
   if (SupportFieldPresence(descriptor_->file())) {
-    AddDeprecatedFlag(writer);
-    writer->WriteLine("public bool Has$0$ {", property_name());
-    writer->WriteLine(" get { return result.$0$; }", has_property_check);
-    writer->WriteLine("}");
+    AddDeprecatedFlag(printer);
+    printer->Print(
+      variables_,
+      "public bool Has$property_name$ {\n"
+      "  get { return result.$has_property_check$; }\n"
+      "}\n");
   }
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
-  writer->WriteLine("  get { return result.$0$ ? ($1$) result.$2$_ : $3$; }",
-		    has_property_check, type_name(), oneof_name(), default_value());
-  writer->WriteLine("  set { Set$0$(value); }", property_name());
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Set$0$($1$ value) {", property_name(),
-                    type_name());
-  AddNullCheck(writer);
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$Case_ = $1$OneofCase.$2$;",
-		    oneof_name(), oneof_property_name(), property_name());
-  writer->WriteLine("  result.$0$_ = value;", oneof_name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Set$0$($1$.Builder builderForValue) {",
-                    property_name(), type_name());
-  AddNullCheck(writer, "builderForValue");
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$Case_ = $1$OneofCase.$2$;",
-		    oneof_name(), oneof_property_name(), property_name());
-  writer->WriteLine("  result.$0$_ = builderForValue.Build();", oneof_name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Merge$0$($1$ value) {", property_name(),
-                    type_name());
-  AddNullCheck(writer);
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  if (result.$0$ &&", has_property_check);
-  writer->WriteLine("      result.$0$ != $1$) {", property_name(), default_value());
-  writer->WriteLine(
-      "    result.$0$_ = $1$.CreateBuilder(result.$2$).MergeFrom(value).BuildPartial();",
-      oneof_name(), type_name(), property_name());
-  writer->WriteLine("  } else {");
-  writer->WriteLine("    result.$0$_ = value;", oneof_name());
-  writer->WriteLine("  }");
-  writer->WriteLine("  result.$0$Case_ = $1$OneofCase.$2$;",
-		    oneof_name(), oneof_property_name(), property_name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Clear$0$() {", property_name());
-  writer->WriteLine("  if (result.$0$) {", has_property_check);
-  writer->WriteLine("    PrepareBuilder();");
-  writer->WriteLine("    result.$0$Case_ = $1$OneofCase.None;",
-		    oneof_name(), oneof_property_name());
-  writer->WriteLine("    result.$0$_ = null;", oneof_name());
-  writer->WriteLine("  }");
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
+  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"
+    "}\n");
 }
 
-void MessageOneofFieldGenerator::GenerateParsingCode(Writer* writer) {
-  writer->WriteLine("$0$.Builder subBuilder = $0$.CreateBuilder();",
-                    type_name());
-  writer->WriteLine("if (result.$0$) {", has_property_check);
-  writer->WriteLine("  subBuilder.MergeFrom($0$);", property_name());
-  writer->WriteLine("}");
+void MessageOneofFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+  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) {
-    writer->WriteLine("input.ReadGroup($0$, subBuilder, extensionRegistry);",
-                      number());
+    printer->Print(
+      variables_,
+      "input.ReadGroup($number$, subBuilder, extensionRegistry);\n");
   } else {
-    writer->WriteLine("input.ReadMessage(subBuilder, extensionRegistry);");
+    printer->Print("input.ReadMessage(subBuilder, extensionRegistry);\n");
   }
-  writer->WriteLine("result.$0$_ = subBuilder.BuildPartial();", oneof_name());
-  writer->WriteLine("result.$0$Case_ = $1$OneofCase.$2$;",
-		    oneof_name(), oneof_property_name(), property_name());
+  printer->Print(
+    variables_,
+    "result.$oneof_name$_ = subBuilder.BuildPartial();\n"
+    "result.$oneof_name$Case_ = $oneof_property_name$OneofCase.$property_name$;\n");
 }
 
-void MessageOneofFieldGenerator::WriteEquals(Writer* writer) {
-  writer->WriteLine("if (!$0$.Equals(other.$0$)) return false;", property_name());
+void MessageOneofFieldGenerator::WriteEquals(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "if (!$property_name$.Equals(other.$property_name$)) return false;\n");
 }
-void MessageOneofFieldGenerator::WriteToString(Writer* writer) {
-  writer->WriteLine("PrintField(\"$0$\", $1$, $2$_, writer);",
-                    descriptor_->name(), has_property_check, oneof_name());
+void MessageOneofFieldGenerator::WriteToString(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "PrintField(\"$descriptor_name$\", $has_property_check$, $oneof_name$_, writer);\n");
 }
 
 }  // namespace csharp

+ 16 - 19
src/google/protobuf/compiler/csharp/csharp_message_field.h

@@ -48,20 +48,17 @@ class MessageFieldGenerator : public FieldGeneratorBase {
   MessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~MessageFieldGenerator();
 
-  virtual void GenerateMembers(Writer* writer);
-  virtual void GenerateBuilderMembers(Writer* writer);
-  virtual void GenerateMergingCode(Writer* writer);
-  virtual void GenerateBuildingCode(Writer* writer);
-  virtual void GenerateParsingCode(Writer* writer);
-  virtual void GenerateSerializationCode(Writer* writer);
-  virtual void GenerateSerializedSizeCode(Writer* writer);
-
-  virtual void WriteHash(Writer* writer);
-  virtual void WriteEquals(Writer* writer);
-  virtual void WriteToString(Writer* writer);
-
- protected:
-  string has_property_check;
+  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);
+
+  virtual void WriteHash(io::Printer* printer);
+  virtual void WriteEquals(io::Printer* printer);
+  virtual void WriteToString(io::Printer* printer);
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
@@ -72,11 +69,11 @@ class MessageOneofFieldGenerator : public MessageFieldGenerator {
   MessageOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~MessageOneofFieldGenerator();
 
-  virtual void GenerateMembers(Writer* writer);
-  virtual void GenerateBuilderMembers(Writer* writer);
-  virtual void WriteEquals(Writer* writer);
-  virtual void WriteToString(Writer* writer);
-  virtual void GenerateParsingCode(Writer* writer);
+  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);
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator);

+ 171 - 142
src/google/protobuf/compiler/csharp/csharp_primitive_field.cc

@@ -40,7 +40,6 @@
 
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
 #include <google/protobuf/compiler/csharp/csharp_primitive_field.h>
-#include <google/protobuf/compiler/csharp/csharp_writer.h>
 
 namespace google {
 namespace protobuf {
@@ -50,202 +49,232 @@ namespace csharp {
 PrimitiveFieldGenerator::PrimitiveFieldGenerator(
     const FieldDescriptor* descriptor, int fieldOrdinal)
     : FieldGeneratorBase(descriptor, fieldOrdinal) {
-  if (SupportFieldPresence(descriptor_->file())) {
-    has_property_check = "has" + property_name();
-  } else {
-    has_property_check = property_name() + " != " + default_value();
-  }
 }
 
 PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {
 
 }
 
-void PrimitiveFieldGenerator::GenerateMembers(Writer* writer) {
+void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) {
   if (SupportFieldPresence(descriptor_->file())) {
-    writer->WriteLine("private bool has$0$;", property_name());
+    printer->Print(variables_, "private bool has$property_name$;\n");
   }
-  writer->WriteLine("private $0$ $1$_$2$;", type_name(), name(),
-                    has_default_value() ? " = " + default_value() : "");
-  AddDeprecatedFlag(writer);
+  printer->Print(
+    variables_,
+    "private $type_name$ $name_def_message$;\n");
+  AddDeprecatedFlag(printer);
   if (SupportFieldPresence(descriptor_->file())) {
-    writer->WriteLine("public bool Has$0$ {", property_name());
-    writer->WriteLine("  get { return has$0$; }", property_name());
-    writer->WriteLine("}");
+    printer->Print(
+      variables_,
+      "public bool Has$property_name$ {\n"
+      "  get { return has$property_name$; }\n"
+      "}\n");
   }
-  AddPublicMemberAttributes(writer);
-  writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
-  writer->WriteLine("  get { return $0$_; }", name());
-  writer->WriteLine("}");
+  AddPublicMemberAttributes(printer);
+  printer->Print(
+    variables_,
+    "public $type_name$ $property_name$ {\n"
+    "  get { return $name$_; }\n"
+    "}\n");
 }
 
-void PrimitiveFieldGenerator::GenerateBuilderMembers(Writer* writer) {
-  AddDeprecatedFlag(writer);
+void PrimitiveFieldGenerator::GenerateBuilderMembers(io::Printer* printer) {
+  AddDeprecatedFlag(printer);
   if (SupportFieldPresence(descriptor_->file())) {
-    writer->WriteLine("public bool Has$0$ {", property_name());
-    writer->WriteLine("  get { return result.has$0$; }", property_name());
-    writer->WriteLine("}");
+    printer->Print(
+      variables_,
+      "public bool Has$property_name$ {\n"
+      "  get { return result.has$property_name$; }\n"
+      "}\n");
   }
-  AddPublicMemberAttributes(writer);
-  writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
-  writer->WriteLine("  get { return result.$0$; }", property_name());
-  writer->WriteLine("  set { Set$0$(value); }", property_name());
-  writer->WriteLine("}");
-  AddPublicMemberAttributes(writer);
-  writer->WriteLine("public Builder Set$0$($1$ value) {", property_name(),
-                    type_name());
-  AddNullCheck(writer);
-  writer->WriteLine("  PrepareBuilder();");
+  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())) {
-    writer->WriteLine("  result.has$0$ = true;", property_name());
+    printer->Print(
+      variables_,
+      "  result.has$property_name$ = true;\n");
   }
-  writer->WriteLine("  result.$0$_ = value;", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Clear$0$() {", property_name());
-  writer->WriteLine("  PrepareBuilder();");
+  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())) {
-    writer->WriteLine("  result.has$0$ = false;", property_name());
+    printer->Print(
+      variables_,
+      "  result.has$property_name$ = false;\n");
   }
-  writer->WriteLine("  result.$0$_ = $1$;", name(), default_value());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
+  printer->Print(
+    variables_,
+    "  result.$name$_ = $default_value$;\n"
+    "  return this;\n"
+    "}\n");
 }
 
-void PrimitiveFieldGenerator::GenerateMergingCode(Writer* writer) {
-  if (SupportFieldPresence(descriptor_->file())) {
-    writer->WriteLine("if (other.Has$0$) {", property_name());
-  } else {
-    writer->WriteLine("if (other.$0$ != $1$) {", property_name(), default_value());
-  }
-  writer->WriteLine("  $0$ = other.$0$;", property_name());
-  writer->WriteLine("}");
+void PrimitiveFieldGenerator::GenerateMergingCode(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "if ($other_has_property_check$) {\n"
+    "  $property_name$ = other.$property_name$;\n"
+    "}\n");
 }
 
-void PrimitiveFieldGenerator::GenerateBuildingCode(Writer* writer) {
+void PrimitiveFieldGenerator::GenerateBuildingCode(io::Printer* printer) {
   // Nothing to do here for primitive types
 }
 
-void PrimitiveFieldGenerator::GenerateParsingCode(Writer* writer) {
+void PrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer) {
   if (SupportFieldPresence(descriptor_->file())) {
-    writer->WriteLine("result.has$0$ = input.Read$1$(ref result.$2$_);",
-                      property_name(), capitalized_type_name(), name());
+    printer->Print(
+      variables_,
+      "result.has$property_name$ = input.Read$capitalized_type_name$(ref result.$name$_);\n");
   } else {
-    writer->WriteLine("input.Read$0$(ref result.$1$_);",
-                      capitalized_type_name(), name());
+    printer->Print(
+      variables_,
+      "input.Read$capitalized_type_name$(ref result.$name$_);\n");
   }
 }
 
-void PrimitiveFieldGenerator::GenerateSerializationCode(Writer* writer) {
-  writer->WriteLine("if ($0$) {", has_property_check);
-  writer->WriteLine("  output.Write$0$($1$, field_names[$3$], $2$);",
-                    capitalized_type_name(), number(), property_name(),
-                    field_ordinal());
-  writer->WriteLine("}");
+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"
+    "}\n");
 }
 
-void PrimitiveFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
-  writer->WriteLine("if ($0$) {", has_property_check);
-  writer->WriteLine("  size += pb::CodedOutputStream.Compute$0$Size($1$, $2$);",
-                    capitalized_type_name(), number(), property_name());
-  writer->WriteLine("}");
+void PrimitiveFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "if ($has_property_check$) {\n"
+    "  size += pb::CodedOutputStream.Compute$capitalized_type_name$Size($number$, $property_name$);\n"
+    "}\n");
 }
 
-void PrimitiveFieldGenerator::WriteHash(Writer* writer) {
-  writer->WriteLine("if ($0$) {", has_property_check);
-  writer->WriteLine("  hash ^= $0$_.GetHashCode();", name());
-  writer->WriteLine("}");
+void PrimitiveFieldGenerator::WriteHash(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "if ($has_property_check$) {\n"
+    "  hash ^= $name$_.GetHashCode();\n"
+    "}\n");
 }
-void PrimitiveFieldGenerator::WriteEquals(Writer* writer) {
+void PrimitiveFieldGenerator::WriteEquals(io::Printer* printer) {
   if (SupportFieldPresence(descriptor_->file())) {
-    writer->WriteLine(
-        "if (has$0$ != other.has$0$ || (has$0$ && !$1$_.Equals(other.$1$_))) return false;",
-        property_name(), name());
+    printer->Print(
+      variables_,
+      "if (has$property_name$ != other.has$property_name$ || (has$property_name$ && !$name$_.Equals(other.$name$_))) return false;\n");
   } else {
-    writer->WriteLine(
-        "if (!$0$_.Equals(other.$0$_)) return false;", name());
+    printer->Print(
+      variables_,
+      "if (!$name$_.Equals(other.$name$_)) return false;\n");
   }
 }
-void PrimitiveFieldGenerator::WriteToString(Writer* writer) {
-  writer->WriteLine("PrintField(\"$0$\", $1$, $2$_, writer);",
-                    descriptor_->name(), has_property_check, name());
+void PrimitiveFieldGenerator::WriteToString(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "PrintField(\"$descriptor_name$\", $has_property_check$, $name$_, writer);\n");
 }
 
 PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator(
     const FieldDescriptor* descriptor, int fieldOrdinal)
     : PrimitiveFieldGenerator(descriptor, fieldOrdinal) {
-  has_property_check = oneof_name() + "Case_ == " + oneof_property_name() +
-    "OneofCase." + property_name();
+  SetCommonOneofFieldVariables(&variables_);
 }
 
 PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {
 }
 
-void PrimitiveOneofFieldGenerator::GenerateMembers(Writer* writer) {
-  AddDeprecatedFlag(writer);
+void PrimitiveOneofFieldGenerator::GenerateMembers(io::Printer* printer) {
+  AddDeprecatedFlag(printer);
   if (SupportFieldPresence(descriptor_->file())) {
-    writer->WriteLine("public bool Has$0$ {", property_name());
-    writer->WriteLine("  get { return $0$; }", has_property_check);
-    writer->WriteLine("}");
+    printer->Print(
+      variables_,
+      "public bool Has$property_name$ {\n"
+      "  get { return $has_property_check$; }\n"
+      "}\n");
   }
-  AddPublicMemberAttributes(writer);
-  writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
-  writer->WriteLine("  get { return $0$ ? ($1$) $2$_ : $3$; }",
-		    has_property_check, type_name(), oneof_name(), default_value());
-  writer->WriteLine("}");
+  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(Writer* writer) {
-  AddDeprecatedFlag(writer);
+void PrimitiveOneofFieldGenerator::GenerateBuilderMembers(io::Printer* printer) {
+  AddDeprecatedFlag(printer);
   if (SupportFieldPresence(descriptor_->file())) {
-    writer->WriteLine("public bool Has$0$ {", property_name());
-    writer->WriteLine("  get { return result.$0$; }", has_property_check);
-    writer->WriteLine("}");
+    printer->Print(
+      variables_,
+      "public bool Has$property_name$ {\n"
+      "  get { return result.$has_property_check$; }\n"
+      "}\n");
   }
-  AddPublicMemberAttributes(writer);
-  writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
-  writer->WriteLine("  get { return result.$0$ ? ($1$) result.$2$_ : $3$; }",
-		    has_property_check, type_name(), oneof_name(), default_value());
-  writer->WriteLine("  set { Set$0$(value); }", property_name());
-  writer->WriteLine("}");
-  AddPublicMemberAttributes(writer);
-  writer->WriteLine("public Builder Set$0$($1$ value) {", property_name(),
-                    type_name());
-  AddNullCheck(writer);
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_ = value;", oneof_name());
-  writer->WriteLine("  result.$0$Case_ = $1$OneofCase.$2$;",
-                    oneof_name(), oneof_property_name(), property_name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Clear$0$() {", property_name());
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  if (result.$0$) {", has_property_check);
-  writer->WriteLine("    result.$0$Case_ = $1$OneofCase.None;",
-                    oneof_name(), oneof_property_name());
-  writer->WriteLine("  }");
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-}
-
-void PrimitiveOneofFieldGenerator::WriteEquals(Writer* writer) {
-  writer->WriteLine("if (!$0$.Equals(other.$0$)) return false;", property_name());
-}
-void PrimitiveOneofFieldGenerator::WriteToString(Writer* writer) {
-  writer->WriteLine("PrintField(\"$0$\", $1$, $2$_, writer);",
-                    descriptor_->name(), has_property_check, oneof_name());
-}
-
-void PrimitiveOneofFieldGenerator::GenerateParsingCode(Writer* writer) {
-  writer->WriteLine("$0$ value = $1$;", type_name(), default_value());
-  writer->WriteLine("if (input.Read$0$(ref value)) {",
-		    capitalized_type_name());
-  writer->WriteLine("  result.$0$_ = value;", oneof_name());
-  writer->WriteLine("  result.$0$Case_ = $1$OneofCase.$2$;",
-		    oneof_name(), oneof_property_name(), property_name());
-  writer->WriteLine("}");
+  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) {
+  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"
+    "}\n");
 }
 
 }  // namespace csharp

+ 16 - 19
src/google/protobuf/compiler/csharp/csharp_primitive_field.h

@@ -48,20 +48,17 @@ class PrimitiveFieldGenerator : public FieldGeneratorBase {
   PrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~PrimitiveFieldGenerator();
 
-  virtual void GenerateMembers(Writer* writer);
-  virtual void GenerateBuilderMembers(Writer* writer);
-  virtual void GenerateMergingCode(Writer* writer);
-  virtual void GenerateBuildingCode(Writer* writer);
-  virtual void GenerateParsingCode(Writer* writer);
-  virtual void GenerateSerializationCode(Writer* writer);
-  virtual void GenerateSerializedSizeCode(Writer* writer);
-
-  virtual void WriteHash(Writer* writer);
-  virtual void WriteEquals(Writer* writer);
-  virtual void WriteToString(Writer* writer);
-
- protected:
-  string has_property_check;
+  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);
+
+  virtual void WriteHash(io::Printer* printer);
+  virtual void WriteEquals(io::Printer* printer);
+  virtual void WriteToString(io::Printer* printer);
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
@@ -72,11 +69,11 @@ class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
   PrimitiveOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~PrimitiveOneofFieldGenerator();
 
-  virtual void GenerateMembers(Writer* writer);
-  virtual void GenerateBuilderMembers(Writer* writer);
-  virtual void WriteEquals(Writer* writer);
-  virtual void WriteToString(Writer* writer);
-  virtual void GenerateParsingCode(Writer* writer);
+  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);
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveOneofFieldGenerator);

+ 151 - 127
src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc

@@ -40,7 +40,6 @@
 
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
 #include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h>
-#include <google/protobuf/compiler/csharp/csharp_writer.h>
 
 namespace google {
 namespace protobuf {
@@ -56,168 +55,193 @@ RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {
 
 }
 
-void RepeatedEnumFieldGenerator::GenerateMembers(Writer* writer) {
+void RepeatedEnumFieldGenerator::GenerateMembers(io::Printer* printer) {
   if (descriptor_->is_packed() && optimize_speed()) {
-    writer->WriteLine("private int $0$MemoizedSerializedSize;", name());
+    printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n");
   }
-  writer->WriteLine(
-      "private pbc::PopsicleList<$0$> $1$_ = new pbc::PopsicleList<$0$>();",
-      type_name(), name());
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public scg::IList<$0$> $1$List {", type_name(),
-                    property_name());
-  writer->WriteLine("  get { return pbc::Lists.AsReadOnly($0$_); }", name());
-  writer->WriteLine("}");
+  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(writer);
-  writer->WriteLine("public int $0$Count {", property_name());
-  writer->WriteLine("  get { return $0$_.Count; }", name());
-  writer->WriteLine("}");
-
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public $0$ Get$1$(int index) {", type_name(),
-                    property_name());
-  writer->WriteLine("  return $0$_[index];", name());
-  writer->WriteLine("}");
+  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(Writer* writer) {
+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(writer);
-  writer->WriteLine("public pbc::IPopsicleList<$0$> $1$List {", type_name(),
-                    property_name());
-  writer->WriteLine("  get { return PrepareBuilder().$0$_; }", name());
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public int $0$Count {", property_name());
-  writer->WriteLine("  get { return result.$0$Count; }", property_name());
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public $0$ Get$1$(int index) {", type_name(),
-                    property_name());
-  writer->WriteLine("  return result.Get$0$(index);", property_name());
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Set$0$(int index, $1$ value) {",
-                    property_name(), type_name());
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_[index] = value;", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Add$0$($1$ value) {", property_name(),
-                    type_name());
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_.Add(value);", name(), type_name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine(
-      "public Builder AddRange$0$(scg::IEnumerable<$1$> values) {",
-      property_name(), type_name());
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_.Add(values);", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Clear$0$() {", property_name());
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_.Clear();", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
+  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");
+  AddDeprecatedFlag(printer);
+  printer->Print(
+    variables_,
+    "public Builder Clear$property_name$() {\n"
+    "  PrepareBuilder();\n"
+    "  result.$name$_.Clear();\n"
+    "  return this;\n"
+    "}\n");
 }
 
-void RepeatedEnumFieldGenerator::GenerateMergingCode(Writer* writer) {
-  writer->WriteLine("if (other.$0$_.Count != 0) {", name());
-  writer->WriteLine("  result.$0$_.Add(other.$0$_);", name());
-  writer->WriteLine("}");
+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(Writer* writer) {
-  writer->WriteLine("$0$_.MakeReadOnly();", name());
+void RepeatedEnumFieldGenerator::GenerateBuildingCode(io::Printer* printer) {
+  printer->Print(variables_, "$name$_.MakeReadOnly();\n");
 }
 
-void RepeatedEnumFieldGenerator::GenerateParsingCode(Writer* writer) {
-  writer->WriteLine("scg::ICollection<object> unknownItems;");
-  writer->WriteLine(
-      "input.ReadEnumArray<$0$>(tag, field_name, result.$1$_, out unknownItems);",
-      type_name(), name());
+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()) {
-    writer->WriteLine("if (unknownItems != null) {");
-    writer->WriteLine("  if (unknownFields == null) {");
-    writer->WriteLine(
-        "    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
-    writer->WriteLine("  }");
-    writer->WriteLine("  foreach (object rawValue in unknownItems)");
-    writer->WriteLine("    if (rawValue is int)");
-    writer->WriteLine(
-        "      unknownFields.MergeVarintField($0$, (ulong)(int)rawValue);",
-        number());
-    writer->WriteLine("}");
+    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");
   }
 }
 
-void RepeatedEnumFieldGenerator::GenerateSerializationCode(Writer* writer) {
-  writer->WriteLine("if ($0$_.Count > 0) {", name());
-  writer->Indent();
+void RepeatedEnumFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+  printer->Print(variables_, "if ($name$_.Count > 0) {\n");
+  printer->Indent();
   if (descriptor_->is_packed()) {
-    writer->WriteLine(
-        "output.WritePackedEnumArray($0$, field_names[$2$], $1$MemoizedSerializedSize, $1$_);",
-        number(), name(), field_ordinal());
+    printer->Print(
+      variables_,
+      "output.WritePackedEnumArray($number$, field_names[$field_ordinal$], $name$MemoizedSerializedSize, $name$_);\n");
   } else {
-    writer->WriteLine("output.WriteEnumArray($0$, field_names[$2$], $1$_);",
-                      number(), name(), field_ordinal());
+    printer->Print(variables_,
+      "output.WriteEnumArray($number$, field_names[$field_ordinal$], $name$_);\n");
   }
-  writer->Outdent();
-  writer->WriteLine("}");
+  printer->Outdent();
+  printer->Print("}\n");
 }
 
-void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
-  writer->WriteLine("{");
-  writer->Indent();
-  writer->WriteLine("int dataSize = 0;");
-  writer->WriteLine("if ($0$_.Count > 0) {", name());
-  writer->Indent();
-  writer->WriteLine("foreach ($0$ element in $1$_) {", type_name(), name());
-  writer->WriteLine(
-      "  dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);");
-  writer->WriteLine("}");
-  writer->WriteLine("size += dataSize;");
+void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+  printer->Print("{\n");
+  printer->Indent();
+  printer->Print(
+    variables_,
+    "int dataSize = 0;\n"
+    "if ($name$_.Count > 0) {\n");
+  printer->Indent();
+  printer->Print(
+    variables_,
+    "foreach ($type_name$ element in $name$_) {\n"
+    "  dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);\n"
+    "}\n"
+    "size += dataSize;\n");
   int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type());
   if (descriptor_->is_packed()) {
-    writer->WriteLine("size += $0$;", SimpleItoa(tagSize));
-    writer->WriteLine(
-        "size += pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);");
+    printer->Print(
+      "size += $tag_size$;\n"
+      "size += pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);\n",
+      "tag_size", SimpleItoa(tagSize));
   } else {
-    writer->WriteLine("size += $0$ * $1$_.Count;", SimpleItoa(tagSize), name());
+    printer->Print(
+      "size += $tag_size$ * $name$_.Count;\n",
+      "tag_size", SimpleItoa(tagSize), "name", name());
   }
-  writer->Outdent();
-  writer->WriteLine("}");
+  printer->Outdent();
+  printer->Print("}\n");
   // cache the data size for packed fields.
   if (descriptor_->is_packed()) {
-    writer->WriteLine("$0$MemoizedSerializedSize = dataSize;", name());
+    printer->Print(variables_,
+      "$name$MemoizedSerializedSize = dataSize;\n");
   }
-  writer->Outdent();
-  writer->WriteLine("}");
+  printer->Outdent();
+  printer->Print("}\n");
 }
 
-void RepeatedEnumFieldGenerator::WriteHash(Writer* writer) {
-  writer->WriteLine("foreach($0$ i in $1$_)", type_name(), name());
-  writer->WriteLine("  hash ^= i.GetHashCode();");
+void RepeatedEnumFieldGenerator::WriteHash(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "foreach($type_name$ i in $name$_)\n"
+    "  hash ^= i.GetHashCode();\n");
 }
 
-void RepeatedEnumFieldGenerator::WriteEquals(Writer* writer) {
-  writer->WriteLine("if($0$_.Count != other.$0$_.Count) return false;", name());
-  writer->WriteLine("for(int ix=0; ix < $0$_.Count; ix++)", name());
-  writer->WriteLine("  if(!$0$_[ix].Equals(other.$0$_[ix])) return false;",
-                    name());
+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");
 }
 
-void RepeatedEnumFieldGenerator::WriteToString(Writer* writer) {
-  writer->WriteLine("PrintField(\"$0$\", $1$_, writer);", descriptor_->name(),
-                    name());
+void RepeatedEnumFieldGenerator::WriteToString(io::Printer* printer) {
+  printer->Print(variables_,
+    "PrintField(\"$descriptor_name$\", $name$_, writer);\n");
 }
 
 }  // namespace csharp

+ 10 - 10
src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h

@@ -48,17 +48,17 @@ class RepeatedEnumFieldGenerator : public FieldGeneratorBase {
   RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~RepeatedEnumFieldGenerator();
 
-  virtual void GenerateMembers(Writer* writer);
-  virtual void GenerateBuilderMembers(Writer* writer);
-  virtual void GenerateMergingCode(Writer* writer);
-  virtual void GenerateBuildingCode(Writer* writer);
-  virtual void GenerateParsingCode(Writer* writer);
-  virtual void GenerateSerializationCode(Writer* writer);
-  virtual void GenerateSerializedSizeCode(Writer* writer);
+  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);
 
-  virtual void WriteHash(Writer* writer);
-  virtual void WriteEquals(Writer* writer);
-  virtual void WriteToString(Writer* writer);
+  virtual void WriteHash(io::Printer* printer);
+  virtual void WriteEquals(io::Printer* printer);
+  virtual void WriteToString(io::Printer* printer);
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);

+ 143 - 117
src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc

@@ -39,7 +39,6 @@
 
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
 #include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h>
-#include <google/protobuf/compiler/csharp/csharp_writer.h>
 
 namespace google {
 namespace protobuf {
@@ -49,150 +48,177 @@ namespace csharp {
 RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
     const FieldDescriptor* descriptor, int fieldOrdinal)
     : FieldGeneratorBase(descriptor, fieldOrdinal) {
+  variables_["message_or_group"] = message_or_group();
 }
 
 RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {
 
 }
 
-void RepeatedMessageFieldGenerator::GenerateMembers(Writer* writer) {
-  writer->WriteLine(
-      "private pbc::PopsicleList<$0$> $1$_ = new pbc::PopsicleList<$0$>();",
-      type_name(), name());
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public scg::IList<$0$> $1$List {", type_name(),
-                    property_name());
-  writer->WriteLine("  get { return $0$_; }", name());
-  writer->WriteLine("}");
+void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) {
+  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 $name$_; }\n"
+    "}\n");
 
   // TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public int $0$Count {", property_name());
-  writer->WriteLine("  get { return $0$_.Count; }", name());
-  writer->WriteLine("}");
-
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public $0$ Get$1$(int index) {", type_name(),
-                    property_name());
-  writer->WriteLine("  return $0$_[index];", name());
-  writer->WriteLine("}");
+  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 RepeatedMessageFieldGenerator::GenerateBuilderMembers(Writer* writer) {
+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(writer);
-  writer->WriteLine("public pbc::IPopsicleList<$0$> $1$List {", type_name(),
-                    property_name());
-  writer->WriteLine("  get { return PrepareBuilder().$0$_; }", name());
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public int $0$Count {", property_name());
-  writer->WriteLine("  get { return result.$0$Count; }", property_name());
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public $0$ Get$1$(int index) {", type_name(),
-                    property_name());
-  writer->WriteLine("  return result.Get$0$(index);", property_name());
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Set$0$(int index, $1$ value) {",
-                    property_name(), type_name());
-  AddNullCheck(writer);
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_[index] = value;", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
+  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(writer);
-  writer->WriteLine(
-      "public Builder Set$0$(int index, $1$.Builder builderForValue) {",
-      property_name(), type_name());
-  AddNullCheck(writer, "builderForValue");
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_[index] = builderForValue.Build();", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Add$0$($1$ value) {", property_name(),
-                    type_name());
-  AddNullCheck(writer);
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_.Add(value);", name(), type_name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
+  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(writer);
-  writer->WriteLine("public Builder Add$0$($1$.Builder builderForValue) {",
-                    property_name(), type_name());
-  AddNullCheck(writer, "builderForValue");
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_.Add(builderForValue.Build());", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine(
-      "public Builder AddRange$0$(scg::IEnumerable<$1$> values) {",
-      property_name(), type_name());
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_.Add(values);", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Clear$0$() {", property_name());
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_.Clear();", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
+  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(Writer* writer) {
-  writer->WriteLine("if (other.$0$_.Count != 0) {", name());
-  writer->WriteLine("  result.$0$_.Add(other.$0$_);", name());
-  writer->WriteLine("}");
+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(Writer* writer) {
-  writer->WriteLine("$0$_.MakeReadOnly();", name());
+void RepeatedMessageFieldGenerator::GenerateBuildingCode(io::Printer* printer) {
+  printer->Print(variables_, "$name$_.MakeReadOnly();\n");
 }
 
-void RepeatedMessageFieldGenerator::GenerateParsingCode(Writer* writer) {
-  writer->WriteLine(
-      "input.Read$0$Array(tag, field_name, result.$1$_, $2$.DefaultInstance, extensionRegistry);",
-      message_or_group(), name(), type_name());
+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");
 }
 
-void RepeatedMessageFieldGenerator::GenerateSerializationCode(Writer* writer) {
-  writer->WriteLine("if ($0$_.Count > 0) {", name());
-  writer->Indent();
-  writer->WriteLine("output.Write$0$Array($1$, field_names[$3$], $2$_);",
-                    message_or_group(), number(), name(), field_ordinal());
-  writer->Outdent();
-  writer->WriteLine("}");
+void RepeatedMessageFieldGenerator::GenerateSerializationCode(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "if ($name$_.Count > 0) {\n"
+    "  output.Write$message_or_group$Array($number$, field_names[$field_ordinal$], $name$_);\n"
+    "}\n");
 }
 
-void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
-  writer->WriteLine("foreach ($0$ element in $1$List) {", type_name(),
-                    property_name());
-  writer->WriteLine(
-      "  size += pb::CodedOutputStream.Compute$0$Size($1$, element);",
-      message_or_group(), number());
-  writer->WriteLine("}");
+void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "foreach ($type_name$ element in $property_name$List) {\n"
+    "  size += pb::CodedOutputStream.Compute$message_or_group$Size($number$, element);\n"
+    "}\n");
 }
 
-void RepeatedMessageFieldGenerator::WriteHash(Writer* writer) {
-  writer->WriteLine("foreach($0$ i in $1$_)", type_name(), name());
-  writer->WriteLine("  hash ^= i.GetHashCode();");
+void RepeatedMessageFieldGenerator::WriteHash(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "foreach($type_name$ i in $name$_)\n"
+    "  hash ^= i.GetHashCode();\n");
 }
-void RepeatedMessageFieldGenerator::WriteEquals(Writer* writer) {
-  writer->WriteLine("if($0$_.Count != other.$0$_.Count) return false;", name());
-  writer->WriteLine("for(int ix=0; ix < $0$_.Count; ix++)", name());
-  writer->WriteLine("  if(!$0$_[ix].Equals(other.$0$_[ix])) return false;",
-                    name());
+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");
 }
-void RepeatedMessageFieldGenerator::WriteToString(Writer* writer) {
-  writer->WriteLine("PrintField(\"$0$\", $1$_, writer);",
-                    GetFieldName(descriptor_), name());
+void RepeatedMessageFieldGenerator::WriteToString(io::Printer* printer) {
+  variables_["field_name"] = GetFieldName(descriptor_);
+  printer->Print(
+    variables_,
+    "PrintField(\"$field_name$\", $name$_, writer);\n");
 }
 
 }  // namespace csharp

+ 10 - 10
src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h

@@ -48,17 +48,17 @@ class RepeatedMessageFieldGenerator : public FieldGeneratorBase {
   RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~RepeatedMessageFieldGenerator();
 
-  virtual void GenerateMembers(Writer* writer);
-  virtual void GenerateBuilderMembers(Writer* writer);
-  virtual void GenerateMergingCode(Writer* writer);
-  virtual void GenerateBuildingCode(Writer* writer);
-  virtual void GenerateParsingCode(Writer* writer);
-  virtual void GenerateSerializationCode(Writer* writer);
-  virtual void GenerateSerializedSizeCode(Writer* writer);
+  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);
 
-  virtual void WriteHash(Writer* writer);
-  virtual void WriteEquals(Writer* writer);
-  virtual void WriteToString(Writer* writer);
+  virtual void WriteHash(io::Printer* printer);
+  virtual void WriteEquals(io::Printer* printer);
+  virtual void WriteToString(io::Printer* printer);
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);

+ 138 - 118
src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc

@@ -40,7 +40,6 @@
 
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
 #include <google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h>
-#include <google/protobuf/compiler/csharp/csharp_writer.h>
 
 namespace google {
 namespace protobuf {
@@ -56,161 +55,182 @@ RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {
 
 }
 
-void RepeatedPrimitiveFieldGenerator::GenerateMembers(Writer* writer) {
+void RepeatedPrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) {
   if (descriptor_->is_packed() && optimize_speed()) {
-    writer->WriteLine("private int $0$MemoizedSerializedSize;", name());
+    printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n");
   }
-  writer->WriteLine(
-      "private pbc::PopsicleList<$0$> $1$_ = new pbc::PopsicleList<$0$>();",
-      type_name(), name());
-  AddPublicMemberAttributes(writer);
-  writer->WriteLine("public scg::IList<$0$> $1$List {", type_name(),
-                    property_name());
-  writer->WriteLine("  get { return pbc::Lists.AsReadOnly($0$_); }", name());
-  writer->WriteLine("}");
+  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.
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public int $0$Count {", property_name());
-  writer->WriteLine("  get { return $0$_.Count; }", name());
-  writer->WriteLine("}");
-
-  AddPublicMemberAttributes(writer);
-  writer->WriteLine("public $0$ Get$1$(int index) {", type_name(),
-                    property_name());
-  writer->WriteLine("  return $0$_[index];", name());
-  writer->WriteLine("}");
+  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(Writer* writer) {
+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(writer);
-  writer->WriteLine("public pbc::IPopsicleList<$0$> $1$List {", type_name(),
-                    property_name());
-  writer->WriteLine("  get { return PrepareBuilder().$0$_; }", name());
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public int $0$Count {", property_name());
-  writer->WriteLine("  get { return result.$0$Count; }", property_name());
-  writer->WriteLine("}");
-  AddPublicMemberAttributes(writer);
-  writer->WriteLine("public $0$ Get$1$(int index) {", type_name(),
-                    property_name());
-  writer->WriteLine("  return result.Get$0$(index);", property_name());
-  writer->WriteLine("}");
-  AddPublicMemberAttributes(writer);
-  writer->WriteLine("public Builder Set$0$(int index, $1$ value) {",
-                    property_name(), type_name());
-  AddNullCheck(writer);
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_[index] = value;", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddPublicMemberAttributes(writer);
-  writer->WriteLine("public Builder Add$0$($1$ value) {", property_name(),
-                    type_name());
-  AddNullCheck(writer);
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_.Add(value);", name(), type_name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddPublicMemberAttributes(writer);
-  writer->WriteLine(
-      "public Builder AddRange$0$(scg::IEnumerable<$1$> values) {",
-      property_name(), type_name());
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_.Add(values);", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
-  AddDeprecatedFlag(writer);
-  writer->WriteLine("public Builder Clear$0$() {", property_name());
-  writer->WriteLine("  PrepareBuilder();");
-  writer->WriteLine("  result.$0$_.Clear();", name());
-  writer->WriteLine("  return this;");
-  writer->WriteLine("}");
+  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"
+    "}\n");
 }
 
-void RepeatedPrimitiveFieldGenerator::GenerateMergingCode(Writer* writer) {
-  writer->WriteLine("if (other.$0$_.Count != 0) {", name());
-  writer->WriteLine("  result.$0$_.Add(other.$0$_);", name());
-  writer->WriteLine("}");
+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(Writer* writer) {
-  writer->WriteLine("$0$_.MakeReadOnly();", name());
+void RepeatedPrimitiveFieldGenerator::GenerateBuildingCode(io::Printer* printer) {
+  printer->Print(variables_, "$name$_.MakeReadOnly();\n");
 }
 
-void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(Writer* writer) {
-  writer->WriteLine("input.Read$0$Array(tag, field_name, result.$1$_);",
-                    capitalized_type_name(), name());
+void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(io::Printer* printer) {
+  printer->Print(variables_,
+    "input.Read$capitalized_type_name$Array(tag, field_name, result.$name$_);\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(
-    Writer* writer) {
-  writer->WriteLine("if ($0$_.Count > 0) {", name());
-  writer->Indent();
+    io::Printer* printer) {
+  printer->Print(variables_, "if ($name$_.Count > 0) {\n");
+  printer->Indent();
   if (descriptor_->is_packed()) {
-    writer->WriteLine(
-        "output.WritePacked$0$Array($1$, field_names[$3$], $2$MemoizedSerializedSize, $2$_);",
-        capitalized_type_name(), number(), name(), field_ordinal());
+    printer->Print(variables_,
+      "output.WritePacked$capitalized_type_name$Array($number$, field_names[$field_ordinal$], $name$MemoizedSerializedSize, $name$_);\n");
   } else {
-    writer->WriteLine("output.Write$0$Array($1$, field_names[$3$], $2$_);",
-                      capitalized_type_name(), number(), name(),
-                      field_ordinal());
+    printer->Print(variables_,
+      "output.Write$capitalized_type_name$Array($number$, field_names[$field_ordinal$], $name$_);\n");
   }
-  writer->Outdent();
-  writer->WriteLine("}");
+  printer->Outdent();
+  printer->Print("}\n");
 }
 
 void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(
-    Writer* writer) {
-  writer->WriteLine("{");
-  writer->Indent();
-  writer->WriteLine("int dataSize = 0;");
+    io::Printer* printer) {
+  printer->Print("{\n");
+  printer->Indent();
+  printer->Print("int dataSize = 0;\n");
   int fixedSize = GetFixedSize(descriptor_->type());
   if (fixedSize == -1) {
-    writer->WriteLine("foreach ($0$ element in $1$List) {", type_name(),
-                      property_name());
-    writer->WriteLine(
-        "  dataSize += pb::CodedOutputStream.Compute$0$SizeNoTag(element);",
-        capitalized_type_name(), number());
-    writer->WriteLine("}");
+    printer->Print(
+      variables_,
+      "foreach ($type_name$ element in $property_name$List) {\n"
+      "  dataSize += pb::CodedOutputStream.Compute$capitalized_type_name$SizeNoTag(element);\n"
+      "}\n");
   } else {
-    writer->WriteLine("dataSize = $0$ * $1$_.Count;", SimpleItoa(fixedSize), name());
+    printer->Print(
+      "dataSize = $size$ * $name$_.Count;\n",
+      "size", SimpleItoa(fixedSize), "name", name());
   }
-  writer->WriteLine("size += dataSize;");
+  printer->Print("size += dataSize;\n");
   int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type());
   if (descriptor_->is_packed()) {
-    writer->WriteLine("if ($0$_.Count != 0) {", name());
-    writer->WriteLine(
-        "  size += $0$ + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);",
-        SimpleItoa(tagSize));
-    writer->WriteLine("}");
+    printer->Print(
+      "if ($name$_.Count != 0) {\n"
+      "  size += $tag_size$ + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);\n"
+      "}\n",
+      "name", name(), "tag_size", SimpleItoa(tagSize));
   } else {
-    writer->WriteLine("size += $0$ * $1$_.Count;", SimpleItoa(tagSize), name());
+    printer->Print(
+      "size += $tag_size$ * $name$_.Count;\n",
+      "tag_size", SimpleItoa(tagSize), "name", name());
   }
   // cache the data size for packed fields.
   if (descriptor_->is_packed()) {
-    writer->WriteLine("$0$MemoizedSerializedSize = dataSize;", name());
+    printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n");
   }
-  writer->Outdent();
-  writer->WriteLine("}");
+  printer->Outdent();
+  printer->Print("}\n");
 }
 
-void RepeatedPrimitiveFieldGenerator::WriteHash(Writer* writer) {
-  writer->WriteLine("foreach($0$ i in $1$_)", type_name(), name());
-  writer->WriteLine("  hash ^= i.GetHashCode();");
+void RepeatedPrimitiveFieldGenerator::WriteHash(io::Printer* printer) {
+  printer->Print(
+    variables_,
+    "foreach($type_name$ i in $name$_)\n"
+    "  hash ^= i.GetHashCode();\n");
 }
-void RepeatedPrimitiveFieldGenerator::WriteEquals(Writer* writer) {
-  writer->WriteLine("if($0$_.Count != other.$0$_.Count) return false;", name());
-  writer->WriteLine("for(int ix=0; ix < $0$_.Count; ix++)", name());
-  writer->WriteLine("  if(!$0$_[ix].Equals(other.$0$_[ix])) return false;",
-                    name());
+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");
 }
-void RepeatedPrimitiveFieldGenerator::WriteToString(Writer* writer) {
-  writer->WriteLine("PrintField(\"$0$\", $1$_, writer);", descriptor_->name(),
-                    name());
+void RepeatedPrimitiveFieldGenerator::WriteToString(io::Printer* printer) {
+  printer->Print(variables_,
+    "PrintField(\"$descriptor_name$\", $name$_, writer);\n");
 }
 
 }  // namespace csharp

+ 10 - 10
src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h

@@ -48,17 +48,17 @@ class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase {
   RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
   ~RepeatedPrimitiveFieldGenerator();
 
-  virtual void GenerateMembers(Writer* writer);
-  virtual void GenerateBuilderMembers(Writer* writer);
-  virtual void GenerateMergingCode(Writer* writer);
-  virtual void GenerateBuildingCode(Writer* writer);
-  virtual void GenerateParsingCode(Writer* writer);
-  virtual void GenerateSerializationCode(Writer* writer);
-  virtual void GenerateSerializedSizeCode(Writer* writer);
+  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);
 
-  virtual void WriteHash(Writer* writer);
-  virtual void WriteEquals(Writer* writer);
-  virtual void WriteToString(Writer* writer);
+  virtual void WriteHash(io::Printer* printer);
+  virtual void WriteEquals(io::Printer* printer);
+  virtual void WriteToString(io::Printer* printer);
 
  private:
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);

+ 1 - 2
src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc

@@ -39,7 +39,6 @@
 
 #include <google/protobuf/compiler/csharp/csharp_source_generator_base.h>
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
-#include <google/protobuf/compiler/csharp/csharp_writer.h>
 
 namespace google {
 namespace protobuf {
@@ -61,7 +60,7 @@ SourceGeneratorBase::SourceGeneratorBase(const FileDescriptor* descriptor)
 SourceGeneratorBase::~SourceGeneratorBase() {
 }
 
-void SourceGeneratorBase::WriteGeneratedCodeAttributes(Writer* writer) {
+void SourceGeneratorBase::WriteGeneratedCodeAttributes(io::Printer* printer) {
   // This hook can be used to reintroduce generated code attributes in the future.
 }
 

+ 1 - 3
src/google/protobuf/compiler/csharp/csharp_source_generator_base.h

@@ -40,8 +40,6 @@ namespace protobuf {
 namespace compiler {
 namespace csharp {
 
-class Writer;
-
 class SourceGeneratorBase {
  protected:
   SourceGeneratorBase(const FileDescriptor* descriptor);
@@ -62,7 +60,7 @@ class SourceGeneratorBase {
     return runtimeSuffix_;
   }
 
-  void WriteGeneratedCodeAttributes(Writer* writer);
+  void WriteGeneratedCodeAttributes(io::Printer* printer);
 
  private:
   const FileDescriptor* descriptor_;

+ 127 - 122
src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc

@@ -42,7 +42,6 @@
 #include <google/protobuf/compiler/csharp/csharp_extension.h>
 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
 #include <google/protobuf/compiler/csharp/csharp_message.h>
-#include <google/protobuf/compiler/csharp/csharp_writer.h>
 
 namespace google {
 namespace protobuf {
@@ -60,218 +59,224 @@ UmbrellaClassGenerator::UmbrellaClassGenerator(const FileDescriptor* file)
 UmbrellaClassGenerator::~UmbrellaClassGenerator() {
 }
 
-void UmbrellaClassGenerator::Generate(Writer* writer) {
-  WriteIntroduction(writer);
-  WriteExtensionRegistration(writer);
+void UmbrellaClassGenerator::Generate(io::Printer* printer) {
+  WriteIntroduction(printer);
+  WriteExtensionRegistration(printer);
 
   // write children: Extensions
   if (file_->extension_count() > 0) {
-    writer->WriteLine("#region Extensions");
+    printer->Print("#region Extensions\n");
     for (int i = 0; i < file_->extension_count(); i++) {
       ExtensionGenerator extensionGenerator(file_->extension(i));
-      extensionGenerator.Generate(writer);
+      extensionGenerator.Generate(printer);
     }
-    writer->WriteLine("#endregion");
-    writer->WriteLine();
+    printer->Print("#endregion\n");
+    printer->Print("\n");
   }
 
-  writer->WriteLine("#region Static variables");
+  printer->Print("#region Static variables\n");
   for (int i = 0; i < file_->message_type_count(); i++) {
     MessageGenerator messageGenerator(file_->message_type(i));
-    messageGenerator.GenerateStaticVariables(writer);
+    messageGenerator.GenerateStaticVariables(printer);
   }
-  writer->WriteLine("#endregion");
+  printer->Print("#endregion\n");
   if (!use_lite_runtime()) {
-    WriteDescriptor(writer);
+    WriteDescriptor(printer);
   } else {
-    WriteLiteExtensions(writer);
+    WriteLiteExtensions(printer);
   }
   // Close the class declaration.
-  writer->Outdent();
-  writer->WriteLine("}");
+  printer->Outdent();
+  printer->Print("}\n");
 
   // Close the namespace around the umbrella class if defined
   if (!umbrellaNamespace_.empty()) {
-    writer->Outdent();
-    writer->WriteLine("}");
+    printer->Outdent();
+    printer->Print("}\n");
   }
 
   // write children: Enums
   if (file_->enum_type_count() > 0) {
-    writer->WriteLine("#region Enums");
+    printer->Print("#region Enums\n");
     for (int i = 0; i < file_->enum_type_count(); i++) {
       EnumGenerator enumGenerator(file_->enum_type(i));
-      enumGenerator.Generate(writer);
+      enumGenerator.Generate(printer);
     }
-    writer->WriteLine("#endregion");
-    writer->WriteLine();
+    printer->Print("#endregion\n");
+    printer->Print("\n");
   }
 
   // write children: Messages
   if (file_->message_type_count() > 0) {
-    writer->WriteLine("#region Messages");
+    printer->Print("#region Messages\n");
     for (int i = 0; i < file_->message_type_count(); i++) {
       MessageGenerator messageGenerator(file_->message_type(i));
-      messageGenerator.Generate(writer);
+      messageGenerator.Generate(printer);
     }
-    writer->WriteLine("#endregion");
-    writer->WriteLine();
+    printer->Print("#endregion\n");
+    printer->Print("\n");
   }
 
   // TODO(jtattermusch): add insertion point for services.
 
   if (!namespace_.empty()) {
-    writer->Outdent();
-    writer->WriteLine("}");
+    printer->Outdent();
+    printer->Print("}\n");
   }
-  writer->WriteLine();
-  writer->WriteLine("#endregion Designer generated code");
+  printer->Print("\n");
+  printer->Print("#endregion Designer generated code\n");
 }
 
-void UmbrellaClassGenerator::WriteIntroduction(Writer* writer) {
-  writer->WriteLine(
-      "// Generated by the protocol buffer compiler.  DO NOT EDIT!");
-  writer->WriteLine("// source: $0$", file_->name());
-  writer->WriteLine("#pragma warning disable 1591, 0612, 3021");
-  writer->WriteLine("#region Designer generated code");
-
-  writer->WriteLine();
-  writer->WriteLine("using pb = global::Google.ProtocolBuffers;");
-  writer->WriteLine("using pbc = global::Google.ProtocolBuffers.Collections;");
-  writer->WriteLine("using pbd = global::Google.ProtocolBuffers.Descriptors;");
-  writer->WriteLine("using scg = global::System.Collections.Generic;");
+void UmbrellaClassGenerator::WriteIntroduction(io::Printer* printer) {
+  printer->Print(
+    "// Generated by the protocol buffer compiler.  DO NOT EDIT!\n"
+    "// source: $file_name$\n"
+    "#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 scg = global::System.Collections.Generic;\n",
+    "file_name", file_->name());
 
   if (!namespace_.empty()) {
-    writer->WriteLine("namespace $0$ {", namespace_);
-    writer->Indent();
-    writer->WriteLine();
+    printer->Print("namespace $namespace$ {\n", "namespace", namespace_);
+    printer->Indent();
+    printer->Print("\n");
   }
 
   // Add the namespace around the umbrella class if defined
   if (!umbrellaNamespace_.empty()) {
-    writer->WriteLine("namespace $0$ {", umbrellaNamespace_);
-    writer->Indent();
-    writer->WriteLine();
+    printer->Print("namespace $umbrella_namespace$ {\n",
+                   "umbrella_namespace", umbrellaNamespace_);
+    printer->Indent();
+    printer->Print("\n");
   }
 
-  writer->WriteLine(
-      "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]");
-  WriteGeneratedCodeAttributes(writer);
-  writer->WriteLine("$0$ static partial class $1$ {", class_access_level(),
-                    umbrellaClassname_);
-  writer->WriteLine();
-  writer->Indent();
+  printer->Print(
+    "[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n");
+  WriteGeneratedCodeAttributes(printer);
+  printer->Print(
+    "$access_level$ static partial class $umbrella_class_name$ {\n"
+    "\n",
+    "access_level", class_access_level(),
+    "umbrella_class_name", umbrellaClassname_);
+  printer->Indent();
 }
 
-void UmbrellaClassGenerator::WriteExtensionRegistration(Writer* writer) {
-  writer->WriteLine("#region Extension registration");
-  writer->WriteLine(
-      "public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {");
-  writer->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(writer);
+    extensionGenerator.GenerateExtensionRegistrationCode(printer);
   }
   for (int i = 0; i < file_->message_type_count(); i++) {
     MessageGenerator messageGenerator(file_->message_type(i));
-    messageGenerator.GenerateExtensionRegistrationCode(writer);
+    messageGenerator.GenerateExtensionRegistrationCode(printer);
   }
-  writer->Outdent();
-  writer->WriteLine("}");
-  writer->WriteLine("#endregion");
+  printer->Outdent();
+  printer->Print("}\n");
+  printer->Print("#endregion\n");
 }
 
-void UmbrellaClassGenerator::WriteDescriptor(Writer* writer) {
-  writer->WriteLine("#region Descriptor");
-
-  writer->WriteLine("public static pbd::FileDescriptor Descriptor {");
-  writer->WriteLine("  get { return descriptor; }");
-  writer->WriteLine("}");
-  writer->WriteLine("private static pbd::FileDescriptor descriptor;");
-  writer->WriteLine();
-  writer->WriteLine("static $0$() {", umbrellaClassname_);
-  writer->Indent();
-  writer->WriteLine(
-      "byte[] descriptorData = global::System.Convert.FromBase64String(");
-  writer->Indent();
-  writer->Indent();
-  writer->WriteLine("string.Concat(");
-  writer->Indent();
+void UmbrellaClassGenerator::WriteDescriptor(io::Printer* printer) {
+  printer->Print(
+    "#region Descriptor\n"
+    "public static pbd::FileDescriptor Descriptor {\n"
+    "  get { return descriptor; }\n"
+    "}\n"
+    "private static pbd::FileDescriptor descriptor;\n"
+    "\n"
+    "static $umbrella_class_name$() {\n",
+    "umbrella_class_name", umbrellaClassname_);
+  printer->Indent();
+  printer->Print(
+    "byte[] descriptorData = global::System.Convert.FromBase64String(\n");
+  printer->Indent();
+  printer->Indent();
+  printer->Print("string.Concat(\n");
+  printer->Indent();
 
   // TODO(jonskeet): Consider a C#-escaping format here instead of just Base64.
   std::string base64 = FileDescriptorToBase64(file_);
   while (base64.size() > 60) {
-    writer->WriteLine("\"$0$\", ", base64.substr(0, 60));
+    printer->Print("\"$base64$\", \n", "base64", base64.substr(0, 60));
     base64 = base64.substr(60);
   }
-  writer->Outdent();
-  writer->WriteLine("\"$0$\"));", base64);
-  writer->Outdent();
-  writer->Outdent();
-  writer->WriteLine(
-      "pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {");
-  writer->Indent();
-  writer->WriteLine("descriptor = root;");
+  printer->Outdent();
+  printer->Print("\"$base64$\"));\n", "base64", base64);
+  printer->Outdent();
+  printer->Outdent();
+  printer->Print(
+    "pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {\n");
+  printer->Indent();
+  printer->Print("descriptor = root;\n");
   for (int i = 0; i < file_->message_type_count(); i++) {
     MessageGenerator messageGenerator(file_->message_type(i));
-    messageGenerator.GenerateStaticVariableInitializers(writer);
+    messageGenerator.GenerateStaticVariableInitializers(printer);
   }
   for (int i = 0; i < file_->extension_count(); i++) {
     ExtensionGenerator extensionGenerator(file_->extension(i));
-    extensionGenerator.GenerateStaticVariableInitializers(writer);
+    extensionGenerator.GenerateStaticVariableInitializers(printer);
   }
 
   if (uses_extensions()) {
     // Must construct an ExtensionRegistry containing all possible extensions
     // and return it.
-    writer->WriteLine(
-        "pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();");
-    writer->WriteLine("RegisterAllExtensions(registry);");
+    printer->Print(
+        "pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();\n");
+    printer->Print("RegisterAllExtensions(registry);\n");
     for (int i = 0; i < file_->dependency_count(); i++) {
-      writer->WriteLine("$0$.RegisterAllExtensions(registry);",
-                        GetFullUmbrellaClassName(file_->dependency(i)));
+      printer->Print("$dependency$.RegisterAllExtensions(registry);\n",
+		     "dependency", GetFullUmbrellaClassName(file_->dependency(i)));
     }
-    writer->WriteLine("return registry;");
+    printer->Print("return registry;\n");
   } else {
-    writer->WriteLine("return null;");
+    printer->Print("return null;\n");
   }
-  writer->Outdent();
-  writer->WriteLine("};");
+  printer->Outdent();
+  printer->Print("};\n");
 
   // -----------------------------------------------------------------
   // Invoke internalBuildGeneratedFileFrom() to build the file.
-  writer->WriteLine(
-      "pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,");
-  writer->WriteLine("    new pbd::FileDescriptor[] {");
+  printer->Print(
+      "pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,\n");
+  printer->Print("    new pbd::FileDescriptor[] {\n");
   for (int i = 0; i < file_->dependency_count(); i++) {
-    writer->WriteLine("    $0$.Descriptor, ",
-                      GetFullUmbrellaClassName(file_->dependency(i)));
+    printer->Print(
+      "    $full_umbrella_class_name$.Descriptor, \n",
+      "full_umbrella_class_name",
+      GetFullUmbrellaClassName(file_->dependency(i)));
   }
-  writer->WriteLine("    }, assigner);");
-  writer->Outdent();
-  writer->WriteLine("}");
-  writer->WriteLine("#endregion");
-  writer->WriteLine();
+  printer->Print("    }, assigner);\n");
+  printer->Outdent();
+  printer->Print("}\n");
+  printer->Print("#endregion\n\n");
 }
 
-void UmbrellaClassGenerator::WriteLiteExtensions(Writer* writer) {
-  writer->WriteLine("#region Extensions");
-  writer->WriteLine("internal static readonly object Descriptor;");
-  writer->WriteLine("static $0$() {", umbrellaClassname_);
-  writer->Indent();
-  writer->WriteLine("Descriptor = null;");
+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(writer);
+    messageGenerator.GenerateStaticVariableInitializers(printer);
   }
   for (int i = 0; i < file_->extension_count(); i++) {
     ExtensionGenerator extensionGenerator(file_->extension(i));
-    extensionGenerator.GenerateStaticVariableInitializers(writer);
+    extensionGenerator.GenerateStaticVariableInitializers(printer);
   }
-  writer->Outdent();
-  writer->WriteLine("}");
-  writer->WriteLine("#endregion");
-  writer->WriteLine();
+  printer->Outdent();
+  printer->Print("}\n");
+  printer->Print("#endregion\n\n");
 }
 
 bool UmbrellaClassGenerator::uses_extensions() {

+ 5 - 5
src/google/protobuf/compiler/csharp/csharp_umbrella_class.h

@@ -48,7 +48,7 @@ class UmbrellaClassGenerator : public SourceGeneratorBase {
   UmbrellaClassGenerator(const FileDescriptor* file);
   ~UmbrellaClassGenerator();
 
-  void Generate(Writer* write);
+  void Generate(io::Printer* printer);
 
  private:
   const FileDescriptor* file_;
@@ -57,10 +57,10 @@ class UmbrellaClassGenerator : public SourceGeneratorBase {
   std::string umbrellaClassname_;
   std::string umbrellaNamespace_;
 
-  void WriteIntroduction(Writer* writer);
-  void WriteExtensionRegistration(Writer* writer);
-  void WriteDescriptor(Writer* writer);
-  void WriteLiteExtensions(Writer* write);
+  void WriteIntroduction(io::Printer* printer);
+  void WriteExtensionRegistration(io::Printer* printer);
+  void WriteDescriptor(io::Printer* printer);
+  void WriteLiteExtensions(io::Printer* printer);
 
   bool uses_extensions();
 

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно