diff options
author | Jon Skeet <jonskeet@google.com> | 2015-06-23 11:54:19 +0100 |
---|---|---|
committer | Jon Skeet <jonskeet@google.com> | 2015-06-23 12:42:20 +0100 |
commit | 6c1fe6ea3e4e3915fc4164c43230210f9a0ac24f (patch) | |
tree | 3acd6ea7eebd05c6e12958ec3cf901d098ad9b14 /src/google/protobuf/compiler/csharp/csharp_message.cc | |
parent | 45b70328f218dc2b3e20191c2cfa92872ef10d04 (diff) |
Implement Clone.
Fixes issue #527.
Diffstat (limited to 'src/google/protobuf/compiler/csharp/csharp_message.cc')
-rw-r--r-- | src/google/protobuf/compiler/csharp/csharp_message.cc | 59 |
1 files changed, 51 insertions, 8 deletions
diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc index aca68fb7..32d0a82d 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -179,7 +179,7 @@ void MessageGenerator::Generate(io::Printer* printer) { WriteGeneratedCodeAttributes(printer); printer->Print( vars, - "$access_level$ sealed partial class $class_name$ : pb::IMessage<$class_name$>, global::System.IEquatable<$class_name$> {\n"); + "$access_level$ sealed partial class $class_name$ : pb::IMessage<$class_name$>, global::System.IEquatable<$class_name$>, pb::IDeepCloneable<$class_name$> {\n"); printer->Indent(); // All static fields and properties @@ -213,16 +213,12 @@ void MessageGenerator::Generate(io::Printer* printer) { "}\n" "\n"); - // Constructors + // Parameterless constructor printer->Print( vars, - "public $class_name$() { }\n"); // Public parameterless ctor. + "public $class_name$() { }\n\n"); - printer->Print( - vars, - "public $class_name$($class_name$ other) {\n" - " MergeFrom(other);\n" - "}\n"); // Merge ctor. + GenerateCloningCode(printer); // Fields/properties for (int i = 0; i < descriptor_->field_count(); i++) { @@ -303,6 +299,53 @@ void MessageGenerator::Generate(io::Printer* printer) { } +void MessageGenerator::GenerateCloningCode(io::Printer* printer) { + map<string, string> vars; + vars["class_name"] = class_name(); + printer->Print( + vars, + "public $class_name$($class_name$ other) {\n"); + printer->Indent(); + // Clone non-oneof fields first + for (int i = 0; i < descriptor_->field_count(); i++) { + if (!descriptor_->field(i)->containing_oneof()) { + scoped_ptr<FieldGeneratorBase> generator( + CreateFieldGeneratorInternal(descriptor_->field(i))); + generator->GenerateCloningCode(printer); + } + } + // Clone just the right field for each oneof + for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) { + vars["name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false); + vars["property_name"] = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true); + printer->Print(vars, "switch (other.$property_name$Case) {\n"); + printer->Indent(); + for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { + const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); + scoped_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field)); + vars["field_property_name"] = GetPropertyName(field); + printer->Print( + vars, + "case $property_name$OneofCase.$field_property_name$:\n"); + printer->Indent(); + generator->GenerateCloningCode(printer); + printer->Print("break;\n"); + printer->Outdent(); + } + printer->Outdent(); + printer->Print("}\n\n"); + } + + printer->Outdent(); + printer->Print("}\n\n"); + + printer->Print( + vars, + "public $class_name$ Clone() {\n" + " return new $class_name$(this);\n" + "}\n\n"); +} + void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { map<string, string> vars; vars["class_name"] = class_name(); |