aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Jie Luo <anandolee@gmail.com>2015-05-29 17:19:46 -0700
committerGravatar Jie Luo <anandolee@gmail.com>2015-05-29 17:19:46 -0700
commit802e1848ada7d95e867b178314ee89629680c771 (patch)
treed33bc7c6b42955601e290909e47bcb273292b30d /src
parent252daef02beb27dfb271af8c191102bd24ffd3e3 (diff)
parentf7b417ddfe63cb4d39775e5fd4560894cc547d65 (diff)
Merge pull request #404 from anandolee/master
Add oneof support for c#
Diffstat (limited to 'src')
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_enum_field.cc117
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_enum_field.h18
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_field_base.cc8
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_field_base.h2
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_helpers.cc18
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_message.cc95
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_message_field.cc118
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_message_field.h18
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_primitive_field.cc104
-rw-r--r--src/google/protobuf/compiler/csharp/csharp_primitive_field.h18
10 files changed, 463 insertions, 53 deletions
diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
index 34d1c5c6..a2d8a98b 100644
--- a/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_enum_field.cc
@@ -49,6 +49,11 @@ namespace csharp {
EnumFieldGenerator::EnumFieldGenerator(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();
+ }
}
EnumFieldGenerator::~EnumFieldGenerator() {
@@ -122,8 +127,7 @@ void EnumFieldGenerator::GenerateBuildingCode(Writer* writer) {
void EnumFieldGenerator::GenerateParsingCode(Writer* writer) {
writer->WriteLine("object unknown;");
- writer->WriteLine("if(input.ReadEnum(ref result.$0$_, out unknown)) {",
- name());
+ writer->WriteLine("if(input.ReadEnum(ref result.$0$_, out unknown)) {", name());
if (SupportFieldPresence(descriptor_->file())) {
writer->WriteLine(" result.has$0$ = true;", property_name());
}
@@ -141,11 +145,7 @@ void EnumFieldGenerator::GenerateParsingCode(Writer* writer) {
}
void EnumFieldGenerator::GenerateSerializationCode(Writer* writer) {
- if (SupportFieldPresence(descriptor_->file())) {
- writer->WriteLine("if (has$0$) {", property_name());
- } else {
- writer->WriteLine("if ($0$ != $1$) {", property_name(), default_value());
- }
+ writer->WriteLine("if ($0$) {", has_property_check);
writer->WriteLine(
" output.WriteEnum($0$, field_names[$2$], (int) $1$, $1$);", number(),
property_name(), field_ordinal());
@@ -153,11 +153,7 @@ void EnumFieldGenerator::GenerateSerializationCode(Writer* writer) {
}
void EnumFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
- if (SupportFieldPresence(descriptor_->file())) {
- writer->WriteLine("if (has$0$) {", property_name());
- } else {
- writer->WriteLine("if ($0$ != $1$) {", property_name(), default_value());
- }
+ writer->WriteLine("if ($0$) {", has_property_check);
writer->WriteLine(
" size += pb::CodedOutputStream.ComputeEnumSize($0$, (int) $1$);",
number(), property_name());
@@ -165,11 +161,7 @@ void EnumFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
}
void EnumFieldGenerator::WriteHash(Writer* writer) {
- if (SupportFieldPresence(descriptor_->file())) {
- writer->WriteLine("if (has$0$) {", property_name());
- } else {
- writer->WriteLine("if ($0$ != $1$) {", property_name(), default_value());
- }
+ writer->WriteLine("if ($0$) {", has_property_check);
writer->WriteLine(" hash ^= $0$_.GetHashCode();", name());
writer->WriteLine("}");
}
@@ -184,13 +176,94 @@ void EnumFieldGenerator::WriteEquals(Writer* writer) {
}
}
void EnumFieldGenerator::WriteToString(Writer* writer) {
+ writer->WriteLine("PrintField(\"$0$\", $1$, $2$_, writer);",
+ descriptor_->name(), has_property_check, name());
+}
+
+EnumOneofFieldGenerator::EnumOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal)
+ : EnumFieldGenerator(descriptor, fieldOrdinal) {
+ has_property_check = oneof_name() + "Case_ == " + oneof_property_name() +
+ "OneofCase." + property_name();
+}
+
+EnumOneofFieldGenerator::~EnumOneofFieldGenerator() {
+}
+
+void EnumOneofFieldGenerator::GenerateMembers(Writer* writer) {
+ AddDeprecatedFlag(writer);
if (SupportFieldPresence(descriptor_->file())) {
- writer->WriteLine("PrintField(\"$0$\", has$1$, $2$_, writer);",
- descriptor_->name(), property_name(), name());
- } else {
- writer->WriteLine("PrintField(\"$0$\", $1$_, writer);",
- descriptor_->name(), name());
+ writer->WriteLine("public bool Has$0$ {", property_name());
+ writer->WriteLine(" get { return $0$; }", has_property_check);
+ writer->WriteLine("}");
+ }
+ 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("}");
+}
+
+void EnumOneofFieldGenerator::GenerateBuilderMembers(Writer* writer) {
+ AddDeprecatedFlag(writer);
+ if (SupportFieldPresence(descriptor_->file())) {
+ writer->WriteLine("public bool Has$0$ {", property_name());
+ writer->WriteLine(" get { return result.$0$; }", has_property_check);
+ writer->WriteLine("}");
}
+ 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());
+ 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 EnumOneofFieldGenerator::WriteEquals(Writer* writer) {
+ writer->WriteLine("if (!$0$.Equals(other.$0$)) return false;", property_name());
+}
+void EnumOneofFieldGenerator::WriteToString(Writer* writer) {
+ writer->WriteLine("PrintField(\"$0$\", $1$, $2$_, writer);",
+ descriptor_->name(), has_property_check, oneof_name());
+}
+
+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) {");
+ 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());
+ }
+ writer->WriteLine("}");
}
} // namespace csharp
diff --git a/src/google/protobuf/compiler/csharp/csharp_enum_field.h b/src/google/protobuf/compiler/csharp/csharp_enum_field.h
index b21fa9dc..565287b2 100644
--- a/src/google/protobuf/compiler/csharp/csharp_enum_field.h
+++ b/src/google/protobuf/compiler/csharp/csharp_enum_field.h
@@ -60,10 +60,28 @@ class EnumFieldGenerator : public FieldGeneratorBase {
virtual void WriteEquals(Writer* writer);
virtual void WriteToString(Writer* writer);
+ protected:
+ string has_property_check;
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
};
+class EnumOneofFieldGenerator : public EnumFieldGenerator {
+ public:
+ EnumOneofFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
+ ~EnumOneofFieldGenerator();
+
+ 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);
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumOneofFieldGenerator);
+};
+
} // namespace csharp
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc
index 145b6743..dfc803e6 100644
--- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc
@@ -81,6 +81,14 @@ void FieldGeneratorBase::AddPublicMemberAttributes(Writer* writer) {
AddDeprecatedFlag(writer);
}
+std::string FieldGeneratorBase::oneof_property_name() {
+ return UnderscoresToCamelCase(descriptor_->containing_oneof()->name(), true);
+}
+
+std::string FieldGeneratorBase::oneof_name() {
+ return UnderscoresToCamelCase(descriptor_->containing_oneof()->name(), false);
+}
+
std::string FieldGeneratorBase::property_name() {
return GetPropertyName(descriptor_);
}
diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.h b/src/google/protobuf/compiler/csharp/csharp_field_base.h
index 311f7a6e..312da12b 100644
--- a/src/google/protobuf/compiler/csharp/csharp_field_base.h
+++ b/src/google/protobuf/compiler/csharp/csharp_field_base.h
@@ -71,6 +71,8 @@ class FieldGeneratorBase : public SourceGeneratorBase {
void AddPublicMemberAttributes(Writer* writer);
+ std::string oneof_property_name();
+ std::string oneof_name();
std::string property_name();
std::string name();
std::string type_name();
diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc
index 4580b7be..76e2c850 100644
--- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc
@@ -346,19 +346,31 @@ FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor,
if (descriptor->is_repeated()) {
return new RepeatedMessageFieldGenerator(descriptor, fieldOrdinal);
} else {
- return new MessageFieldGenerator(descriptor, fieldOrdinal);
+ if (descriptor->containing_oneof()) {
+ return new MessageOneofFieldGenerator(descriptor, fieldOrdinal);
+ } else {
+ return new MessageFieldGenerator(descriptor, fieldOrdinal);
+ }
}
case FieldDescriptor::TYPE_ENUM:
if (descriptor->is_repeated()) {
return new RepeatedEnumFieldGenerator(descriptor, fieldOrdinal);
} else {
- return new EnumFieldGenerator(descriptor, fieldOrdinal);
+ if (descriptor->containing_oneof()) {
+ return new EnumOneofFieldGenerator(descriptor, fieldOrdinal);
+ } else {
+ return new EnumFieldGenerator(descriptor, fieldOrdinal);
+ }
}
default:
if (descriptor->is_repeated()) {
return new RepeatedPrimitiveFieldGenerator(descriptor, fieldOrdinal);
} else {
- return new PrimitiveFieldGenerator(descriptor, fieldOrdinal);
+ if (descriptor->containing_oneof()) {
+ return new PrimitiveOneofFieldGenerator(descriptor, fieldOrdinal);
+ } else {
+ return new PrimitiveFieldGenerator(descriptor, fieldOrdinal);
+ }
}
}
}
diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc
index 96f7c17c..22681235 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message.cc
@@ -156,6 +156,10 @@ void MessageGenerator::GenerateStaticVariableInitializers(Writer* writer) {
for (int i = 0; i < descriptor_->field_count(); i++) {
writer->Write("\"$0$\", ", GetPropertyName(descriptor_->field(i)));
}
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ writer->Write("\"$0$\", ",
+ UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
+ }
writer->WriteLine("});");
}
@@ -260,6 +264,31 @@ void MessageGenerator::Generate(Writer* writer) {
writer->WriteLine();
}
+ // oneof
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ string name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
+ string property_name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true);
+ writer->WriteLine("private object $0$_;", name);
+ writer->WriteLine("public enum $0$OneofCase {", property_name);
+ writer->Indent();
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+ writer->WriteLine("$0$ = $1$,",
+ GetPropertyName(field),
+ SimpleItoa(field->number()));
+ }
+ writer->WriteLine("None = 0,");
+ writer->Outdent();
+ writer->WriteLine("}");
+ writer->WriteLine("private $0$OneofCase $1$Case_ = $0$OneofCase.None;",
+ property_name, name);
+ writer->WriteLine("public $0$OneofCase $0$Case {", property_name);
+ writer->WriteLine(" get { return $0$Case_; }", name);
+ writer->WriteLine("}");
+ writer->WriteLine();
+ }
+
+ // Fields
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
@@ -310,9 +339,19 @@ void MessageGenerator::GenerateLiteRuntimeMethods(Writer* writer) {
writer->Indent();
writer->WriteLine("int hash = GetType().GetHashCode();");
for (int i = 0; i < descriptor_->field_count(); i++) {
- scoped_ptr<FieldGeneratorBase> generator(
- CreateFieldGeneratorInternal(descriptor_->field(i)));
- generator->WriteHash(writer);
+ const FieldDescriptor* field = descriptor_->field(i);
+ if (field->containing_oneof() == NULL) {
+ scoped_ptr<FieldGeneratorBase> generator(
+ CreateFieldGeneratorInternal(field));
+ generator->WriteHash(writer);
+ }
+ }
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ string name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
+ string property_name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true);
+ writer->WriteLine("if ($0$Case_ != $1$OneofCase.None) {", name, property_name);
+ writer->WriteLine(" hash ^= $0$_.GetHashCode();", name);
+ writer->WriteLine("}");
}
if (callbase) {
writer->WriteLine("hash ^= base.GetHashCode();");
@@ -577,6 +616,23 @@ void MessageGenerator::GenerateBuilder(Writer* writer) {
// No field comment :(
generator->GenerateBuilderMembers(writer);
}
+
+ // oneof
+ for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+ writer->WriteLine();
+ string name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
+ string property_name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true);
+ writer->WriteLine("public $0$OneofCase $0$Case {", property_name);
+ writer->WriteLine(" get { return result.$0$Case_; }", name);
+ writer->WriteLine("}");
+ writer->WriteLine("public Builder Clear$0$() {", property_name);
+ writer->WriteLine(" PrepareBuilder();");
+ writer->WriteLine(" result.$0$_ = null;", name);
+ writer->WriteLine(" result.$0$Case_ = $1$OneofCase.None;", name, property_name);
+ writer->WriteLine(" return this;");
+ writer->WriteLine("}");
+ }
+
writer->Outdent();
writer->WriteLine("}");
}
@@ -675,10 +731,37 @@ void MessageGenerator::GenerateCommonBuilderMethods(Writer* writer) {
full_class_name());
writer->WriteLine("PrepareBuilder();");
for (int i = 0; i < descriptor_->field_count(); i++) {
- scoped_ptr<FieldGeneratorBase> generator(
- CreateFieldGeneratorInternal(descriptor_->field(i)));
- generator->GenerateMergingCode(writer);
+ if (!descriptor_->field(i)->containing_oneof()) {
+ scoped_ptr<FieldGeneratorBase> generator(
+ CreateFieldGeneratorInternal(descriptor_->field(i)));
+ generator->GenerateMergingCode(writer);
+ }
+ }
+
+ // Merge oneof fields
+ for (int i = 0; i < descriptor_->oneof_decl_count(); ++i) {
+ string name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false);
+ string property_name = UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true);
+ writer->WriteLine("switch (other.$0$Case) {", property_name);
+ writer->Indent();
+ for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
+ const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
+ writer->WriteLine("case $0$OneofCase.$1$: {",
+ property_name, GetPropertyName(field));
+ if (field->type() == FieldDescriptor::TYPE_GROUP ||
+ field->type() == FieldDescriptor::TYPE_MESSAGE) {
+ writer->WriteLine(" Merge$0$(other.$0$);", GetPropertyName(field));
+ } else {
+ writer->WriteLine(" Set$0$(other.$0$);", GetPropertyName(field));
+ }
+ writer->WriteLine(" break;");
+ writer->WriteLine("}");
+ }
+ writer->WriteLine("case $0$OneofCase.None: { break; }", property_name);
+ writer->Outdent();
+ writer->WriteLine("}");
}
+
// if message type has extensions
if (descriptor_->extension_range_count() > 0) {
writer->WriteLine(" this.MergeExtensionFields(other);");
diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc
index 10464c4b..b533d735 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc
@@ -50,6 +50,7 @@ namespace csharp {
MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal)
: FieldGeneratorBase(descriptor, fieldOrdinal) {
+ has_property_check = "has" + property_name();
}
MessageFieldGenerator::~MessageFieldGenerator() {
@@ -149,7 +150,7 @@ void MessageFieldGenerator::GenerateParsingCode(Writer* writer) {
}
void MessageFieldGenerator::GenerateSerializationCode(Writer* writer) {
- writer->WriteLine("if (has$0$) {", property_name());
+ 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());
@@ -157,7 +158,7 @@ void MessageFieldGenerator::GenerateSerializationCode(Writer* writer) {
}
void MessageFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
- writer->WriteLine("if (has$0$) {", property_name());
+ 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("}");
@@ -177,6 +178,119 @@ void MessageFieldGenerator::WriteToString(Writer* writer) {
property_name(), name(), GetFieldName(descriptor_));
}
+MessageOneofFieldGenerator::MessageOneofFieldGenerator(const FieldDescriptor* descriptor,
+ int fieldOrdinal)
+ : MessageFieldGenerator(descriptor, fieldOrdinal) {
+ has_property_check = oneof_name() + "Case_ == " + oneof_property_name() +
+ "OneofCase." + property_name();
+}
+
+MessageOneofFieldGenerator::~MessageOneofFieldGenerator() {
+
+}
+
+void MessageOneofFieldGenerator::GenerateMembers(Writer* writer) {
+ 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(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("}");
+}
+
+void MessageOneofFieldGenerator::GenerateBuilderMembers(Writer* writer) {
+ 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(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("}");
+}
+
+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("}");
+
+ if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
+ writer->WriteLine("input.ReadGroup($0$, subBuilder, extensionRegistry);",
+ number());
+ } else {
+ writer->WriteLine("input.ReadMessage(subBuilder, extensionRegistry);");
+ }
+ writer->WriteLine("result.$0$_ = subBuilder.BuildPartial();", oneof_name());
+ writer->WriteLine("result.$0$Case_ = $1$OneofCase.$2$;",
+ oneof_name(), oneof_property_name(), property_name());
+}
+
+void MessageOneofFieldGenerator::WriteEquals(Writer* writer) {
+ writer->WriteLine("if (!$0$.Equals(other.$0$)) return false;", property_name());
+}
+void MessageOneofFieldGenerator::WriteToString(Writer* writer) {
+ writer->WriteLine("PrintField(\"$0$\", $1$, $2$_, writer);",
+ descriptor_->name(), has_property_check, oneof_name());
+}
+
} // namespace csharp
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.h b/src/google/protobuf/compiler/csharp/csharp_message_field.h
index 48bf8be5..d455ade5 100644
--- a/src/google/protobuf/compiler/csharp/csharp_message_field.h
+++ b/src/google/protobuf/compiler/csharp/csharp_message_field.h
@@ -60,10 +60,28 @@ class MessageFieldGenerator : public FieldGeneratorBase {
virtual void WriteEquals(Writer* writer);
virtual void WriteToString(Writer* writer);
+ protected:
+ string has_property_check;
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
};
+class MessageOneofFieldGenerator : public MessageFieldGenerator {
+ public:
+ 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);
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageOneofFieldGenerator);
+};
+
} // namespace csharp
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
index a193afda..a54edfe3 100644
--- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
+++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
@@ -50,6 +50,11 @@ 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() {
@@ -133,11 +138,7 @@ void PrimitiveFieldGenerator::GenerateParsingCode(Writer* writer) {
}
void PrimitiveFieldGenerator::GenerateSerializationCode(Writer* writer) {
- if (SupportFieldPresence(descriptor_->file())) {
- writer->WriteLine("if (has$0$) {", property_name());
- } else {
- writer->WriteLine("if ($0$ != $1$) {", property_name(), default_value());
- }
+ 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());
@@ -145,22 +146,14 @@ void PrimitiveFieldGenerator::GenerateSerializationCode(Writer* writer) {
}
void PrimitiveFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
- if (SupportFieldPresence(descriptor_->file())) {
- writer->WriteLine("if (has$0$) {", property_name());
- } else {
- writer->WriteLine("if ($0$ != $1$) {", property_name(), default_value());
- }
+ 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::WriteHash(Writer* writer) {
- if (SupportFieldPresence(descriptor_->file())) {
- writer->WriteLine("if (has$0$) {", property_name());
- } else {
- writer->WriteLine("if ($0$ != $1$) {", property_name(), default_value());
- }
+ writer->WriteLine("if ($0$) {", has_property_check);
writer->WriteLine(" hash ^= $0$_.GetHashCode();", name());
writer->WriteLine("}");
}
@@ -175,13 +168,84 @@ void PrimitiveFieldGenerator::WriteEquals(Writer* writer) {
}
}
void PrimitiveFieldGenerator::WriteToString(Writer* writer) {
+ writer->WriteLine("PrintField(\"$0$\", $1$, $2$_, writer);",
+ descriptor_->name(), has_property_check, name());
+}
+
+PrimitiveOneofFieldGenerator::PrimitiveOneofFieldGenerator(
+ const FieldDescriptor* descriptor, int fieldOrdinal)
+ : PrimitiveFieldGenerator(descriptor, fieldOrdinal) {
+ has_property_check = oneof_name() + "Case_ == " + oneof_property_name() +
+ "OneofCase." + property_name();
+}
+
+PrimitiveOneofFieldGenerator::~PrimitiveOneofFieldGenerator() {
+}
+
+void PrimitiveOneofFieldGenerator::GenerateMembers(Writer* writer) {
+ AddDeprecatedFlag(writer);
if (SupportFieldPresence(descriptor_->file())) {
- writer->WriteLine("PrintField(\"$0$\", has$1$, $2$_, writer);",
- descriptor_->name(), property_name(), name());
- } else {
- writer->WriteLine("PrintField(\"$0$\", $1$_, writer);",
- descriptor_->name(), name());
+ writer->WriteLine("public bool Has$0$ {", property_name());
+ writer->WriteLine(" get { return $0$; }", has_property_check);
+ writer->WriteLine("}");
}
+ 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("}");
+}
+
+void PrimitiveOneofFieldGenerator::GenerateBuilderMembers(Writer* writer) {
+ AddDeprecatedFlag(writer);
+ if (SupportFieldPresence(descriptor_->file())) {
+ writer->WriteLine("public bool Has$0$ {", property_name());
+ writer->WriteLine(" get { return result.$0$; }", has_property_check);
+ writer->WriteLine("}");
+ }
+ 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("}");
}
} // namespace csharp
diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.h b/src/google/protobuf/compiler/csharp/csharp_primitive_field.h
index fb27ab43..ecc6ed91 100644
--- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.h
+++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.h
@@ -60,10 +60,28 @@ class PrimitiveFieldGenerator : public FieldGeneratorBase {
virtual void WriteEquals(Writer* writer);
virtual void WriteToString(Writer* writer);
+ protected:
+ string has_property_check;
+
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
};
+class PrimitiveOneofFieldGenerator : public PrimitiveFieldGenerator {
+ public:
+ 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);
+
+ private:
+ GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveOneofFieldGenerator);
+};
+
} // namespace csharp
} // namespace compiler
} // namespace protobuf