diff options
Diffstat (limited to 'src/google/protobuf/compiler/csharp')
12 files changed, 118 insertions, 78 deletions
diff --git a/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc b/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc index 636a76a0..a21dc0a4 100644 --- a/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc +++ b/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc @@ -56,7 +56,7 @@ void WriteDocCommentBodyImpl(io::Printer* printer, SourceLocation location) { // node of a summary element, not part of an attribute. comments = StringReplace(comments, "&", "&", true); comments = StringReplace(comments, "<", "<", true); - vector<string> lines = Split(comments, "\n", false /* skip_empty */); + std::vector<string> lines = Split(comments, "\n", false /* skip_empty */); // TODO: We really should work out which part to put in the summary and which to put in the remarks... // but that needs to be part of a bigger effort to understand the markdown better anyway. printer->Print("/// <summary>\n"); diff --git a/src/google/protobuf/compiler/csharp/csharp_enum.cc b/src/google/protobuf/compiler/csharp/csharp_enum.cc index 9759e3ef..32c71990 100644 --- a/src/google/protobuf/compiler/csharp/csharp_enum.cc +++ b/src/google/protobuf/compiler/csharp/csharp_enum.cc @@ -43,8 +43,6 @@ #include <google/protobuf/compiler/csharp/csharp_helpers.h> #include <google/protobuf/compiler/csharp/csharp_options.h> -using google::protobuf::internal::scoped_ptr; - namespace google { namespace protobuf { namespace compiler { diff --git a/src/google/protobuf/compiler/csharp/csharp_field_base.cc b/src/google/protobuf/compiler/csharp/csharp_field_base.cc index ecf29ece..7e737e47 100644 --- a/src/google/protobuf/compiler/csharp/csharp_field_base.cc +++ b/src/google/protobuf/compiler/csharp/csharp_field_base.cc @@ -46,8 +46,6 @@ #include <google/protobuf/compiler/csharp/csharp_helpers.h> #include <google/protobuf/compiler/csharp/csharp_names.h> -using google::protobuf::internal::scoped_ptr; - namespace google { namespace protobuf { namespace compiler { diff --git a/src/google/protobuf/compiler/csharp/csharp_generator.cc b/src/google/protobuf/compiler/csharp/csharp_generator.cc index c13ed65b..0c93fc29 100644 --- a/src/google/protobuf/compiler/csharp/csharp_generator.cc +++ b/src/google/protobuf/compiler/csharp/csharp_generator.cc @@ -44,8 +44,6 @@ #include <google/protobuf/compiler/csharp/csharp_options.h> #include <google/protobuf/compiler/csharp/csharp_reflection_class.h> -using google::protobuf::internal::scoped_ptr; - namespace google { namespace protobuf { namespace compiler { @@ -64,7 +62,7 @@ bool Generator::Generate( GeneratorContext* generator_context, string* error) const { - vector<pair<string, string> > options; + std::vector<std::pair<string, string> > options; ParseGeneratorParameter(parameter, &options); // We only support proto3 - but we make an exception for descriptor.proto. @@ -100,7 +98,7 @@ bool Generator::Generate( *error = filename_error; return false; } - scoped_ptr<io::ZeroCopyOutputStream> output( + std::unique_ptr<io::ZeroCopyOutputStream> output( generator_context->Open(filename)); io::Printer printer(output.get(), '$'); diff --git a/src/google/protobuf/compiler/csharp/csharp_helpers.cc b/src/google/protobuf/compiler/csharp/csharp_helpers.cc index 5bca1ffa..04b61074 100644 --- a/src/google/protobuf/compiler/csharp/csharp_helpers.cc +++ b/src/google/protobuf/compiler/csharp/csharp_helpers.cc @@ -169,7 +169,7 @@ std::string UnderscoresToCamelCase(const std::string& input, } } // Add a trailing "_" if the name should be altered. - if (input[input.size() - 1] == '#') { + if (input.size() > 0 && input[input.size() - 1] == '#') { result += '_'; } return result; diff --git a/src/google/protobuf/compiler/csharp/csharp_map_field.cc b/src/google/protobuf/compiler/csharp/csharp_map_field.cc index e6eac6ed..d58514ce 100644 --- a/src/google/protobuf/compiler/csharp/csharp_map_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_map_field.cc @@ -63,9 +63,9 @@ void MapFieldGenerator::GenerateMembers(io::Printer* printer) { descriptor_->message_type()->FindFieldByName("value"); variables_["key_type_name"] = type_name(key_descriptor); variables_["value_type_name"] = type_name(value_descriptor); - scoped_ptr<FieldGeneratorBase> key_generator( + std::unique_ptr<FieldGeneratorBase> key_generator( CreateFieldGenerator(key_descriptor, 1, this->options())); - scoped_ptr<FieldGeneratorBase> value_generator( + std::unique_ptr<FieldGeneratorBase> value_generator( CreateFieldGenerator(value_descriptor, 2, this->options())); printer->Print( diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc index ad9f8a16..8a4307f1 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message.cc @@ -49,8 +49,6 @@ #include <google/protobuf/compiler/csharp/csharp_message.h> #include <google/protobuf/compiler/csharp/csharp_names.h> -using google::protobuf::internal::scoped_ptr; - namespace google { namespace protobuf { namespace compiler { @@ -111,7 +109,7 @@ void MessageGenerator::Generate(io::Printer* printer) { WriteMessageDocComment(printer, descriptor_); AddDeprecatedFlag(printer); - + printer->Print( vars, "$access_level$ sealed partial class $class_name$ : pb::IMessage<$class_name$> {\n"); @@ -119,14 +117,17 @@ void MessageGenerator::Generate(io::Printer* printer) { // All static fields and properties printer->Print( - vars, - "private static readonly pb::MessageParser<$class_name$> _parser = new pb::MessageParser<$class_name$>(() => new $class_name$());\n"); + vars, + "private static readonly pb::MessageParser<$class_name$> _parser = new pb::MessageParser<$class_name$>(() => new $class_name$());\n"); + + printer->Print( + "private pb::UnknownFieldSet _unknownFields;\n"); WriteGeneratedCodeAttributes(printer); printer->Print( - vars, - "public static pb::MessageParser<$class_name$> Parser { get { return _parser; } }\n\n"); + vars, + "public static pb::MessageParser<$class_name$> Parser { get { return _parser; } }\n\n"); // Access the message descriptor via the relevant file descriptor or containing message descriptor. if (!descriptor_->containing_type()) { @@ -139,14 +140,14 @@ void MessageGenerator::Generate(io::Printer* printer) { WriteGeneratedCodeAttributes(printer); printer->Print( - vars, - "public static pbr::MessageDescriptor Descriptor {\n" - " get { return $descriptor_accessor$; }\n" - "}\n" - "\n"); + vars, + "public static pbr::MessageDescriptor Descriptor {\n" + " get { return $descriptor_accessor$; }\n" + "}\n" + "\n"); WriteGeneratedCodeAttributes(printer); printer->Print( - vars, + vars, "pbr::MessageDescriptor pb::IMessage.Descriptor {\n" " get { return Descriptor; }\n" "}\n" @@ -181,7 +182,7 @@ void MessageGenerator::Generate(io::Printer* printer) { "field_name", fieldDescriptor->name(), "field_constant_name", GetFieldConstantName(fieldDescriptor), "index", SimpleItoa(fieldDescriptor->number())); - scoped_ptr<FieldGeneratorBase> generator( + std::unique_ptr<FieldGeneratorBase> generator( CreateFieldGeneratorInternal(fieldDescriptor)); generator->GenerateMembers(printer); printer->Print("\n"); @@ -209,18 +210,18 @@ void MessageGenerator::Generate(io::Printer* printer) { printer->Print("}\n"); // TODO: Should we put the oneof .proto comments here? // It's unclear exactly where they should go. - printer->Print( - vars, - "private $property_name$OneofCase $name$Case_ = $property_name$OneofCase.None;\n"); - WriteGeneratedCodeAttributes(printer); - printer->Print( - vars, - "public $property_name$OneofCase $property_name$Case {\n" - " get { return $name$Case_; }\n" - "}\n\n"); - WriteGeneratedCodeAttributes(printer); - printer->Print( - vars, + printer->Print( + vars, + "private $property_name$OneofCase $name$Case_ = $property_name$OneofCase.None;\n"); + WriteGeneratedCodeAttributes(printer); + printer->Print( + vars, + "public $property_name$OneofCase $property_name$Case {\n" + " get { return $name$Case_; }\n" + "}\n\n"); + WriteGeneratedCodeAttributes(printer); + printer->Print( + vars, "public void Clear$property_name$() {\n" " $name$Case_ = $property_name$OneofCase.None;\n" " $name$_ = null;\n" @@ -290,7 +291,7 @@ void MessageGenerator::GenerateCloningCode(io::Printer* printer) { // Clone non-oneof fields first for (int i = 0; i < descriptor_->field_count(); i++) { if (!descriptor_->field(i)->containing_oneof()) { - scoped_ptr<FieldGeneratorBase> generator( + std::unique_ptr<FieldGeneratorBase> generator( CreateFieldGeneratorInternal(descriptor_->field(i))); generator->GenerateCloningCode(printer); } @@ -304,7 +305,7 @@ void MessageGenerator::GenerateCloningCode(io::Printer* printer) { 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)); + std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field)); vars["field_property_name"] = GetPropertyName(field); printer->Print( vars, @@ -317,6 +318,9 @@ void MessageGenerator::GenerateCloningCode(io::Printer* printer) { printer->Outdent(); printer->Print("}\n\n"); } + // Clone unknown fields + printer->Print( + "_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);\n"); printer->Outdent(); printer->Print("}\n\n"); @@ -337,15 +341,15 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { vars["class_name"] = class_name(); // Equality - WriteGeneratedCodeAttributes(printer); + WriteGeneratedCodeAttributes(printer); printer->Print( vars, "public override bool Equals(object other) {\n" " return Equals(other as $class_name$);\n" "}\n\n"); - WriteGeneratedCodeAttributes(printer); - printer->Print( - vars, + WriteGeneratedCodeAttributes(printer); + printer->Print( + vars, "public bool Equals($class_name$ other) {\n" " if (ReferenceEquals(other, null)) {\n" " return false;\n" @@ -355,7 +359,7 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { " }\n"); printer->Indent(); for (int i = 0; i < descriptor_->field_count(); i++) { - scoped_ptr<FieldGeneratorBase> generator( + std::unique_ptr<FieldGeneratorBase> generator( CreateFieldGeneratorInternal(descriptor_->field(i))); generator->WriteEquals(printer); } @@ -365,18 +369,18 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { } printer->Outdent(); printer->Print( - " return true;\n" + " return Equals(_unknownFields, other._unknownFields);\n" "}\n\n"); // GetHashCode // Start with a non-zero value to easily distinguish between null and "empty" messages. - WriteGeneratedCodeAttributes(printer); - printer->Print( + WriteGeneratedCodeAttributes(printer); + printer->Print( "public override int GetHashCode() {\n" " int hash = 1;\n"); printer->Indent(); for (int i = 0; i < descriptor_->field_count(); i++) { - scoped_ptr<FieldGeneratorBase> generator( + std::unique_ptr<FieldGeneratorBase> generator( CreateFieldGeneratorInternal(descriptor_->field(i))); generator->WriteHash(printer); } @@ -384,12 +388,16 @@ void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { printer->Print("hash ^= (int) $name$Case_;\n", "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false)); } - printer->Print("return hash;\n"); + printer->Print( + "if (_unknownFields != null) {\n" + " hash ^= _unknownFields.GetHashCode();\n" + "}\n" + "return hash;\n"); printer->Outdent(); printer->Print("}\n\n"); - WriteGeneratedCodeAttributes(printer); - printer->Print( + WriteGeneratedCodeAttributes(printer); + printer->Print( "public override string ToString() {\n" " return pb::JsonFormatter.ToDiagnosticString(this);\n" "}\n\n"); @@ -403,26 +411,38 @@ void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer) // Serialize all the fields for (int i = 0; i < fields_by_number().size(); i++) { - scoped_ptr<FieldGeneratorBase> generator( + std::unique_ptr<FieldGeneratorBase> generator( CreateFieldGeneratorInternal(fields_by_number()[i])); generator->GenerateSerializationCode(printer); } + // Serialize unknown fields + printer->Print( + "if (_unknownFields != null) {\n" + " _unknownFields.WriteTo(output);\n" + "}\n"); + // TODO(jonskeet): Memoize size of frozen messages? printer->Outdent(); printer->Print( - "}\n" - "\n"); + "}\n" + "\n"); WriteGeneratedCodeAttributes(printer); printer->Print( "public int CalculateSize() {\n"); printer->Indent(); printer->Print("int size = 0;\n"); for (int i = 0; i < descriptor_->field_count(); i++) { - scoped_ptr<FieldGeneratorBase> generator( + std::unique_ptr<FieldGeneratorBase> generator( CreateFieldGeneratorInternal(descriptor_->field(i))); generator->GenerateSerializedSizeCode(printer); } + + printer->Print( + "if (_unknownFields != null) {\n" + " size += _unknownFields.CalculateSize();\n" + "}\n"); + printer->Print("return size;\n"); printer->Outdent(); printer->Print("}\n\n"); @@ -447,7 +467,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { // Merge non-oneof fields for (int i = 0; i < descriptor_->field_count(); i++) { if (!descriptor_->field(i)->containing_oneof()) { - scoped_ptr<FieldGeneratorBase> generator( + std::unique_ptr<FieldGeneratorBase> generator( CreateFieldGeneratorInternal(descriptor_->field(i))); generator->GenerateMergingCode(printer); } @@ -465,7 +485,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { vars, "case $property_name$OneofCase.$field_property_name$:\n"); printer->Indent(); - scoped_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field)); + std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field)); generator->GenerateMergingCode(printer); printer->Print("break;\n"); printer->Outdent(); @@ -473,8 +493,14 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { printer->Outdent(); printer->Print("}\n\n"); } + // Merge unknown fields. + printer->Print( + "_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);\n"); + printer->Outdent(); printer->Print("}\n\n"); + + WriteGeneratedCodeAttributes(printer); printer->Print("public void MergeFrom(pb::CodedInputStream input) {\n"); printer->Indent(); @@ -486,14 +512,14 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { printer->Indent(); // Option messages need to store unknown fields so that options can be parsed later. if (IsDescriptorOptionMessage(descriptor_)) { - printer->Print( + printer->Print( "default:\n" " CustomOptions = CustomOptions.ReadOrSkipUnknownField(input);\n" " break;\n"); } else { printer->Print( "default:\n" - " input.SkipLastField();\n" // We're not storing the data, but we still need to consume it. + " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);\n" " break;\n"); } for (int i = 0; i < fields_by_number().size(); i++) { @@ -518,7 +544,7 @@ void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { printer->Print("case $tag$: {\n", "tag", SimpleItoa(tag)); printer->Indent(); - scoped_ptr<FieldGeneratorBase> generator( + std::unique_ptr<FieldGeneratorBase> generator( CreateFieldGeneratorInternal(field)); generator->GenerateParsingCode(printer); printer->Print("break;\n"); diff --git a/src/google/protobuf/compiler/csharp/csharp_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_message_field.cc index 59b7edfb..cf1b4dbf 100644 --- a/src/google/protobuf/compiler/csharp/csharp_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_message_field.cc @@ -133,7 +133,7 @@ void MessageFieldGenerator::WriteToString(io::Printer* printer) { void MessageFieldGenerator::GenerateCloningCode(io::Printer* printer) { printer->Print(variables_, - "$property_name$ = other.$has_property_check$ ? other.$property_name$.Clone() : null;\n"); + "$name$_ = other.$has_property_check$ ? other.$name$_.Clone() : null;\n"); } void MessageFieldGenerator::GenerateFreezingCode(io::Printer* printer) { diff --git a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc index 931adb4a..c3003e3d 100644 --- a/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_primitive_field.cc @@ -137,14 +137,22 @@ void PrimitiveFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { } void PrimitiveFieldGenerator::WriteHash(io::Printer* printer) { - printer->Print( - variables_, - "if ($has_property_check$) hash ^= $property_name$.GetHashCode();\n"); + const char *text = "if ($has_property_check$) hash ^= $property_name$.GetHashCode();\n"; + if (descriptor_->type() == FieldDescriptor::TYPE_FLOAT) { + text = "if ($has_property_check$) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode($property_name$);\n"; + } else if (descriptor_->type() == FieldDescriptor::TYPE_DOUBLE) { + text = "if ($has_property_check$) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode($property_name$);\n"; + } + printer->Print(variables_, text); } void PrimitiveFieldGenerator::WriteEquals(io::Printer* printer) { - printer->Print( - variables_, - "if ($property_name$ != other.$property_name$) return false;\n"); + const char *text = "if ($property_name$ != other.$property_name$) return false;\n"; + if (descriptor_->type() == FieldDescriptor::TYPE_FLOAT) { + text = "if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals($property_name$, other.$property_name$)) return false;\n"; + } else if (descriptor_->type() == FieldDescriptor::TYPE_DOUBLE) { + text = "if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals($property_name$, other.$property_name$)) return false;\n"; + } + printer->Print(variables_, text); } void PrimitiveFieldGenerator::WriteToString(io::Printer* printer) { printer->Print( diff --git a/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc b/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc index bac9aef7..5ddd616e 100644 --- a/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc +++ b/src/google/protobuf/compiler/csharp/csharp_reflection_class.cc @@ -104,8 +104,10 @@ void ReflectionClassGenerator::Generate(io::Printer* printer) { void ReflectionClassGenerator::WriteIntroduction(io::Printer* printer) { printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "// source: $file_name$\n" + "// <auto-generated>\n" + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $file_name$\n" + "// </auto-generated>\n" "#pragma warning disable 1591, 0612, 3021\n" "#region Designer generated code\n" "\n" diff --git a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc index 8fa0b050..90af569c 100644 --- a/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc @@ -66,11 +66,11 @@ void RepeatedMessageFieldGenerator::GenerateMembers(io::Printer* printer) { // "create single field generator for this repeated field" // function, but it doesn't seem worth it for just this. if (IsWrapperType(descriptor_)) { - scoped_ptr<FieldGeneratorBase> single_generator( + std::unique_ptr<FieldGeneratorBase> single_generator( new WrapperFieldGenerator(descriptor_, fieldOrdinal_, this->options())); single_generator->GenerateCodecCode(printer); } else { - scoped_ptr<FieldGeneratorBase> single_generator( + std::unique_ptr<FieldGeneratorBase> single_generator( new MessageFieldGenerator(descriptor_, fieldOrdinal_, this->options())); single_generator->GenerateCodecCode(printer); } diff --git a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc index 997969a0..047edf73 100644 --- a/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc +++ b/src/google/protobuf/compiler/csharp/csharp_wrapper_field.cc @@ -120,15 +120,25 @@ void WrapperFieldGenerator::GenerateSerializedSizeCode(io::Printer* printer) { } void WrapperFieldGenerator::WriteHash(io::Printer* printer) { - printer->Print( - variables_, - "if ($has_property_check$) hash ^= $property_name$.GetHashCode();\n"); + const char *text = "if ($has_property_check$) hash ^= $property_name$.GetHashCode();\n"; + if (descriptor_->message_type()->field(0)->type() == FieldDescriptor::TYPE_FLOAT) { + text = "if ($has_property_check$) hash ^= pbc::ProtobufEqualityComparers.BitwiseNullableSingleEqualityComparer.GetHashCode($property_name$);\n"; + } + else if (descriptor_->message_type()->field(0)->type() == FieldDescriptor::TYPE_DOUBLE) { + text = "if ($has_property_check$) hash ^= pbc::ProtobufEqualityComparers.BitwiseNullableDoubleEqualityComparer.GetHashCode($property_name$);\n"; + } + printer->Print(variables_, text); } void WrapperFieldGenerator::WriteEquals(io::Printer* printer) { - printer->Print( - variables_, - "if ($property_name$ != other.$property_name$) return false;\n"); + const char *text = "if ($property_name$ != other.$property_name$) return false;\n"; + if (descriptor_->message_type()->field(0)->type() == FieldDescriptor::TYPE_FLOAT) { + text = "if (!pbc::ProtobufEqualityComparers.BitwiseNullableSingleEqualityComparer.Equals($property_name$, other.$property_name$)) return false;\n"; + } + else if (descriptor_->message_type()->field(0)->type() == FieldDescriptor::TYPE_DOUBLE) { + text = "if (!pbc::ProtobufEqualityComparers.BitwiseNullableDoubleEqualityComparer.Equals($property_name$, other.$property_name$)) return false;\n"; + } + printer->Print(variables_, text); } void WrapperFieldGenerator::WriteToString(io::Printer* printer) { |