Merge pull request #1 from jtattermusch/csharp_protogen_rewrite
Rewrite of C# protogen to C++ (initial version)
This commit is contained in:
commit
8394a8daef
36 changed files with 5199 additions and 52 deletions
|
@ -126,7 +126,8 @@ nobase_include_HEADERS = \
|
|||
google/protobuf/compiler/java/java_names.h \
|
||||
google/protobuf/compiler/javanano/javanano_generator.h \
|
||||
google/protobuf/compiler/python/python_generator.h \
|
||||
google/protobuf/compiler/ruby/ruby_generator.h
|
||||
google/protobuf/compiler/ruby/ruby_generator.h \
|
||||
google/protobuf/compiler/csharp/csharp_generator.h
|
||||
|
||||
nobase_nodist_include_HEADERS = \
|
||||
$(public_config)
|
||||
|
@ -288,7 +289,22 @@ libprotoc_la_SOURCES = \
|
|||
google/protobuf/compiler/javanano/javanano_primitive_field.cc \
|
||||
google/protobuf/compiler/javanano/javanano_primitive_field.h \
|
||||
google/protobuf/compiler/python/python_generator.cc \
|
||||
google/protobuf/compiler/ruby/ruby_generator.cc
|
||||
google/protobuf/compiler/ruby/ruby_generator.cc \
|
||||
google/protobuf/compiler/csharp/csharp_enum.cc \
|
||||
google/protobuf/compiler/csharp/csharp_enum_field.cc \
|
||||
google/protobuf/compiler/csharp/csharp_extension.cc \
|
||||
google/protobuf/compiler/csharp/csharp_field_base.cc \
|
||||
google/protobuf/compiler/csharp/csharp_generator.cc \
|
||||
google/protobuf/compiler/csharp/csharp_helpers.cc \
|
||||
google/protobuf/compiler/csharp/csharp_message.cc \
|
||||
google/protobuf/compiler/csharp/csharp_message_field.cc \
|
||||
google/protobuf/compiler/csharp/csharp_primitive_field.cc \
|
||||
google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc \
|
||||
google/protobuf/compiler/csharp/csharp_repeated_message_field.cc \
|
||||
google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc \
|
||||
google/protobuf/compiler/csharp/csharp_source_generator_base.cc \
|
||||
google/protobuf/compiler/csharp/csharp_umbrella_class.cc \
|
||||
google/protobuf/compiler/csharp/csharp_writer.cc
|
||||
|
||||
bin_PROGRAMS = protoc
|
||||
protoc_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la
|
||||
|
@ -493,6 +509,7 @@ protobuf_test_SOURCES = \
|
|||
google/protobuf/compiler/java/java_doc_comment_unittest.cc \
|
||||
google/protobuf/compiler/python/python_plugin_unittest.cc \
|
||||
google/protobuf/compiler/ruby/ruby_generator_unittest.cc \
|
||||
google/protobuf/compiler/csharp/csharp_generator_unittest.cc \
|
||||
$(COMMON_TEST_SOURCES)
|
||||
nodist_protobuf_test_SOURCES = $(protoc_outputs)
|
||||
|
||||
|
|
79
src/google/protobuf/compiler/csharp/csharp_enum.cc
Normal file
79
src/google/protobuf/compiler/csharp/csharp_enum.cc
Normal file
|
@ -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
|
65
src/google/protobuf/compiler/csharp/csharp_enum.h
Normal file
65
src/google/protobuf/compiler/csharp/csharp_enum.h
Normal file
|
@ -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__
|
||||
|
160
src/google/protobuf/compiler/csharp/csharp_enum_field.cc
Normal file
160
src/google/protobuf/compiler/csharp/csharp_enum_field.cc
Normal file
|
@ -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
|
73
src/google/protobuf/compiler/csharp/csharp_enum_field.h
Normal file
73
src/google/protobuf/compiler/csharp/csharp_enum_field.h
Normal file
|
@ -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__
|
||||
|
174
src/google/protobuf/compiler/csharp/csharp_extension.cc
Normal file
174
src/google/protobuf/compiler/csharp/csharp_extension.cc
Normal file
|
@ -0,0 +1,174 @@
|
|||
// 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 (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): include the following check
|
||||
//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);
|
||||
}
|
||||
writer->WriteLine(
|
||||
"$0$,",
|
||||
(GetCSharpType(descriptor_->type()) == CSHARPTYPE_MESSAGE) ?
|
||||
type_name() + ".DefaultInstance" : "null");
|
||||
writer->WriteLine(
|
||||
"$0$,",
|
||||
(GetCSharpType(descriptor_->type()) == CSHARPTYPE_ENUM) ?
|
||||
"new EnumLiteMap<" + type_name() + ">()" : "null");
|
||||
writer->WriteLine("$0$.$1$FieldNumber,", scope_,
|
||||
GetPropertyName(descriptor_));
|
||||
writer->Write("pbd::FieldType.$0$", capitalized_type_name());
|
||||
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
|
80
src/google/protobuf/compiler/csharp/csharp_extension.h
Normal file
80
src/google/protobuf/compiler/csharp/csharp_extension.h
Normal file
|
@ -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__
|
||||
|
393
src/google/protobuf/compiler/csharp/csharp_field_base.cc
Normal file
393
src/google/protobuf/compiler/csharp/csharp_field_base.cc
Normal file
|
@ -0,0 +1,393 @@
|
|||
// 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) {
|
||||
if (descriptor_->options().deprecated())
|
||||
{
|
||||
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 (cls_compliance() && !is_cls_compliant()) {
|
||||
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
|
100
src/google/protobuf/compiler/csharp/csharp_field_base.h
Normal file
100
src/google/protobuf/compiler/csharp/csharp_field_base.h
Normal file
|
@ -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__
|
||||
|
99
src/google/protobuf/compiler/csharp/csharp_generator.cc
Normal file
99
src/google/protobuf/compiler/csharp/csharp_generator.cc
Normal file
|
@ -0,0 +1,99 @@
|
|||
// 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 {
|
||||
|
||||
std::string GetOutputFile(const google::protobuf::FileDescriptor* file, const std::string file_extension)
|
||||
{
|
||||
return GetFileUmbrellaClassname(file) + file_extension;
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
vector<pair<string, string> > options;
|
||||
ParseGeneratorParameter(parameter, &options);
|
||||
|
||||
std::string file_extension = ".cs";
|
||||
for (int i = 0; i < options.size(); i++) {
|
||||
if (options[i].first == "no_cls_compliance") {
|
||||
*error = "Turning off CLS compliance is not implemented yet.";
|
||||
return false;
|
||||
} else if (options[i].first == "file_extension") {
|
||||
file_extension = options[i].second;
|
||||
} else {
|
||||
*error = "Unknown generator option: " + options[i].first;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
std::string filename = GetOutputFile(file, file_extension);
|
||||
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
|
58
src/google/protobuf/compiler/csharp/csharp_generator.h
Normal file
58
src/google/protobuf/compiler/csharp/csharp_generator.h
Normal file
|
@ -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
|
409
src/google/protobuf/compiler/csharp/csharp_helpers.cc
Normal file
409
src/google/protobuf/compiler/csharp/csharp_helpers.cc
Normal file
|
@ -0,0 +1,409 @@
|
|||
// 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) {
|
||||
// umbrella_classname can no longer be set using message option.
|
||||
return GetUmbrellaClassNameInternal(descriptor->name());
|
||||
}
|
||||
|
||||
std::string GetFileUmbrellaNamespace(const FileDescriptor* descriptor) {
|
||||
// TODO(jtattermusch): reintroduce csharp_umbrella_namespace option
|
||||
bool collision = false;
|
||||
std::string umbrella_classname = GetFileUmbrellaClassname(descriptor);
|
||||
for(int i = 0; i < descriptor->message_type_count(); i++) {
|
||||
if (descriptor->message_type(i)->name() == umbrella_classname) {
|
||||
collision = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < descriptor->service_count(); i++) {
|
||||
if (descriptor->service(i)->name() == umbrella_classname) {
|
||||
collision = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < descriptor->enum_type_count(); i++) {
|
||||
if (descriptor->enum_type(i)->name() == umbrella_classname) {
|
||||
collision = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return collision ? "Proto" : "";
|
||||
}
|
||||
|
||||
// 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 (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 (!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(jtattermusch): consider introducing csharp_property_name field option
|
||||
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, std::set<const Descriptor*>* already_seen) {
|
||||
if (already_seen->find(descriptor) != already_seen->end()) {
|
||||
// The type is already in cache. This means that either:
|
||||
// a. The type has no required fields.
|
||||
// b. We are in the midst of checking if the type has required fields,
|
||||
// somewhere up the stack. In this case, we know that if the type
|
||||
// has any required fields, they'll be found when we return to it,
|
||||
// and the whole call to HasRequiredFields() will return true.
|
||||
// Therefore, we don't have to check if this type has required fields
|
||||
// here.
|
||||
return false;
|
||||
}
|
||||
already_seen->insert(descriptor);
|
||||
|
||||
// If the type has extensions, an extension with message type could contain
|
||||
// required fields, so we have to be conservative and assume such an
|
||||
// extension exists.
|
||||
if (descriptor->extension_count() > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < descriptor->field_count(); i++) {
|
||||
const FieldDescriptor* field = descriptor->field(i);
|
||||
if (field->is_required()) {
|
||||
return true;
|
||||
}
|
||||
if (GetCSharpType(field->type()) == CSHARPTYPE_MESSAGE) {
|
||||
if (HasRequiredFields(field->message_type(), already_seen)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HasRequiredFields(const Descriptor* descriptor) {
|
||||
std::set<const Descriptor*> already_seen;
|
||||
return HasRequiredFields(descriptor, &already_seen);
|
||||
}
|
||||
|
||||
} // namespace java
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
108
src/google/protobuf/compiler/csharp/csharp_helpers.h
Normal file
108
src/google/protobuf/compiler/csharp/csharp_helpers.h
Normal file
|
@ -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__
|
897
src/google/protobuf/compiler/csharp/csharp_message.cc
Normal file
897
src/google/protobuf/compiler/csharp/csharp_message.cc
Normal file
|
@ -0,0 +1,897 @@
|
|||
// 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() {
|
||||
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 = "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) {
|
||||
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();
|
||||
writer->WriteLine("private $0$() { }", class_name()); // Private ctor.
|
||||
// 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 (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("CalcSerializedSize();");
|
||||
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("return CalcSerializedSize();");
|
||||
writer->Outdent();
|
||||
writer->WriteLine("}");
|
||||
writer->Outdent();
|
||||
writer->WriteLine("}");
|
||||
writer->WriteLine();
|
||||
|
||||
writer->WriteLine("private int CalcSerializedSize() {");
|
||||
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("}");
|
||||
}
|
||||
|
||||
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();
|
||||
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
|
98
src/google/protobuf/compiler/csharp/csharp_message.h
Normal file
98
src/google/protobuf/compiler/csharp/csharp_message.h
Normal file
|
@ -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__
|
||||
|
183
src/google/protobuf/compiler/csharp/csharp_message_field.cc
Normal file
183
src/google/protobuf/compiler/csharp/csharp_message_field.cc
Normal file
|
@ -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
|
73
src/google/protobuf/compiler/csharp/csharp_message_field.h
Normal file
73
src/google/protobuf/compiler/csharp/csharp_message_field.h
Normal file
|
@ -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__
|
||||
|
148
src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
Normal file
148
src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
Normal file
|
@ -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
|
73
src/google/protobuf/compiler/csharp/csharp_primitive_field.h
Normal file
73
src/google/protobuf/compiler/csharp/csharp_primitive_field.h
Normal file
|
@ -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,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.
|
||||
|
||||
#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) {
|
||||
// This hook can be used to reintroduce generated code attributes in the future.
|
||||
}
|
||||
|
||||
std::string SourceGeneratorBase::class_access_level() {
|
||||
return "public"; // public_classes is always on.
|
||||
}
|
||||
|
||||
bool SourceGeneratorBase::cls_compliance() {
|
||||
// TODO(jtattermusch): implement this based on "cls_compliance" cmdline param.
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace csharp
|
||||
} // namespace compiler
|
||||
} // namespace protobuf
|
||||
} // namespace google
|
|
@ -0,0 +1,84 @@
|
|||
// 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 cls_compliance();
|
||||
|
||||
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__
|
||||
|
286
src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc
Normal file
286
src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc
Normal file
|
@ -0,0 +1,286 @@
|
|||
// 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);
|
||||
}
|
||||
// Close the class declaration.
|
||||
writer->Outdent();
|
||||
writer->WriteLine("}");
|
||||
|
||||
// Close the namespace around the umbrella class if defined
|
||||
if (!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 insertion point for services.
|
||||
|
||||
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 (!umbrellaNamespace_.empty()) {
|
||||
writer->WriteLine("namespace $0$ {", umbrellaNamespace_);
|
||||
writer->Indent();
|
||||
writer->WriteLine();
|
||||
}
|
||||
|
||||
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
|
76
src/google/protobuf/compiler/csharp/csharp_umbrella_class.h
Normal file
76
src/google/protobuf/compiler/csharp/csharp_umbrella_class.h
Normal file
|
@ -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__
|
||||
|
136
src/google/protobuf/compiler/csharp/csharp_writer.cc
Normal file
136
src/google/protobuf/compiler/csharp/csharp_writer.cc
Normal file
|
@ -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
|
93
src/google/protobuf/compiler/csharp/csharp_writer.h
Normal file
93
src/google/protobuf/compiler/csharp/csharp_writer.h
Normal file
|
@ -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__
|
|
@ -36,6 +36,7 @@
|
|||
#include <google/protobuf/compiler/java/java_generator.h>
|
||||
#include <google/protobuf/compiler/javanano/javanano_generator.h>
|
||||
#include <google/protobuf/compiler/ruby/ruby_generator.h>
|
||||
#include <google/protobuf/compiler/csharp/csharp_generator.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
|
@ -68,5 +69,10 @@ int main(int argc, char* argv[]) {
|
|||
cli.RegisterGenerator("--ruby_out", &rb_generator,
|
||||
"Generate Ruby source file.");
|
||||
|
||||
// CSharp
|
||||
google::protobuf::compiler::csharp::Generator csharp_generator;
|
||||
cli.RegisterGenerator("--csharp_out", &csharp_generator,
|
||||
"Generate C# source file.");
|
||||
|
||||
return cli.Run(argc, argv);
|
||||
}
|
||||
|
|
|
@ -289,7 +289,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
|
|||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _internal_metadata_),
|
||||
-1);
|
||||
FileOptions_descriptor_ = file->message_type(9);
|
||||
static const int FileOptions_offsets_[14] = {
|
||||
static const int FileOptions_offsets_[15] = {
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_),
|
||||
|
@ -303,6 +303,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
|
|||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, deprecated_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_enable_arenas_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, objc_class_prefix_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_namespace_),
|
||||
GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_),
|
||||
};
|
||||
FileOptions_reflection_ =
|
||||
|
@ -663,7 +664,7 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
|
|||
"t_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google.p"
|
||||
"rotobuf.MethodOptions\022\037\n\020client_streamin"
|
||||
"g\030\005 \001(\010:\005false\022\037\n\020server_streaming\030\006 \001(\010"
|
||||
":\005false\"\347\004\n\013FileOptions\022\024\n\014java_package\030"
|
||||
":\005false\"\201\005\n\013FileOptions\022\024\n\014java_package\030"
|
||||
"\001 \001(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023j"
|
||||
"ava_multiple_files\030\n \001(\010:\005false\022,\n\035java_"
|
||||
"generate_equals_and_hash\030\024 \001(\010:\005false\022%\n"
|
||||
|
@ -675,50 +676,51 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
|
|||
"se\022\"\n\023py_generic_services\030\022 \001(\010:\005false\022\031"
|
||||
"\n\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_enable_a"
|
||||
"renas\030\037 \001(\010:\005false\022\031\n\021objc_class_prefix\030"
|
||||
"$ \001(\t\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g"
|
||||
"oogle.protobuf.UninterpretedOption\":\n\014Op"
|
||||
"timizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014"
|
||||
"LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\346\001\n\016MessageOpt"
|
||||
"ions\022&\n\027message_set_wire_format\030\001 \001(\010:\005f"
|
||||
"alse\022.\n\037no_standard_descriptor_accessor\030"
|
||||
"\002 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022"
|
||||
"\021\n\tmap_entry\030\007 \001(\010\022C\n\024uninterpreted_opti"
|
||||
"on\030\347\007 \003(\0132$.google.protobuf.Uninterprete"
|
||||
"dOption*\t\010\350\007\020\200\200\200\200\002\"\240\002\n\014FieldOptions\022:\n\005c"
|
||||
"type\030\001 \001(\0162#.google.protobuf.FieldOption"
|
||||
"s.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\023\n\004lazy\030"
|
||||
"\005 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022"
|
||||
"\023\n\004weak\030\n \001(\010:\005false\022C\n\024uninterpreted_op"
|
||||
"tion\030\347\007 \003(\0132$.google.protobuf.Uninterpre"
|
||||
"tedOption\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001"
|
||||
"\022\020\n\014STRING_PIECE\020\002*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013EnumOp"
|
||||
"tions\022\023\n\013allow_alias\030\002 \001(\010\022\031\n\ndeprecated"
|
||||
"\030\003 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007"
|
||||
" \003(\0132$.google.protobuf.UninterpretedOpti"
|
||||
"on*\t\010\350\007\020\200\200\200\200\002\"}\n\020EnumValueOptions\022\031\n\ndep"
|
||||
"recated\030\001 \001(\010:\005false\022C\n\024uninterpreted_op"
|
||||
"tion\030\347\007 \003(\0132$.google.protobuf.Uninterpre"
|
||||
"tedOption*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031"
|
||||
"\n\ndeprecated\030! \001(\010:\005false\022C\n\024uninterpret"
|
||||
"ed_option\030\347\007 \003(\0132$.google.protobuf.Unint"
|
||||
"erpretedOption*\t\010\350\007\020\200\200\200\200\002\"z\n\rMethodOptio"
|
||||
"ns\022\031\n\ndeprecated\030! \001(\010:\005false\022C\n\024uninter"
|
||||
"preted_option\030\347\007 \003(\0132$.google.protobuf.U"
|
||||
"ninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023Uninte"
|
||||
"rpretedOption\022;\n\004name\030\002 \003(\0132-.google.pro"
|
||||
"tobuf.UninterpretedOption.NamePart\022\030\n\020id"
|
||||
"entifier_value\030\003 \001(\t\022\032\n\022positive_int_val"
|
||||
"ue\030\004 \001(\004\022\032\n\022negative_int_value\030\005 \001(\003\022\024\n\014"
|
||||
"double_value\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014"
|
||||
"\022\027\n\017aggregate_value\030\010 \001(\t\0323\n\010NamePart\022\021\n"
|
||||
"\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010\"\325"
|
||||
"\001\n\016SourceCodeInfo\022:\n\010location\030\001 \003(\0132(.go"
|
||||
"ogle.protobuf.SourceCodeInfo.Location\032\206\001"
|
||||
"\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003"
|
||||
"(\005B\002\020\001\022\030\n\020leading_comments\030\003 \001(\t\022\031\n\021trai"
|
||||
"ling_comments\030\004 \001(\t\022!\n\031leading_detached_"
|
||||
"comments\030\006 \003(\tB)\n\023com.google.protobufB\020D"
|
||||
"escriptorProtosH\001", 4617);
|
||||
"$ \001(\t\022\030\n\020csharp_namespace\030% \001(\t\022C\n\024unint"
|
||||
"erpreted_option\030\347\007 \003(\0132$.google.protobuf"
|
||||
".UninterpretedOption\":\n\014OptimizeMode\022\t\n\005"
|
||||
"SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RUNTIME\020\003"
|
||||
"*\t\010\350\007\020\200\200\200\200\002\"\346\001\n\016MessageOptions\022&\n\027messag"
|
||||
"e_set_wire_format\030\001 \001(\010:\005false\022.\n\037no_sta"
|
||||
"ndard_descriptor_accessor\030\002 \001(\010:\005false\022\031"
|
||||
"\n\ndeprecated\030\003 \001(\010:\005false\022\021\n\tmap_entry\030\007"
|
||||
" \001(\010\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go"
|
||||
"ogle.protobuf.UninterpretedOption*\t\010\350\007\020\200"
|
||||
"\200\200\200\002\"\240\002\n\014FieldOptions\022:\n\005ctype\030\001 \001(\0162#.g"
|
||||
"oogle.protobuf.FieldOptions.CType:\006STRIN"
|
||||
"G\022\016\n\006packed\030\002 \001(\010\022\023\n\004lazy\030\005 \001(\010:\005false\022\031"
|
||||
"\n\ndeprecated\030\003 \001(\010:\005false\022\023\n\004weak\030\n \001(\010:"
|
||||
"\005false\022C\n\024uninterpreted_option\030\347\007 \003(\0132$."
|
||||
"google.protobuf.UninterpretedOption\"/\n\005C"
|
||||
"Type\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIE"
|
||||
"CE\020\002*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013EnumOptions\022\023\n\013allow"
|
||||
"_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001(\010:\005false\022"
|
||||
"C\n\024uninterpreted_option\030\347\007 \003(\0132$.google."
|
||||
"protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002\""
|
||||
"}\n\020EnumValueOptions\022\031\n\ndeprecated\030\001 \001(\010:"
|
||||
"\005false\022C\n\024uninterpreted_option\030\347\007 \003(\0132$."
|
||||
"google.protobuf.UninterpretedOption*\t\010\350\007"
|
||||
"\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndeprecated\030!"
|
||||
" \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003"
|
||||
"(\0132$.google.protobuf.UninterpretedOption"
|
||||
"*\t\010\350\007\020\200\200\200\200\002\"z\n\rMethodOptions\022\031\n\ndeprecat"
|
||||
"ed\030! \001(\010:\005false\022C\n\024uninterpreted_option\030"
|
||||
"\347\007 \003(\0132$.google.protobuf.UninterpretedOp"
|
||||
"tion*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023UninterpretedOption\022"
|
||||
";\n\004name\030\002 \003(\0132-.google.protobuf.Uninterp"
|
||||
"retedOption.NamePart\022\030\n\020identifier_value"
|
||||
"\030\003 \001(\t\022\032\n\022positive_int_value\030\004 \001(\004\022\032\n\022ne"
|
||||
"gative_int_value\030\005 \001(\003\022\024\n\014double_value\030\006"
|
||||
" \001(\001\022\024\n\014string_value\030\007 \001(\014\022\027\n\017aggregate_"
|
||||
"value\030\010 \001(\t\0323\n\010NamePart\022\021\n\tname_part\030\001 \002"
|
||||
"(\t\022\024\n\014is_extension\030\002 \002(\010\"\325\001\n\016SourceCodeI"
|
||||
"nfo\022:\n\010location\030\001 \003(\0132(.google.protobuf."
|
||||
"SourceCodeInfo.Location\032\206\001\n\010Location\022\020\n\004"
|
||||
"path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022\030\n\020lead"
|
||||
"ing_comments\030\003 \001(\t\022\031\n\021trailing_comments\030"
|
||||
"\004 \001(\t\022!\n\031leading_detached_comments\030\006 \003(\t"
|
||||
"B)\n\023com.google.protobufB\020DescriptorProto"
|
||||
"sH\001", 4643);
|
||||
::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
|
||||
"google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
|
||||
FileDescriptorSet::default_instance_ = new FileDescriptorSet();
|
||||
|
@ -7016,6 +7018,7 @@ const int FileOptions::kPyGenericServicesFieldNumber;
|
|||
const int FileOptions::kDeprecatedFieldNumber;
|
||||
const int FileOptions::kCcEnableArenasFieldNumber;
|
||||
const int FileOptions::kObjcClassPrefixFieldNumber;
|
||||
const int FileOptions::kCsharpNamespaceFieldNumber;
|
||||
const int FileOptions::kUninterpretedOptionFieldNumber;
|
||||
#endif // !_MSC_VER
|
||||
|
||||
|
@ -7052,6 +7055,7 @@ void FileOptions::SharedCtor() {
|
|||
deprecated_ = false;
|
||||
cc_enable_arenas_ = false;
|
||||
objc_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
csharp_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
::memset(_has_bits_, 0, sizeof(_has_bits_));
|
||||
}
|
||||
|
||||
|
@ -7065,6 +7069,7 @@ void FileOptions::SharedDtor() {
|
|||
java_outer_classname_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
go_package_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
objc_class_prefix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
csharp_namespace_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
if (this != default_instance_) {
|
||||
}
|
||||
}
|
||||
|
@ -7117,11 +7122,14 @@ void FileOptions::Clear() {
|
|||
go_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
}
|
||||
if (_has_bits_[8 / 32] & 7936) {
|
||||
if (_has_bits_[8 / 32] & 16128) {
|
||||
ZR_(java_generic_services_, cc_enable_arenas_);
|
||||
if (has_objc_class_prefix()) {
|
||||
objc_class_prefix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
if (has_csharp_namespace()) {
|
||||
csharp_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
}
|
||||
|
||||
#undef ZR_HELPER_
|
||||
|
@ -7347,6 +7355,23 @@ bool FileOptions::MergePartialFromCodedStream(
|
|||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectTag(298)) goto parse_csharp_namespace;
|
||||
break;
|
||||
}
|
||||
|
||||
// optional string csharp_namespace = 37;
|
||||
case 37: {
|
||||
if (tag == 298) {
|
||||
parse_csharp_namespace:
|
||||
DO_(::google::protobuf::internal::WireFormatLite::ReadString(
|
||||
input, this->mutable_csharp_namespace()));
|
||||
::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
|
||||
this->csharp_namespace().data(), this->csharp_namespace().length(),
|
||||
::google::protobuf::internal::WireFormat::PARSE,
|
||||
"google.protobuf.FileOptions.csharp_namespace");
|
||||
} else {
|
||||
goto handle_unusual;
|
||||
}
|
||||
if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
|
||||
break;
|
||||
}
|
||||
|
@ -7481,6 +7506,16 @@ void FileOptions::SerializeWithCachedSizes(
|
|||
36, this->objc_class_prefix(), output);
|
||||
}
|
||||
|
||||
// optional string csharp_namespace = 37;
|
||||
if (has_csharp_namespace()) {
|
||||
::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
|
||||
this->csharp_namespace().data(), this->csharp_namespace().length(),
|
||||
::google::protobuf::internal::WireFormat::SERIALIZE,
|
||||
"google.protobuf.FileOptions.csharp_namespace");
|
||||
::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
|
||||
37, this->csharp_namespace(), output);
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
|
||||
for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
|
||||
::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
|
||||
|
@ -7591,6 +7626,17 @@ void FileOptions::SerializeWithCachedSizes(
|
|||
36, this->objc_class_prefix(), target);
|
||||
}
|
||||
|
||||
// optional string csharp_namespace = 37;
|
||||
if (has_csharp_namespace()) {
|
||||
::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
|
||||
this->csharp_namespace().data(), this->csharp_namespace().length(),
|
||||
::google::protobuf::internal::WireFormat::SERIALIZE,
|
||||
"google.protobuf.FileOptions.csharp_namespace");
|
||||
target =
|
||||
::google::protobuf::internal::WireFormatLite::WriteStringToArray(
|
||||
37, this->csharp_namespace(), target);
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
|
||||
for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
|
||||
target = ::google::protobuf::internal::WireFormatLite::
|
||||
|
@ -7662,7 +7708,7 @@ int FileOptions::ByteSize() const {
|
|||
}
|
||||
|
||||
}
|
||||
if (_has_bits_[8 / 32] & 7936) {
|
||||
if (_has_bits_[8 / 32] & 16128) {
|
||||
// optional bool java_generic_services = 17 [default = false];
|
||||
if (has_java_generic_services()) {
|
||||
total_size += 2 + 1;
|
||||
|
@ -7690,6 +7736,13 @@ int FileOptions::ByteSize() const {
|
|||
this->objc_class_prefix());
|
||||
}
|
||||
|
||||
// optional string csharp_namespace = 37;
|
||||
if (has_csharp_namespace()) {
|
||||
total_size += 2 +
|
||||
::google::protobuf::internal::WireFormatLite::StringSize(
|
||||
this->csharp_namespace());
|
||||
}
|
||||
|
||||
}
|
||||
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
|
||||
total_size += 2 * this->uninterpreted_option_size();
|
||||
|
@ -7773,6 +7826,10 @@ void FileOptions::MergeFrom(const FileOptions& from) {
|
|||
set_has_objc_class_prefix();
|
||||
objc_class_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.objc_class_prefix_);
|
||||
}
|
||||
if (from.has_csharp_namespace()) {
|
||||
set_has_csharp_namespace();
|
||||
csharp_namespace_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.csharp_namespace_);
|
||||
}
|
||||
}
|
||||
_extensions_.MergeFrom(from._extensions_);
|
||||
if (from._internal_metadata_.have_unknown_fields()) {
|
||||
|
@ -7817,6 +7874,7 @@ void FileOptions::InternalSwap(FileOptions* other) {
|
|||
std::swap(deprecated_, other->deprecated_);
|
||||
std::swap(cc_enable_arenas_, other->cc_enable_arenas_);
|
||||
objc_class_prefix_.Swap(&other->objc_class_prefix_);
|
||||
csharp_namespace_.Swap(&other->csharp_namespace_);
|
||||
uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
|
||||
std::swap(_has_bits_[0], other->_has_bits_[0]);
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
|
@ -8264,6 +8322,59 @@ void FileOptions::InternalSwap(FileOptions* other) {
|
|||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix)
|
||||
}
|
||||
|
||||
// optional string csharp_namespace = 37;
|
||||
bool FileOptions::has_csharp_namespace() const {
|
||||
return (_has_bits_[0] & 0x00002000u) != 0;
|
||||
}
|
||||
void FileOptions::set_has_csharp_namespace() {
|
||||
_has_bits_[0] |= 0x00002000u;
|
||||
}
|
||||
void FileOptions::clear_has_csharp_namespace() {
|
||||
_has_bits_[0] &= ~0x00002000u;
|
||||
}
|
||||
void FileOptions::clear_csharp_namespace() {
|
||||
csharp_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
clear_has_csharp_namespace();
|
||||
}
|
||||
const ::std::string& FileOptions::csharp_namespace() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_namespace)
|
||||
return csharp_namespace_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
void FileOptions::set_csharp_namespace(const ::std::string& value) {
|
||||
set_has_csharp_namespace();
|
||||
csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_namespace)
|
||||
}
|
||||
void FileOptions::set_csharp_namespace(const char* value) {
|
||||
set_has_csharp_namespace();
|
||||
csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
|
||||
// @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace)
|
||||
}
|
||||
void FileOptions::set_csharp_namespace(const char* value, size_t size) {
|
||||
set_has_csharp_namespace();
|
||||
csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
::std::string(reinterpret_cast<const char*>(value), size));
|
||||
// @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.csharp_namespace)
|
||||
}
|
||||
::std::string* FileOptions::mutable_csharp_namespace() {
|
||||
set_has_csharp_namespace();
|
||||
// @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_namespace)
|
||||
return csharp_namespace_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
::std::string* FileOptions::release_csharp_namespace() {
|
||||
clear_has_csharp_namespace();
|
||||
return csharp_namespace_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
void FileOptions::set_allocated_csharp_namespace(::std::string* csharp_namespace) {
|
||||
if (csharp_namespace != NULL) {
|
||||
set_has_csharp_namespace();
|
||||
} else {
|
||||
clear_has_csharp_namespace();
|
||||
}
|
||||
csharp_namespace_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), csharp_namespace);
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_namespace)
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
|
||||
int FileOptions::uninterpreted_option_size() const {
|
||||
return uninterpreted_option_.size();
|
||||
|
|
|
@ -1837,6 +1837,18 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
|
|||
::std::string* release_objc_class_prefix();
|
||||
void set_allocated_objc_class_prefix(::std::string* objc_class_prefix);
|
||||
|
||||
// optional string csharp_namespace = 37;
|
||||
bool has_csharp_namespace() const;
|
||||
void clear_csharp_namespace();
|
||||
static const int kCsharpNamespaceFieldNumber = 37;
|
||||
const ::std::string& csharp_namespace() const;
|
||||
void set_csharp_namespace(const ::std::string& value);
|
||||
void set_csharp_namespace(const char* value);
|
||||
void set_csharp_namespace(const char* value, size_t size);
|
||||
::std::string* mutable_csharp_namespace();
|
||||
::std::string* release_csharp_namespace();
|
||||
void set_allocated_csharp_namespace(::std::string* csharp_namespace);
|
||||
|
||||
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
|
||||
int uninterpreted_option_size() const;
|
||||
void clear_uninterpreted_option();
|
||||
|
@ -1878,6 +1890,8 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
|
|||
inline void clear_has_cc_enable_arenas();
|
||||
inline void set_has_objc_class_prefix();
|
||||
inline void clear_has_objc_class_prefix();
|
||||
inline void set_has_csharp_namespace();
|
||||
inline void clear_has_csharp_namespace();
|
||||
|
||||
::google::protobuf::internal::ExtensionSet _extensions_;
|
||||
|
||||
|
@ -1893,6 +1907,7 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
|
|||
int optimize_for_;
|
||||
::google::protobuf::internal::ArenaStringPtr go_package_;
|
||||
::google::protobuf::internal::ArenaStringPtr objc_class_prefix_;
|
||||
::google::protobuf::internal::ArenaStringPtr csharp_namespace_;
|
||||
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
|
||||
bool java_generic_services_;
|
||||
bool py_generic_services_;
|
||||
|
@ -5502,6 +5517,59 @@ inline void FileOptions::set_allocated_objc_class_prefix(::std::string* objc_cla
|
|||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix)
|
||||
}
|
||||
|
||||
// optional string csharp_namespace = 37;
|
||||
inline bool FileOptions::has_csharp_namespace() const {
|
||||
return (_has_bits_[0] & 0x00002000u) != 0;
|
||||
}
|
||||
inline void FileOptions::set_has_csharp_namespace() {
|
||||
_has_bits_[0] |= 0x00002000u;
|
||||
}
|
||||
inline void FileOptions::clear_has_csharp_namespace() {
|
||||
_has_bits_[0] &= ~0x00002000u;
|
||||
}
|
||||
inline void FileOptions::clear_csharp_namespace() {
|
||||
csharp_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
clear_has_csharp_namespace();
|
||||
}
|
||||
inline const ::std::string& FileOptions::csharp_namespace() const {
|
||||
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_namespace)
|
||||
return csharp_namespace_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline void FileOptions::set_csharp_namespace(const ::std::string& value) {
|
||||
set_has_csharp_namespace();
|
||||
csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
|
||||
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_namespace)
|
||||
}
|
||||
inline void FileOptions::set_csharp_namespace(const char* value) {
|
||||
set_has_csharp_namespace();
|
||||
csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
|
||||
// @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace)
|
||||
}
|
||||
inline void FileOptions::set_csharp_namespace(const char* value, size_t size) {
|
||||
set_has_csharp_namespace();
|
||||
csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
|
||||
::std::string(reinterpret_cast<const char*>(value), size));
|
||||
// @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.csharp_namespace)
|
||||
}
|
||||
inline ::std::string* FileOptions::mutable_csharp_namespace() {
|
||||
set_has_csharp_namespace();
|
||||
// @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_namespace)
|
||||
return csharp_namespace_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline ::std::string* FileOptions::release_csharp_namespace() {
|
||||
clear_has_csharp_namespace();
|
||||
return csharp_namespace_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
|
||||
}
|
||||
inline void FileOptions::set_allocated_csharp_namespace(::std::string* csharp_namespace) {
|
||||
if (csharp_namespace != NULL) {
|
||||
set_has_csharp_namespace();
|
||||
} else {
|
||||
clear_has_csharp_namespace();
|
||||
}
|
||||
csharp_namespace_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), csharp_namespace);
|
||||
// @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_namespace)
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
|
||||
inline int FileOptions::uninterpreted_option_size() const {
|
||||
return uninterpreted_option_.size();
|
||||
|
|
|
@ -351,6 +351,9 @@ message FileOptions {
|
|||
// generated classes from this .proto. There is no default.
|
||||
optional string objc_class_prefix = 36;
|
||||
|
||||
// Namespace for generated classes; defaults to the package.
|
||||
optional string csharp_namespace = 37;
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
|
@ -481,8 +484,6 @@ message FieldOptions {
|
|||
// For Google-internal migration only. Do not use.
|
||||
optional bool weak = 10 [default=false];
|
||||
|
||||
|
||||
|
||||
// The parser stores options it doesn't recognize here. See above.
|
||||
repeated UninterpretedOption uninterpreted_option = 999;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue