aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/compiler/csharp/csharp_message.cc
diff options
context:
space:
mode:
authorGravatar Jon Skeet <jonskeet@google.com>2015-06-23 11:54:19 +0100
committerGravatar Jon Skeet <jonskeet@google.com>2015-06-23 12:42:20 +0100
commit6c1fe6ea3e4e3915fc4164c43230210f9a0ac24f (patch)
tree3acd6ea7eebd05c6e12958ec3cf901d098ad9b14 /src/google/protobuf/compiler/csharp/csharp_message.cc
parent45b70328f218dc2b3e20191c2cfa92872ef10d04 (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.cc59
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();