diff options
Diffstat (limited to 'src/google/protobuf/compiler/csharp/csharp_message.cc')
-rw-r--r-- | src/google/protobuf/compiler/csharp/csharp_message.cc | 528 |
1 files changed, 0 insertions, 528 deletions
diff --git a/src/google/protobuf/compiler/csharp/csharp_message.cc b/src/google/protobuf/compiler/csharp/csharp_message.cc deleted file mode 100644 index ed744854..00000000 --- a/src/google/protobuf/compiler/csharp/csharp_message.cc +++ /dev/null @@ -1,528 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include <sstream> -#include <algorithm> -#include <map> - -#include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/compiler/plugin.h> -#include <google/protobuf/descriptor.h> -#include <google/protobuf/descriptor.pb.h> -#include <google/protobuf/io/printer.h> -#include <google/protobuf/io/zero_copy_stream.h> -#include <google/protobuf/stubs/strutil.h> -#include <google/protobuf/wire_format.h> -#include <google/protobuf/wire_format_lite.h> - -#include <google/protobuf/compiler/csharp/csharp_doc_comment.h> -#include <google/protobuf/compiler/csharp/csharp_enum.h> -#include <google/protobuf/compiler/csharp/csharp_field_base.h> -#include <google/protobuf/compiler/csharp/csharp_helpers.h> -#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 { -namespace csharp { - -bool CompareFieldNumbers(const FieldDescriptor* d1, const FieldDescriptor* d2) { - return d1->number() < d2->number(); -} - -MessageGenerator::MessageGenerator(const Descriptor* descriptor, - const Options* options) - : SourceGeneratorBase(descriptor->file(), options), - descriptor_(descriptor) { - - // sorted field names - for (int i = 0; i < descriptor_->field_count(); i++) { - field_names_.push_back(descriptor_->field(i)->name()); - } - std::sort(field_names_.begin(), field_names_.end()); - - // fields by number - for (int i = 0; i < descriptor_->field_count(); i++) { - fields_by_number_.push_back(descriptor_->field(i)); - } - std::sort(fields_by_number_.begin(), fields_by_number_.end(), - CompareFieldNumbers); -} - -MessageGenerator::~MessageGenerator() { -} - -std::string MessageGenerator::class_name() { - return descriptor_->name(); -} - -std::string MessageGenerator::full_class_name() { - return GetClassName(descriptor_); -} - -const std::vector<std::string>& MessageGenerator::field_names() { - return field_names_; -} - -const std::vector<const FieldDescriptor*>& MessageGenerator::fields_by_number() { - return fields_by_number_; -} - -void MessageGenerator::Generate(io::Printer* printer) { - map<string, string> vars; - vars["class_name"] = class_name(); - vars["access_level"] = class_access_level(); - - WriteMessageDocComment(printer, descriptor_); - printer->Print( - vars, - "$access_level$ sealed partial class $class_name$ : pb::IMessage<$class_name$> {\n"); - printer->Indent(); - - // 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"); - - WriteGeneratedCodeAttributes(printer); - printer->Print( - 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()) { - vars["descriptor_accessor"] = GetReflectionClassName(descriptor_->file()) - + ".Descriptor.MessageTypes[" + SimpleItoa(descriptor_->index()) + "]"; - } else { - vars["descriptor_accessor"] = GetClassName(descriptor_->containing_type()) - + ".Descriptor.NestedTypes[" + SimpleItoa(descriptor_->index()) + "]"; - } - - WriteGeneratedCodeAttributes(printer); - printer->Print( - vars, - "public static pbr::MessageDescriptor Descriptor {\n" - " get { return $descriptor_accessor$; }\n" - "}\n" - "\n"); - WriteGeneratedCodeAttributes(printer); - printer->Print( - vars, - "pbr::MessageDescriptor pb::IMessage.Descriptor {\n" - " get { return Descriptor; }\n" - "}\n" - "\n"); - - // Parameterless constructor and partial OnConstruction method. - WriteGeneratedCodeAttributes(printer); - printer->Print( - vars, - "public $class_name$() {\n" - " OnConstruction();\n" - "}\n\n" - "partial void OnConstruction();\n\n"); - - GenerateCloningCode(printer); - GenerateFreezingCode(printer); - - // Fields/properties - for (int i = 0; i < descriptor_->field_count(); i++) { - const FieldDescriptor* fieldDescriptor = descriptor_->field(i); - - // Rats: we lose the debug comment here :( - printer->Print( - "/// <summary>Field number for the \"$field_name$\" field.</summary>\n" - "public const int $field_constant_name$ = $index$;\n", - "field_name", fieldDescriptor->name(), - "field_constant_name", GetFieldConstantName(fieldDescriptor), - "index", SimpleItoa(fieldDescriptor->number())); - scoped_ptr<FieldGeneratorBase> generator( - CreateFieldGeneratorInternal(fieldDescriptor)); - generator->GenerateMembers(printer); - printer->Print("\n"); - } - - // oneof properties - 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); - vars["original_name"] = descriptor_->oneof_decl(i)->name(); - printer->Print( - vars, - "private object $name$_;\n" - "/// <summary>Enum of possible cases for the \"$original_name$\" oneof.</summary>\n" - "public enum $property_name$OneofCase {\n"); - printer->Indent(); - printer->Print("None = 0,\n"); - for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) { - const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j); - printer->Print("$field_property_name$ = $index$,\n", - "field_property_name", GetPropertyName(field), - "index", SimpleItoa(field->number())); - } - printer->Outdent(); - 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, - "public void Clear$property_name$() {\n" - " $name$Case_ = $property_name$OneofCase.None;\n" - " $name$_ = null;\n" - "}\n\n"); - } - - // Standard methods - GenerateFrameworkMethods(printer); - GenerateMessageSerializationMethods(printer); - GenerateMergingMethods(printer); - - // Nested messages and enums - if (HasNestedGeneratedTypes()) { - printer->Print( - vars, - "#region Nested types\n" - "/// <summary>Container for nested types declared in the $class_name$ message type.</summary>\n"); - WriteGeneratedCodeAttributes(printer); - printer->Print("public static partial class Types {\n"); - printer->Indent(); - for (int i = 0; i < descriptor_->enum_type_count(); i++) { - EnumGenerator enumGenerator(descriptor_->enum_type(i), this->options()); - enumGenerator.Generate(printer); - } - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - // Don't generate nested types for maps... - if (!IsMapEntryMessage(descriptor_->nested_type(i))) { - MessageGenerator messageGenerator( - descriptor_->nested_type(i), this->options()); - messageGenerator.Generate(printer); - } - } - printer->Outdent(); - printer->Print("}\n" - "#endregion\n" - "\n"); - } - - printer->Outdent(); - printer->Print("}\n"); - printer->Print("\n"); -} - -// Helper to work out whether we need to generate a class to hold nested types/enums. -// Only tricky because we don't want to generate map entry types. -bool MessageGenerator::HasNestedGeneratedTypes() -{ - if (descriptor_->enum_type_count() > 0) { - return true; - } - for (int i = 0; i < descriptor_->nested_type_count(); i++) { - if (!IsMapEntryMessage(descriptor_->nested_type(i))) { - return true; - } - } - return false; -} - -void MessageGenerator::GenerateCloningCode(io::Printer* printer) { - map<string, string> vars; - WriteGeneratedCodeAttributes(printer); - vars["class_name"] = class_name(); - printer->Print( - vars, - "public $class_name$($class_name$ other) : this() {\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"); - - WriteGeneratedCodeAttributes(printer); - printer->Print( - vars, - "public $class_name$ Clone() {\n" - " return new $class_name$(this);\n" - "}\n\n"); -} - -void MessageGenerator::GenerateFreezingCode(io::Printer* printer) { -} - -void MessageGenerator::GenerateFrameworkMethods(io::Printer* printer) { - map<string, string> vars; - vars["class_name"] = class_name(); - - // Equality - 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, - "public bool Equals($class_name$ other) {\n" - " if (ReferenceEquals(other, null)) {\n" - " return false;\n" - " }\n" - " if (ReferenceEquals(other, this)) {\n" - " return true;\n" - " }\n"); - printer->Indent(); - for (int i = 0; i < descriptor_->field_count(); i++) { - scoped_ptr<FieldGeneratorBase> generator( - CreateFieldGeneratorInternal(descriptor_->field(i))); - generator->WriteEquals(printer); - } - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - printer->Print("if ($property_name$Case != other.$property_name$Case) return false;\n", - "property_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true)); - } - printer->Outdent(); - printer->Print( - " return true;\n" - "}\n\n"); - - // GetHashCode - // Start with a non-zero value to easily distinguish between null and "empty" messages. - 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( - CreateFieldGeneratorInternal(descriptor_->field(i))); - generator->WriteHash(printer); - } - for (int i = 0; i < descriptor_->oneof_decl_count(); i++) { - printer->Print("hash ^= (int) $name$Case_;\n", - "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false)); - } - printer->Print("return hash;\n"); - printer->Outdent(); - printer->Print("}\n\n"); - - WriteGeneratedCodeAttributes(printer); - printer->Print( - "public override string ToString() {\n" - " return pb::JsonFormatter.ToDiagnosticString(this);\n" - "}\n\n"); -} - -void MessageGenerator::GenerateMessageSerializationMethods(io::Printer* printer) { - WriteGeneratedCodeAttributes(printer); - printer->Print( - "public void WriteTo(pb::CodedOutputStream output) {\n"); - printer->Indent(); - - // Serialize all the fields - for (int i = 0; i < fields_by_number().size(); i++) { - scoped_ptr<FieldGeneratorBase> generator( - CreateFieldGeneratorInternal(fields_by_number()[i])); - generator->GenerateSerializationCode(printer); - } - - // TODO(jonskeet): Memoize size of frozen messages? - printer->Outdent(); - printer->Print( - "}\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( - CreateFieldGeneratorInternal(descriptor_->field(i))); - generator->GenerateSerializedSizeCode(printer); - } - printer->Print("return size;\n"); - printer->Outdent(); - printer->Print("}\n\n"); -} - -void MessageGenerator::GenerateMergingMethods(io::Printer* printer) { - // Note: These are separate from GenerateMessageSerializationMethods() - // because they need to be generated even for messages that are optimized - // for code size. - map<string, string> vars; - vars["class_name"] = class_name(); - - WriteGeneratedCodeAttributes(printer); - printer->Print( - vars, - "public void MergeFrom($class_name$ other) {\n"); - printer->Indent(); - printer->Print( - "if (other == null) {\n" - " return;\n" - "}\n"); - // Merge non-oneof fields - for (int i = 0; i < descriptor_->field_count(); i++) { - if (!descriptor_->field(i)->containing_oneof()) { - scoped_ptr<FieldGeneratorBase> generator( - CreateFieldGeneratorInternal(descriptor_->field(i))); - generator->GenerateMergingCode(printer); - } - } - // Merge oneof fields - 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); - vars["field_property_name"] = GetPropertyName(field); - printer->Print( - vars, - "case $property_name$OneofCase.$field_property_name$:\n" - " $field_property_name$ = other.$field_property_name$;\n" - " break;\n"); - } - printer->Outdent(); - printer->Print("}\n\n"); - } - printer->Outdent(); - printer->Print("}\n\n"); - WriteGeneratedCodeAttributes(printer); - printer->Print("public void MergeFrom(pb::CodedInputStream input) {\n"); - printer->Indent(); - printer->Print( - "uint tag;\n" - "while ((tag = input.ReadTag()) != 0) {\n" - " switch(tag) {\n"); - printer->Indent(); - printer->Indent(); - printer->Print( - "default:\n" - " input.SkipLastField();\n" // We're not storing the data, but we still need to consume it. - " break;\n"); - for (int i = 0; i < fields_by_number().size(); i++) { - const FieldDescriptor* field = fields_by_number()[i]; - internal::WireFormatLite::WireType wt = - internal::WireFormat::WireTypeForFieldType(field->type()); - uint32 tag = internal::WireFormatLite::MakeTag(field->number(), wt); - // Handle both packed and unpacked repeated fields with the same Read*Array call; - // the two generated cases are the packed and unpacked tags. - // TODO(jonskeet): Check that is_packable is equivalent to - // is_repeated && wt in { VARINT, FIXED32, FIXED64 }. - // It looks like it is... - if (field->is_packable()) { - printer->Print( - "case $packed_tag$:\n", - "packed_tag", - SimpleItoa( - internal::WireFormatLite::MakeTag( - field->number(), - internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED))); - } - - printer->Print("case $tag$: {\n", "tag", SimpleItoa(tag)); - printer->Indent(); - scoped_ptr<FieldGeneratorBase> generator( - CreateFieldGeneratorInternal(field)); - generator->GenerateParsingCode(printer); - printer->Print("break;\n"); - printer->Outdent(); - printer->Print("}\n"); - } - printer->Outdent(); - printer->Print("}\n"); // switch - printer->Outdent(); - printer->Print("}\n"); // while - printer->Outdent(); - printer->Print("}\n\n"); // method -} - -int MessageGenerator::GetFieldOrdinal(const FieldDescriptor* descriptor) { - for (int i = 0; i < field_names().size(); i++) { - if (field_names()[i] == descriptor->name()) { - return i; - } - } - GOOGLE_LOG(DFATAL)<< "Could not find ordinal for field " << descriptor->name(); - return -1; -} - -FieldGeneratorBase* MessageGenerator::CreateFieldGeneratorInternal( - const FieldDescriptor* descriptor) { - return CreateFieldGenerator(descriptor, GetFieldOrdinal(descriptor), this->options()); -} - -} // namespace csharp -} // namespace compiler -} // namespace protobuf -} // namespace google |