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