parent
813d6d652d
commit
685ae36ca2
36 changed files with 6640 additions and 49 deletions
@ -0,0 +1,79 @@ |
||||
// 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 <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/compiler/csharp/csharp_enum.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_writer.h> |
||||
|
||||
using google::protobuf::internal::scoped_ptr; |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) : |
||||
SourceGeneratorBase(descriptor->file()), |
||||
descriptor_(descriptor) { |
||||
} |
||||
|
||||
EnumGenerator::~EnumGenerator() { |
||||
} |
||||
|
||||
void EnumGenerator::Generate(Writer* writer) { |
||||
WriteGeneratedCodeAttributes(writer); |
||||
writer->WriteLine("$0$ enum $1$ {", |
||||
class_access_level(), |
||||
descriptor_->name()); |
||||
writer->Indent(); |
||||
for (int i = 0; i < descriptor_->value_count(); i++) { |
||||
writer->WriteLine("$0$ = $1$,", |
||||
descriptor_->value(i)->name(), |
||||
SimpleItoa(descriptor_->value(i)->number())); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,65 @@ |
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__ |
||||
|
||||
#include <string> |
||||
|
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class Writer; |
||||
|
||||
class EnumGenerator : public SourceGeneratorBase { |
||||
public: |
||||
EnumGenerator(const EnumDescriptor* descriptor); |
||||
~EnumGenerator(); |
||||
|
||||
void Generate(Writer* writer); |
||||
|
||||
private: |
||||
const EnumDescriptor* descriptor_; |
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator); |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__
|
||||
|
@ -0,0 +1,160 @@ |
||||
// 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 <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/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_enum_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_writer.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor, |
||||
int fieldOrdinal) |
||||
: FieldGeneratorBase(descriptor, fieldOrdinal) { |
||||
} |
||||
|
||||
EnumFieldGenerator::~EnumFieldGenerator() { |
||||
|
||||
} |
||||
|
||||
void EnumFieldGenerator::GenerateMembers(Writer* writer) { |
||||
writer->WriteLine("private bool has$0$;", property_name()); |
||||
writer->WriteLine("private $0$ $1$_ = $2$;", type_name(), name(), |
||||
default_value()); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public bool Has$0$ {", property_name()); |
||||
writer->WriteLine(" get { return has$0$; }", property_name()); |
||||
writer->WriteLine("}"); |
||||
AddPublicMemberAttributes(writer); |
||||
writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); |
||||
writer->WriteLine(" get { return $0$_; }", name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void EnumFieldGenerator::GenerateBuilderMembers(Writer* writer) { |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public bool Has$0$ {", property_name()); |
||||
writer->WriteLine(" get { return result.has$0$; }", property_name()); |
||||
writer->WriteLine("}"); |
||||
AddPublicMemberAttributes(writer); |
||||
writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); |
||||
writer->WriteLine(" get { return result.$0$; }", property_name()); |
||||
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.has$0$ = true;", property_name()); |
||||
writer->WriteLine(" result.$0$_ = value;", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public Builder Clear$0$() {", property_name()); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.has$0$ = false;", property_name()); |
||||
writer->WriteLine(" result.$0$_ = $1$;", name(), default_value()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void EnumFieldGenerator::GenerateMergingCode(Writer* writer) { |
||||
writer->WriteLine("if (other.Has$0$) {", property_name()); |
||||
writer->WriteLine(" $0$ = other.$0$;", property_name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void EnumFieldGenerator::GenerateBuildingCode(Writer* writer) { |
||||
// Nothing to do here for enum types
|
||||
} |
||||
|
||||
void EnumFieldGenerator::GenerateParsingCode(Writer* writer) { |
||||
writer->WriteLine("object unknown;"); |
||||
writer->WriteLine("if(input.ReadEnum(ref result.$0$_, out unknown)) {", |
||||
name()); |
||||
writer->WriteLine(" result.has$0$ = true;", 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("}"); |
||||
} |
||||
|
||||
void EnumFieldGenerator::GenerateSerializationCode(Writer* writer) { |
||||
writer->WriteLine("if (has$0$) {", property_name()); |
||||
writer->WriteLine( |
||||
" output.WriteEnum($0$, field_names[$2$], (int) $1$, $1$);", number(), |
||||
property_name(), field_ordinal()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void EnumFieldGenerator::GenerateSerializedSizeCode(Writer* writer) { |
||||
writer->WriteLine("if (has$0$) {", property_name()); |
||||
writer->WriteLine( |
||||
" size += pb::CodedOutputStream.ComputeEnumSize($0$, (int) $1$);", |
||||
number(), property_name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void EnumFieldGenerator::WriteHash(Writer* writer) { |
||||
writer->WriteLine("if (has$0$) hash ^= $1$_.GetHashCode();", property_name(), |
||||
name()); |
||||
} |
||||
void EnumFieldGenerator::WriteEquals(Writer* writer) { |
||||
writer->WriteLine( |
||||
"if (has$0$ != other.has$0$ || (has$0$ && !$1$_.Equals(other.$1$_))) return false;", |
||||
property_name(), name()); |
||||
} |
||||
void EnumFieldGenerator::WriteToString(Writer* writer) { |
||||
writer->WriteLine("PrintField(\"$0$\", has$1$, $2$_, writer);", |
||||
descriptor_->name(), property_name(), name()); |
||||
} |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,73 @@ |
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__ |
||||
|
||||
#include <string> |
||||
|
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_field_base.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class Writer; |
||||
|
||||
class EnumFieldGenerator : public FieldGeneratorBase { |
||||
public: |
||||
EnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); |
||||
~EnumFieldGenerator(); |
||||
|
||||
virtual void GenerateMembers(Writer* writer); |
||||
virtual void GenerateBuilderMembers(Writer* writer); |
||||
virtual void GenerateMergingCode(Writer* writer); |
||||
virtual void GenerateBuildingCode(Writer* writer); |
||||
virtual void GenerateParsingCode(Writer* writer); |
||||
virtual void GenerateSerializationCode(Writer* writer); |
||||
virtual void GenerateSerializedSizeCode(Writer* writer); |
||||
|
||||
virtual void WriteHash(Writer* writer); |
||||
virtual void WriteEquals(Writer* writer); |
||||
virtual void WriteToString(Writer* writer); |
||||
|
||||
private: |
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator); |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__
|
||||
|
@ -0,0 +1,170 @@ |
||||
// 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 <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/compiler/csharp/csharp_extension.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_writer.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_field_base.h> |
||||
|
||||
using google::protobuf::internal::scoped_ptr; |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor) |
||||
: FieldGeneratorBase(descriptor, 0) { |
||||
if (descriptor_->extension_scope()) { |
||||
scope_ = GetClassName(descriptor_->extension_scope()); |
||||
} else { |
||||
scope_ = GetFullUmbrellaClassName(descriptor_->file()); |
||||
} |
||||
extends_ = GetClassName(descriptor_->containing_type()); |
||||
} |
||||
|
||||
ExtensionGenerator::~ExtensionGenerator() { |
||||
} |
||||
|
||||
void ExtensionGenerator::Generate(Writer* writer) { |
||||
if (descriptor_->file()->options().csharp_cls_compliance() |
||||
&& (GetFieldConstantName(descriptor_).substr(0, 1) == "_")) { |
||||
writer->WriteLine("[global::System.CLSCompliant(false)]"); |
||||
} |
||||
|
||||
writer->WriteLine("public const int $0$ = $1$;", |
||||
GetFieldConstantName(descriptor_), |
||||
SimpleItoa(descriptor_->number())); |
||||
|
||||
if (use_lite_runtime()) { |
||||
// TODO(jtattermusch): check the argument...
|
||||
//if (Descriptor.MappedType == MappedType.Message && Descriptor.MessageType.Options.MessageSetWireFormat)
|
||||
//{
|
||||
// throw new ArgumentException(
|
||||
// "option message_set_wire_format = true; is not supported in Lite runtime extensions.");
|
||||
//}
|
||||
|
||||
AddClsComplianceCheck(writer); |
||||
writer->Write("$0$ ", class_access_level()); |
||||
writer->WriteLine( |
||||
"static pb::$3$<$0$, $1$> $2$;", |
||||
extends_, |
||||
type_name(), |
||||
property_name(), |
||||
descriptor_->is_repeated() ? |
||||
"GeneratedRepeatExtensionLite" : "GeneratedExtensionLite"); |
||||
} else if (descriptor_->is_repeated()) { |
||||
AddClsComplianceCheck(writer); |
||||
writer->WriteLine( |
||||
"$0$ static pb::GeneratedExtensionBase<scg::IList<$1$>> $2$;", |
||||
class_access_level(), type_name(), property_name()); |
||||
} else { |
||||
AddClsComplianceCheck(writer); |
||||
writer->WriteLine("$0$ static pb::GeneratedExtensionBase<$1$> $2$;", |
||||
class_access_level(), type_name(), property_name()); |
||||
} |
||||
} |
||||
|
||||
void ExtensionGenerator::GenerateStaticVariableInitializers(Writer* writer) { |
||||
if (use_lite_runtime()) { |
||||
writer->WriteLine("$0$.$1$ = ", scope_, property_name()); |
||||
writer->Indent(); |
||||
writer->WriteLine( |
||||
"new pb::$0$<$1$, $2$>(", |
||||
descriptor_->is_repeated() ? |
||||
"GeneratedRepeatExtensionLite" : "GeneratedExtensionLite", |
||||
extends_, type_name()); |
||||
writer->Indent(); |
||||
writer->WriteLine("\"$0$\",", descriptor_->full_name()); |
||||
writer->WriteLine("$0$.DefaultInstance,", extends_); |
||||
if (!descriptor_->is_repeated()) { |
||||
std::string default_val; |
||||
if (descriptor_->has_default_value()) { |
||||
default_val = default_value(); |
||||
} else { |
||||
default_val = is_nullable_type() ? "null" : ("default(" + type_name() + ")"); |
||||
} |
||||
writer->WriteLine("$0$,", default_val); |
||||
} |
||||
// TODO(jtattermusch):
|
||||
//writer.WriteLine("{0},",
|
||||
// (Descriptor.MappedType == MappedType.Message) ? type + ".DefaultInstance" : "null");
|
||||
//writer.WriteLine("{0},",
|
||||
// (Descriptor.MappedType == MappedType.Enum) ? "new EnumLiteMap<" + type + ">()" : "null");
|
||||
//writer.WriteLine("{0}.{1}FieldNumber,", scope, name);
|
||||
//writer.Write("pbd::FieldType.{0}", Descriptor.FieldType);
|
||||
if (descriptor_->is_repeated()) { |
||||
writer->WriteLine(","); |
||||
writer->Write(descriptor_->is_packed() ? "true" : "false"); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine(");"); |
||||
writer->Outdent(); |
||||
} |
||||
else if (descriptor_->is_repeated()) |
||||
{ |
||||
writer->WriteLine( |
||||
"$0$.$1$ = pb::GeneratedRepeatExtension<$2$>.CreateInstance($0$.Descriptor.Extensions[$3$]);", |
||||
scope_, property_name(), type_name(), SimpleItoa(descriptor_->index())); |
||||
} |
||||
else |
||||
{ |
||||
writer->WriteLine( |
||||
"$0$.$1$ = pb::GeneratedSingleExtension<$2$>.CreateInstance($0$.Descriptor.Extensions[$3$]);", |
||||
scope_, property_name(), type_name(), SimpleItoa(descriptor_->index())); |
||||
} |
||||
} |
||||
|
||||
void ExtensionGenerator::GenerateExtensionRegistrationCode(Writer* writer) { |
||||
writer->WriteLine("registry.Add($0$.$1$);", scope_, property_name()); |
||||
} |
||||
|
||||
void ExtensionGenerator::WriteHash(Writer* writer) { |
||||
} |
||||
|
||||
void ExtensionGenerator::WriteEquals(Writer* writer) { |
||||
} |
||||
|
||||
void ExtensionGenerator::WriteToString(Writer* writer) { |
||||
} |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,80 @@ |
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_EXTENSION_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_EXTENSION_H__ |
||||
|
||||
#include <string> |
||||
|
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_field_base.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class Writer; |
||||
|
||||
class ExtensionGenerator : public FieldGeneratorBase { |
||||
public: |
||||
ExtensionGenerator(const FieldDescriptor* descriptor); |
||||
~ExtensionGenerator(); |
||||
|
||||
void GenerateStaticVariableInitializers(Writer* writer); |
||||
void GenerateExtensionRegistrationCode(Writer* writer); |
||||
void Generate(Writer* writer); |
||||
|
||||
virtual void WriteHash(Writer* writer); |
||||
virtual void WriteEquals(Writer* writer); |
||||
virtual void WriteToString(Writer* writer); |
||||
|
||||
virtual void GenerateMembers(Writer* writer) {}; |
||||
virtual void GenerateBuilderMembers(Writer* writer) {}; |
||||
virtual void GenerateMergingCode(Writer* writer) {}; |
||||
virtual void GenerateBuildingCode(Writer* writer) {}; |
||||
virtual void GenerateParsingCode(Writer* writer) {}; |
||||
virtual void GenerateSerializationCode(Writer* writer) {}; |
||||
virtual void GenerateSerializedSizeCode(Writer* writer) {}; |
||||
|
||||
private: |
||||
std::string scope_; |
||||
std::string extends_; |
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator); |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_EXTENSION_H__
|
||||
|
@ -0,0 +1,394 @@ |
||||
// 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 <limits> |
||||
#include <sstream> |
||||
|
||||
#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/compiler/csharp/csharp_field_base.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_writer.h> |
||||
|
||||
using google::protobuf::internal::scoped_ptr; |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* descriptor, |
||||
int fieldOrdinal) |
||||
: SourceGeneratorBase(descriptor->file()), |
||||
descriptor_(descriptor), |
||||
fieldOrdinal_(fieldOrdinal) { |
||||
} |
||||
|
||||
FieldGeneratorBase::~FieldGeneratorBase() { |
||||
} |
||||
|
||||
void FieldGeneratorBase::AddDeprecatedFlag(Writer* writer) { |
||||
// TODO(jtattermusch):
|
||||
//if (IsObsolete)
|
||||
//{
|
||||
// writer.WriteLine("[global::System.ObsoleteAttribute()]");
|
||||
//}
|
||||
} |
||||
|
||||
void FieldGeneratorBase::AddNullCheck(Writer* writer) { |
||||
AddNullCheck(writer, "value"); |
||||
} |
||||
|
||||
void FieldGeneratorBase::AddNullCheck(Writer* writer, const std::string& name) { |
||||
if (is_nullable_type()) { |
||||
writer->WriteLine(" pb::ThrowHelper.ThrowIfNull($0$, \"$0$\");", name); |
||||
} |
||||
} |
||||
|
||||
void FieldGeneratorBase::AddPublicMemberAttributes(Writer* writer) { |
||||
AddDeprecatedFlag(writer); |
||||
AddClsComplianceCheck(writer); |
||||
} |
||||
|
||||
void FieldGeneratorBase::AddClsComplianceCheck(Writer* writer) { |
||||
if (!is_cls_compliant() && descriptor_->file()->options().csharp_cls_compliance()) { |
||||
writer->WriteLine("[global::System.CLSCompliant(false)]"); |
||||
} |
||||
} |
||||
|
||||
std::string FieldGeneratorBase::property_name() { |
||||
return GetPropertyName(descriptor_); |
||||
} |
||||
|
||||
std::string FieldGeneratorBase::name() { |
||||
return UnderscoresToCamelCase(GetFieldName(descriptor_), false); |
||||
} |
||||
|
||||
std::string FieldGeneratorBase::type_name() { |
||||
switch (descriptor_->type()) { |
||||
case FieldDescriptor::TYPE_ENUM: |
||||
return GetClassName(descriptor_->enum_type()); |
||||
case FieldDescriptor::TYPE_MESSAGE: |
||||
case FieldDescriptor::TYPE_GROUP: |
||||
return GetClassName(descriptor_->message_type()); |
||||
case FieldDescriptor::TYPE_DOUBLE: |
||||
return "double"; |
||||
case FieldDescriptor::TYPE_FLOAT: |
||||
return "float"; |
||||
case FieldDescriptor::TYPE_INT64: |
||||
return "long"; |
||||
case FieldDescriptor::TYPE_UINT64: |
||||
return "ulong"; |
||||
case FieldDescriptor::TYPE_INT32: |
||||
return "int"; |
||||
case FieldDescriptor::TYPE_FIXED64: |
||||
return "ulong"; |
||||
case FieldDescriptor::TYPE_FIXED32: |
||||
return "uint"; |
||||
case FieldDescriptor::TYPE_BOOL: |
||||
return "bool"; |
||||
case FieldDescriptor::TYPE_STRING: |
||||
return "string"; |
||||
case FieldDescriptor::TYPE_BYTES: |
||||
return "pb::ByteString"; |
||||
case FieldDescriptor::TYPE_UINT32: |
||||
return "uint"; |
||||
case FieldDescriptor::TYPE_SFIXED32: |
||||
return "int"; |
||||
case FieldDescriptor::TYPE_SFIXED64: |
||||
return "long"; |
||||
case FieldDescriptor::TYPE_SINT32: |
||||
return "int"; |
||||
case FieldDescriptor::TYPE_SINT64: |
||||
return "long"; |
||||
default: |
||||
GOOGLE_LOG(FATAL)<< "Unknown field type."; |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
bool FieldGeneratorBase::has_default_value() { |
||||
switch (descriptor_->type()) { |
||||
case FieldDescriptor::TYPE_ENUM: |
||||
case FieldDescriptor::TYPE_MESSAGE: |
||||
case FieldDescriptor::TYPE_GROUP: |
||||
return true; |
||||
case FieldDescriptor::TYPE_DOUBLE: |
||||
return descriptor_->default_value_double() != 0.0; |
||||
case FieldDescriptor::TYPE_FLOAT: |
||||
return descriptor_->default_value_float() != 0.0; |
||||
case FieldDescriptor::TYPE_INT64: |
||||
return descriptor_->default_value_int64() != 0L; |
||||
case FieldDescriptor::TYPE_UINT64: |
||||
return descriptor_->default_value_uint64() != 0L; |
||||
case FieldDescriptor::TYPE_INT32: |
||||
return descriptor_->default_value_int32() != 0; |
||||
case FieldDescriptor::TYPE_FIXED64: |
||||
return descriptor_->default_value_uint64() != 0L; |
||||
case FieldDescriptor::TYPE_FIXED32: |
||||
return descriptor_->default_value_uint32() != 0; |
||||
case FieldDescriptor::TYPE_BOOL: |
||||
return descriptor_->default_value_bool(); |
||||
case FieldDescriptor::TYPE_STRING: |
||||
return true; |
||||
case FieldDescriptor::TYPE_BYTES: |
||||
return true; |
||||
case FieldDescriptor::TYPE_UINT32: |
||||
return descriptor_->default_value_uint32() != 0; |
||||
case FieldDescriptor::TYPE_SFIXED32: |
||||
return descriptor_->default_value_int32() != 0; |
||||
case FieldDescriptor::TYPE_SFIXED64: |
||||
return descriptor_->default_value_int64() != 0L; |
||||
case FieldDescriptor::TYPE_SINT32: |
||||
return descriptor_->default_value_int32() != 0; |
||||
case FieldDescriptor::TYPE_SINT64: |
||||
return descriptor_->default_value_int64() != 0L; |
||||
default: |
||||
GOOGLE_LOG(FATAL)<< "Unknown field type."; |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
bool FieldGeneratorBase::is_nullable_type() { |
||||
switch (descriptor_->type()) { |
||||
case FieldDescriptor::TYPE_ENUM: |
||||
case FieldDescriptor::TYPE_DOUBLE: |
||||
case FieldDescriptor::TYPE_FLOAT: |
||||
case FieldDescriptor::TYPE_INT64: |
||||
case FieldDescriptor::TYPE_UINT64: |
||||
case FieldDescriptor::TYPE_INT32: |
||||
case FieldDescriptor::TYPE_FIXED64: |
||||
case FieldDescriptor::TYPE_FIXED32: |
||||
case FieldDescriptor::TYPE_BOOL: |
||||
case FieldDescriptor::TYPE_UINT32: |
||||
case FieldDescriptor::TYPE_SFIXED32: |
||||
case FieldDescriptor::TYPE_SFIXED64: |
||||
case FieldDescriptor::TYPE_SINT32: |
||||
case FieldDescriptor::TYPE_SINT64: |
||||
return false; |
||||
|
||||
case FieldDescriptor::TYPE_MESSAGE: |
||||
case FieldDescriptor::TYPE_GROUP: |
||||
case FieldDescriptor::TYPE_STRING: |
||||
case FieldDescriptor::TYPE_BYTES: |
||||
return true; |
||||
|
||||
default: |
||||
GOOGLE_LOG(FATAL)<< "Unknown field type."; |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
bool FieldGeneratorBase::is_cls_compliant() { |
||||
CSharpType type = GetCSharpType(descriptor_->type()); |
||||
return (type != CSHARPTYPE_UINT32) && (type != CSHARPTYPE_UINT64) |
||||
&& (UnderscoresToPascalCase(name()).substr(0, 1) != "_"); |
||||
} |
||||
|
||||
inline bool IsNaN(double value) { |
||||
// NaN is never equal to anything, even itself.
|
||||
return value != value; |
||||
} |
||||
|
||||
bool AllPrintableAscii(const std::string& text) { |
||||
for(int i = 0; i < text.size(); i++) { |
||||
if (text[i] < 0x20 || text[i] > 0x7e) { |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
std::string FieldGeneratorBase::GetStringDefaultValueInternal() { |
||||
if (!descriptor_->has_default_value()) { |
||||
return "\"\""; |
||||
} |
||||
if (AllPrintableAscii(descriptor_->default_value_string())) { |
||||
// All chars are ASCII and printable. In this case we only
|
||||
// need to escape quotes and backslashes.
|
||||
std::string temp = descriptor_->default_value_string(); |
||||
temp = StringReplace(temp, "\\", "\\\\", true); |
||||
temp = StringReplace(temp, "'", "\\'", true); |
||||
temp = StringReplace(temp, "\"", "\\\"", true); |
||||
return "\"" + temp + "\""; |
||||
} |
||||
if (use_lite_runtime()) { |
||||
return "pb::ByteString.FromBase64(\"" |
||||
+ StringToBase64(descriptor_->default_value_string()) |
||||
+ "\").ToStringUtf8()"; |
||||
} |
||||
return "(string) " + GetClassName(descriptor_->containing_type()) |
||||
+ ".Descriptor.Fields[" + SimpleItoa(descriptor_->index()) |
||||
+ "].DefaultValue"; |
||||
} |
||||
|
||||
std::string FieldGeneratorBase::GetBytesDefaultValueInternal() { |
||||
if (!descriptor_->has_default_value()) { |
||||
return "pb::ByteString.Empty"; |
||||
} |
||||
if (use_lite_runtime()) { |
||||
return "pb::ByteString.FromBase64(\"" + StringToBase64(descriptor_->default_value_string()) + "\")"; |
||||
} |
||||
return "(pb::ByteString) "+ GetClassName(descriptor_->containing_type()) + |
||||
".Descriptor.Fields[" + SimpleItoa(descriptor_->index()) + "].DefaultValue"; |
||||
} |
||||
|
||||
std::string FieldGeneratorBase::default_value() { |
||||
switch (descriptor_->type()) { |
||||
case FieldDescriptor::TYPE_ENUM: |
||||
return type_name() + "." + descriptor_->default_value_enum()->name(); |
||||
case FieldDescriptor::TYPE_MESSAGE: |
||||
case FieldDescriptor::TYPE_GROUP: |
||||
return type_name() + ".DefaultInstance"; |
||||
case FieldDescriptor::TYPE_DOUBLE: { |
||||
double value = descriptor_->default_value_double(); |
||||
if (value == numeric_limits<double>::infinity()) { |
||||
return "double.PositiveInfinity"; |
||||
} else if (value == -numeric_limits<double>::infinity()) { |
||||
return "double.NegativeInfinity"; |
||||
} else if (IsNaN(value)) { |
||||
return "double.NaN"; |
||||
} |
||||
return SimpleDtoa(value) + "D"; |
||||
} |
||||
case FieldDescriptor::TYPE_FLOAT: { |
||||
float value = descriptor_->default_value_float(); |
||||
if (value == numeric_limits<float>::infinity()) { |
||||
return "float.PositiveInfinity"; |
||||
} else if (value == -numeric_limits<float>::infinity()) { |
||||
return "float.NegativeInfinity"; |
||||
} else if (IsNaN(value)) { |
||||
return "float.NaN"; |
||||
} |
||||
return SimpleFtoa(value) + "F"; |
||||
} |
||||
case FieldDescriptor::TYPE_INT64: |
||||
return SimpleItoa(descriptor_->default_value_int64()) + "L"; |
||||
case FieldDescriptor::TYPE_UINT64: |
||||
return SimpleItoa(descriptor_->default_value_uint64()) + "UL"; |
||||
case FieldDescriptor::TYPE_INT32: |
||||
return SimpleItoa(descriptor_->default_value_int32()); |
||||
case FieldDescriptor::TYPE_FIXED64: |
||||
return SimpleItoa(descriptor_->default_value_uint64()) + "UL"; |
||||
case FieldDescriptor::TYPE_FIXED32: |
||||
return SimpleItoa(descriptor_->default_value_uint32()); |
||||
case FieldDescriptor::TYPE_BOOL: |
||||
if (descriptor_->default_value_bool()) { |
||||
return "true"; |
||||
} else { |
||||
return "false"; |
||||
} |
||||
case FieldDescriptor::TYPE_STRING: |
||||
return GetStringDefaultValueInternal(); |
||||
case FieldDescriptor::TYPE_BYTES: |
||||
return GetBytesDefaultValueInternal(); |
||||
case FieldDescriptor::TYPE_UINT32: |
||||
return SimpleItoa(descriptor_->default_value_uint32()); |
||||
case FieldDescriptor::TYPE_SFIXED32: |
||||
return SimpleItoa(descriptor_->default_value_int32()); |
||||
case FieldDescriptor::TYPE_SFIXED64: |
||||
return SimpleItoa(descriptor_->default_value_int64()) + "L"; |
||||
case FieldDescriptor::TYPE_SINT32: |
||||
return SimpleItoa(descriptor_->default_value_int32()); |
||||
case FieldDescriptor::TYPE_SINT64: |
||||
return SimpleItoa(descriptor_->default_value_int64()) + "L"; |
||||
default: |
||||
GOOGLE_LOG(FATAL)<< "Unknown field type."; |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
std::string FieldGeneratorBase::number() { |
||||
return SimpleItoa(descriptor_->number()); |
||||
} |
||||
|
||||
std::string FieldGeneratorBase::message_or_group() { |
||||
return |
||||
(descriptor_->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message"; |
||||
} |
||||
|
||||
std::string FieldGeneratorBase::capitalized_type_name() { |
||||
switch (descriptor_->type()) { |
||||
case FieldDescriptor::TYPE_ENUM: |
||||
return "Enum"; |
||||
case FieldDescriptor::TYPE_MESSAGE: |
||||
return "Message"; |
||||
case FieldDescriptor::TYPE_GROUP: |
||||
return "Group"; |
||||
case FieldDescriptor::TYPE_DOUBLE: |
||||
return "Double"; |
||||
case FieldDescriptor::TYPE_FLOAT: |
||||
return "Float"; |
||||
case FieldDescriptor::TYPE_INT64: |
||||
return "Int64"; |
||||
case FieldDescriptor::TYPE_UINT64: |
||||
return "UInt64"; |
||||
case FieldDescriptor::TYPE_INT32: |
||||
return "Int32"; |
||||
case FieldDescriptor::TYPE_FIXED64: |
||||
return "Fixed64"; |
||||
case FieldDescriptor::TYPE_FIXED32: |
||||
return "Fixed32"; |
||||
case FieldDescriptor::TYPE_BOOL: |
||||
return "Bool"; |
||||
case FieldDescriptor::TYPE_STRING: |
||||
return "String"; |
||||
case FieldDescriptor::TYPE_BYTES: |
||||
return "Bytes"; |
||||
case FieldDescriptor::TYPE_UINT32: |
||||
return "UInt32"; |
||||
case FieldDescriptor::TYPE_SFIXED32: |
||||
return "SFixed32"; |
||||
case FieldDescriptor::TYPE_SFIXED64: |
||||
return "SFixed64"; |
||||
case FieldDescriptor::TYPE_SINT32: |
||||
return "SInt32"; |
||||
case FieldDescriptor::TYPE_SINT64: |
||||
return "SInt64"; |
||||
default: |
||||
GOOGLE_LOG(FATAL)<< "Unknown field type."; |
||||
return ""; |
||||
} |
||||
} |
||||
|
||||
std::string FieldGeneratorBase::field_ordinal() { |
||||
return SimpleItoa(fieldOrdinal_); |
||||
} |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,100 @@ |
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_BASE_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_BASE_H__ |
||||
|
||||
#include <string> |
||||
#include <google/protobuf/stubs/strutil.h> |
||||
|
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class Writer; |
||||
|
||||
class FieldGeneratorBase : public SourceGeneratorBase { |
||||
public: |
||||
FieldGeneratorBase(const FieldDescriptor* descriptor, int fieldOrdinal); |
||||
~FieldGeneratorBase(); |
||||
|
||||
virtual void GenerateMembers(Writer* writer) = 0; |
||||
virtual void GenerateBuilderMembers(Writer* writer) = 0; |
||||
virtual void GenerateMergingCode(Writer* writer) = 0; |
||||
virtual void GenerateBuildingCode(Writer* writer) = 0; |
||||
virtual void GenerateParsingCode(Writer* writer) = 0; |
||||
virtual void GenerateSerializationCode(Writer* writer) = 0; |
||||
virtual void GenerateSerializedSizeCode(Writer* writer) = 0; |
||||
|
||||
virtual void WriteHash(Writer* writer) = 0; |
||||
virtual void WriteEquals(Writer* writer) = 0; |
||||
virtual void WriteToString(Writer* writer) = 0; |
||||
|
||||
protected: |
||||
const FieldDescriptor* descriptor_; |
||||
const int fieldOrdinal_; |
||||
|
||||
void AddDeprecatedFlag(Writer* writer); |
||||
void AddNullCheck(Writer* writer); |
||||
void AddNullCheck(Writer* writer, const std::string& name); |
||||
|
||||
void AddPublicMemberAttributes(Writer* writer); |
||||
void AddClsComplianceCheck(Writer* writer); |
||||
|
||||
std::string property_name(); |
||||
std::string name(); |
||||
std::string type_name(); |
||||
bool has_default_value(); |
||||
bool is_nullable_type(); |
||||
bool is_cls_compliant(); |
||||
std::string default_value(); |
||||
std::string number(); |
||||
std::string message_or_group(); |
||||
std::string capitalized_type_name(); |
||||
std::string field_ordinal(); |
||||
|
||||
private: |
||||
std::string GetStringDefaultValueInternal(); |
||||
std::string GetBytesDefaultValueInternal(); |
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorBase); |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_BASE_H__
|
||||
|
@ -0,0 +1,82 @@ |
||||
// 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 <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/compiler/csharp/csharp_generator.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_umbrella_class.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_writer.h> |
||||
|
||||
using google::protobuf::internal::scoped_ptr; |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
void GenerateFile(const google::protobuf::FileDescriptor* file, |
||||
Writer* writer) { |
||||
UmbrellaClassGenerator umbrellaGenerator(file); |
||||
umbrellaGenerator.Generate(writer); |
||||
} |
||||
|
||||
bool Generator::Generate( |
||||
const FileDescriptor* file, |
||||
const string& parameter, |
||||
GeneratorContext* generator_context, |
||||
string* error) const { |
||||
|
||||
// TODO: parse generator parameters...
|
||||
|
||||
// TODO: file output file naming logic
|
||||
std::string filename = |
||||
StripDotProto(file->name()) + ".cs"; |
||||
scoped_ptr<io::ZeroCopyOutputStream> output( |
||||
generator_context->Open(filename)); |
||||
io::Printer printer(output.get(), '$'); |
||||
Writer writer(&printer); |
||||
|
||||
GenerateFile(file, &writer); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,58 @@ |
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__ |
||||
|
||||
#include <string> |
||||
|
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class LIBPROTOC_EXPORT Generator |
||||
: public google::protobuf::compiler::CodeGenerator { |
||||
virtual bool Generate( |
||||
const FileDescriptor* file, |
||||
const string& parameter, |
||||
GeneratorContext* generator_context, |
||||
string* error) const; |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__
|
||||
|
@ -0,0 +1,54 @@ |
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2014 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 <memory> |
||||
|
||||
#include <google/protobuf/compiler/ruby/ruby_generator.h> |
||||
#include <google/protobuf/compiler/command_line_interface.h> |
||||
#include <google/protobuf/io/zero_copy_stream.h> |
||||
#include <google/protobuf/io/printer.h> |
||||
|
||||
#include <google/protobuf/testing/googletest.h> |
||||
#include <gtest/gtest.h> |
||||
#include <google/protobuf/testing/file.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
namespace { |
||||
|
||||
// TODO(jtattermusch): add some tests.
|
||||
|
||||
} // namespace
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,383 @@ |
||||
// 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.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#include <algorithm> |
||||
#include <google/protobuf/stubs/hash.h> |
||||
#include <limits> |
||||
#include <vector> |
||||
|
||||
#include <google/protobuf/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/descriptor.pb.h> |
||||
#include <google/protobuf/io/printer.h> |
||||
#include <google/protobuf/wire_format.h> |
||||
#include <google/protobuf/stubs/strutil.h> |
||||
#include <google/protobuf/stubs/substitute.h> |
||||
|
||||
#include <google/protobuf/compiler/csharp/csharp_field_base.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_enum_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_message_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_primitive_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
CSharpType GetCSharpType(FieldDescriptor::Type type) { |
||||
switch (type) { |
||||
case FieldDescriptor::TYPE_INT32: |
||||
return CSHARPTYPE_INT32; |
||||
case FieldDescriptor::TYPE_INT64: |
||||
return CSHARPTYPE_INT64; |
||||
case FieldDescriptor::TYPE_UINT32: |
||||
return CSHARPTYPE_UINT32; |
||||
case FieldDescriptor::TYPE_UINT64: |
||||
return CSHARPTYPE_UINT32; |
||||
case FieldDescriptor::TYPE_SINT32: |
||||
return CSHARPTYPE_INT32; |
||||
case FieldDescriptor::TYPE_SINT64: |
||||
return CSHARPTYPE_INT64; |
||||
case FieldDescriptor::TYPE_FIXED32: |
||||
return CSHARPTYPE_UINT32; |
||||
case FieldDescriptor::TYPE_FIXED64: |
||||
return CSHARPTYPE_UINT64; |
||||
case FieldDescriptor::TYPE_SFIXED32: |
||||
return CSHARPTYPE_INT32; |
||||
case FieldDescriptor::TYPE_SFIXED64: |
||||
return CSHARPTYPE_INT64; |
||||
case FieldDescriptor::TYPE_FLOAT: |
||||
return CSHARPTYPE_FLOAT; |
||||
case FieldDescriptor::TYPE_DOUBLE: |
||||
return CSHARPTYPE_DOUBLE; |
||||
case FieldDescriptor::TYPE_BOOL: |
||||
return CSHARPTYPE_BOOL; |
||||
case FieldDescriptor::TYPE_ENUM: |
||||
return CSHARPTYPE_ENUM; |
||||
case FieldDescriptor::TYPE_STRING: |
||||
return CSHARPTYPE_STRING; |
||||
case FieldDescriptor::TYPE_BYTES: |
||||
return CSHARPTYPE_BYTESTRING; |
||||
case FieldDescriptor::TYPE_GROUP: |
||||
return CSHARPTYPE_MESSAGE; |
||||
case FieldDescriptor::TYPE_MESSAGE: |
||||
return CSHARPTYPE_MESSAGE; |
||||
|
||||
// No default because we want the compiler to complain if any new
|
||||
// types are added.
|
||||
} |
||||
GOOGLE_LOG(FATAL)<< "Can't get here."; |
||||
return (CSharpType) -1; |
||||
} |
||||
|
||||
std::string StripDotProto(const std::string& proto_file) { |
||||
int lastindex = proto_file.find_last_of("."); |
||||
return proto_file.substr(0, lastindex); |
||||
} |
||||
|
||||
std::string GetFileNamespace(const FileDescriptor* descriptor) { |
||||
if (descriptor->options().has_csharp_namespace()) { |
||||
return descriptor->options().csharp_namespace(); |
||||
} |
||||
return descriptor->package(); |
||||
} |
||||
|
||||
std::string GetUmbrellaClassNameInternal(const std::string& proto_file) { |
||||
int lastslash = proto_file.find_last_of("/"); |
||||
std::string base = proto_file.substr(lastslash + 1); |
||||
return UnderscoresToPascalCase(StripDotProto(base)); |
||||
} |
||||
|
||||
std::string GetFileUmbrellaClassname(const FileDescriptor* descriptor) { |
||||
if (descriptor->options().has_csharp_umbrella_classname()) { |
||||
return descriptor->options().csharp_umbrella_namespace(); |
||||
} else { |
||||
return GetUmbrellaClassNameInternal(descriptor->name()); |
||||
} |
||||
} |
||||
|
||||
std::string GetFileUmbrellaNamespace(const FileDescriptor* descriptor) { |
||||
if (!descriptor->options().csharp_nest_classes() |
||||
&& !descriptor->options().has_csharp_umbrella_namespace()) { |
||||
bool collision = false; |
||||
// TODO(jtattermusch): detect collisions!
|
||||
// foreach (IDescriptor d in MessageTypes)
|
||||
// {
|
||||
// collision |= d.Name == builder.UmbrellaClassname;
|
||||
// }
|
||||
// foreach (IDescriptor d in Services)
|
||||
// {
|
||||
// collision |= d.Name == builder.UmbrellaClassname;
|
||||
// }
|
||||
// foreach (IDescriptor d in EnumTypes)
|
||||
// {
|
||||
// collision |= d.Name == builder.UmbrellaClassname;
|
||||
// }
|
||||
if (collision) { |
||||
return "Proto"; |
||||
} |
||||
} |
||||
return ""; |
||||
} |
||||
|
||||
// TODO(jtattermusch): can we reuse a utility function?
|
||||
std::string UnderscoresToCamelCase(const std::string& input, |
||||
bool cap_next_letter) { |
||||
string result; |
||||
// Note: I distrust ctype.h due to locales.
|
||||
for (int i = 0; i < input.size(); i++) { |
||||
if ('a' <= input[i] && input[i] <= 'z') { |
||||
if (cap_next_letter) { |
||||
result += input[i] + ('A' - 'a'); |
||||
} else { |
||||
result += input[i]; |
||||
} |
||||
cap_next_letter = false; |
||||
} else if ('A' <= input[i] && input[i] <= 'Z') { |
||||
if (i == 0 && !cap_next_letter) { |
||||
// Force first letter to lower-case unless explicitly told to
|
||||
// capitalize it.
|
||||
result += input[i] + ('a' - 'A'); |
||||
} else { |
||||
// Capital letters after the first are left as-is.
|
||||
result += input[i]; |
||||
} |
||||
cap_next_letter = false; |
||||
} else if ('0' <= input[i] && input[i] <= '9') { |
||||
result += input[i]; |
||||
cap_next_letter = true; |
||||
} else { |
||||
cap_next_letter = true; |
||||
} |
||||
} |
||||
// Add a trailing "_" if the name should be altered.
|
||||
if (input[input.size() - 1] == '#') { |
||||
result += '_'; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
std::string UnderscoresToPascalCase(const std::string& input) { |
||||
return UnderscoresToCamelCase(input, true); |
||||
} |
||||
|
||||
std::string ToCSharpName(const std::string& name, const FileDescriptor* file) { |
||||
std::string result = GetFileNamespace(file); |
||||
if (file->options().csharp_nest_classes()) { |
||||
if (result != "") { |
||||
result += "."; |
||||
} |
||||
result += GetFileUmbrellaClassname(file); |
||||
} |
||||
if (result != "") { |
||||
result += '.'; |
||||
} |
||||
string classname; |
||||
if (file->package().empty()) { |
||||
classname = name; |
||||
} else { |
||||
// Strip the proto package from full_name since we've replaced it with
|
||||
// the C# namespace.
|
||||
classname = name.substr(file->package().size() + 1); |
||||
} |
||||
result += StringReplace(classname, ".", ".Types.", false); |
||||
return "global::" + result; |
||||
} |
||||
|
||||
|
||||
|
||||
std::string GetFullUmbrellaClassName(const FileDescriptor* descriptor) { |
||||
std::string result = GetFileNamespace(descriptor); |
||||
if (!result.empty()) { |
||||
result += '.'; |
||||
} |
||||
result += GetQualifiedUmbrellaClassName(descriptor); |
||||
return "global::" + result; |
||||
} |
||||
|
||||
std::string GetQualifiedUmbrellaClassName(const FileDescriptor* descriptor) { |
||||
std::string umbrellaNamespace = GetFileUmbrellaNamespace(descriptor); |
||||
std::string umbrellaClassname = GetFileUmbrellaClassname(descriptor); |
||||
|
||||
std::string fullName = umbrellaClassname; |
||||
if (!descriptor->options().csharp_nest_classes() |
||||
&& !umbrellaNamespace.empty()) { |
||||
fullName = umbrellaNamespace + "." + umbrellaClassname; |
||||
} |
||||
return fullName; |
||||
} |
||||
|
||||
std::string GetClassName(const Descriptor* descriptor) { |
||||
return ToCSharpName(descriptor->full_name(), descriptor->file()); |
||||
} |
||||
|
||||
std::string GetClassName(const EnumDescriptor* descriptor) { |
||||
return ToCSharpName(descriptor->full_name(), descriptor->file()); |
||||
} |
||||
|
||||
// Groups are hacky: The name of the field is just the lower-cased name
|
||||
// of the group type. In C#, though, we would like to retain the original
|
||||
// capitalization of the type name.
|
||||
std::string GetFieldName(const FieldDescriptor* descriptor) { |
||||
if (descriptor->type() == FieldDescriptor::TYPE_GROUP) { |
||||
return descriptor->message_type()->name(); |
||||
} else { |
||||
return descriptor->name(); |
||||
} |
||||
} |
||||
|
||||
std::string GetFieldConstantName(const FieldDescriptor* field) { |
||||
return GetPropertyName(field) + "FieldNumber"; |
||||
} |
||||
|
||||
std::string GetPropertyName(const FieldDescriptor* descriptor) { |
||||
// TODO: fix this.
|
||||
std::string property_name = UnderscoresToPascalCase(GetFieldName(descriptor)); |
||||
if (property_name == descriptor->containing_type()->name()) { |
||||
property_name += "_"; |
||||
} |
||||
return property_name; |
||||
} |
||||
|
||||
// TODO: c&p from Java protoc plugin
|
||||
// For encodings with fixed sizes, returns that size in bytes. Otherwise
|
||||
// returns -1.
|
||||
int GetFixedSize(FieldDescriptor::Type type) { |
||||
switch (type) { |
||||
case FieldDescriptor::TYPE_INT32 : return -1; |
||||
case FieldDescriptor::TYPE_INT64 : return -1; |
||||
case FieldDescriptor::TYPE_UINT32 : return -1; |
||||
case FieldDescriptor::TYPE_UINT64 : return -1; |
||||
case FieldDescriptor::TYPE_SINT32 : return -1; |
||||
case FieldDescriptor::TYPE_SINT64 : return -1; |
||||
case FieldDescriptor::TYPE_FIXED32 : return internal::WireFormatLite::kFixed32Size; |
||||
case FieldDescriptor::TYPE_FIXED64 : return internal::WireFormatLite::kFixed64Size; |
||||
case FieldDescriptor::TYPE_SFIXED32: return internal::WireFormatLite::kSFixed32Size; |
||||
case FieldDescriptor::TYPE_SFIXED64: return internal::WireFormatLite::kSFixed64Size; |
||||
case FieldDescriptor::TYPE_FLOAT : return internal::WireFormatLite::kFloatSize; |
||||
case FieldDescriptor::TYPE_DOUBLE : return internal::WireFormatLite::kDoubleSize; |
||||
|
||||
case FieldDescriptor::TYPE_BOOL : return internal::WireFormatLite::kBoolSize; |
||||
case FieldDescriptor::TYPE_ENUM : return -1; |
||||
|
||||
case FieldDescriptor::TYPE_STRING : return -1; |
||||
case FieldDescriptor::TYPE_BYTES : return -1; |
||||
case FieldDescriptor::TYPE_GROUP : return -1; |
||||
case FieldDescriptor::TYPE_MESSAGE : return -1; |
||||
|
||||
// No default because we want the compiler to complain if any new
|
||||
// types are added.
|
||||
} |
||||
GOOGLE_LOG(FATAL) << "Can't get here."; |
||||
return -1; |
||||
} |
||||
|
||||
static const char base64_chars[] = |
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
||||
|
||||
std::string StringToBase64(const std::string& input) { |
||||
std::string result; |
||||
size_t remaining = input.size(); |
||||
const unsigned char *src = (const unsigned char*) input.c_str(); |
||||
while (remaining > 2) { |
||||
result += base64_chars[src[0] >> 2]; |
||||
result += base64_chars[((src[0] & 0x3) << 4) | (src[1] >> 4)]; |
||||
result += base64_chars[((src[1] & 0xf) << 2) | (src[2] >> 6)]; |
||||
result += base64_chars[src[2] & 0x3f]; |
||||
remaining -= 3; |
||||
src += 3; |
||||
} |
||||
switch (remaining) { |
||||
case 2: |
||||
result += base64_chars[src[0] >> 2]; |
||||
result += base64_chars[((src[0] & 0x3) << 4) | (src[1] >> 4)]; |
||||
result += base64_chars[(src[1] & 0xf) << 2]; |
||||
result += '='; |
||||
src += 2; |
||||
break; |
||||
case 1: |
||||
result += base64_chars[src[0] >> 2]; |
||||
result += base64_chars[((src[0] & 0x3) << 4)]; |
||||
result += '='; |
||||
result += '='; |
||||
src += 1; |
||||
break; |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
std::string FileDescriptorToBase64(const FileDescriptor* descriptor) { |
||||
std::string fdp_bytes; |
||||
FileDescriptorProto fdp; |
||||
descriptor->CopyTo(&fdp); |
||||
fdp.SerializeToString(&fdp_bytes); |
||||
return StringToBase64(fdp_bytes); |
||||
} |
||||
|
||||
FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor, |
||||
int fieldOrdinal) { |
||||
switch (descriptor->type()) { |
||||
case FieldDescriptor::TYPE_GROUP: |
||||
case FieldDescriptor::TYPE_MESSAGE: |
||||
if (descriptor->is_repeated()) { |
||||
return new RepeatedMessageFieldGenerator(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); |
||||
} |
||||
default: |
||||
if (descriptor->is_repeated()) { |
||||
return new RepeatedPrimitiveFieldGenerator(descriptor, fieldOrdinal); |
||||
} else { |
||||
return new PrimitiveFieldGenerator(descriptor, fieldOrdinal); |
||||
} |
||||
} |
||||
} |
||||
|
||||
bool HasRequiredFields(const Descriptor* descriptor) { |
||||
// TODO(jtattermusch): implement this.
|
||||
return true; |
||||
} |
||||
|
||||
} // namespace java
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,108 @@ |
||||
// 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.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__ |
||||
|
||||
#include <string> |
||||
#include <google/protobuf/descriptor.pb.h> |
||||
#include <google/protobuf/descriptor.h> |
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
#include <google/protobuf/io/printer.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class FieldGeneratorBase; |
||||
|
||||
// TODO: start using this enum.
|
||||
enum CSharpType { |
||||
CSHARPTYPE_INT32 = 1, |
||||
CSHARPTYPE_INT64 = 2, |
||||
CSHARPTYPE_UINT32 = 3, |
||||
CSHARPTYPE_UINT64 = 4, |
||||
CSHARPTYPE_FLOAT = 5, |
||||
CSHARPTYPE_DOUBLE = 6, |
||||
CSHARPTYPE_BOOL = 7, |
||||
CSHARPTYPE_STRING = 8, |
||||
CSHARPTYPE_BYTESTRING = 9, |
||||
CSHARPTYPE_MESSAGE = 10, |
||||
CSHARPTYPE_ENUM = 11, |
||||
MAX_CSHARPTYPE = 11 |
||||
}; |
||||
|
||||
// Converts field type to corresponding C# type.
|
||||
CSharpType GetCSharpType(FieldDescriptor::Type type); |
||||
|
||||
std::string StripDotProto(const std::string& proto_file); |
||||
|
||||
std::string GetFileNamespace(const FileDescriptor* descriptor); |
||||
std::string GetFileUmbrellaClassname(const FileDescriptor* descriptor); |
||||
std::string GetFileUmbrellaNamespace(const FileDescriptor* descriptor); |
||||
|
||||
std::string GetFullUmbrellaClassName(const FileDescriptor* descriptor); |
||||
|
||||
std::string GetQualifiedUmbrellaClassName(const FileDescriptor* descriptor); |
||||
|
||||
std::string GetClassName(const Descriptor* descriptor); |
||||
std::string GetClassName(const EnumDescriptor* descriptor); |
||||
|
||||
std::string GetFieldName(const FieldDescriptor* descriptor); |
||||
|
||||
std::string GetFieldConstantName(const FieldDescriptor* field); |
||||
|
||||
std::string GetPropertyName(const FieldDescriptor* descriptor); |
||||
|
||||
int GetFixedSize(FieldDescriptor::Type type); |
||||
|
||||
std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter); |
||||
|
||||
std::string UnderscoresToPascalCase(const std::string& input); |
||||
|
||||
// TODO(jtattermusch): perhaps we could move this to strutil
|
||||
std::string StringToBase64(const std::string& input); |
||||
|
||||
std::string FileDescriptorToBase64(const FileDescriptor* descriptor); |
||||
|
||||
FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); |
||||
|
||||
bool HasRequiredFields(const Descriptor* descriptor); |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__
|
@ -0,0 +1,900 @@ |
||||
// 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 <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_enum.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_extension.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_message.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_field_base.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_writer.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) |
||||
: SourceGeneratorBase(descriptor->file()), |
||||
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() { |
||||
// TODO: check correctness.
|
||||
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_; |
||||
} |
||||
|
||||
/// Get an identifier that uniquely identifies this type within the file.
|
||||
/// This is used to declare static variables related to this type at the
|
||||
/// outermost file scope.
|
||||
std::string GetUniqueFileScopeIdentifier(const Descriptor* descriptor) { |
||||
std::string result = descriptor->full_name(); |
||||
std::replace(result.begin(), result.end(), '.', '_'); |
||||
return "static_" + result; |
||||
} |
||||
|
||||
void MessageGenerator::GenerateStaticVariables(Writer* writer) { |
||||
// Because descriptor.proto (Google.ProtocolBuffers.DescriptorProtos) is
|
||||
// used in the construction of descriptors, we have a tricky bootstrapping
|
||||
// problem. To help control static initialization order, we make sure all
|
||||
// descriptors and other static data that depends on them are members of
|
||||
// the proto-descriptor class. This way, they will be initialized in
|
||||
// a deterministic order.
|
||||
|
||||
std::string identifier = GetUniqueFileScopeIdentifier(descriptor_); |
||||
|
||||
if (!use_lite_runtime()) { |
||||
// The descriptor for this type.
|
||||
std::string access = |
||||
descriptor_->file()->options().csharp_nest_classes() ? |
||||
"private" : "internal"; |
||||
writer->WriteLine( |
||||
"$0$ static pbd::MessageDescriptor internal__$1$__Descriptor;", access, |
||||
identifier); |
||||
writer->WriteLine( |
||||
"$0$ static pb::FieldAccess.FieldAccessorTable<$1$, $1$.Builder> internal__$2$__FieldAccessorTable;", |
||||
access, full_class_name(), identifier); |
||||
} |
||||
|
||||
for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
||||
MessageGenerator messageGenerator(descriptor_->nested_type(i)); |
||||
messageGenerator.GenerateStaticVariables(writer); |
||||
} |
||||
} |
||||
|
||||
void MessageGenerator::GenerateStaticVariableInitializers(Writer* writer) { |
||||
std::string identifier = GetUniqueFileScopeIdentifier(descriptor_); |
||||
|
||||
if (!use_lite_runtime()) { |
||||
writer->Write("internal__$0$__Descriptor = ", identifier); |
||||
|
||||
if (!descriptor_->containing_type()) { |
||||
writer->WriteLine("Descriptor.MessageTypes[$0$];", |
||||
SimpleItoa(descriptor_->index())); |
||||
} else { |
||||
writer->WriteLine( |
||||
"internal__$0$__Descriptor.NestedTypes[$1$];", |
||||
GetUniqueFileScopeIdentifier(descriptor_->containing_type()), |
||||
SimpleItoa(descriptor_->index())); |
||||
} |
||||
|
||||
writer->WriteLine("internal__$0$__FieldAccessorTable = ", identifier); |
||||
writer->WriteLine( |
||||
" new pb::FieldAccess.FieldAccessorTable<$1$, $1$.Builder>(internal__$0$__Descriptor,", |
||||
identifier, full_class_name()); |
||||
writer->Write(" new string[] { "); |
||||
for (int i = 0; i < descriptor_->field_count(); i++) { |
||||
writer->Write("\"$0$\", ", GetPropertyName(descriptor_->field(i))); |
||||
} |
||||
writer->WriteLine("});"); |
||||
} |
||||
|
||||
// Generate static member initializers for all nested types.
|
||||
for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
||||
MessageGenerator messageGenerator(descriptor_->nested_type(i)); |
||||
messageGenerator.GenerateStaticVariableInitializers(writer); |
||||
} |
||||
|
||||
for (int i = 0; i < descriptor_->extension_count(); i++) { |
||||
ExtensionGenerator extensionGenerator(descriptor_->extension(i)); |
||||
extensionGenerator.GenerateStaticVariableInitializers(writer); |
||||
} |
||||
} |
||||
|
||||
void MessageGenerator::Generate(Writer* writer) { |
||||
if (descriptor_->file()->options().csharp_add_serializable()) { |
||||
writer->WriteLine("[global::System.SerializableAttribute()]"); |
||||
} |
||||
writer->WriteLine( |
||||
"[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]"); |
||||
WriteGeneratedCodeAttributes(writer); |
||||
writer->WriteLine( |
||||
"$0$ sealed partial class $1$ : pb::$2$Message$3$<$1$, $1$.Builder> {", |
||||
class_access_level(), class_name(), |
||||
descriptor_->extension_range_count() > 0 ? "Extendable" : "Generated", |
||||
runtime_suffix()); |
||||
writer->Indent(); |
||||
if (descriptor_->file()->options().csharp_generate_private_ctor()) { |
||||
writer->WriteLine("private $0$() { }", class_name()); |
||||
} |
||||
// Must call MakeReadOnly() to make sure all lists are made read-only
|
||||
writer->WriteLine( |
||||
"private static readonly $0$ defaultInstance = new $0$().MakeReadOnly();", |
||||
class_name()); |
||||
|
||||
if (optimize_speed()) { |
||||
writer->WriteLine( |
||||
"private static readonly string[] _$0$FieldNames = new string[] { $2$$1$$2$ };", |
||||
UnderscoresToCamelCase(class_name(), false), |
||||
JoinStrings(field_names(), "\", \""), |
||||
field_names().size() > 0 ? "\"" : ""); |
||||
std::vector<std::string> tags; |
||||
for (int i = 0; i < field_names().size(); i++) { |
||||
uint32 tag = internal::WireFormat::MakeTag( |
||||
descriptor_->FindFieldByName(field_names()[i])); |
||||
tags.push_back(SimpleItoa(tag)); |
||||
} |
||||
writer->WriteLine( |
||||
"private static readonly uint[] _$0$FieldTags = new uint[] { $1$ };", |
||||
UnderscoresToCamelCase(class_name(), false), JoinStrings(tags, ", ")); |
||||
} |
||||
writer->WriteLine("public static $0$ DefaultInstance {", class_name()); |
||||
writer->WriteLine(" get { return defaultInstance; }"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
writer->WriteLine("public override $0$ DefaultInstanceForType {", |
||||
class_name()); |
||||
writer->WriteLine(" get { return DefaultInstance; }"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
writer->WriteLine("protected override $0$ ThisMessage {", class_name()); |
||||
writer->WriteLine(" get { return this; }"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
if (!use_lite_runtime()) { |
||||
writer->WriteLine("public static pbd::MessageDescriptor Descriptor {"); |
||||
writer->WriteLine(" get { return $0$.internal__$1$__Descriptor; }", |
||||
GetFullUmbrellaClassName(descriptor_->file()), |
||||
GetUniqueFileScopeIdentifier(descriptor_)); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
writer->WriteLine( |
||||
"protected override pb::FieldAccess.FieldAccessorTable<$0$, $0$.Builder> InternalFieldAccessors {", |
||||
class_name()); |
||||
writer->WriteLine(" get { return $0$.internal__$1$__FieldAccessorTable; }", |
||||
GetFullUmbrellaClassName(descriptor_->file()), |
||||
GetUniqueFileScopeIdentifier(descriptor_)); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
// Extensions don't need to go in an extra nested type
|
||||
for (int i = 0; i < descriptor_->extension_count(); i++) { |
||||
ExtensionGenerator extensionGenerator(descriptor_->extension(i)); |
||||
extensionGenerator.Generate(writer); |
||||
} |
||||
|
||||
if (descriptor_->enum_type_count() + descriptor_->nested_type_count() > 0) { |
||||
writer->WriteLine("#region Nested types"); |
||||
writer->WriteLine( |
||||
"[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]"); |
||||
WriteGeneratedCodeAttributes(writer); |
||||
writer->WriteLine("public static partial class Types {"); |
||||
writer->Indent(); |
||||
for (int i = 0; i < descriptor_->enum_type_count(); i++) { |
||||
EnumGenerator enumGenerator(descriptor_->enum_type(i)); |
||||
enumGenerator.Generate(writer); |
||||
} |
||||
for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
||||
MessageGenerator messageGenerator(descriptor_->nested_type(i)); |
||||
messageGenerator.Generate(writer); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine("#endregion"); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
for (int i = 0; i < descriptor_->field_count(); i++) { |
||||
const FieldDescriptor* fieldDescriptor = descriptor_->field(i); |
||||
// TODO(jtattermusch): same code for cls compliance is in csharp_extension
|
||||
if (descriptor_->file()->options().csharp_cls_compliance() |
||||
&& GetFieldConstantName(fieldDescriptor)[0] == '_') { |
||||
writer->WriteLine("[global::System.CLSCompliant(false)]"); |
||||
} |
||||
|
||||
// Rats: we lose the debug comment here :(
|
||||
writer->WriteLine("public const int $0$ = $1$;", |
||||
GetFieldConstantName(fieldDescriptor), |
||||
SimpleItoa(fieldDescriptor->number())); |
||||
scoped_ptr<FieldGeneratorBase> generator( |
||||
CreateFieldGeneratorInternal(fieldDescriptor)); |
||||
generator->GenerateMembers(writer); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
if (optimize_speed()) { |
||||
GenerateIsInitialized(writer); |
||||
GenerateMessageSerializationMethods(writer); |
||||
} |
||||
if (use_lite_runtime()) { |
||||
GenerateLiteRuntimeMethods(writer); |
||||
} |
||||
|
||||
GenerateParseFromMethods(writer); |
||||
GenerateBuilder(writer); |
||||
|
||||
// Force the static initialization code for the file to run, since it may
|
||||
// initialize static variables declared in this class.
|
||||
writer->WriteLine("static $0$() {", class_name()); |
||||
// We call object.ReferenceEquals() just to make it a valid statement on its own.
|
||||
// Another option would be GetType(), but that causes problems in DescriptorProtoFile,
|
||||
// where the bootstrapping is somewhat recursive - type initializers call
|
||||
// each other, effectively. We temporarily see Descriptor as null.
|
||||
writer->WriteLine(" object.ReferenceEquals($0$.Descriptor, null);", |
||||
GetFullUmbrellaClassName(descriptor_->file())); |
||||
writer->WriteLine("}"); |
||||
|
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
|
||||
} |
||||
|
||||
void MessageGenerator::GenerateLiteRuntimeMethods(Writer* writer) { |
||||
bool callbase = descriptor_->extension_range_count() > 0; |
||||
writer->WriteLine("#region Lite runtime methods"); |
||||
writer->WriteLine("public override int GetHashCode() {"); |
||||
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); |
||||
} |
||||
if (callbase) { |
||||
writer->WriteLine("hash ^= base.GetHashCode();"); |
||||
} |
||||
writer->WriteLine("return hash;"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
|
||||
writer->WriteLine("public override bool Equals(object obj) {"); |
||||
writer->Indent(); |
||||
writer->WriteLine("$0$ other = obj as $0$;", class_name()); |
||||
writer->WriteLine("if (other == null) return false;"); |
||||
for (int i = 0; i < descriptor_->field_count(); i++) { |
||||
scoped_ptr<FieldGeneratorBase> generator( |
||||
CreateFieldGeneratorInternal(descriptor_->field(i))); |
||||
generator->WriteEquals(writer); |
||||
} |
||||
if (callbase) { |
||||
writer->WriteLine("if (!base.Equals(other)) return false;"); |
||||
} |
||||
writer->WriteLine("return true;"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
|
||||
writer->WriteLine( |
||||
"public override void PrintTo(global::System.IO.TextWriter writer) {"); |
||||
writer->Indent(); |
||||
|
||||
for (int i = 0; i < fields_by_number().size(); i++) { |
||||
scoped_ptr<FieldGeneratorBase> generator( |
||||
CreateFieldGeneratorInternal(fields_by_number()[i])); |
||||
generator->WriteToString(writer); |
||||
} |
||||
|
||||
if (callbase) { |
||||
writer->WriteLine("base.PrintTo(writer);"); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine("#endregion"); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
bool CompareExtensionRangesStart(const Descriptor::ExtensionRange* r1, |
||||
const Descriptor::ExtensionRange* r2) { |
||||
return r1->start < r2->start; |
||||
} |
||||
|
||||
void MessageGenerator::GenerateMessageSerializationMethods(Writer* writer) { |
||||
std::vector<const Descriptor::ExtensionRange*> extension_ranges_sorted; |
||||
for (int i = 0; i < descriptor_->extension_range_count(); i++) { |
||||
extension_ranges_sorted.push_back(descriptor_->extension_range(i)); |
||||
} |
||||
std::sort(extension_ranges_sorted.begin(), extension_ranges_sorted.end(), |
||||
CompareExtensionRangesStart); |
||||
|
||||
writer->WriteLine( |
||||
"public override void WriteTo(pb::ICodedOutputStream output) {"); |
||||
writer->Indent(); |
||||
// Make sure we've computed the serialized length, so that packed fields are generated correctly.
|
||||
writer->WriteLine("int size = SerializedSize;"); |
||||
writer->WriteLine("string[] field_names = _$0$FieldNames;", |
||||
UnderscoresToCamelCase(class_name(), false)); |
||||
if (descriptor_->extension_range_count()) { |
||||
writer->WriteLine( |
||||
"pb::ExtendableMessage$1$<$0$, $0$.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);", |
||||
class_name(), runtime_suffix()); |
||||
} |
||||
|
||||
// Merge the fields and the extension ranges, both sorted by field number.
|
||||
for (int i = 0, j = 0; |
||||
i < fields_by_number().size() || j < extension_ranges_sorted.size();) { |
||||
if (i == fields_by_number().size()) { |
||||
GenerateSerializeOneExtensionRange(writer, extension_ranges_sorted[j++]); |
||||
} else if (j == extension_ranges_sorted.size()) { |
||||
GenerateSerializeOneField(writer, fields_by_number()[i++]); |
||||
} else if (fields_by_number()[i]->number() |
||||
< extension_ranges_sorted[j]->start) { |
||||
GenerateSerializeOneField(writer, fields_by_number()[i++]); |
||||
} else { |
||||
GenerateSerializeOneExtensionRange(writer, extension_ranges_sorted[j++]); |
||||
} |
||||
} |
||||
|
||||
if (!use_lite_runtime()) { |
||||
if (descriptor_->options().message_set_wire_format()) |
||||
{ |
||||
writer->WriteLine("UnknownFields.WriteAsMessageSetTo(output);"); |
||||
} else { |
||||
writer->WriteLine("UnknownFields.WriteTo(output);"); |
||||
} |
||||
} |
||||
|
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
writer->WriteLine("private int memoizedSerializedSize = -1;"); |
||||
writer->WriteLine("public override int SerializedSize {"); |
||||
writer->Indent(); |
||||
writer->WriteLine("get {"); |
||||
writer->Indent(); |
||||
writer->WriteLine("int size = memoizedSerializedSize;"); |
||||
writer->WriteLine("if (size != -1) return size;"); |
||||
writer->WriteLine(); |
||||
writer->WriteLine("size = 0;"); |
||||
for (int i = 0; i < descriptor_->field_count(); i++) { |
||||
scoped_ptr<FieldGeneratorBase> generator( |
||||
CreateFieldGeneratorInternal(descriptor_->field(i))); |
||||
generator->GenerateSerializedSizeCode(writer); |
||||
} |
||||
if (descriptor_->extension_range_count() > 0) { |
||||
writer->WriteLine("size += ExtensionsSerializedSize;"); |
||||
} |
||||
|
||||
if (!use_lite_runtime()) { |
||||
if (descriptor_->options().message_set_wire_format()) { |
||||
writer->WriteLine("size += UnknownFields.SerializedSizeAsMessageSet;"); |
||||
} else { |
||||
writer->WriteLine("size += UnknownFields.SerializedSize;"); |
||||
} |
||||
} |
||||
writer->WriteLine("memoizedSerializedSize = size;"); |
||||
writer->WriteLine("return size;"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
void MessageGenerator::GenerateSerializeOneField( |
||||
Writer* writer, const FieldDescriptor* fieldDescriptor) { |
||||
scoped_ptr<FieldGeneratorBase> generator( |
||||
CreateFieldGeneratorInternal(fieldDescriptor)); |
||||
generator->GenerateSerializationCode(writer); |
||||
} |
||||
|
||||
void MessageGenerator::GenerateSerializeOneExtensionRange( |
||||
Writer* writer, const Descriptor::ExtensionRange* extensionRange) { |
||||
writer->WriteLine("extensionWriter.WriteUntil($0$, output);", |
||||
SimpleItoa(extensionRange->end)); |
||||
} |
||||
|
||||
void MessageGenerator::GenerateParseFromMethods(Writer* writer) { |
||||
// Note: These are separate from GenerateMessageSerializationMethods()
|
||||
// because they need to be generated even for messages that are optimized
|
||||
// for code size.
|
||||
|
||||
writer->WriteLine("public static $0$ ParseFrom(pb::ByteString data) {", |
||||
class_name()); |
||||
writer->WriteLine( |
||||
" return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine( |
||||
"public static $0$ ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {", |
||||
class_name()); |
||||
writer->WriteLine( |
||||
" return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine("public static $0$ ParseFrom(byte[] data) {", class_name()); |
||||
writer->WriteLine( |
||||
" return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine( |
||||
"public static $0$ ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {", |
||||
class_name()); |
||||
writer->WriteLine( |
||||
" return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine( |
||||
"public static $0$ ParseFrom(global::System.IO.Stream input) {", |
||||
class_name()); |
||||
writer->WriteLine( |
||||
" return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine( |
||||
"public static $0$ ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {", |
||||
class_name()); |
||||
writer->WriteLine( |
||||
" return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine( |
||||
"public static $0$ ParseDelimitedFrom(global::System.IO.Stream input) {", |
||||
class_name()); |
||||
writer->WriteLine( |
||||
" return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine( |
||||
"public static $0$ ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {", |
||||
class_name()); |
||||
writer->WriteLine( |
||||
" return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine( |
||||
"public static $0$ ParseFrom(pb::ICodedInputStream input) {", |
||||
class_name()); |
||||
writer->WriteLine( |
||||
" return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine( |
||||
"public static $0$ ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {", |
||||
class_name()); |
||||
writer->WriteLine( |
||||
" return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();"); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void MessageGenerator::GenerateBuilder(Writer* writer) { |
||||
writer->WriteLine("private $0$ MakeReadOnly() {", class_name()); |
||||
writer->Indent(); |
||||
for (int i = 0; i < descriptor_->field_count(); i++) { |
||||
scoped_ptr<FieldGeneratorBase> generator( |
||||
CreateFieldGeneratorInternal(descriptor_->field(i))); |
||||
generator->GenerateBuildingCode(writer); |
||||
} |
||||
writer->WriteLine("return this;"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
|
||||
writer->WriteLine( |
||||
"public static Builder CreateBuilder() { return new Builder(); }"); |
||||
writer->WriteLine( |
||||
"public override Builder ToBuilder() { return CreateBuilder(this); }"); |
||||
writer->WriteLine( |
||||
"public override Builder CreateBuilderForType() { return new Builder(); }"); |
||||
writer->WriteLine("public static Builder CreateBuilder($0$ prototype) {", |
||||
class_name()); |
||||
writer->WriteLine(" return new Builder(prototype);"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
if (descriptor_->file()->options().csharp_add_serializable()) { |
||||
writer->WriteLine("[global::System.SerializableAttribute()]"); |
||||
} |
||||
writer->WriteLine( |
||||
"[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]"); |
||||
WriteGeneratedCodeAttributes(writer); |
||||
writer->WriteLine( |
||||
"$0$ sealed partial class Builder : pb::$2$Builder$3$<$1$, Builder> {", |
||||
class_access_level(), class_name(), |
||||
descriptor_->extension_range_count() > 0 ? "Extendable" : "Generated", |
||||
runtime_suffix()); |
||||
writer->Indent(); |
||||
writer->WriteLine("protected override Builder ThisBuilder {"); |
||||
writer->WriteLine(" get { return this; }"); |
||||
writer->WriteLine("}"); |
||||
GenerateCommonBuilderMethods(writer); |
||||
if (optimize_speed()) { |
||||
GenerateBuilderParsingMethods(writer); |
||||
} |
||||
for (int i = 0; i < descriptor_->field_count(); i++) { |
||||
scoped_ptr<FieldGeneratorBase> generator( |
||||
CreateFieldGeneratorInternal(descriptor_->field(i))); |
||||
writer->WriteLine(); |
||||
// No field comment :(
|
||||
generator->GenerateBuilderMembers(writer); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void MessageGenerator::GenerateCommonBuilderMethods(Writer* writer) { |
||||
//default constructor
|
||||
writer->WriteLine("public Builder() {"); |
||||
//Durring static initialization of message, DefaultInstance is expected to return null.
|
||||
writer->WriteLine(" result = DefaultInstance;"); |
||||
writer->WriteLine(" resultIsReadOnly = true;"); |
||||
writer->WriteLine("}"); |
||||
//clone constructor
|
||||
writer->WriteLine("internal Builder($0$ cloneFrom) {", class_name()); |
||||
writer->WriteLine(" result = cloneFrom;"); |
||||
writer->WriteLine(" resultIsReadOnly = true;"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
writer->WriteLine("private bool resultIsReadOnly;"); |
||||
writer->WriteLine("private $0$ result;", class_name()); |
||||
writer->WriteLine(); |
||||
writer->WriteLine("private $0$ PrepareBuilder() {", class_name()); |
||||
writer->WriteLine(" if (resultIsReadOnly) {"); |
||||
writer->WriteLine(" $0$ original = result;", class_name()); |
||||
writer->WriteLine(" result = new $0$();", class_name()); |
||||
writer->WriteLine(" resultIsReadOnly = false;"); |
||||
writer->WriteLine(" MergeFrom(original);"); |
||||
writer->WriteLine(" }"); |
||||
writer->WriteLine(" return result;"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
writer->WriteLine("public override bool IsInitialized {"); |
||||
writer->WriteLine(" get { return result.IsInitialized; }"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
writer->WriteLine("protected override $0$ MessageBeingBuilt {", class_name()); |
||||
writer->WriteLine(" get { return PrepareBuilder(); }"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
//Not actually expecting that DefaultInstance would ever be null here; however, we will ensure it does not break
|
||||
writer->WriteLine("public override Builder Clear() {"); |
||||
writer->WriteLine(" result = DefaultInstance;"); |
||||
writer->WriteLine(" resultIsReadOnly = true;"); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
writer->WriteLine("public override Builder Clone() {"); |
||||
writer->WriteLine(" if (resultIsReadOnly) {"); |
||||
writer->WriteLine(" return new Builder(result);"); |
||||
writer->WriteLine(" } else {"); |
||||
writer->WriteLine(" return new Builder().MergeFrom(result);"); |
||||
writer->WriteLine(" }"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
if (!use_lite_runtime()) { |
||||
writer->WriteLine( |
||||
"public override pbd::MessageDescriptor DescriptorForType {"); |
||||
writer->WriteLine(" get { return $0$.Descriptor; }", full_class_name()); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
} |
||||
writer->WriteLine("public override $0$ DefaultInstanceForType {", |
||||
class_name()); |
||||
writer->WriteLine(" get { return $0$.DefaultInstance; }", full_class_name()); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
|
||||
writer->WriteLine("public override $0$ BuildPartial() {", class_name()); |
||||
writer->Indent(); |
||||
writer->WriteLine("if (resultIsReadOnly) {"); |
||||
writer->WriteLine(" return result;"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine("resultIsReadOnly = true;"); |
||||
writer->WriteLine("return result.MakeReadOnly();"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
|
||||
if (optimize_speed()) { |
||||
writer->WriteLine( |
||||
"public override Builder MergeFrom(pb::IMessage$0$ other) {", |
||||
runtime_suffix()); |
||||
writer->WriteLine(" if (other is $0$) {", class_name()); |
||||
writer->WriteLine(" return MergeFrom(($0$) other);", class_name()); |
||||
writer->WriteLine(" } else {"); |
||||
writer->WriteLine(" base.MergeFrom(other);"); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine(" }"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
writer->WriteLine("public override Builder MergeFrom($0$ other) {", |
||||
class_name()); |
||||
// Optimization: If other is the default instance, we know none of its
|
||||
// fields are set so we can skip the merge.
|
||||
writer->Indent(); |
||||
writer->WriteLine("if (other == $0$.DefaultInstance) return this;", |
||||
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 message type has extensions
|
||||
if (descriptor_->extension_range_count() > 0) { |
||||
writer->WriteLine(" this.MergeExtensionFields(other);"); |
||||
} |
||||
if (!use_lite_runtime()) { |
||||
writer->WriteLine("this.MergeUnknownFields(other.UnknownFields);"); |
||||
} |
||||
writer->WriteLine("return this;"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
} |
||||
|
||||
void MessageGenerator::GenerateBuilderParsingMethods(Writer* writer) { |
||||
writer->WriteLine( |
||||
"public override Builder MergeFrom(pb::ICodedInputStream input) {"); |
||||
writer->WriteLine(" return MergeFrom(input, pb::ExtensionRegistry.Empty);"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
writer->WriteLine( |
||||
"public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {"); |
||||
writer->Indent(); |
||||
writer->WriteLine("PrepareBuilder();"); |
||||
if (!use_lite_runtime()) { |
||||
writer->WriteLine("pb::UnknownFieldSet.Builder unknownFields = null;"); |
||||
} |
||||
writer->WriteLine("uint tag;"); |
||||
writer->WriteLine("string field_name;"); |
||||
writer->WriteLine("while (input.ReadTag(out tag, out field_name)) {"); |
||||
writer->Indent(); |
||||
writer->WriteLine("if(tag == 0 && field_name != null) {"); |
||||
writer->Indent(); |
||||
//if you change from StringComparer.Ordinal, the array sort in FieldNames { get; } must also change
|
||||
writer->WriteLine( |
||||
"int field_ordinal = global::System.Array.BinarySearch(_$0$FieldNames, field_name, global::System.StringComparer.Ordinal);", |
||||
UnderscoresToCamelCase(class_name(), false)); |
||||
writer->WriteLine("if(field_ordinal >= 0)"); |
||||
writer->WriteLine(" tag = _$0$FieldTags[field_ordinal];", |
||||
UnderscoresToCamelCase(class_name(), false)); |
||||
writer->WriteLine("else {"); |
||||
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( |
||||
" ParseUnknownField(input, $0$extensionRegistry, tag, field_name);", |
||||
use_lite_runtime() ? "" : "unknownFields, "); |
||||
writer->WriteLine(" continue;"); |
||||
writer->WriteLine("}"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
|
||||
writer->WriteLine("switch (tag) {"); |
||||
writer->Indent(); |
||||
writer->WriteLine("case 0: {"); // 0 signals EOF / limit reached
|
||||
writer->WriteLine(" throw pb::InvalidProtocolBufferException.InvalidTag();"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine("default: {"); |
||||
writer->WriteLine(" if (pb::WireFormat.IsEndGroupTag(tag)) {"); |
||||
if (!use_lite_runtime()) { |
||||
writer->WriteLine(" if (unknownFields != null) {"); |
||||
writer->WriteLine(" this.UnknownFields = unknownFields.Build();"); |
||||
writer->WriteLine(" }"); |
||||
} |
||||
writer->WriteLine(" return this;"); // it's an endgroup tag
|
||||
writer->WriteLine(" }"); |
||||
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( |
||||
" ParseUnknownField(input, $0$extensionRegistry, tag, field_name);", |
||||
use_lite_runtime() ? "" : "unknownFields, "); |
||||
writer->WriteLine(" break;"); |
||||
writer->WriteLine("}"); |
||||
|
||||
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); |
||||
if (field->is_repeated() |
||||
&& (wt == internal::WireFormatLite::WIRETYPE_VARINT |
||||
|| wt == internal::WireFormatLite::WIRETYPE_FIXED32 |
||||
|| wt == internal::WireFormatLite::WIRETYPE_FIXED64)) { |
||||
writer->WriteLine( |
||||
"case $0$:", |
||||
SimpleItoa( |
||||
internal::WireFormatLite::MakeTag( |
||||
field->number(), |
||||
internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED))); |
||||
} |
||||
|
||||
writer->WriteLine("case $0$: {", SimpleItoa(tag)); |
||||
writer->Indent(); |
||||
scoped_ptr<FieldGeneratorBase> generator( |
||||
CreateFieldGeneratorInternal(field)); |
||||
generator->GenerateParsingCode(writer); |
||||
writer->WriteLine("break;"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
if (!use_lite_runtime()) { |
||||
writer->WriteLine("if (unknownFields != null) {"); |
||||
writer->WriteLine(" this.UnknownFields = unknownFields.Build();"); |
||||
writer->WriteLine("}"); |
||||
} |
||||
writer->WriteLine("return this;"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
void MessageGenerator::GenerateIsInitialized(Writer* writer) { |
||||
writer->WriteLine("public override bool IsInitialized {"); |
||||
writer->Indent(); |
||||
writer->WriteLine("get {"); |
||||
writer->Indent(); |
||||
|
||||
// Check that all required fields in this message are set.
|
||||
// TODO(kenton): We can optimize this when we switch to putting all the
|
||||
// "has" fields into a single bitfield.
|
||||
for (int i = 0; i < descriptor_->field_count(); i++) { |
||||
if (descriptor_->field(i)->is_required()) { |
||||
writer->WriteLine("if (!has$0$) return false;", |
||||
GetPropertyName(descriptor_->field(i))); |
||||
} |
||||
} |
||||
|
||||
// Now check that all embedded messages are initialized.
|
||||
for (int i = 0; i < descriptor_->field_count(); i++) { |
||||
const FieldDescriptor* field = descriptor_->field(i); |
||||
|
||||
if (field->type() != FieldDescriptor::TYPE_MESSAGE || |
||||
!HasRequiredFields(field->message_type())) |
||||
{ |
||||
continue; |
||||
} |
||||
// TODO(jtattermusch): shouldn't we use GetPropertyName here?
|
||||
string propertyName = UnderscoresToPascalCase(GetFieldName(field)); |
||||
if (field->is_repeated()) |
||||
{ |
||||
writer->WriteLine("foreach ($0$ element in $1$List) {", |
||||
GetClassName(field->message_type()), |
||||
propertyName); |
||||
writer->WriteLine(" if (!element.IsInitialized) return false;"); |
||||
writer->WriteLine("}"); |
||||
} |
||||
else if (field->is_optional()) |
||||
{ |
||||
writer->WriteLine("if (Has$0$) {", propertyName); |
||||
writer->WriteLine(" if (!$0$.IsInitialized) return false;", propertyName); |
||||
writer->WriteLine("}"); |
||||
} |
||||
else |
||||
{ |
||||
writer->WriteLine("if (!$0$.IsInitialized) return false;", propertyName); |
||||
} |
||||
} |
||||
|
||||
if (descriptor_->extension_range_count() > 0) { |
||||
writer->WriteLine("if (!ExtensionsAreInitialized) return false;"); |
||||
} |
||||
writer->WriteLine("return true;"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
void MessageGenerator::GenerateExtensionRegistrationCode(Writer* writer) { |
||||
for (int i = 0; i < descriptor_->extension_count(); i++) { |
||||
ExtensionGenerator extensionGenerator(descriptor_->extension(i)); |
||||
extensionGenerator.GenerateExtensionRegistrationCode(writer); |
||||
} |
||||
for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
||||
MessageGenerator messageGenerator(descriptor_->nested_type(i)); |
||||
messageGenerator.GenerateExtensionRegistrationCode(writer); |
||||
} |
||||
} |
||||
|
||||
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)); |
||||
} |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,98 @@ |
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__ |
||||
|
||||
#include <string> |
||||
#include <vector> |
||||
|
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_helpers.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class Writer; |
||||
class FieldGeneratorBase; |
||||
|
||||
class MessageGenerator : public SourceGeneratorBase { |
||||
public: |
||||
MessageGenerator(const Descriptor* descriptor); |
||||
~MessageGenerator(); |
||||
|
||||
void GenerateStaticVariables(Writer* printer); |
||||
void GenerateStaticVariableInitializers(Writer* printer); |
||||
void GenerateExtensionRegistrationCode(Writer* printer); |
||||
void Generate(Writer* printer); |
||||
|
||||
private: |
||||
const Descriptor* descriptor_; |
||||
std::vector<std::string> field_names_; |
||||
std::vector<const FieldDescriptor*> fields_by_number_; |
||||
|
||||
void GenerateLiteRuntimeMethods(Writer* writer); |
||||
void GenerateMessageSerializationMethods(Writer* writer); |
||||
void GenerateSerializeOneField(Writer* writer, |
||||
const FieldDescriptor* fieldDescriptor); |
||||
void GenerateSerializeOneExtensionRange( |
||||
Writer* writer, const Descriptor::ExtensionRange* extendsionRange); |
||||
void GenerateParseFromMethods(Writer* writer); |
||||
void GenerateBuilder(Writer* writer); |
||||
void GenerateCommonBuilderMethods(Writer* writer); |
||||
void GenerateBuilderParsingMethods(Writer* writer); |
||||
void GenerateIsInitialized(Writer* writer); |
||||
|
||||
int GetFieldOrdinal(const FieldDescriptor* descriptor); |
||||
FieldGeneratorBase* CreateFieldGeneratorInternal( |
||||
const FieldDescriptor* descriptor); |
||||
|
||||
std::string class_name(); |
||||
std::string full_class_name(); |
||||
|
||||
// field names sorted alphabetically
|
||||
const std::vector<std::string>& field_names(); |
||||
|
||||
// field descriptors sorted by number
|
||||
const std::vector<const FieldDescriptor*>& fields_by_number(); |
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator); |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__
|
||||
|
@ -0,0 +1,183 @@ |
||||
// 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 <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/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_message_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_writer.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, |
||||
int fieldOrdinal) |
||||
: FieldGeneratorBase(descriptor, fieldOrdinal) { |
||||
} |
||||
|
||||
MessageFieldGenerator::~MessageFieldGenerator() { |
||||
|
||||
} |
||||
|
||||
void MessageFieldGenerator::GenerateMembers(Writer* writer) { |
||||
writer->WriteLine("private bool has$0$;", property_name()); |
||||
writer->WriteLine("private $0$ $1$_;", type_name(), name()); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public bool Has$0$ {", property_name()); |
||||
writer->WriteLine(" get { return has$0$; }", property_name()); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); |
||||
writer->WriteLine(" get { return $0$_ ?? $1$; }", name(), default_value()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void MessageFieldGenerator::GenerateBuilderMembers(Writer* writer) { |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public bool Has$0$ {", property_name()); |
||||
writer->WriteLine(" get { return result.has$0$; }", property_name()); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); |
||||
writer->WriteLine(" get { return result.$0$; }", property_name()); |
||||
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.has$0$ = true;", property_name()); |
||||
writer->WriteLine(" result.$0$_ = value;", 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.has$0$ = true;", property_name()); |
||||
writer->WriteLine(" result.$0$_ = builderForValue.Build();", 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.has$0$ &&", property_name()); |
||||
writer->WriteLine(" result.$0$_ != $1$) {", name(), default_value()); |
||||
writer->WriteLine( |
||||
" result.$0$_ = $1$.CreateBuilder(result.$0$_).MergeFrom(value).BuildPartial();", |
||||
name(), type_name()); |
||||
writer->WriteLine(" } else {"); |
||||
writer->WriteLine(" result.$0$_ = value;", name()); |
||||
writer->WriteLine(" }"); |
||||
writer->WriteLine(" result.has$0$ = true;", property_name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public Builder Clear$0$() {", property_name()); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.has$0$ = false;", property_name()); |
||||
writer->WriteLine(" result.$0$_ = null;", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void MessageFieldGenerator::GenerateMergingCode(Writer* writer) { |
||||
writer->WriteLine("if (other.Has$0$) {", property_name()); |
||||
writer->WriteLine(" Merge$0$(other.$0$);", property_name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void MessageFieldGenerator::GenerateBuildingCode(Writer* writer) { |
||||
// Nothing to do for singular fields
|
||||
} |
||||
|
||||
void MessageFieldGenerator::GenerateParsingCode(Writer* writer) { |
||||
writer->WriteLine("$0$.Builder subBuilder = $0$.CreateBuilder();", |
||||
type_name()); |
||||
writer->WriteLine("if (result.has$0$) {", property_name()); |
||||
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("$0$ = subBuilder.BuildPartial();", property_name()); |
||||
} |
||||
|
||||
void MessageFieldGenerator::GenerateSerializationCode(Writer* writer) { |
||||
writer->WriteLine("if (has$0$) {", property_name()); |
||||
writer->WriteLine(" output.Write$0$($1$, field_names[$3$], $2$);", |
||||
message_or_group(), number(), property_name(), |
||||
field_ordinal()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void MessageFieldGenerator::GenerateSerializedSizeCode(Writer* writer) { |
||||
writer->WriteLine("if (has$0$) {", property_name()); |
||||
writer->WriteLine(" size += pb::CodedOutputStream.Compute$0$Size($1$, $2$);", |
||||
message_or_group(), number(), property_name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void MessageFieldGenerator::WriteHash(Writer* writer) { |
||||
writer->WriteLine("if (has$0$) hash ^= $1$_.GetHashCode();", property_name(), |
||||
name()); |
||||
} |
||||
void MessageFieldGenerator::WriteEquals(Writer* writer) { |
||||
writer->WriteLine( |
||||
"if (has$0$ != other.has$0$ || (has$0$ && !$1$_.Equals(other.$1$_))) return false;", |
||||
property_name(), name()); |
||||
} |
||||
void MessageFieldGenerator::WriteToString(Writer* writer) { |
||||
writer->WriteLine("PrintField(\"$2$\", has$0$, $1$_, writer);", |
||||
property_name(), name(), GetFieldName(descriptor_)); |
||||
} |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,73 @@ |
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__ |
||||
|
||||
#include <string> |
||||
|
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_field_base.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class Writer; |
||||
|
||||
class MessageFieldGenerator : public FieldGeneratorBase { |
||||
public: |
||||
MessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); |
||||
~MessageFieldGenerator(); |
||||
|
||||
virtual void GenerateMembers(Writer* writer); |
||||
virtual void GenerateBuilderMembers(Writer* writer); |
||||
virtual void GenerateMergingCode(Writer* writer); |
||||
virtual void GenerateBuildingCode(Writer* writer); |
||||
virtual void GenerateParsingCode(Writer* writer); |
||||
virtual void GenerateSerializationCode(Writer* writer); |
||||
virtual void GenerateSerializedSizeCode(Writer* writer); |
||||
|
||||
virtual void WriteHash(Writer* writer); |
||||
virtual void WriteEquals(Writer* writer); |
||||
virtual void WriteToString(Writer* writer); |
||||
|
||||
private: |
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator); |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__
|
||||
|
@ -0,0 +1,148 @@ |
||||
// 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 <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/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_primitive_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_writer.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
PrimitiveFieldGenerator::PrimitiveFieldGenerator( |
||||
const FieldDescriptor* descriptor, int fieldOrdinal) |
||||
: FieldGeneratorBase(descriptor, fieldOrdinal) { |
||||
} |
||||
|
||||
PrimitiveFieldGenerator::~PrimitiveFieldGenerator() { |
||||
|
||||
} |
||||
|
||||
void PrimitiveFieldGenerator::GenerateMembers(Writer* writer) { |
||||
writer->WriteLine("private bool has$0$;", property_name()); |
||||
writer->WriteLine("private $0$ $1$_$2$;", type_name(), name(), |
||||
has_default_value() ? " = " + default_value() : ""); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public bool Has$0$ {", property_name()); |
||||
writer->WriteLine(" get { return has$0$; }", property_name()); |
||||
writer->WriteLine("}"); |
||||
AddPublicMemberAttributes(writer); |
||||
writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); |
||||
writer->WriteLine(" get { return $0$_; }", name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void PrimitiveFieldGenerator::GenerateBuilderMembers(Writer* writer) { |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public bool Has$0$ {", property_name()); |
||||
writer->WriteLine(" get { return result.has$0$; }", property_name()); |
||||
writer->WriteLine("}"); |
||||
AddPublicMemberAttributes(writer); |
||||
writer->WriteLine("public $0$ $1$ {", type_name(), property_name()); |
||||
writer->WriteLine(" get { return result.$0$; }", property_name()); |
||||
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.has$0$ = true;", property_name()); |
||||
writer->WriteLine(" result.$0$_ = value;", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public Builder Clear$0$() {", property_name()); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.has$0$ = false;", property_name()); |
||||
writer->WriteLine(" result.$0$_ = $1$;", name(), default_value()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void PrimitiveFieldGenerator::GenerateMergingCode(Writer* writer) { |
||||
writer->WriteLine("if (other.Has$0$) {", property_name()); |
||||
writer->WriteLine(" $0$ = other.$0$;", property_name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void PrimitiveFieldGenerator::GenerateBuildingCode(Writer* writer) { |
||||
// Nothing to do here for primitive types
|
||||
} |
||||
|
||||
void PrimitiveFieldGenerator::GenerateParsingCode(Writer* writer) { |
||||
writer->WriteLine("result.has$0$ = input.Read$1$(ref result.$2$_);", |
||||
property_name(), capitalized_type_name(), name()); |
||||
} |
||||
|
||||
void PrimitiveFieldGenerator::GenerateSerializationCode(Writer* writer) { |
||||
writer->WriteLine("if (has$0$) {", property_name()); |
||||
writer->WriteLine(" output.Write$0$($1$, field_names[$3$], $2$);", |
||||
capitalized_type_name(), number(), property_name(), |
||||
field_ordinal()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void PrimitiveFieldGenerator::GenerateSerializedSizeCode(Writer* writer) { |
||||
writer->WriteLine("if (has$0$) {", property_name()); |
||||
writer->WriteLine(" size += pb::CodedOutputStream.Compute$0$Size($1$, $2$);", |
||||
capitalized_type_name(), number(), property_name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void PrimitiveFieldGenerator::WriteHash(Writer* writer) { |
||||
writer->WriteLine("if (has$0$) hash ^= $1$_.GetHashCode();", property_name(), |
||||
name()); |
||||
} |
||||
void PrimitiveFieldGenerator::WriteEquals(Writer* writer) { |
||||
writer->WriteLine( |
||||
"if (has$0$ != other.has$0$ || (has$0$ && !$1$_.Equals(other.$1$_))) return false;", |
||||
property_name(), name()); |
||||
} |
||||
void PrimitiveFieldGenerator::WriteToString(Writer* writer) { |
||||
writer->WriteLine("PrintField(\"$0$\", has$1$, $2$_, writer);", |
||||
descriptor_->name(), property_name(), name()); |
||||
} |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,73 @@ |
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__ |
||||
|
||||
#include <string> |
||||
|
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_field_base.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class Writer; |
||||
|
||||
class PrimitiveFieldGenerator : public FieldGeneratorBase { |
||||
public: |
||||
PrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); |
||||
~PrimitiveFieldGenerator(); |
||||
|
||||
virtual void GenerateMembers(Writer* writer); |
||||
virtual void GenerateBuilderMembers(Writer* writer); |
||||
virtual void GenerateMergingCode(Writer* writer); |
||||
virtual void GenerateBuildingCode(Writer* writer); |
||||
virtual void GenerateParsingCode(Writer* writer); |
||||
virtual void GenerateSerializationCode(Writer* writer); |
||||
virtual void GenerateSerializedSizeCode(Writer* writer); |
||||
|
||||
virtual void WriteHash(Writer* writer); |
||||
virtual void WriteEquals(Writer* writer); |
||||
virtual void WriteToString(Writer* writer); |
||||
|
||||
private: |
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator); |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__
|
||||
|
@ -0,0 +1,226 @@ |
||||
// 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 <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/wire_format.h> |
||||
|
||||
#include <google/protobuf/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_writer.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( |
||||
const FieldDescriptor* descriptor, int fieldOrdinal) |
||||
: FieldGeneratorBase(descriptor, fieldOrdinal) { |
||||
} |
||||
|
||||
RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() { |
||||
|
||||
} |
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateMembers(Writer* writer) { |
||||
if (descriptor_->is_packed() && optimize_speed()) { |
||||
writer->WriteLine("private int $0$MemoizedSerializedSize;", name()); |
||||
} |
||||
writer->WriteLine( |
||||
"private pbc::PopsicleList<$0$> $1$_ = new pbc::PopsicleList<$0$>();", |
||||
type_name(), name()); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public scg::IList<$0$> $1$List {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine(" get { return pbc::Lists.AsReadOnly($0$_); }", name()); |
||||
writer->WriteLine("}"); |
||||
|
||||
// TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
|
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public int $0$Count {", property_name()); |
||||
writer->WriteLine(" get { return $0$_.Count; }", name()); |
||||
writer->WriteLine("}"); |
||||
|
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public $0$ Get$1$(int index) {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine(" return $0$_[index];", name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateBuilderMembers(Writer* writer) { |
||||
// Note: We can return the original list here, because we make it unmodifiable when we build
|
||||
// We return it via IPopsicleList so that collection initializers work more pleasantly.
|
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public pbc::IPopsicleList<$0$> $1$List {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine(" get { return PrepareBuilder().$0$_; }", name()); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public int $0$Count {", property_name()); |
||||
writer->WriteLine(" get { return result.$0$Count; }", property_name()); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public $0$ Get$1$(int index) {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine(" return result.Get$0$(index);", property_name()); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public Builder Set$0$(int index, $1$ value) {", |
||||
property_name(), type_name()); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_[index] = value;", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public Builder Add$0$($1$ value) {", property_name(), |
||||
type_name()); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_.Add(value);", name(), type_name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine( |
||||
"public Builder AddRange$0$(scg::IEnumerable<$1$> values) {", |
||||
property_name(), type_name()); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_.Add(values);", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public Builder Clear$0$() {", property_name()); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_.Clear();", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateMergingCode(Writer* writer) { |
||||
writer->WriteLine("if (other.$0$_.Count != 0) {", name()); |
||||
writer->WriteLine(" result.$0$_.Add(other.$0$_);", name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateBuildingCode(Writer* writer) { |
||||
writer->WriteLine("$0$_.MakeReadOnly();", name()); |
||||
} |
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateParsingCode(Writer* writer) { |
||||
writer->WriteLine("scg::ICollection<object> unknownItems;"); |
||||
writer->WriteLine( |
||||
"input.ReadEnumArray<$0$>(tag, field_name, result.$1$_, out unknownItems);", |
||||
type_name(), name()); |
||||
if (!use_lite_runtime()) { |
||||
writer->WriteLine("if (unknownItems != null) {"); |
||||
writer->WriteLine(" if (unknownFields == null) {"); |
||||
writer->WriteLine( |
||||
" unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);"); |
||||
writer->WriteLine(" }"); |
||||
writer->WriteLine(" foreach (object rawValue in unknownItems)"); |
||||
writer->WriteLine(" if (rawValue is int)"); |
||||
writer->WriteLine( |
||||
" unknownFields.MergeVarintField($0$, (ulong)(int)rawValue);", |
||||
number()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
} |
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateSerializationCode(Writer* writer) { |
||||
writer->WriteLine("if ($0$_.Count > 0) {", name()); |
||||
writer->Indent(); |
||||
if (descriptor_->is_packed()) { |
||||
writer->WriteLine( |
||||
"output.WritePackedEnumArray($0$, field_names[$2$], $1$MemoizedSerializedSize, $1$_);", |
||||
number(), name(), field_ordinal()); |
||||
} else { |
||||
writer->WriteLine("output.WriteEnumArray($0$, field_names[$2$], $1$_);", |
||||
number(), name(), field_ordinal()); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(Writer* writer) { |
||||
writer->WriteLine("{"); |
||||
writer->Indent(); |
||||
writer->WriteLine("int dataSize = 0;"); |
||||
writer->WriteLine("if ($0$_.Count > 0) {", name()); |
||||
writer->Indent(); |
||||
writer->WriteLine("foreach ($0$ element in $1$_) {", type_name(), name()); |
||||
writer->WriteLine( |
||||
" dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine("size += dataSize;"); |
||||
int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()); |
||||
if (descriptor_->is_packed()) { |
||||
writer->WriteLine("size += $0$;", SimpleItoa(tagSize)); |
||||
writer->WriteLine( |
||||
"size += pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);"); |
||||
} else { |
||||
writer->WriteLine("size += $0$ * $1$_.Count;", SimpleItoa(tagSize), name()); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
// cache the data size for packed fields.
|
||||
if (descriptor_->is_packed()) { |
||||
writer->WriteLine("$0$MemoizedSerializedSize = dataSize;", name()); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedEnumFieldGenerator::WriteHash(Writer* writer) { |
||||
writer->WriteLine("foreach($0$ i in $1$_)", type_name(), name()); |
||||
writer->WriteLine(" hash ^= i.GetHashCode();"); |
||||
} |
||||
|
||||
void RepeatedEnumFieldGenerator::WriteEquals(Writer* writer) { |
||||
writer->WriteLine("if($0$_.Count != other.$0$_.Count) return false;", name()); |
||||
writer->WriteLine("for(int ix=0; ix < $0$_.Count; ix++)", name()); |
||||
writer->WriteLine(" if(!$0$_[ix].Equals(other.$0$_[ix])) return false;", |
||||
name()); |
||||
} |
||||
|
||||
void RepeatedEnumFieldGenerator::WriteToString(Writer* writer) { |
||||
writer->WriteLine("PrintField(\"$0$\", $1$_, writer);", descriptor_->name(), |
||||
name()); |
||||
} |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,73 @@ |
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__ |
||||
|
||||
#include <string> |
||||
|
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_field_base.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class Writer; |
||||
|
||||
class RepeatedEnumFieldGenerator : public FieldGeneratorBase { |
||||
public: |
||||
RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); |
||||
~RepeatedEnumFieldGenerator(); |
||||
|
||||
virtual void GenerateMembers(Writer* writer); |
||||
virtual void GenerateBuilderMembers(Writer* writer); |
||||
virtual void GenerateMergingCode(Writer* writer); |
||||
virtual void GenerateBuildingCode(Writer* writer); |
||||
virtual void GenerateParsingCode(Writer* writer); |
||||
virtual void GenerateSerializationCode(Writer* writer); |
||||
virtual void GenerateSerializedSizeCode(Writer* writer); |
||||
|
||||
virtual void WriteHash(Writer* writer); |
||||
virtual void WriteEquals(Writer* writer); |
||||
virtual void WriteToString(Writer* writer); |
||||
|
||||
private: |
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator); |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__
|
||||
|
@ -0,0 +1,201 @@ |
||||
// 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 <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/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_writer.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( |
||||
const FieldDescriptor* descriptor, int fieldOrdinal) |
||||
: FieldGeneratorBase(descriptor, fieldOrdinal) { |
||||
} |
||||
|
||||
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() { |
||||
|
||||
} |
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateMembers(Writer* writer) { |
||||
writer->WriteLine( |
||||
"private pbc::PopsicleList<$0$> $1$_ = new pbc::PopsicleList<$0$>();", |
||||
type_name(), name()); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public scg::IList<$0$> $1$List {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine(" get { return $0$_; }", name()); |
||||
writer->WriteLine("}"); |
||||
|
||||
// TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
|
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public int $0$Count {", property_name()); |
||||
writer->WriteLine(" get { return $0$_.Count; }", name()); |
||||
writer->WriteLine("}"); |
||||
|
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public $0$ Get$1$(int index) {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine(" return $0$_[index];", name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateBuilderMembers(Writer* writer) { |
||||
// Note: We can return the original list here, because we make it unmodifiable when we build
|
||||
// We return it via IPopsicleList so that collection initializers work more pleasantly.
|
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public pbc::IPopsicleList<$0$> $1$List {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine(" get { return PrepareBuilder().$0$_; }", name()); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public int $0$Count {", property_name()); |
||||
writer->WriteLine(" get { return result.$0$Count; }", property_name()); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public $0$ Get$1$(int index) {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine(" return result.Get$0$(index);", property_name()); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public Builder Set$0$(int index, $1$ value) {", |
||||
property_name(), type_name()); |
||||
AddNullCheck(writer); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_[index] = value;", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
// Extra overload for builder (just on messages)
|
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine( |
||||
"public Builder Set$0$(int index, $1$.Builder builderForValue) {", |
||||
property_name(), type_name()); |
||||
AddNullCheck(writer, "builderForValue"); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_[index] = builderForValue.Build();", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public Builder Add$0$($1$ value) {", property_name(), |
||||
type_name()); |
||||
AddNullCheck(writer); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_.Add(value);", name(), type_name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
// Extra overload for builder (just on messages)
|
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public Builder Add$0$($1$.Builder builderForValue) {", |
||||
property_name(), type_name()); |
||||
AddNullCheck(writer, "builderForValue"); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_.Add(builderForValue.Build());", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine( |
||||
"public Builder AddRange$0$(scg::IEnumerable<$1$> values) {", |
||||
property_name(), type_name()); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_.Add(values);", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public Builder Clear$0$() {", property_name()); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_.Clear();", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateMergingCode(Writer* writer) { |
||||
writer->WriteLine("if (other.$0$_.Count != 0) {", name()); |
||||
writer->WriteLine(" result.$0$_.Add(other.$0$_);", name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateBuildingCode(Writer* writer) { |
||||
writer->WriteLine("$0$_.MakeReadOnly();", name()); |
||||
} |
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateParsingCode(Writer* writer) { |
||||
writer->WriteLine( |
||||
"input.Read$0$Array(tag, field_name, result.$1$_, $2$.DefaultInstance, extensionRegistry);", |
||||
message_or_group(), name(), type_name()); |
||||
} |
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateSerializationCode(Writer* writer) { |
||||
writer->WriteLine("if ($0$_.Count > 0) {", name()); |
||||
writer->Indent(); |
||||
writer->WriteLine("output.Write$0$Array($1$, field_names[$3$], $2$_);", |
||||
message_or_group(), number(), name(), field_ordinal()); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(Writer* writer) { |
||||
writer->WriteLine("foreach ($0$ element in $1$List) {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine( |
||||
" size += pb::CodedOutputStream.Compute$0$Size($1$, element);", |
||||
message_or_group(), number()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedMessageFieldGenerator::WriteHash(Writer* writer) { |
||||
writer->WriteLine("foreach($0$ i in $1$_)", type_name(), name()); |
||||
writer->WriteLine(" hash ^= i.GetHashCode();"); |
||||
} |
||||
void RepeatedMessageFieldGenerator::WriteEquals(Writer* writer) { |
||||
writer->WriteLine("if($0$_.Count != other.$0$_.Count) return false;", name()); |
||||
writer->WriteLine("for(int ix=0; ix < $0$_.Count; ix++)", name()); |
||||
writer->WriteLine(" if(!$0$_[ix].Equals(other.$0$_[ix])) return false;", |
||||
name()); |
||||
} |
||||
void RepeatedMessageFieldGenerator::WriteToString(Writer* writer) { |
||||
writer->WriteLine("PrintField(\"$0$\", $1$_, writer);", |
||||
GetFieldName(descriptor_), name()); |
||||
} |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,73 @@ |
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__ |
||||
|
||||
#include <string> |
||||
|
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_field_base.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class Writer; |
||||
|
||||
class RepeatedMessageFieldGenerator : public FieldGeneratorBase { |
||||
public: |
||||
RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); |
||||
~RepeatedMessageFieldGenerator(); |
||||
|
||||
virtual void GenerateMembers(Writer* writer); |
||||
virtual void GenerateBuilderMembers(Writer* writer); |
||||
virtual void GenerateMergingCode(Writer* writer); |
||||
virtual void GenerateBuildingCode(Writer* writer); |
||||
virtual void GenerateParsingCode(Writer* writer); |
||||
virtual void GenerateSerializationCode(Writer* writer); |
||||
virtual void GenerateSerializedSizeCode(Writer* writer); |
||||
|
||||
virtual void WriteHash(Writer* writer); |
||||
virtual void WriteEquals(Writer* writer); |
||||
virtual void WriteToString(Writer* writer); |
||||
|
||||
private: |
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator); |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__
|
||||
|
@ -0,0 +1,219 @@ |
||||
// 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 <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/wire_format.h> |
||||
|
||||
#include <google/protobuf/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_writer.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( |
||||
const FieldDescriptor* descriptor, int fieldOrdinal) |
||||
: FieldGeneratorBase(descriptor, fieldOrdinal) { |
||||
} |
||||
|
||||
RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() { |
||||
|
||||
} |
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateMembers(Writer* writer) { |
||||
if (descriptor_->is_packed() && optimize_speed()) { |
||||
writer->WriteLine("private int $0$MemoizedSerializedSize;", name()); |
||||
} |
||||
writer->WriteLine( |
||||
"private pbc::PopsicleList<$0$> $1$_ = new pbc::PopsicleList<$0$>();", |
||||
type_name(), name()); |
||||
AddPublicMemberAttributes(writer); |
||||
writer->WriteLine("public scg::IList<$0$> $1$List {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine(" get { return pbc::Lists.AsReadOnly($0$_); }", name()); |
||||
writer->WriteLine("}"); |
||||
|
||||
// TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
|
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public int $0$Count {", property_name()); |
||||
writer->WriteLine(" get { return $0$_.Count; }", name()); |
||||
writer->WriteLine("}"); |
||||
|
||||
AddPublicMemberAttributes(writer); |
||||
writer->WriteLine("public $0$ Get$1$(int index) {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine(" return $0$_[index];", name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateBuilderMembers(Writer* writer) { |
||||
// Note: We can return the original list here, because we make it unmodifiable when we build
|
||||
// We return it via IPopsicleList so that collection initializers work more pleasantly.
|
||||
AddPublicMemberAttributes(writer); |
||||
writer->WriteLine("public pbc::IPopsicleList<$0$> $1$List {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine(" get { return PrepareBuilder().$0$_; }", name()); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public int $0$Count {", property_name()); |
||||
writer->WriteLine(" get { return result.$0$Count; }", property_name()); |
||||
writer->WriteLine("}"); |
||||
AddPublicMemberAttributes(writer); |
||||
writer->WriteLine("public $0$ Get$1$(int index) {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine(" return result.Get$0$(index);", property_name()); |
||||
writer->WriteLine("}"); |
||||
AddPublicMemberAttributes(writer); |
||||
writer->WriteLine("public Builder Set$0$(int index, $1$ value) {", |
||||
property_name(), type_name()); |
||||
AddNullCheck(writer); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_[index] = value;", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
AddPublicMemberAttributes(writer); |
||||
writer->WriteLine("public Builder Add$0$($1$ value) {", property_name(), |
||||
type_name()); |
||||
AddNullCheck(writer); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_.Add(value);", name(), type_name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
AddPublicMemberAttributes(writer); |
||||
writer->WriteLine( |
||||
"public Builder AddRange$0$(scg::IEnumerable<$1$> values) {", |
||||
property_name(), type_name()); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_.Add(values);", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
AddDeprecatedFlag(writer); |
||||
writer->WriteLine("public Builder Clear$0$() {", property_name()); |
||||
writer->WriteLine(" PrepareBuilder();"); |
||||
writer->WriteLine(" result.$0$_.Clear();", name()); |
||||
writer->WriteLine(" return this;"); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateMergingCode(Writer* writer) { |
||||
writer->WriteLine("if (other.$0$_.Count != 0) {", name()); |
||||
writer->WriteLine(" result.$0$_.Add(other.$0$_);", name()); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateBuildingCode(Writer* writer) { |
||||
writer->WriteLine("$0$_.MakeReadOnly();", name()); |
||||
} |
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(Writer* writer) { |
||||
writer->WriteLine("input.Read$0$Array(tag, field_name, result.$1$_);", |
||||
capitalized_type_name(), name()); |
||||
} |
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode( |
||||
Writer* writer) { |
||||
writer->WriteLine("if ($0$_.Count > 0) {", name()); |
||||
writer->Indent(); |
||||
if (descriptor_->is_packed()) { |
||||
writer->WriteLine( |
||||
"output.WritePacked$0$Array($1$, field_names[$3$], $2$MemoizedSerializedSize, $2$_);", |
||||
capitalized_type_name(), number(), name(), field_ordinal()); |
||||
} else { |
||||
writer->WriteLine("output.Write$0$Array($1$, field_names[$3$], $2$_);", |
||||
capitalized_type_name(), number(), name(), |
||||
field_ordinal()); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode( |
||||
Writer* writer) { |
||||
writer->WriteLine("{"); |
||||
writer->Indent(); |
||||
writer->WriteLine("int dataSize = 0;"); |
||||
int fixedSize = GetFixedSize(descriptor_->type()); |
||||
if (fixedSize == -1) { |
||||
writer->WriteLine("foreach ($0$ element in $1$List) {", type_name(), |
||||
property_name()); |
||||
writer->WriteLine( |
||||
" dataSize += pb::CodedOutputStream.Compute$0$SizeNoTag(element);", |
||||
capitalized_type_name(), number()); |
||||
writer->WriteLine("}"); |
||||
} else { |
||||
writer->WriteLine("dataSize = $0$ * $1$_.Count;", SimpleItoa(fixedSize), name()); |
||||
} |
||||
writer->WriteLine("size += dataSize;"); |
||||
int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type()); |
||||
if (descriptor_->is_packed()) { |
||||
writer->WriteLine("if ($0$_.Count != 0) {", name()); |
||||
writer->WriteLine( |
||||
" size += $0$ + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);", |
||||
SimpleItoa(tagSize)); |
||||
writer->WriteLine("}"); |
||||
} else { |
||||
writer->WriteLine("size += $0$ * $1$_.Count;", SimpleItoa(tagSize), name()); |
||||
} |
||||
// cache the data size for packed fields.
|
||||
if (descriptor_->is_packed()) { |
||||
writer->WriteLine("$0$MemoizedSerializedSize = dataSize;", name()); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
} |
||||
|
||||
void RepeatedPrimitiveFieldGenerator::WriteHash(Writer* writer) { |
||||
writer->WriteLine("foreach($0$ i in $1$_)", type_name(), name()); |
||||
writer->WriteLine(" hash ^= i.GetHashCode();"); |
||||
} |
||||
void RepeatedPrimitiveFieldGenerator::WriteEquals(Writer* writer) { |
||||
writer->WriteLine("if($0$_.Count != other.$0$_.Count) return false;", name()); |
||||
writer->WriteLine("for(int ix=0; ix < $0$_.Count; ix++)", name()); |
||||
writer->WriteLine(" if(!$0$_[ix].Equals(other.$0$_[ix])) return false;", |
||||
name()); |
||||
} |
||||
void RepeatedPrimitiveFieldGenerator::WriteToString(Writer* writer) { |
||||
writer->WriteLine("PrintField(\"$0$\", $1$_, writer);", descriptor_->name(), |
||||
name()); |
||||
} |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,73 @@ |
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__ |
||||
|
||||
#include <string> |
||||
|
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_field_base.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class Writer; |
||||
|
||||
class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase { |
||||
public: |
||||
RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal); |
||||
~RepeatedPrimitiveFieldGenerator(); |
||||
|
||||
virtual void GenerateMembers(Writer* writer); |
||||
virtual void GenerateBuilderMembers(Writer* writer); |
||||
virtual void GenerateMergingCode(Writer* writer); |
||||
virtual void GenerateBuildingCode(Writer* writer); |
||||
virtual void GenerateParsingCode(Writer* writer); |
||||
virtual void GenerateSerializationCode(Writer* writer); |
||||
virtual void GenerateSerializedSizeCode(Writer* writer); |
||||
|
||||
virtual void WriteHash(Writer* writer); |
||||
virtual void WriteEquals(Writer* writer); |
||||
virtual void WriteToString(Writer* writer); |
||||
|
||||
private: |
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator); |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__
|
||||
|
@ -0,0 +1,82 @@ |
||||
// 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 <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/compiler/csharp/csharp_source_generator_base.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_writer.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
SourceGeneratorBase::SourceGeneratorBase(const FileDescriptor* descriptor) |
||||
: descriptor_(descriptor) { |
||||
optimizeSize_ = (descriptor->options().optimize_for() |
||||
== FileOptions::CODE_SIZE); |
||||
optimizeSpeed_ = (descriptor->options().optimize_for() == FileOptions::SPEED); |
||||
useLiteRuntime_ = (descriptor->options().optimize_for() |
||||
== FileOptions::LITE_RUNTIME); |
||||
|
||||
optimizeSpeed_ |= useLiteRuntime_; |
||||
runtimeSuffix_ = useLiteRuntime_ ? "Lite" : ""; |
||||
} |
||||
|
||||
SourceGeneratorBase::~SourceGeneratorBase() { |
||||
} |
||||
|
||||
void SourceGeneratorBase::WriteGeneratedCodeAttributes(Writer* writer) { |
||||
// TODO(jtattermusch):
|
||||
//if (descriptor.File.CSharpOptions.GeneratedCodeAttributes)
|
||||
// {
|
||||
// writer.WriteLine("[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]");
|
||||
// writer.WriteLine("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"{0}\", \"{1}\")]",
|
||||
// GetType().Assembly.GetName().Name, GetType().Assembly.GetName().Version);
|
||||
// }
|
||||
} |
||||
|
||||
std::string SourceGeneratorBase::class_access_level() { |
||||
// TODO(jtattermusch): implement this
|
||||
return "public"; |
||||
} |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,83 @@ |
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_SOURCE_GENERATOR_BASE_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_SOURCE_GENERATOR_BASE_H__ |
||||
|
||||
#include <string> |
||||
|
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class Writer; |
||||
|
||||
class SourceGeneratorBase { |
||||
protected: |
||||
SourceGeneratorBase(const FileDescriptor* descriptor); |
||||
virtual ~SourceGeneratorBase(); |
||||
|
||||
std::string class_access_level(); |
||||
|
||||
bool optimize_size() { |
||||
return optimizeSize_; |
||||
} |
||||
bool optimize_speed() { |
||||
return optimizeSpeed_; |
||||
} |
||||
bool use_lite_runtime() { |
||||
return useLiteRuntime_; |
||||
} |
||||
std::string runtime_suffix() { |
||||
return runtimeSuffix_; |
||||
} |
||||
|
||||
void WriteGeneratedCodeAttributes(Writer* writer); |
||||
|
||||
private: |
||||
const FileDescriptor* descriptor_; |
||||
bool optimizeSize_; |
||||
bool optimizeSpeed_; |
||||
bool useLiteRuntime_; |
||||
std::string runtimeSuffix_; |
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceGeneratorBase); |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_SOURCE_GENERATOR_BASE_H__
|
||||
|
@ -0,0 +1,297 @@ |
||||
// 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 <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/compiler/csharp/csharp_umbrella_class.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_enum.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_extension.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_helpers.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_message.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_writer.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
UmbrellaClassGenerator::UmbrellaClassGenerator(const FileDescriptor* file) |
||||
: SourceGeneratorBase(file), |
||||
file_(file) { |
||||
namespace_ = GetFileNamespace(file); |
||||
umbrellaClassname_ = GetFileUmbrellaClassname(file); |
||||
umbrellaNamespace_ = GetFileUmbrellaNamespace(file); |
||||
} |
||||
|
||||
UmbrellaClassGenerator::~UmbrellaClassGenerator() { |
||||
} |
||||
|
||||
void UmbrellaClassGenerator::Generate(Writer* writer) { |
||||
WriteIntroduction(writer); |
||||
WriteExtensionRegistration(writer); |
||||
|
||||
// write children: Extensions
|
||||
if (file_->extension_count() > 0) { |
||||
writer->WriteLine("#region Extensions"); |
||||
for (int i = 0; i < file_->extension_count(); i++) { |
||||
ExtensionGenerator extensionGenerator(file_->extension(i)); |
||||
extensionGenerator.Generate(writer); |
||||
} |
||||
writer->WriteLine("#endregion"); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
writer->WriteLine("#region Static variables"); |
||||
for (int i = 0; i < file_->message_type_count(); i++) { |
||||
MessageGenerator messageGenerator(file_->message_type(i)); |
||||
messageGenerator.GenerateStaticVariables(writer); |
||||
} |
||||
writer->WriteLine("#endregion"); |
||||
if (!use_lite_runtime()) { |
||||
WriteDescriptor(writer); |
||||
} else { |
||||
WriteLiteExtensions(writer); |
||||
} |
||||
// The class declaration either gets closed before or after the children are written.
|
||||
if (!file_->options().csharp_nest_classes()) { |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
|
||||
// Close the namespace around the umbrella class if defined
|
||||
if (!file_->options().csharp_nest_classes() |
||||
&& !umbrellaNamespace_.empty()) { |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
} |
||||
} |
||||
|
||||
// write children: Enums
|
||||
if (file_->enum_type_count() > 0) { |
||||
writer->WriteLine("#region Enums"); |
||||
for (int i = 0; i < file_->enum_type_count(); i++) { |
||||
EnumGenerator enumGenerator(file_->enum_type(i)); |
||||
enumGenerator.Generate(writer); |
||||
} |
||||
writer->WriteLine("#endregion"); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
// write children: Messages
|
||||
if (file_->message_type_count() > 0) { |
||||
writer->WriteLine("#region Messages"); |
||||
for (int i = 0; i < file_->message_type_count(); i++) { |
||||
MessageGenerator messageGenerator(file_->message_type(i)); |
||||
messageGenerator.Generate(writer); |
||||
} |
||||
writer->WriteLine("#endregion"); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
// TODO(jtattermusch): add support for generating services.
|
||||
//WriteChildren(writer, "Services", Descriptor.Services);
|
||||
if (file_->options().csharp_nest_classes()) { |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
} |
||||
if (!namespace_.empty()) { |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
} |
||||
writer->WriteLine(); |
||||
writer->WriteLine("#endregion Designer generated code"); |
||||
} |
||||
|
||||
void UmbrellaClassGenerator::WriteIntroduction(Writer* writer) { |
||||
writer->WriteLine( |
||||
"// Generated by the protocol buffer compiler. DO NOT EDIT!"); |
||||
writer->WriteLine("// source: $0$", file_->name()); |
||||
writer->WriteLine("#pragma warning disable 1591, 0612, 3021"); |
||||
writer->WriteLine("#region Designer generated code"); |
||||
|
||||
writer->WriteLine(); |
||||
writer->WriteLine("using pb = global::Google.ProtocolBuffers;"); |
||||
writer->WriteLine("using pbc = global::Google.ProtocolBuffers.Collections;"); |
||||
writer->WriteLine("using pbd = global::Google.ProtocolBuffers.Descriptors;"); |
||||
writer->WriteLine("using scg = global::System.Collections.Generic;"); |
||||
|
||||
if (!namespace_.empty()) { |
||||
writer->WriteLine("namespace $0$ {", namespace_); |
||||
writer->Indent(); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
// Add the namespace around the umbrella class if defined
|
||||
if (!file_->options().csharp_nest_classes() && !umbrellaNamespace_.empty()) { |
||||
writer->WriteLine("namespace $0$ {", umbrellaNamespace_); |
||||
writer->Indent(); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
if (file_->options().csharp_code_contracts()) { |
||||
writer->WriteLine( |
||||
"[global::System.Diagnostics.Contracts.ContractVerificationAttribute(false)]"); |
||||
} |
||||
writer->WriteLine( |
||||
"[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]"); |
||||
WriteGeneratedCodeAttributes(writer); |
||||
writer->WriteLine("$0$ static partial class $1$ {", class_access_level(), |
||||
umbrellaClassname_); |
||||
writer->WriteLine(); |
||||
writer->Indent(); |
||||
} |
||||
|
||||
void UmbrellaClassGenerator::WriteExtensionRegistration(Writer* writer) { |
||||
writer->WriteLine("#region Extension registration"); |
||||
writer->WriteLine( |
||||
"public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {"); |
||||
writer->Indent(); |
||||
for (int i = 0; i < file_->extension_count(); i++) { |
||||
ExtensionGenerator extensionGenerator(file_->extension(i)); |
||||
extensionGenerator.GenerateExtensionRegistrationCode(writer); |
||||
} |
||||
for (int i = 0; i < file_->message_type_count(); i++) { |
||||
MessageGenerator messageGenerator(file_->message_type(i)); |
||||
messageGenerator.GenerateExtensionRegistrationCode(writer); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine("#endregion"); |
||||
} |
||||
|
||||
void UmbrellaClassGenerator::WriteDescriptor(Writer* writer) { |
||||
writer->WriteLine("#region Descriptor"); |
||||
|
||||
writer->WriteLine("public static pbd::FileDescriptor Descriptor {"); |
||||
writer->WriteLine(" get { return descriptor; }"); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine("private static pbd::FileDescriptor descriptor;"); |
||||
writer->WriteLine(); |
||||
writer->WriteLine("static $0$() {", umbrellaClassname_); |
||||
writer->Indent(); |
||||
writer->WriteLine( |
||||
"byte[] descriptorData = global::System.Convert.FromBase64String("); |
||||
writer->Indent(); |
||||
writer->Indent(); |
||||
writer->WriteLine("string.Concat("); |
||||
writer->Indent(); |
||||
|
||||
// TODO(jonskeet): Consider a C#-escaping format here instead of just Base64.
|
||||
std::string base64 = FileDescriptorToBase64(file_); |
||||
while (base64.size() > 60) { |
||||
writer->WriteLine("\"$0$\", ", base64.substr(0, 60)); |
||||
base64 = base64.substr(60); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine("\"$0$\"));", base64); |
||||
writer->Outdent(); |
||||
writer->Outdent(); |
||||
writer->WriteLine( |
||||
"pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {"); |
||||
writer->Indent(); |
||||
writer->WriteLine("descriptor = root;"); |
||||
for (int i = 0; i < file_->message_type_count(); i++) { |
||||
MessageGenerator messageGenerator(file_->message_type(i)); |
||||
messageGenerator.GenerateStaticVariableInitializers(writer); |
||||
} |
||||
for (int i = 0; i < file_->extension_count(); i++) { |
||||
ExtensionGenerator extensionGenerator(file_->extension(i)); |
||||
extensionGenerator.GenerateStaticVariableInitializers(writer); |
||||
} |
||||
|
||||
if (uses_extensions()) { |
||||
// Must construct an ExtensionRegistry containing all possible extensions
|
||||
// and return it.
|
||||
writer->WriteLine( |
||||
"pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();"); |
||||
writer->WriteLine("RegisterAllExtensions(registry);"); |
||||
for (int i = 0; i < file_->dependency_count(); i++) { |
||||
writer->WriteLine("$0$.RegisterAllExtensions(registry);", |
||||
GetFullUmbrellaClassName(file_->dependency(i))); |
||||
} |
||||
writer->WriteLine("return registry;"); |
||||
} else { |
||||
writer->WriteLine("return null;"); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine("};"); |
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Invoke internalBuildGeneratedFileFrom() to build the file.
|
||||
writer->WriteLine( |
||||
"pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,"); |
||||
writer->WriteLine(" new pbd::FileDescriptor[] {"); |
||||
for (int i = 0; i < file_->dependency_count(); i++) { |
||||
writer->WriteLine(" $0$.Descriptor, ", |
||||
GetFullUmbrellaClassName(file_->dependency(i))); |
||||
} |
||||
writer->WriteLine(" }, assigner);"); |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine("#endregion"); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
void UmbrellaClassGenerator::WriteLiteExtensions(Writer* writer) { |
||||
writer->WriteLine("#region Extensions"); |
||||
writer->WriteLine("internal static readonly object Descriptor;"); |
||||
writer->WriteLine("static $0$() {", umbrellaClassname_); |
||||
writer->Indent(); |
||||
writer->WriteLine("Descriptor = null;"); |
||||
for (int i = 0; i < file_->message_type_count(); i++) { |
||||
MessageGenerator messageGenerator(file_->message_type(i)); |
||||
messageGenerator.GenerateStaticVariableInitializers(writer); |
||||
} |
||||
for (int i = 0; i < file_->extension_count(); i++) { |
||||
ExtensionGenerator extensionGenerator(file_->extension(i)); |
||||
extensionGenerator.GenerateStaticVariableInitializers(writer); |
||||
} |
||||
writer->Outdent(); |
||||
writer->WriteLine("}"); |
||||
writer->WriteLine("#endregion"); |
||||
writer->WriteLine(); |
||||
} |
||||
|
||||
bool UmbrellaClassGenerator::uses_extensions() { |
||||
// TODO(jtattermusch): implement recursive descent that looks for extensions.
|
||||
// For now, we conservatively assume that extensions are used.
|
||||
return true; |
||||
} |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,76 @@ |
||||
// 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.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_UMBRELLA_CLASS_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_UMBRELLA_CLASS_H__ |
||||
|
||||
#include <string> |
||||
|
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
class Writer; |
||||
|
||||
class UmbrellaClassGenerator : public SourceGeneratorBase { |
||||
public: |
||||
UmbrellaClassGenerator(const FileDescriptor* file); |
||||
~UmbrellaClassGenerator(); |
||||
|
||||
void Generate(Writer* write); |
||||
|
||||
private: |
||||
const FileDescriptor* file_; |
||||
|
||||
std::string namespace_; |
||||
std::string umbrellaClassname_; |
||||
std::string umbrellaNamespace_; |
||||
|
||||
void WriteIntroduction(Writer* writer); |
||||
void WriteExtensionRegistration(Writer* writer); |
||||
void WriteDescriptor(Writer* writer); |
||||
void WriteLiteExtensions(Writer* write); |
||||
|
||||
bool uses_extensions(); |
||||
|
||||
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UmbrellaClassGenerator); |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_UMBRELLA_CLASS_H__
|
||||
|
@ -0,0 +1,136 @@ |
||||
// 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.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#include <algorithm> |
||||
#include <google/protobuf/stubs/hash.h> |
||||
#include <limits> |
||||
#include <vector> |
||||
|
||||
#include <google/protobuf/compiler/csharp/csharp_writer.h> |
||||
#include <google/protobuf/descriptor.pb.h> |
||||
#include <google/protobuf/io/printer.h> |
||||
#include <google/protobuf/wire_format.h> |
||||
#include <google/protobuf/stubs/strutil.h> |
||||
#include <google/protobuf/stubs/substitute.h> |
||||
|
||||
#include <google/protobuf/compiler/csharp/csharp_field_base.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_enum_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_message_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_primitive_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h> |
||||
#include <google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
Writer::Writer(google::protobuf::io::Printer* printer) |
||||
: printer_(printer), |
||||
newline_("\n") { |
||||
// TODO(jtattermusch): make newline customizable.
|
||||
} |
||||
|
||||
Writer::~Writer() { |
||||
} |
||||
|
||||
void Writer::Indent() { |
||||
printer_->Indent(); |
||||
} |
||||
|
||||
void Writer::Outdent() { |
||||
printer_->Outdent(); |
||||
} |
||||
|
||||
void Writer::Write(const char* text) { |
||||
printer_->Print(text); |
||||
} |
||||
|
||||
void Writer::Write(const char* text, const string& value0) { |
||||
printer_->Print(text, "0", value0); |
||||
} |
||||
|
||||
void Writer::Write(const char* text, const string& value0, |
||||
const string& value1) { |
||||
printer_->Print(text, "0", value0, "1", value1); |
||||
} |
||||
|
||||
void Writer::Write(const char* text, const string& value0, const string& value1, |
||||
const string& value2) { |
||||
printer_->Print(text, "0", value0, "1", value1, "2", value2); |
||||
} |
||||
|
||||
void Writer::Write(const char* text, const string& value0, const string& value1, |
||||
const string& value2, const string& value3) { |
||||
printer_->Print(text, "0", value0, "1", value1, "2", value2, "3", value3); |
||||
} |
||||
|
||||
void Writer::WriteLine() { |
||||
printer_->Print(newline_); |
||||
} |
||||
|
||||
void Writer::WriteLine(const char* text) { |
||||
Write(text); |
||||
WriteLine(); |
||||
} |
||||
|
||||
void Writer::WriteLine(const char* text, const string& value0) { |
||||
Write(text, value0); |
||||
WriteLine(); |
||||
} |
||||
|
||||
void Writer::WriteLine(const char* text, const string& value0, |
||||
const string& value1) { |
||||
Write(text, value0, value1); |
||||
WriteLine(); |
||||
} |
||||
|
||||
void Writer::WriteLine(const char* text, const string& value0, |
||||
const string& value1, const string& value2) { |
||||
Write(text, value0, value1, value2); |
||||
WriteLine(); |
||||
} |
||||
|
||||
void Writer::WriteLine(const char* text, const string& value0, |
||||
const string& value1, const string& value2, |
||||
const string& value3) { |
||||
Write(text, value0, value1, value2, value3); |
||||
WriteLine(); |
||||
} |
||||
|
||||
} // namespace java
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
@ -0,0 +1,93 @@ |
||||
// 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.
|
||||
|
||||
// Author: kenton@google.com (Kenton Varda)
|
||||
// Based on original Protocol Buffers design by
|
||||
// Sanjay Ghemawat, Jeff Dean, and others.
|
||||
|
||||
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_WRITER_H__ |
||||
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_WRITER_H__ |
||||
|
||||
#include <string> |
||||
#include <google/protobuf/descriptor.pb.h> |
||||
#include <google/protobuf/descriptor.h> |
||||
#include <google/protobuf/compiler/code_generator.h> |
||||
#include <google/protobuf/io/printer.h> |
||||
|
||||
namespace google { |
||||
namespace protobuf { |
||||
namespace compiler { |
||||
namespace csharp { |
||||
|
||||
// Simple wrapper around Printer that supports customizable line endings
|
||||
// and number-based variables (e.g. $0$).
|
||||
class Writer { |
||||
public: |
||||
Writer(io::Printer* printer); |
||||
~Writer(); |
||||
|
||||
void Indent(); |
||||
void Outdent(); |
||||
|
||||
void Write(const char* text); |
||||
|
||||
void Write(const char* text, const string& value0); |
||||
|
||||
void Write(const char* text, const string& value0, const string& value1); |
||||
|
||||
void Write(const char* text, const string& value0, const string& value1, |
||||
const string& value2); |
||||
|
||||
void Write(const char* text, const string& value0, const string& value1, |
||||
const string& value2, const string& value3); |
||||
|
||||
void WriteLine(); |
||||
|
||||
void WriteLine(const char* text); |
||||
|
||||
void WriteLine(const char* text, const string& value0); |
||||
|
||||
void WriteLine(const char* text, const string& value0, const string& value1); |
||||
|
||||
void WriteLine(const char* text, const string& value0, const string& value1, |
||||
const string& value2); |
||||
|
||||
void WriteLine(const char* text, const string& value0, const string& value1, |
||||
const string& value2, const string& value3); |
||||
private: |
||||
io::Printer* printer_; |
||||
const char* newline_; |
||||
}; |
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
||||
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_WRITER_H__
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue