Merge pull request #1 from jtattermusch/csharp_protogen_rewrite

Rewrite of C# protogen to C++ (initial version)
This commit is contained in:
Jan Tattermusch 2015-04-17 15:02:14 -07:00
commit 8394a8daef
36 changed files with 5199 additions and 52 deletions

View file

@ -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)

View 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

View 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__

View 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

View 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__

View 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

View 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__

View 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

View 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__

View 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

View 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__

View file

@ -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

View 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

View 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__

View 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

View 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__

View 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

View 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__

View 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

View 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__

View file

@ -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

View 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_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__

View file

@ -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

View 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_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__

View file

@ -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

View 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_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__

View 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.
#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

View file

@ -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__

View 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

View 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__

View 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

View 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__

View file

@ -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);
}

View file

@ -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();

View file

@ -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();

View file

@ -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;