Rewrote C# protogen to C++ (initial version)

pull/256/head
Jan Tattermusch 10 years ago
parent 813d6d652d
commit 685ae36ca2
  1. 21
      src/Makefile.am
  2. 79
      src/google/protobuf/compiler/csharp/csharp_enum.cc
  3. 65
      src/google/protobuf/compiler/csharp/csharp_enum.h
  4. 160
      src/google/protobuf/compiler/csharp/csharp_enum_field.cc
  5. 73
      src/google/protobuf/compiler/csharp/csharp_enum_field.h
  6. 170
      src/google/protobuf/compiler/csharp/csharp_extension.cc
  7. 80
      src/google/protobuf/compiler/csharp/csharp_extension.h
  8. 394
      src/google/protobuf/compiler/csharp/csharp_field_base.cc
  9. 100
      src/google/protobuf/compiler/csharp/csharp_field_base.h
  10. 82
      src/google/protobuf/compiler/csharp/csharp_generator.cc
  11. 58
      src/google/protobuf/compiler/csharp/csharp_generator.h
  12. 54
      src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc
  13. 383
      src/google/protobuf/compiler/csharp/csharp_helpers.cc
  14. 108
      src/google/protobuf/compiler/csharp/csharp_helpers.h
  15. 900
      src/google/protobuf/compiler/csharp/csharp_message.cc
  16. 98
      src/google/protobuf/compiler/csharp/csharp_message.h
  17. 183
      src/google/protobuf/compiler/csharp/csharp_message_field.cc
  18. 73
      src/google/protobuf/compiler/csharp/csharp_message_field.h
  19. 148
      src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
  20. 73
      src/google/protobuf/compiler/csharp/csharp_primitive_field.h
  21. 226
      src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
  22. 73
      src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h
  23. 201
      src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc
  24. 73
      src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h
  25. 219
      src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
  26. 73
      src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
  27. 82
      src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc
  28. 83
      src/google/protobuf/compiler/csharp/csharp_source_generator_base.h
  29. 297
      src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc
  30. 76
      src/google/protobuf/compiler/csharp/csharp_umbrella_class.h
  31. 136
      src/google/protobuf/compiler/csharp/csharp_writer.cc
  32. 93
      src/google/protobuf/compiler/csharp/csharp_writer.h
  33. 6
      src/google/protobuf/compiler/main.cc
  34. 1116
      src/google/protobuf/descriptor.pb.cc
  35. 581
      src/google/protobuf/descriptor.pb.h
  36. 52
      src/google/protobuf/descriptor.proto

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

@ -0,0 +1,79 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/compiler/csharp/csharp_enum.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
using google::protobuf::internal::scoped_ptr;
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
EnumGenerator::EnumGenerator(const EnumDescriptor* descriptor) :
SourceGeneratorBase(descriptor->file()),
descriptor_(descriptor) {
}
EnumGenerator::~EnumGenerator() {
}
void EnumGenerator::Generate(Writer* writer) {
WriteGeneratedCodeAttributes(writer);
writer->WriteLine("$0$ enum $1$ {",
class_access_level(),
descriptor_->name());
writer->Indent();
for (int i = 0; i < descriptor_->value_count(); i++) {
writer->WriteLine("$0$ = $1$,",
descriptor_->value(i)->name(),
SimpleItoa(descriptor_->value(i)->number()));
}
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine();
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,65 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class Writer;
class EnumGenerator : public SourceGeneratorBase {
public:
EnumGenerator(const EnumDescriptor* descriptor);
~EnumGenerator();
void Generate(Writer* writer);
private:
const EnumDescriptor* descriptor_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumGenerator);
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_H__

@ -0,0 +1,160 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_enum_field.h>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal)
: FieldGeneratorBase(descriptor, fieldOrdinal) {
}
EnumFieldGenerator::~EnumFieldGenerator() {
}
void EnumFieldGenerator::GenerateMembers(Writer* writer) {
writer->WriteLine("private bool has$0$;", property_name());
writer->WriteLine("private $0$ $1$_ = $2$;", type_name(), name(),
default_value());
AddDeprecatedFlag(writer);
writer->WriteLine("public bool Has$0$ {", property_name());
writer->WriteLine(" get { return has$0$; }", property_name());
writer->WriteLine("}");
AddPublicMemberAttributes(writer);
writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
writer->WriteLine(" get { return $0$_; }", name());
writer->WriteLine("}");
}
void EnumFieldGenerator::GenerateBuilderMembers(Writer* writer) {
AddDeprecatedFlag(writer);
writer->WriteLine("public bool Has$0$ {", property_name());
writer->WriteLine(" get { return result.has$0$; }", property_name());
writer->WriteLine("}");
AddPublicMemberAttributes(writer);
writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
writer->WriteLine(" get { return result.$0$; }", property_name());
writer->WriteLine(" set { Set$0$(value); }", property_name());
writer->WriteLine("}");
AddPublicMemberAttributes(writer);
writer->WriteLine("public Builder Set$0$($1$ value) {", property_name(),
type_name());
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.has$0$ = true;", property_name());
writer->WriteLine(" result.$0$_ = value;", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Clear$0$() {", property_name());
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.has$0$ = false;", property_name());
writer->WriteLine(" result.$0$_ = $1$;", name(), default_value());
writer->WriteLine(" return this;");
writer->WriteLine("}");
}
void EnumFieldGenerator::GenerateMergingCode(Writer* writer) {
writer->WriteLine("if (other.Has$0$) {", property_name());
writer->WriteLine(" $0$ = other.$0$;", property_name());
writer->WriteLine("}");
}
void EnumFieldGenerator::GenerateBuildingCode(Writer* writer) {
// Nothing to do here for enum types
}
void EnumFieldGenerator::GenerateParsingCode(Writer* writer) {
writer->WriteLine("object unknown;");
writer->WriteLine("if(input.ReadEnum(ref result.$0$_, out unknown)) {",
name());
writer->WriteLine(" result.has$0$ = true;", property_name());
writer->WriteLine("} else if(unknown is int) {");
if (!use_lite_runtime()) {
writer->WriteLine(" if (unknownFields == null) {"); // First unknown field - create builder now
writer->WriteLine(
" unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
writer->WriteLine(" }");
writer->WriteLine(
" unknownFields.MergeVarintField($0$, (ulong)(int)unknown);",
number());
}
writer->WriteLine("}");
}
void EnumFieldGenerator::GenerateSerializationCode(Writer* writer) {
writer->WriteLine("if (has$0$) {", property_name());
writer->WriteLine(
" output.WriteEnum($0$, field_names[$2$], (int) $1$, $1$);", number(),
property_name(), field_ordinal());
writer->WriteLine("}");
}
void EnumFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
writer->WriteLine("if (has$0$) {", property_name());
writer->WriteLine(
" size += pb::CodedOutputStream.ComputeEnumSize($0$, (int) $1$);",
number(), property_name());
writer->WriteLine("}");
}
void EnumFieldGenerator::WriteHash(Writer* writer) {
writer->WriteLine("if (has$0$) hash ^= $1$_.GetHashCode();", property_name(),
name());
}
void EnumFieldGenerator::WriteEquals(Writer* writer) {
writer->WriteLine(
"if (has$0$ != other.has$0$ || (has$0$ && !$1$_.Equals(other.$1$_))) return false;",
property_name(), name());
}
void EnumFieldGenerator::WriteToString(Writer* writer) {
writer->WriteLine("PrintField(\"$0$\", has$1$, $2$_, writer);",
descriptor_->name(), property_name(), name());
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,73 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class Writer;
class EnumFieldGenerator : public FieldGeneratorBase {
public:
EnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
~EnumFieldGenerator();
virtual void GenerateMembers(Writer* writer);
virtual void GenerateBuilderMembers(Writer* writer);
virtual void GenerateMergingCode(Writer* writer);
virtual void GenerateBuildingCode(Writer* writer);
virtual void GenerateParsingCode(Writer* writer);
virtual void GenerateSerializationCode(Writer* writer);
virtual void GenerateSerializedSizeCode(Writer* writer);
virtual void WriteHash(Writer* writer);
virtual void WriteEquals(Writer* writer);
virtual void WriteToString(Writer* writer);
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumFieldGenerator);
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_ENUM_FIELD_H__

@ -0,0 +1,170 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/compiler/csharp/csharp_extension.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h>
using google::protobuf::internal::scoped_ptr;
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor)
: FieldGeneratorBase(descriptor, 0) {
if (descriptor_->extension_scope()) {
scope_ = GetClassName(descriptor_->extension_scope());
} else {
scope_ = GetFullUmbrellaClassName(descriptor_->file());
}
extends_ = GetClassName(descriptor_->containing_type());
}
ExtensionGenerator::~ExtensionGenerator() {
}
void ExtensionGenerator::Generate(Writer* writer) {
if (descriptor_->file()->options().csharp_cls_compliance()
&& (GetFieldConstantName(descriptor_).substr(0, 1) == "_")) {
writer->WriteLine("[global::System.CLSCompliant(false)]");
}
writer->WriteLine("public const int $0$ = $1$;",
GetFieldConstantName(descriptor_),
SimpleItoa(descriptor_->number()));
if (use_lite_runtime()) {
// TODO(jtattermusch): check the argument...
//if (Descriptor.MappedType == MappedType.Message && Descriptor.MessageType.Options.MessageSetWireFormat)
//{
// throw new ArgumentException(
// "option message_set_wire_format = true; is not supported in Lite runtime extensions.");
//}
AddClsComplianceCheck(writer);
writer->Write("$0$ ", class_access_level());
writer->WriteLine(
"static pb::$3$<$0$, $1$> $2$;",
extends_,
type_name(),
property_name(),
descriptor_->is_repeated() ?
"GeneratedRepeatExtensionLite" : "GeneratedExtensionLite");
} else if (descriptor_->is_repeated()) {
AddClsComplianceCheck(writer);
writer->WriteLine(
"$0$ static pb::GeneratedExtensionBase<scg::IList<$1$>> $2$;",
class_access_level(), type_name(), property_name());
} else {
AddClsComplianceCheck(writer);
writer->WriteLine("$0$ static pb::GeneratedExtensionBase<$1$> $2$;",
class_access_level(), type_name(), property_name());
}
}
void ExtensionGenerator::GenerateStaticVariableInitializers(Writer* writer) {
if (use_lite_runtime()) {
writer->WriteLine("$0$.$1$ = ", scope_, property_name());
writer->Indent();
writer->WriteLine(
"new pb::$0$<$1$, $2$>(",
descriptor_->is_repeated() ?
"GeneratedRepeatExtensionLite" : "GeneratedExtensionLite",
extends_, type_name());
writer->Indent();
writer->WriteLine("\"$0$\",", descriptor_->full_name());
writer->WriteLine("$0$.DefaultInstance,", extends_);
if (!descriptor_->is_repeated()) {
std::string default_val;
if (descriptor_->has_default_value()) {
default_val = default_value();
} else {
default_val = is_nullable_type() ? "null" : ("default(" + type_name() + ")");
}
writer->WriteLine("$0$,", default_val);
}
// TODO(jtattermusch):
//writer.WriteLine("{0},",
// (Descriptor.MappedType == MappedType.Message) ? type + ".DefaultInstance" : "null");
//writer.WriteLine("{0},",
// (Descriptor.MappedType == MappedType.Enum) ? "new EnumLiteMap<" + type + ">()" : "null");
//writer.WriteLine("{0}.{1}FieldNumber,", scope, name);
//writer.Write("pbd::FieldType.{0}", Descriptor.FieldType);
if (descriptor_->is_repeated()) {
writer->WriteLine(",");
writer->Write(descriptor_->is_packed() ? "true" : "false");
}
writer->Outdent();
writer->WriteLine(");");
writer->Outdent();
}
else if (descriptor_->is_repeated())
{
writer->WriteLine(
"$0$.$1$ = pb::GeneratedRepeatExtension<$2$>.CreateInstance($0$.Descriptor.Extensions[$3$]);",
scope_, property_name(), type_name(), SimpleItoa(descriptor_->index()));
}
else
{
writer->WriteLine(
"$0$.$1$ = pb::GeneratedSingleExtension<$2$>.CreateInstance($0$.Descriptor.Extensions[$3$]);",
scope_, property_name(), type_name(), SimpleItoa(descriptor_->index()));
}
}
void ExtensionGenerator::GenerateExtensionRegistrationCode(Writer* writer) {
writer->WriteLine("registry.Add($0$.$1$);", scope_, property_name());
}
void ExtensionGenerator::WriteHash(Writer* writer) {
}
void ExtensionGenerator::WriteEquals(Writer* writer) {
}
void ExtensionGenerator::WriteToString(Writer* writer) {
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,80 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_EXTENSION_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_EXTENSION_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class Writer;
class ExtensionGenerator : public FieldGeneratorBase {
public:
ExtensionGenerator(const FieldDescriptor* descriptor);
~ExtensionGenerator();
void GenerateStaticVariableInitializers(Writer* writer);
void GenerateExtensionRegistrationCode(Writer* writer);
void Generate(Writer* writer);
virtual void WriteHash(Writer* writer);
virtual void WriteEquals(Writer* writer);
virtual void WriteToString(Writer* writer);
virtual void GenerateMembers(Writer* writer) {};
virtual void GenerateBuilderMembers(Writer* writer) {};
virtual void GenerateMergingCode(Writer* writer) {};
virtual void GenerateBuildingCode(Writer* writer) {};
virtual void GenerateParsingCode(Writer* writer) {};
virtual void GenerateSerializationCode(Writer* writer) {};
virtual void GenerateSerializedSizeCode(Writer* writer) {};
private:
std::string scope_;
std::string extends_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ExtensionGenerator);
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_EXTENSION_H__

@ -0,0 +1,394 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <limits>
#include <sstream>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
using google::protobuf::internal::scoped_ptr;
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
FieldGeneratorBase::FieldGeneratorBase(const FieldDescriptor* descriptor,
int fieldOrdinal)
: SourceGeneratorBase(descriptor->file()),
descriptor_(descriptor),
fieldOrdinal_(fieldOrdinal) {
}
FieldGeneratorBase::~FieldGeneratorBase() {
}
void FieldGeneratorBase::AddDeprecatedFlag(Writer* writer) {
// TODO(jtattermusch):
//if (IsObsolete)
//{
// writer.WriteLine("[global::System.ObsoleteAttribute()]");
//}
}
void FieldGeneratorBase::AddNullCheck(Writer* writer) {
AddNullCheck(writer, "value");
}
void FieldGeneratorBase::AddNullCheck(Writer* writer, const std::string& name) {
if (is_nullable_type()) {
writer->WriteLine(" pb::ThrowHelper.ThrowIfNull($0$, \"$0$\");", name);
}
}
void FieldGeneratorBase::AddPublicMemberAttributes(Writer* writer) {
AddDeprecatedFlag(writer);
AddClsComplianceCheck(writer);
}
void FieldGeneratorBase::AddClsComplianceCheck(Writer* writer) {
if (!is_cls_compliant() && descriptor_->file()->options().csharp_cls_compliance()) {
writer->WriteLine("[global::System.CLSCompliant(false)]");
}
}
std::string FieldGeneratorBase::property_name() {
return GetPropertyName(descriptor_);
}
std::string FieldGeneratorBase::name() {
return UnderscoresToCamelCase(GetFieldName(descriptor_), false);
}
std::string FieldGeneratorBase::type_name() {
switch (descriptor_->type()) {
case FieldDescriptor::TYPE_ENUM:
return GetClassName(descriptor_->enum_type());
case FieldDescriptor::TYPE_MESSAGE:
case FieldDescriptor::TYPE_GROUP:
return GetClassName(descriptor_->message_type());
case FieldDescriptor::TYPE_DOUBLE:
return "double";
case FieldDescriptor::TYPE_FLOAT:
return "float";
case FieldDescriptor::TYPE_INT64:
return "long";
case FieldDescriptor::TYPE_UINT64:
return "ulong";
case FieldDescriptor::TYPE_INT32:
return "int";
case FieldDescriptor::TYPE_FIXED64:
return "ulong";
case FieldDescriptor::TYPE_FIXED32:
return "uint";
case FieldDescriptor::TYPE_BOOL:
return "bool";
case FieldDescriptor::TYPE_STRING:
return "string";
case FieldDescriptor::TYPE_BYTES:
return "pb::ByteString";
case FieldDescriptor::TYPE_UINT32:
return "uint";
case FieldDescriptor::TYPE_SFIXED32:
return "int";
case FieldDescriptor::TYPE_SFIXED64:
return "long";
case FieldDescriptor::TYPE_SINT32:
return "int";
case FieldDescriptor::TYPE_SINT64:
return "long";
default:
GOOGLE_LOG(FATAL)<< "Unknown field type.";
return "";
}
}
bool FieldGeneratorBase::has_default_value() {
switch (descriptor_->type()) {
case FieldDescriptor::TYPE_ENUM:
case FieldDescriptor::TYPE_MESSAGE:
case FieldDescriptor::TYPE_GROUP:
return true;
case FieldDescriptor::TYPE_DOUBLE:
return descriptor_->default_value_double() != 0.0;
case FieldDescriptor::TYPE_FLOAT:
return descriptor_->default_value_float() != 0.0;
case FieldDescriptor::TYPE_INT64:
return descriptor_->default_value_int64() != 0L;
case FieldDescriptor::TYPE_UINT64:
return descriptor_->default_value_uint64() != 0L;
case FieldDescriptor::TYPE_INT32:
return descriptor_->default_value_int32() != 0;
case FieldDescriptor::TYPE_FIXED64:
return descriptor_->default_value_uint64() != 0L;
case FieldDescriptor::TYPE_FIXED32:
return descriptor_->default_value_uint32() != 0;
case FieldDescriptor::TYPE_BOOL:
return descriptor_->default_value_bool();
case FieldDescriptor::TYPE_STRING:
return true;
case FieldDescriptor::TYPE_BYTES:
return true;
case FieldDescriptor::TYPE_UINT32:
return descriptor_->default_value_uint32() != 0;
case FieldDescriptor::TYPE_SFIXED32:
return descriptor_->default_value_int32() != 0;
case FieldDescriptor::TYPE_SFIXED64:
return descriptor_->default_value_int64() != 0L;
case FieldDescriptor::TYPE_SINT32:
return descriptor_->default_value_int32() != 0;
case FieldDescriptor::TYPE_SINT64:
return descriptor_->default_value_int64() != 0L;
default:
GOOGLE_LOG(FATAL)<< "Unknown field type.";
return true;
}
}
bool FieldGeneratorBase::is_nullable_type() {
switch (descriptor_->type()) {
case FieldDescriptor::TYPE_ENUM:
case FieldDescriptor::TYPE_DOUBLE:
case FieldDescriptor::TYPE_FLOAT:
case FieldDescriptor::TYPE_INT64:
case FieldDescriptor::TYPE_UINT64:
case FieldDescriptor::TYPE_INT32:
case FieldDescriptor::TYPE_FIXED64:
case FieldDescriptor::TYPE_FIXED32:
case FieldDescriptor::TYPE_BOOL:
case FieldDescriptor::TYPE_UINT32:
case FieldDescriptor::TYPE_SFIXED32:
case FieldDescriptor::TYPE_SFIXED64:
case FieldDescriptor::TYPE_SINT32:
case FieldDescriptor::TYPE_SINT64:
return false;
case FieldDescriptor::TYPE_MESSAGE:
case FieldDescriptor::TYPE_GROUP:
case FieldDescriptor::TYPE_STRING:
case FieldDescriptor::TYPE_BYTES:
return true;
default:
GOOGLE_LOG(FATAL)<< "Unknown field type.";
return true;
}
}
bool FieldGeneratorBase::is_cls_compliant() {
CSharpType type = GetCSharpType(descriptor_->type());
return (type != CSHARPTYPE_UINT32) && (type != CSHARPTYPE_UINT64)
&& (UnderscoresToPascalCase(name()).substr(0, 1) != "_");
}
inline bool IsNaN(double value) {
// NaN is never equal to anything, even itself.
return value != value;
}
bool AllPrintableAscii(const std::string& text) {
for(int i = 0; i < text.size(); i++) {
if (text[i] < 0x20 || text[i] > 0x7e) {
return false;
}
}
return true;
}
std::string FieldGeneratorBase::GetStringDefaultValueInternal() {
if (!descriptor_->has_default_value()) {
return "\"\"";
}
if (AllPrintableAscii(descriptor_->default_value_string())) {
// All chars are ASCII and printable. In this case we only
// need to escape quotes and backslashes.
std::string temp = descriptor_->default_value_string();
temp = StringReplace(temp, "\\", "\\\\", true);
temp = StringReplace(temp, "'", "\\'", true);
temp = StringReplace(temp, "\"", "\\\"", true);
return "\"" + temp + "\"";
}
if (use_lite_runtime()) {
return "pb::ByteString.FromBase64(\""
+ StringToBase64(descriptor_->default_value_string())
+ "\").ToStringUtf8()";
}
return "(string) " + GetClassName(descriptor_->containing_type())
+ ".Descriptor.Fields[" + SimpleItoa(descriptor_->index())
+ "].DefaultValue";
}
std::string FieldGeneratorBase::GetBytesDefaultValueInternal() {
if (!descriptor_->has_default_value()) {
return "pb::ByteString.Empty";
}
if (use_lite_runtime()) {
return "pb::ByteString.FromBase64(\"" + StringToBase64(descriptor_->default_value_string()) + "\")";
}
return "(pb::ByteString) "+ GetClassName(descriptor_->containing_type()) +
".Descriptor.Fields[" + SimpleItoa(descriptor_->index()) + "].DefaultValue";
}
std::string FieldGeneratorBase::default_value() {
switch (descriptor_->type()) {
case FieldDescriptor::TYPE_ENUM:
return type_name() + "." + descriptor_->default_value_enum()->name();
case FieldDescriptor::TYPE_MESSAGE:
case FieldDescriptor::TYPE_GROUP:
return type_name() + ".DefaultInstance";
case FieldDescriptor::TYPE_DOUBLE: {
double value = descriptor_->default_value_double();
if (value == numeric_limits<double>::infinity()) {
return "double.PositiveInfinity";
} else if (value == -numeric_limits<double>::infinity()) {
return "double.NegativeInfinity";
} else if (IsNaN(value)) {
return "double.NaN";
}
return SimpleDtoa(value) + "D";
}
case FieldDescriptor::TYPE_FLOAT: {
float value = descriptor_->default_value_float();
if (value == numeric_limits<float>::infinity()) {
return "float.PositiveInfinity";
} else if (value == -numeric_limits<float>::infinity()) {
return "float.NegativeInfinity";
} else if (IsNaN(value)) {
return "float.NaN";
}
return SimpleFtoa(value) + "F";
}
case FieldDescriptor::TYPE_INT64:
return SimpleItoa(descriptor_->default_value_int64()) + "L";
case FieldDescriptor::TYPE_UINT64:
return SimpleItoa(descriptor_->default_value_uint64()) + "UL";
case FieldDescriptor::TYPE_INT32:
return SimpleItoa(descriptor_->default_value_int32());
case FieldDescriptor::TYPE_FIXED64:
return SimpleItoa(descriptor_->default_value_uint64()) + "UL";
case FieldDescriptor::TYPE_FIXED32:
return SimpleItoa(descriptor_->default_value_uint32());
case FieldDescriptor::TYPE_BOOL:
if (descriptor_->default_value_bool()) {
return "true";
} else {
return "false";
}
case FieldDescriptor::TYPE_STRING:
return GetStringDefaultValueInternal();
case FieldDescriptor::TYPE_BYTES:
return GetBytesDefaultValueInternal();
case FieldDescriptor::TYPE_UINT32:
return SimpleItoa(descriptor_->default_value_uint32());
case FieldDescriptor::TYPE_SFIXED32:
return SimpleItoa(descriptor_->default_value_int32());
case FieldDescriptor::TYPE_SFIXED64:
return SimpleItoa(descriptor_->default_value_int64()) + "L";
case FieldDescriptor::TYPE_SINT32:
return SimpleItoa(descriptor_->default_value_int32());
case FieldDescriptor::TYPE_SINT64:
return SimpleItoa(descriptor_->default_value_int64()) + "L";
default:
GOOGLE_LOG(FATAL)<< "Unknown field type.";
return "";
}
}
std::string FieldGeneratorBase::number() {
return SimpleItoa(descriptor_->number());
}
std::string FieldGeneratorBase::message_or_group() {
return
(descriptor_->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message";
}
std::string FieldGeneratorBase::capitalized_type_name() {
switch (descriptor_->type()) {
case FieldDescriptor::TYPE_ENUM:
return "Enum";
case FieldDescriptor::TYPE_MESSAGE:
return "Message";
case FieldDescriptor::TYPE_GROUP:
return "Group";
case FieldDescriptor::TYPE_DOUBLE:
return "Double";
case FieldDescriptor::TYPE_FLOAT:
return "Float";
case FieldDescriptor::TYPE_INT64:
return "Int64";
case FieldDescriptor::TYPE_UINT64:
return "UInt64";
case FieldDescriptor::TYPE_INT32:
return "Int32";
case FieldDescriptor::TYPE_FIXED64:
return "Fixed64";
case FieldDescriptor::TYPE_FIXED32:
return "Fixed32";
case FieldDescriptor::TYPE_BOOL:
return "Bool";
case FieldDescriptor::TYPE_STRING:
return "String";
case FieldDescriptor::TYPE_BYTES:
return "Bytes";
case FieldDescriptor::TYPE_UINT32:
return "UInt32";
case FieldDescriptor::TYPE_SFIXED32:
return "SFixed32";
case FieldDescriptor::TYPE_SFIXED64:
return "SFixed64";
case FieldDescriptor::TYPE_SINT32:
return "SInt32";
case FieldDescriptor::TYPE_SINT64:
return "SInt64";
default:
GOOGLE_LOG(FATAL)<< "Unknown field type.";
return "";
}
}
std::string FieldGeneratorBase::field_ordinal() {
return SimpleItoa(fieldOrdinal_);
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,100 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_BASE_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_BASE_H__
#include <string>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class Writer;
class FieldGeneratorBase : public SourceGeneratorBase {
public:
FieldGeneratorBase(const FieldDescriptor* descriptor, int fieldOrdinal);
~FieldGeneratorBase();
virtual void GenerateMembers(Writer* writer) = 0;
virtual void GenerateBuilderMembers(Writer* writer) = 0;
virtual void GenerateMergingCode(Writer* writer) = 0;
virtual void GenerateBuildingCode(Writer* writer) = 0;
virtual void GenerateParsingCode(Writer* writer) = 0;
virtual void GenerateSerializationCode(Writer* writer) = 0;
virtual void GenerateSerializedSizeCode(Writer* writer) = 0;
virtual void WriteHash(Writer* writer) = 0;
virtual void WriteEquals(Writer* writer) = 0;
virtual void WriteToString(Writer* writer) = 0;
protected:
const FieldDescriptor* descriptor_;
const int fieldOrdinal_;
void AddDeprecatedFlag(Writer* writer);
void AddNullCheck(Writer* writer);
void AddNullCheck(Writer* writer, const std::string& name);
void AddPublicMemberAttributes(Writer* writer);
void AddClsComplianceCheck(Writer* writer);
std::string property_name();
std::string name();
std::string type_name();
bool has_default_value();
bool is_nullable_type();
bool is_cls_compliant();
std::string default_value();
std::string number();
std::string message_or_group();
std::string capitalized_type_name();
std::string field_ordinal();
private:
std::string GetStringDefaultValueInternal();
std::string GetBytesDefaultValueInternal();
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FieldGeneratorBase);
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_FIELD_BASE_H__

@ -0,0 +1,82 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/compiler/csharp/csharp_generator.h>
#include <google/protobuf/compiler/csharp/csharp_umbrella_class.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
using google::protobuf::internal::scoped_ptr;
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
void GenerateFile(const google::protobuf::FileDescriptor* file,
Writer* writer) {
UmbrellaClassGenerator umbrellaGenerator(file);
umbrellaGenerator.Generate(writer);
}
bool Generator::Generate(
const FileDescriptor* file,
const string& parameter,
GeneratorContext* generator_context,
string* error) const {
// TODO: parse generator parameters...
// TODO: file output file naming logic
std::string filename =
StripDotProto(file->name()) + ".cs";
scoped_ptr<io::ZeroCopyOutputStream> output(
generator_context->Open(filename));
io::Printer printer(output.get(), '$');
Writer writer(&printer);
GenerateFile(file, &writer);
return true;
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,58 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class LIBPROTOC_EXPORT Generator
: public google::protobuf::compiler::CodeGenerator {
virtual bool Generate(
const FileDescriptor* file,
const string& parameter,
GeneratorContext* generator_context,
string* error) const;
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_GENERATOR_H__

@ -0,0 +1,54 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2014 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <memory>
#include <google/protobuf/compiler/ruby/ruby_generator.h>
#include <google/protobuf/compiler/command_line_interface.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/testing/googletest.h>
#include <gtest/gtest.h>
#include <google/protobuf/testing/file.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
namespace {
// TODO(jtattermusch): add some tests.
} // namespace
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,383 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <algorithm>
#include <google/protobuf/stubs/hash.h>
#include <limits>
#include <vector>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h>
#include <google/protobuf/compiler/csharp/csharp_enum_field.h>
#include <google/protobuf/compiler/csharp/csharp_message_field.h>
#include <google/protobuf/compiler/csharp/csharp_primitive_field.h>
#include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h>
#include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h>
#include <google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
CSharpType GetCSharpType(FieldDescriptor::Type type) {
switch (type) {
case FieldDescriptor::TYPE_INT32:
return CSHARPTYPE_INT32;
case FieldDescriptor::TYPE_INT64:
return CSHARPTYPE_INT64;
case FieldDescriptor::TYPE_UINT32:
return CSHARPTYPE_UINT32;
case FieldDescriptor::TYPE_UINT64:
return CSHARPTYPE_UINT32;
case FieldDescriptor::TYPE_SINT32:
return CSHARPTYPE_INT32;
case FieldDescriptor::TYPE_SINT64:
return CSHARPTYPE_INT64;
case FieldDescriptor::TYPE_FIXED32:
return CSHARPTYPE_UINT32;
case FieldDescriptor::TYPE_FIXED64:
return CSHARPTYPE_UINT64;
case FieldDescriptor::TYPE_SFIXED32:
return CSHARPTYPE_INT32;
case FieldDescriptor::TYPE_SFIXED64:
return CSHARPTYPE_INT64;
case FieldDescriptor::TYPE_FLOAT:
return CSHARPTYPE_FLOAT;
case FieldDescriptor::TYPE_DOUBLE:
return CSHARPTYPE_DOUBLE;
case FieldDescriptor::TYPE_BOOL:
return CSHARPTYPE_BOOL;
case FieldDescriptor::TYPE_ENUM:
return CSHARPTYPE_ENUM;
case FieldDescriptor::TYPE_STRING:
return CSHARPTYPE_STRING;
case FieldDescriptor::TYPE_BYTES:
return CSHARPTYPE_BYTESTRING;
case FieldDescriptor::TYPE_GROUP:
return CSHARPTYPE_MESSAGE;
case FieldDescriptor::TYPE_MESSAGE:
return CSHARPTYPE_MESSAGE;
// No default because we want the compiler to complain if any new
// types are added.
}
GOOGLE_LOG(FATAL)<< "Can't get here.";
return (CSharpType) -1;
}
std::string StripDotProto(const std::string& proto_file) {
int lastindex = proto_file.find_last_of(".");
return proto_file.substr(0, lastindex);
}
std::string GetFileNamespace(const FileDescriptor* descriptor) {
if (descriptor->options().has_csharp_namespace()) {
return descriptor->options().csharp_namespace();
}
return descriptor->package();
}
std::string GetUmbrellaClassNameInternal(const std::string& proto_file) {
int lastslash = proto_file.find_last_of("/");
std::string base = proto_file.substr(lastslash + 1);
return UnderscoresToPascalCase(StripDotProto(base));
}
std::string GetFileUmbrellaClassname(const FileDescriptor* descriptor) {
if (descriptor->options().has_csharp_umbrella_classname()) {
return descriptor->options().csharp_umbrella_namespace();
} else {
return GetUmbrellaClassNameInternal(descriptor->name());
}
}
std::string GetFileUmbrellaNamespace(const FileDescriptor* descriptor) {
if (!descriptor->options().csharp_nest_classes()
&& !descriptor->options().has_csharp_umbrella_namespace()) {
bool collision = false;
// TODO(jtattermusch): detect collisions!
// foreach (IDescriptor d in MessageTypes)
// {
// collision |= d.Name == builder.UmbrellaClassname;
// }
// foreach (IDescriptor d in Services)
// {
// collision |= d.Name == builder.UmbrellaClassname;
// }
// foreach (IDescriptor d in EnumTypes)
// {
// collision |= d.Name == builder.UmbrellaClassname;
// }
if (collision) {
return "Proto";
}
}
return "";
}
// TODO(jtattermusch): can we reuse a utility function?
std::string UnderscoresToCamelCase(const std::string& input,
bool cap_next_letter) {
string result;
// Note: I distrust ctype.h due to locales.
for (int i = 0; i < input.size(); i++) {
if ('a' <= input[i] && input[i] <= 'z') {
if (cap_next_letter) {
result += input[i] + ('A' - 'a');
} else {
result += input[i];
}
cap_next_letter = false;
} else if ('A' <= input[i] && input[i] <= 'Z') {
if (i == 0 && !cap_next_letter) {
// Force first letter to lower-case unless explicitly told to
// capitalize it.
result += input[i] + ('a' - 'A');
} else {
// Capital letters after the first are left as-is.
result += input[i];
}
cap_next_letter = false;
} else if ('0' <= input[i] && input[i] <= '9') {
result += input[i];
cap_next_letter = true;
} else {
cap_next_letter = true;
}
}
// Add a trailing "_" if the name should be altered.
if (input[input.size() - 1] == '#') {
result += '_';
}
return result;
}
std::string UnderscoresToPascalCase(const std::string& input) {
return UnderscoresToCamelCase(input, true);
}
std::string ToCSharpName(const std::string& name, const FileDescriptor* file) {
std::string result = GetFileNamespace(file);
if (file->options().csharp_nest_classes()) {
if (result != "") {
result += ".";
}
result += GetFileUmbrellaClassname(file);
}
if (result != "") {
result += '.';
}
string classname;
if (file->package().empty()) {
classname = name;
} else {
// Strip the proto package from full_name since we've replaced it with
// the C# namespace.
classname = name.substr(file->package().size() + 1);
}
result += StringReplace(classname, ".", ".Types.", false);
return "global::" + result;
}
std::string GetFullUmbrellaClassName(const FileDescriptor* descriptor) {
std::string result = GetFileNamespace(descriptor);
if (!result.empty()) {
result += '.';
}
result += GetQualifiedUmbrellaClassName(descriptor);
return "global::" + result;
}
std::string GetQualifiedUmbrellaClassName(const FileDescriptor* descriptor) {
std::string umbrellaNamespace = GetFileUmbrellaNamespace(descriptor);
std::string umbrellaClassname = GetFileUmbrellaClassname(descriptor);
std::string fullName = umbrellaClassname;
if (!descriptor->options().csharp_nest_classes()
&& !umbrellaNamespace.empty()) {
fullName = umbrellaNamespace + "." + umbrellaClassname;
}
return fullName;
}
std::string GetClassName(const Descriptor* descriptor) {
return ToCSharpName(descriptor->full_name(), descriptor->file());
}
std::string GetClassName(const EnumDescriptor* descriptor) {
return ToCSharpName(descriptor->full_name(), descriptor->file());
}
// Groups are hacky: The name of the field is just the lower-cased name
// of the group type. In C#, though, we would like to retain the original
// capitalization of the type name.
std::string GetFieldName(const FieldDescriptor* descriptor) {
if (descriptor->type() == FieldDescriptor::TYPE_GROUP) {
return descriptor->message_type()->name();
} else {
return descriptor->name();
}
}
std::string GetFieldConstantName(const FieldDescriptor* field) {
return GetPropertyName(field) + "FieldNumber";
}
std::string GetPropertyName(const FieldDescriptor* descriptor) {
// TODO: fix this.
std::string property_name = UnderscoresToPascalCase(GetFieldName(descriptor));
if (property_name == descriptor->containing_type()->name()) {
property_name += "_";
}
return property_name;
}
// TODO: c&p from Java protoc plugin
// For encodings with fixed sizes, returns that size in bytes. Otherwise
// returns -1.
int GetFixedSize(FieldDescriptor::Type type) {
switch (type) {
case FieldDescriptor::TYPE_INT32 : return -1;
case FieldDescriptor::TYPE_INT64 : return -1;
case FieldDescriptor::TYPE_UINT32 : return -1;
case FieldDescriptor::TYPE_UINT64 : return -1;
case FieldDescriptor::TYPE_SINT32 : return -1;
case FieldDescriptor::TYPE_SINT64 : return -1;
case FieldDescriptor::TYPE_FIXED32 : return internal::WireFormatLite::kFixed32Size;
case FieldDescriptor::TYPE_FIXED64 : return internal::WireFormatLite::kFixed64Size;
case FieldDescriptor::TYPE_SFIXED32: return internal::WireFormatLite::kSFixed32Size;
case FieldDescriptor::TYPE_SFIXED64: return internal::WireFormatLite::kSFixed64Size;
case FieldDescriptor::TYPE_FLOAT : return internal::WireFormatLite::kFloatSize;
case FieldDescriptor::TYPE_DOUBLE : return internal::WireFormatLite::kDoubleSize;
case FieldDescriptor::TYPE_BOOL : return internal::WireFormatLite::kBoolSize;
case FieldDescriptor::TYPE_ENUM : return -1;
case FieldDescriptor::TYPE_STRING : return -1;
case FieldDescriptor::TYPE_BYTES : return -1;
case FieldDescriptor::TYPE_GROUP : return -1;
case FieldDescriptor::TYPE_MESSAGE : return -1;
// No default because we want the compiler to complain if any new
// types are added.
}
GOOGLE_LOG(FATAL) << "Can't get here.";
return -1;
}
static const char base64_chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
std::string StringToBase64(const std::string& input) {
std::string result;
size_t remaining = input.size();
const unsigned char *src = (const unsigned char*) input.c_str();
while (remaining > 2) {
result += base64_chars[src[0] >> 2];
result += base64_chars[((src[0] & 0x3) << 4) | (src[1] >> 4)];
result += base64_chars[((src[1] & 0xf) << 2) | (src[2] >> 6)];
result += base64_chars[src[2] & 0x3f];
remaining -= 3;
src += 3;
}
switch (remaining) {
case 2:
result += base64_chars[src[0] >> 2];
result += base64_chars[((src[0] & 0x3) << 4) | (src[1] >> 4)];
result += base64_chars[(src[1] & 0xf) << 2];
result += '=';
src += 2;
break;
case 1:
result += base64_chars[src[0] >> 2];
result += base64_chars[((src[0] & 0x3) << 4)];
result += '=';
result += '=';
src += 1;
break;
}
return result;
}
std::string FileDescriptorToBase64(const FileDescriptor* descriptor) {
std::string fdp_bytes;
FileDescriptorProto fdp;
descriptor->CopyTo(&fdp);
fdp.SerializeToString(&fdp_bytes);
return StringToBase64(fdp_bytes);
}
FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal) {
switch (descriptor->type()) {
case FieldDescriptor::TYPE_GROUP:
case FieldDescriptor::TYPE_MESSAGE:
if (descriptor->is_repeated()) {
return new RepeatedMessageFieldGenerator(descriptor, fieldOrdinal);
} else {
return new MessageFieldGenerator(descriptor, fieldOrdinal);
}
case FieldDescriptor::TYPE_ENUM:
if (descriptor->is_repeated()) {
return new RepeatedEnumFieldGenerator(descriptor, fieldOrdinal);
} else {
return new EnumFieldGenerator(descriptor, fieldOrdinal);
}
default:
if (descriptor->is_repeated()) {
return new RepeatedPrimitiveFieldGenerator(descriptor, fieldOrdinal);
} else {
return new PrimitiveFieldGenerator(descriptor, fieldOrdinal);
}
}
}
bool HasRequiredFields(const Descriptor* descriptor) {
// TODO(jtattermusch): implement this.
return true;
}
} // namespace java
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,108 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__
#include <string>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/io/printer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class FieldGeneratorBase;
// TODO: start using this enum.
enum CSharpType {
CSHARPTYPE_INT32 = 1,
CSHARPTYPE_INT64 = 2,
CSHARPTYPE_UINT32 = 3,
CSHARPTYPE_UINT64 = 4,
CSHARPTYPE_FLOAT = 5,
CSHARPTYPE_DOUBLE = 6,
CSHARPTYPE_BOOL = 7,
CSHARPTYPE_STRING = 8,
CSHARPTYPE_BYTESTRING = 9,
CSHARPTYPE_MESSAGE = 10,
CSHARPTYPE_ENUM = 11,
MAX_CSHARPTYPE = 11
};
// Converts field type to corresponding C# type.
CSharpType GetCSharpType(FieldDescriptor::Type type);
std::string StripDotProto(const std::string& proto_file);
std::string GetFileNamespace(const FileDescriptor* descriptor);
std::string GetFileUmbrellaClassname(const FileDescriptor* descriptor);
std::string GetFileUmbrellaNamespace(const FileDescriptor* descriptor);
std::string GetFullUmbrellaClassName(const FileDescriptor* descriptor);
std::string GetQualifiedUmbrellaClassName(const FileDescriptor* descriptor);
std::string GetClassName(const Descriptor* descriptor);
std::string GetClassName(const EnumDescriptor* descriptor);
std::string GetFieldName(const FieldDescriptor* descriptor);
std::string GetFieldConstantName(const FieldDescriptor* field);
std::string GetPropertyName(const FieldDescriptor* descriptor);
int GetFixedSize(FieldDescriptor::Type type);
std::string UnderscoresToCamelCase(const std::string& input, bool cap_next_letter);
std::string UnderscoresToPascalCase(const std::string& input);
// TODO(jtattermusch): perhaps we could move this to strutil
std::string StringToBase64(const std::string& input);
std::string FileDescriptorToBase64(const FileDescriptor* descriptor);
FieldGeneratorBase* CreateFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
bool HasRequiredFields(const Descriptor* descriptor);
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_HELPERS_H__

@ -0,0 +1,900 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <algorithm>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/wire_format_lite.h>
#include <google/protobuf/compiler/csharp/csharp_enum.h>
#include <google/protobuf/compiler/csharp/csharp_extension.h>
#include <google/protobuf/compiler/csharp/csharp_message.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
using google::protobuf::internal::scoped_ptr;
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
bool CompareFieldNumbers(const FieldDescriptor* d1, const FieldDescriptor* d2) {
return d1->number() < d2->number();
}
MessageGenerator::MessageGenerator(const Descriptor* descriptor)
: SourceGeneratorBase(descriptor->file()),
descriptor_(descriptor) {
// sorted field names
for (int i = 0; i < descriptor_->field_count(); i++) {
field_names_.push_back(descriptor_->field(i)->name());
}
std::sort(field_names_.begin(), field_names_.end());
// fields by number
for (int i = 0; i < descriptor_->field_count(); i++) {
fields_by_number_.push_back(descriptor_->field(i));
}
std::sort(fields_by_number_.begin(), fields_by_number_.end(),
CompareFieldNumbers);
}
MessageGenerator::~MessageGenerator() {
}
std::string MessageGenerator::class_name() {
// TODO: check correctness.
return descriptor_->name();
}
std::string MessageGenerator::full_class_name() {
return GetClassName(descriptor_);
}
const std::vector<std::string>& MessageGenerator::field_names() {
return field_names_;
}
const std::vector<const FieldDescriptor*>& MessageGenerator::fields_by_number() {
return fields_by_number_;
}
/// Get an identifier that uniquely identifies this type within the file.
/// This is used to declare static variables related to this type at the
/// outermost file scope.
std::string GetUniqueFileScopeIdentifier(const Descriptor* descriptor) {
std::string result = descriptor->full_name();
std::replace(result.begin(), result.end(), '.', '_');
return "static_" + result;
}
void MessageGenerator::GenerateStaticVariables(Writer* writer) {
// Because descriptor.proto (Google.ProtocolBuffers.DescriptorProtos) is
// used in the construction of descriptors, we have a tricky bootstrapping
// problem. To help control static initialization order, we make sure all
// descriptors and other static data that depends on them are members of
// the proto-descriptor class. This way, they will be initialized in
// a deterministic order.
std::string identifier = GetUniqueFileScopeIdentifier(descriptor_);
if (!use_lite_runtime()) {
// The descriptor for this type.
std::string access =
descriptor_->file()->options().csharp_nest_classes() ?
"private" : "internal";
writer->WriteLine(
"$0$ static pbd::MessageDescriptor internal__$1$__Descriptor;", access,
identifier);
writer->WriteLine(
"$0$ static pb::FieldAccess.FieldAccessorTable<$1$, $1$.Builder> internal__$2$__FieldAccessorTable;",
access, full_class_name(), identifier);
}
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
MessageGenerator messageGenerator(descriptor_->nested_type(i));
messageGenerator.GenerateStaticVariables(writer);
}
}
void MessageGenerator::GenerateStaticVariableInitializers(Writer* writer) {
std::string identifier = GetUniqueFileScopeIdentifier(descriptor_);
if (!use_lite_runtime()) {
writer->Write("internal__$0$__Descriptor = ", identifier);
if (!descriptor_->containing_type()) {
writer->WriteLine("Descriptor.MessageTypes[$0$];",
SimpleItoa(descriptor_->index()));
} else {
writer->WriteLine(
"internal__$0$__Descriptor.NestedTypes[$1$];",
GetUniqueFileScopeIdentifier(descriptor_->containing_type()),
SimpleItoa(descriptor_->index()));
}
writer->WriteLine("internal__$0$__FieldAccessorTable = ", identifier);
writer->WriteLine(
" new pb::FieldAccess.FieldAccessorTable<$1$, $1$.Builder>(internal__$0$__Descriptor,",
identifier, full_class_name());
writer->Write(" new string[] { ");
for (int i = 0; i < descriptor_->field_count(); i++) {
writer->Write("\"$0$\", ", GetPropertyName(descriptor_->field(i)));
}
writer->WriteLine("});");
}
// Generate static member initializers for all nested types.
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
MessageGenerator messageGenerator(descriptor_->nested_type(i));
messageGenerator.GenerateStaticVariableInitializers(writer);
}
for (int i = 0; i < descriptor_->extension_count(); i++) {
ExtensionGenerator extensionGenerator(descriptor_->extension(i));
extensionGenerator.GenerateStaticVariableInitializers(writer);
}
}
void MessageGenerator::Generate(Writer* writer) {
if (descriptor_->file()->options().csharp_add_serializable()) {
writer->WriteLine("[global::System.SerializableAttribute()]");
}
writer->WriteLine(
"[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]");
WriteGeneratedCodeAttributes(writer);
writer->WriteLine(
"$0$ sealed partial class $1$ : pb::$2$Message$3$<$1$, $1$.Builder> {",
class_access_level(), class_name(),
descriptor_->extension_range_count() > 0 ? "Extendable" : "Generated",
runtime_suffix());
writer->Indent();
if (descriptor_->file()->options().csharp_generate_private_ctor()) {
writer->WriteLine("private $0$() { }", class_name());
}
// Must call MakeReadOnly() to make sure all lists are made read-only
writer->WriteLine(
"private static readonly $0$ defaultInstance = new $0$().MakeReadOnly();",
class_name());
if (optimize_speed()) {
writer->WriteLine(
"private static readonly string[] _$0$FieldNames = new string[] { $2$$1$$2$ };",
UnderscoresToCamelCase(class_name(), false),
JoinStrings(field_names(), "\", \""),
field_names().size() > 0 ? "\"" : "");
std::vector<std::string> tags;
for (int i = 0; i < field_names().size(); i++) {
uint32 tag = internal::WireFormat::MakeTag(
descriptor_->FindFieldByName(field_names()[i]));
tags.push_back(SimpleItoa(tag));
}
writer->WriteLine(
"private static readonly uint[] _$0$FieldTags = new uint[] { $1$ };",
UnderscoresToCamelCase(class_name(), false), JoinStrings(tags, ", "));
}
writer->WriteLine("public static $0$ DefaultInstance {", class_name());
writer->WriteLine(" get { return defaultInstance; }");
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine("public override $0$ DefaultInstanceForType {",
class_name());
writer->WriteLine(" get { return DefaultInstance; }");
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine("protected override $0$ ThisMessage {", class_name());
writer->WriteLine(" get { return this; }");
writer->WriteLine("}");
writer->WriteLine();
if (!use_lite_runtime()) {
writer->WriteLine("public static pbd::MessageDescriptor Descriptor {");
writer->WriteLine(" get { return $0$.internal__$1$__Descriptor; }",
GetFullUmbrellaClassName(descriptor_->file()),
GetUniqueFileScopeIdentifier(descriptor_));
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine(
"protected override pb::FieldAccess.FieldAccessorTable<$0$, $0$.Builder> InternalFieldAccessors {",
class_name());
writer->WriteLine(" get { return $0$.internal__$1$__FieldAccessorTable; }",
GetFullUmbrellaClassName(descriptor_->file()),
GetUniqueFileScopeIdentifier(descriptor_));
writer->WriteLine("}");
writer->WriteLine();
}
// Extensions don't need to go in an extra nested type
for (int i = 0; i < descriptor_->extension_count(); i++) {
ExtensionGenerator extensionGenerator(descriptor_->extension(i));
extensionGenerator.Generate(writer);
}
if (descriptor_->enum_type_count() + descriptor_->nested_type_count() > 0) {
writer->WriteLine("#region Nested types");
writer->WriteLine(
"[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]");
WriteGeneratedCodeAttributes(writer);
writer->WriteLine("public static partial class Types {");
writer->Indent();
for (int i = 0; i < descriptor_->enum_type_count(); i++) {
EnumGenerator enumGenerator(descriptor_->enum_type(i));
enumGenerator.Generate(writer);
}
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
MessageGenerator messageGenerator(descriptor_->nested_type(i));
messageGenerator.Generate(writer);
}
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine("#endregion");
writer->WriteLine();
}
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
// TODO(jtattermusch): same code for cls compliance is in csharp_extension
if (descriptor_->file()->options().csharp_cls_compliance()
&& GetFieldConstantName(fieldDescriptor)[0] == '_') {
writer->WriteLine("[global::System.CLSCompliant(false)]");
}
// Rats: we lose the debug comment here :(
writer->WriteLine("public const int $0$ = $1$;",
GetFieldConstantName(fieldDescriptor),
SimpleItoa(fieldDescriptor->number()));
scoped_ptr<FieldGeneratorBase> generator(
CreateFieldGeneratorInternal(fieldDescriptor));
generator->GenerateMembers(writer);
writer->WriteLine();
}
if (optimize_speed()) {
GenerateIsInitialized(writer);
GenerateMessageSerializationMethods(writer);
}
if (use_lite_runtime()) {
GenerateLiteRuntimeMethods(writer);
}
GenerateParseFromMethods(writer);
GenerateBuilder(writer);
// Force the static initialization code for the file to run, since it may
// initialize static variables declared in this class.
writer->WriteLine("static $0$() {", class_name());
// We call object.ReferenceEquals() just to make it a valid statement on its own.
// Another option would be GetType(), but that causes problems in DescriptorProtoFile,
// where the bootstrapping is somewhat recursive - type initializers call
// each other, effectively. We temporarily see Descriptor as null.
writer->WriteLine(" object.ReferenceEquals($0$.Descriptor, null);",
GetFullUmbrellaClassName(descriptor_->file()));
writer->WriteLine("}");
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine();
}
void MessageGenerator::GenerateLiteRuntimeMethods(Writer* writer) {
bool callbase = descriptor_->extension_range_count() > 0;
writer->WriteLine("#region Lite runtime methods");
writer->WriteLine("public override int GetHashCode() {");
writer->Indent();
writer->WriteLine("int hash = GetType().GetHashCode();");
for (int i = 0; i < descriptor_->field_count(); i++) {
scoped_ptr<FieldGeneratorBase> generator(
CreateFieldGeneratorInternal(descriptor_->field(i)));
generator->WriteHash(writer);
}
if (callbase) {
writer->WriteLine("hash ^= base.GetHashCode();");
}
writer->WriteLine("return hash;");
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine("public override bool Equals(object obj) {");
writer->Indent();
writer->WriteLine("$0$ other = obj as $0$;", class_name());
writer->WriteLine("if (other == null) return false;");
for (int i = 0; i < descriptor_->field_count(); i++) {
scoped_ptr<FieldGeneratorBase> generator(
CreateFieldGeneratorInternal(descriptor_->field(i)));
generator->WriteEquals(writer);
}
if (callbase) {
writer->WriteLine("if (!base.Equals(other)) return false;");
}
writer->WriteLine("return true;");
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine(
"public override void PrintTo(global::System.IO.TextWriter writer) {");
writer->Indent();
for (int i = 0; i < fields_by_number().size(); i++) {
scoped_ptr<FieldGeneratorBase> generator(
CreateFieldGeneratorInternal(fields_by_number()[i]));
generator->WriteToString(writer);
}
if (callbase) {
writer->WriteLine("base.PrintTo(writer);");
}
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine("#endregion");
writer->WriteLine();
}
bool CompareExtensionRangesStart(const Descriptor::ExtensionRange* r1,
const Descriptor::ExtensionRange* r2) {
return r1->start < r2->start;
}
void MessageGenerator::GenerateMessageSerializationMethods(Writer* writer) {
std::vector<const Descriptor::ExtensionRange*> extension_ranges_sorted;
for (int i = 0; i < descriptor_->extension_range_count(); i++) {
extension_ranges_sorted.push_back(descriptor_->extension_range(i));
}
std::sort(extension_ranges_sorted.begin(), extension_ranges_sorted.end(),
CompareExtensionRangesStart);
writer->WriteLine(
"public override void WriteTo(pb::ICodedOutputStream output) {");
writer->Indent();
// Make sure we've computed the serialized length, so that packed fields are generated correctly.
writer->WriteLine("int size = SerializedSize;");
writer->WriteLine("string[] field_names = _$0$FieldNames;",
UnderscoresToCamelCase(class_name(), false));
if (descriptor_->extension_range_count()) {
writer->WriteLine(
"pb::ExtendableMessage$1$<$0$, $0$.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);",
class_name(), runtime_suffix());
}
// Merge the fields and the extension ranges, both sorted by field number.
for (int i = 0, j = 0;
i < fields_by_number().size() || j < extension_ranges_sorted.size();) {
if (i == fields_by_number().size()) {
GenerateSerializeOneExtensionRange(writer, extension_ranges_sorted[j++]);
} else if (j == extension_ranges_sorted.size()) {
GenerateSerializeOneField(writer, fields_by_number()[i++]);
} else if (fields_by_number()[i]->number()
< extension_ranges_sorted[j]->start) {
GenerateSerializeOneField(writer, fields_by_number()[i++]);
} else {
GenerateSerializeOneExtensionRange(writer, extension_ranges_sorted[j++]);
}
}
if (!use_lite_runtime()) {
if (descriptor_->options().message_set_wire_format())
{
writer->WriteLine("UnknownFields.WriteAsMessageSetTo(output);");
} else {
writer->WriteLine("UnknownFields.WriteTo(output);");
}
}
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine("private int memoizedSerializedSize = -1;");
writer->WriteLine("public override int SerializedSize {");
writer->Indent();
writer->WriteLine("get {");
writer->Indent();
writer->WriteLine("int size = memoizedSerializedSize;");
writer->WriteLine("if (size != -1) return size;");
writer->WriteLine();
writer->WriteLine("size = 0;");
for (int i = 0; i < descriptor_->field_count(); i++) {
scoped_ptr<FieldGeneratorBase> generator(
CreateFieldGeneratorInternal(descriptor_->field(i)));
generator->GenerateSerializedSizeCode(writer);
}
if (descriptor_->extension_range_count() > 0) {
writer->WriteLine("size += ExtensionsSerializedSize;");
}
if (!use_lite_runtime()) {
if (descriptor_->options().message_set_wire_format()) {
writer->WriteLine("size += UnknownFields.SerializedSizeAsMessageSet;");
} else {
writer->WriteLine("size += UnknownFields.SerializedSize;");
}
}
writer->WriteLine("memoizedSerializedSize = size;");
writer->WriteLine("return size;");
writer->Outdent();
writer->WriteLine("}");
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine();
}
void MessageGenerator::GenerateSerializeOneField(
Writer* writer, const FieldDescriptor* fieldDescriptor) {
scoped_ptr<FieldGeneratorBase> generator(
CreateFieldGeneratorInternal(fieldDescriptor));
generator->GenerateSerializationCode(writer);
}
void MessageGenerator::GenerateSerializeOneExtensionRange(
Writer* writer, const Descriptor::ExtensionRange* extensionRange) {
writer->WriteLine("extensionWriter.WriteUntil($0$, output);",
SimpleItoa(extensionRange->end));
}
void MessageGenerator::GenerateParseFromMethods(Writer* writer) {
// Note: These are separate from GenerateMessageSerializationMethods()
// because they need to be generated even for messages that are optimized
// for code size.
writer->WriteLine("public static $0$ ParseFrom(pb::ByteString data) {",
class_name());
writer->WriteLine(
" return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();");
writer->WriteLine("}");
writer->WriteLine(
"public static $0$ ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {",
class_name());
writer->WriteLine(
" return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();");
writer->WriteLine("}");
writer->WriteLine("public static $0$ ParseFrom(byte[] data) {", class_name());
writer->WriteLine(
" return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();");
writer->WriteLine("}");
writer->WriteLine(
"public static $0$ ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {",
class_name());
writer->WriteLine(
" return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();");
writer->WriteLine("}");
writer->WriteLine(
"public static $0$ ParseFrom(global::System.IO.Stream input) {",
class_name());
writer->WriteLine(
" return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();");
writer->WriteLine("}");
writer->WriteLine(
"public static $0$ ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {",
class_name());
writer->WriteLine(
" return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();");
writer->WriteLine("}");
writer->WriteLine(
"public static $0$ ParseDelimitedFrom(global::System.IO.Stream input) {",
class_name());
writer->WriteLine(
" return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();");
writer->WriteLine("}");
writer->WriteLine(
"public static $0$ ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {",
class_name());
writer->WriteLine(
" return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();");
writer->WriteLine("}");
writer->WriteLine(
"public static $0$ ParseFrom(pb::ICodedInputStream input) {",
class_name());
writer->WriteLine(
" return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();");
writer->WriteLine("}");
writer->WriteLine(
"public static $0$ ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {",
class_name());
writer->WriteLine(
" return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();");
writer->WriteLine("}");
}
void MessageGenerator::GenerateBuilder(Writer* writer) {
writer->WriteLine("private $0$ MakeReadOnly() {", class_name());
writer->Indent();
for (int i = 0; i < descriptor_->field_count(); i++) {
scoped_ptr<FieldGeneratorBase> generator(
CreateFieldGeneratorInternal(descriptor_->field(i)));
generator->GenerateBuildingCode(writer);
}
writer->WriteLine("return this;");
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine(
"public static Builder CreateBuilder() { return new Builder(); }");
writer->WriteLine(
"public override Builder ToBuilder() { return CreateBuilder(this); }");
writer->WriteLine(
"public override Builder CreateBuilderForType() { return new Builder(); }");
writer->WriteLine("public static Builder CreateBuilder($0$ prototype) {",
class_name());
writer->WriteLine(" return new Builder(prototype);");
writer->WriteLine("}");
writer->WriteLine();
if (descriptor_->file()->options().csharp_add_serializable()) {
writer->WriteLine("[global::System.SerializableAttribute()]");
}
writer->WriteLine(
"[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]");
WriteGeneratedCodeAttributes(writer);
writer->WriteLine(
"$0$ sealed partial class Builder : pb::$2$Builder$3$<$1$, Builder> {",
class_access_level(), class_name(),
descriptor_->extension_range_count() > 0 ? "Extendable" : "Generated",
runtime_suffix());
writer->Indent();
writer->WriteLine("protected override Builder ThisBuilder {");
writer->WriteLine(" get { return this; }");
writer->WriteLine("}");
GenerateCommonBuilderMethods(writer);
if (optimize_speed()) {
GenerateBuilderParsingMethods(writer);
}
for (int i = 0; i < descriptor_->field_count(); i++) {
scoped_ptr<FieldGeneratorBase> generator(
CreateFieldGeneratorInternal(descriptor_->field(i)));
writer->WriteLine();
// No field comment :(
generator->GenerateBuilderMembers(writer);
}
writer->Outdent();
writer->WriteLine("}");
}
void MessageGenerator::GenerateCommonBuilderMethods(Writer* writer) {
//default constructor
writer->WriteLine("public Builder() {");
//Durring static initialization of message, DefaultInstance is expected to return null.
writer->WriteLine(" result = DefaultInstance;");
writer->WriteLine(" resultIsReadOnly = true;");
writer->WriteLine("}");
//clone constructor
writer->WriteLine("internal Builder($0$ cloneFrom) {", class_name());
writer->WriteLine(" result = cloneFrom;");
writer->WriteLine(" resultIsReadOnly = true;");
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine("private bool resultIsReadOnly;");
writer->WriteLine("private $0$ result;", class_name());
writer->WriteLine();
writer->WriteLine("private $0$ PrepareBuilder() {", class_name());
writer->WriteLine(" if (resultIsReadOnly) {");
writer->WriteLine(" $0$ original = result;", class_name());
writer->WriteLine(" result = new $0$();", class_name());
writer->WriteLine(" resultIsReadOnly = false;");
writer->WriteLine(" MergeFrom(original);");
writer->WriteLine(" }");
writer->WriteLine(" return result;");
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine("public override bool IsInitialized {");
writer->WriteLine(" get { return result.IsInitialized; }");
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine("protected override $0$ MessageBeingBuilt {", class_name());
writer->WriteLine(" get { return PrepareBuilder(); }");
writer->WriteLine("}");
writer->WriteLine();
//Not actually expecting that DefaultInstance would ever be null here; however, we will ensure it does not break
writer->WriteLine("public override Builder Clear() {");
writer->WriteLine(" result = DefaultInstance;");
writer->WriteLine(" resultIsReadOnly = true;");
writer->WriteLine(" return this;");
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine("public override Builder Clone() {");
writer->WriteLine(" if (resultIsReadOnly) {");
writer->WriteLine(" return new Builder(result);");
writer->WriteLine(" } else {");
writer->WriteLine(" return new Builder().MergeFrom(result);");
writer->WriteLine(" }");
writer->WriteLine("}");
writer->WriteLine();
if (!use_lite_runtime()) {
writer->WriteLine(
"public override pbd::MessageDescriptor DescriptorForType {");
writer->WriteLine(" get { return $0$.Descriptor; }", full_class_name());
writer->WriteLine("}");
writer->WriteLine();
}
writer->WriteLine("public override $0$ DefaultInstanceForType {",
class_name());
writer->WriteLine(" get { return $0$.DefaultInstance; }", full_class_name());
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine("public override $0$ BuildPartial() {", class_name());
writer->Indent();
writer->WriteLine("if (resultIsReadOnly) {");
writer->WriteLine(" return result;");
writer->WriteLine("}");
writer->WriteLine("resultIsReadOnly = true;");
writer->WriteLine("return result.MakeReadOnly();");
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine();
if (optimize_speed()) {
writer->WriteLine(
"public override Builder MergeFrom(pb::IMessage$0$ other) {",
runtime_suffix());
writer->WriteLine(" if (other is $0$) {", class_name());
writer->WriteLine(" return MergeFrom(($0$) other);", class_name());
writer->WriteLine(" } else {");
writer->WriteLine(" base.MergeFrom(other);");
writer->WriteLine(" return this;");
writer->WriteLine(" }");
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine("public override Builder MergeFrom($0$ other) {",
class_name());
// Optimization: If other is the default instance, we know none of its
// fields are set so we can skip the merge.
writer->Indent();
writer->WriteLine("if (other == $0$.DefaultInstance) return this;",
full_class_name());
writer->WriteLine("PrepareBuilder();");
for (int i = 0; i < descriptor_->field_count(); i++) {
scoped_ptr<FieldGeneratorBase> generator(
CreateFieldGeneratorInternal(descriptor_->field(i)));
generator->GenerateMergingCode(writer);
}
// if message type has extensions
if (descriptor_->extension_range_count() > 0) {
writer->WriteLine(" this.MergeExtensionFields(other);");
}
if (!use_lite_runtime()) {
writer->WriteLine("this.MergeUnknownFields(other.UnknownFields);");
}
writer->WriteLine("return this;");
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine();
}
}
void MessageGenerator::GenerateBuilderParsingMethods(Writer* writer) {
writer->WriteLine(
"public override Builder MergeFrom(pb::ICodedInputStream input) {");
writer->WriteLine(" return MergeFrom(input, pb::ExtensionRegistry.Empty);");
writer->WriteLine("}");
writer->WriteLine();
writer->WriteLine(
"public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {");
writer->Indent();
writer->WriteLine("PrepareBuilder();");
if (!use_lite_runtime()) {
writer->WriteLine("pb::UnknownFieldSet.Builder unknownFields = null;");
}
writer->WriteLine("uint tag;");
writer->WriteLine("string field_name;");
writer->WriteLine("while (input.ReadTag(out tag, out field_name)) {");
writer->Indent();
writer->WriteLine("if(tag == 0 && field_name != null) {");
writer->Indent();
//if you change from StringComparer.Ordinal, the array sort in FieldNames { get; } must also change
writer->WriteLine(
"int field_ordinal = global::System.Array.BinarySearch(_$0$FieldNames, field_name, global::System.StringComparer.Ordinal);",
UnderscoresToCamelCase(class_name(), false));
writer->WriteLine("if(field_ordinal >= 0)");
writer->WriteLine(" tag = _$0$FieldTags[field_ordinal];",
UnderscoresToCamelCase(class_name(), false));
writer->WriteLine("else {");
if (!use_lite_runtime()) {
writer->WriteLine(" if (unknownFields == null) {"); // First unknown field - create builder now
writer->WriteLine(
" unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
writer->WriteLine(" }");
}
writer->WriteLine(
" ParseUnknownField(input, $0$extensionRegistry, tag, field_name);",
use_lite_runtime() ? "" : "unknownFields, ");
writer->WriteLine(" continue;");
writer->WriteLine("}");
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine("switch (tag) {");
writer->Indent();
writer->WriteLine("case 0: {"); // 0 signals EOF / limit reached
writer->WriteLine(" throw pb::InvalidProtocolBufferException.InvalidTag();");
writer->WriteLine("}");
writer->WriteLine("default: {");
writer->WriteLine(" if (pb::WireFormat.IsEndGroupTag(tag)) {");
if (!use_lite_runtime()) {
writer->WriteLine(" if (unknownFields != null) {");
writer->WriteLine(" this.UnknownFields = unknownFields.Build();");
writer->WriteLine(" }");
}
writer->WriteLine(" return this;"); // it's an endgroup tag
writer->WriteLine(" }");
if (!use_lite_runtime()) {
writer->WriteLine(" if (unknownFields == null) {"); // First unknown field - create builder now
writer->WriteLine(
" unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
writer->WriteLine(" }");
}
writer->WriteLine(
" ParseUnknownField(input, $0$extensionRegistry, tag, field_name);",
use_lite_runtime() ? "" : "unknownFields, ");
writer->WriteLine(" break;");
writer->WriteLine("}");
for (int i = 0; i < fields_by_number().size(); i++) {
const FieldDescriptor* field = fields_by_number()[i];
internal::WireFormatLite::WireType wt =
internal::WireFormat::WireTypeForFieldType(field->type());
uint32 tag = internal::WireFormatLite::MakeTag(field->number(), wt);
if (field->is_repeated()
&& (wt == internal::WireFormatLite::WIRETYPE_VARINT
|| wt == internal::WireFormatLite::WIRETYPE_FIXED32
|| wt == internal::WireFormatLite::WIRETYPE_FIXED64)) {
writer->WriteLine(
"case $0$:",
SimpleItoa(
internal::WireFormatLite::MakeTag(
field->number(),
internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED)));
}
writer->WriteLine("case $0$: {", SimpleItoa(tag));
writer->Indent();
scoped_ptr<FieldGeneratorBase> generator(
CreateFieldGeneratorInternal(field));
generator->GenerateParsingCode(writer);
writer->WriteLine("break;");
writer->Outdent();
writer->WriteLine("}");
}
writer->Outdent();
writer->WriteLine("}");
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine();
if (!use_lite_runtime()) {
writer->WriteLine("if (unknownFields != null) {");
writer->WriteLine(" this.UnknownFields = unknownFields.Build();");
writer->WriteLine("}");
}
writer->WriteLine("return this;");
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine();
}
void MessageGenerator::GenerateIsInitialized(Writer* writer) {
writer->WriteLine("public override bool IsInitialized {");
writer->Indent();
writer->WriteLine("get {");
writer->Indent();
// Check that all required fields in this message are set.
// TODO(kenton): We can optimize this when we switch to putting all the
// "has" fields into a single bitfield.
for (int i = 0; i < descriptor_->field_count(); i++) {
if (descriptor_->field(i)->is_required()) {
writer->WriteLine("if (!has$0$) return false;",
GetPropertyName(descriptor_->field(i)));
}
}
// Now check that all embedded messages are initialized.
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor* field = descriptor_->field(i);
if (field->type() != FieldDescriptor::TYPE_MESSAGE ||
!HasRequiredFields(field->message_type()))
{
continue;
}
// TODO(jtattermusch): shouldn't we use GetPropertyName here?
string propertyName = UnderscoresToPascalCase(GetFieldName(field));
if (field->is_repeated())
{
writer->WriteLine("foreach ($0$ element in $1$List) {",
GetClassName(field->message_type()),
propertyName);
writer->WriteLine(" if (!element.IsInitialized) return false;");
writer->WriteLine("}");
}
else if (field->is_optional())
{
writer->WriteLine("if (Has$0$) {", propertyName);
writer->WriteLine(" if (!$0$.IsInitialized) return false;", propertyName);
writer->WriteLine("}");
}
else
{
writer->WriteLine("if (!$0$.IsInitialized) return false;", propertyName);
}
}
if (descriptor_->extension_range_count() > 0) {
writer->WriteLine("if (!ExtensionsAreInitialized) return false;");
}
writer->WriteLine("return true;");
writer->Outdent();
writer->WriteLine("}");
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine();
}
void MessageGenerator::GenerateExtensionRegistrationCode(Writer* writer) {
for (int i = 0; i < descriptor_->extension_count(); i++) {
ExtensionGenerator extensionGenerator(descriptor_->extension(i));
extensionGenerator.GenerateExtensionRegistrationCode(writer);
}
for (int i = 0; i < descriptor_->nested_type_count(); i++) {
MessageGenerator messageGenerator(descriptor_->nested_type(i));
messageGenerator.GenerateExtensionRegistrationCode(writer);
}
}
int MessageGenerator::GetFieldOrdinal(const FieldDescriptor* descriptor) {
for (int i = 0; i < field_names().size(); i++) {
if (field_names()[i] == descriptor->name()) {
return i;
}
}
GOOGLE_LOG(DFATAL)<< "Could not find ordinal for field " << descriptor->name();
return -1;
}
FieldGeneratorBase* MessageGenerator::CreateFieldGeneratorInternal(
const FieldDescriptor* descriptor) {
return CreateFieldGenerator(descriptor, GetFieldOrdinal(descriptor));
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,98 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__
#include <string>
#include <vector>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class Writer;
class FieldGeneratorBase;
class MessageGenerator : public SourceGeneratorBase {
public:
MessageGenerator(const Descriptor* descriptor);
~MessageGenerator();
void GenerateStaticVariables(Writer* printer);
void GenerateStaticVariableInitializers(Writer* printer);
void GenerateExtensionRegistrationCode(Writer* printer);
void Generate(Writer* printer);
private:
const Descriptor* descriptor_;
std::vector<std::string> field_names_;
std::vector<const FieldDescriptor*> fields_by_number_;
void GenerateLiteRuntimeMethods(Writer* writer);
void GenerateMessageSerializationMethods(Writer* writer);
void GenerateSerializeOneField(Writer* writer,
const FieldDescriptor* fieldDescriptor);
void GenerateSerializeOneExtensionRange(
Writer* writer, const Descriptor::ExtensionRange* extendsionRange);
void GenerateParseFromMethods(Writer* writer);
void GenerateBuilder(Writer* writer);
void GenerateCommonBuilderMethods(Writer* writer);
void GenerateBuilderParsingMethods(Writer* writer);
void GenerateIsInitialized(Writer* writer);
int GetFieldOrdinal(const FieldDescriptor* descriptor);
FieldGeneratorBase* CreateFieldGeneratorInternal(
const FieldDescriptor* descriptor);
std::string class_name();
std::string full_class_name();
// field names sorted alphabetically
const std::vector<std::string>& field_names();
// field descriptors sorted by number
const std::vector<const FieldDescriptor*>& fields_by_number();
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageGenerator);
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_H__

@ -0,0 +1,183 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_message_field.h>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor,
int fieldOrdinal)
: FieldGeneratorBase(descriptor, fieldOrdinal) {
}
MessageFieldGenerator::~MessageFieldGenerator() {
}
void MessageFieldGenerator::GenerateMembers(Writer* writer) {
writer->WriteLine("private bool has$0$;", property_name());
writer->WriteLine("private $0$ $1$_;", type_name(), name());
AddDeprecatedFlag(writer);
writer->WriteLine("public bool Has$0$ {", property_name());
writer->WriteLine(" get { return has$0$; }", property_name());
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
writer->WriteLine(" get { return $0$_ ?? $1$; }", name(), default_value());
writer->WriteLine("}");
}
void MessageFieldGenerator::GenerateBuilderMembers(Writer* writer) {
AddDeprecatedFlag(writer);
writer->WriteLine("public bool Has$0$ {", property_name());
writer->WriteLine(" get { return result.has$0$; }", property_name());
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
writer->WriteLine(" get { return result.$0$; }", property_name());
writer->WriteLine(" set { Set$0$(value); }", property_name());
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Set$0$($1$ value) {", property_name(),
type_name());
AddNullCheck(writer);
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.has$0$ = true;", property_name());
writer->WriteLine(" result.$0$_ = value;", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Set$0$($1$.Builder builderForValue) {",
property_name(), type_name());
AddNullCheck(writer, "builderForValue");
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.has$0$ = true;", property_name());
writer->WriteLine(" result.$0$_ = builderForValue.Build();", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Merge$0$($1$ value) {", property_name(),
type_name());
AddNullCheck(writer);
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" if (result.has$0$ &&", property_name());
writer->WriteLine(" result.$0$_ != $1$) {", name(), default_value());
writer->WriteLine(
" result.$0$_ = $1$.CreateBuilder(result.$0$_).MergeFrom(value).BuildPartial();",
name(), type_name());
writer->WriteLine(" } else {");
writer->WriteLine(" result.$0$_ = value;", name());
writer->WriteLine(" }");
writer->WriteLine(" result.has$0$ = true;", property_name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Clear$0$() {", property_name());
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.has$0$ = false;", property_name());
writer->WriteLine(" result.$0$_ = null;", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
}
void MessageFieldGenerator::GenerateMergingCode(Writer* writer) {
writer->WriteLine("if (other.Has$0$) {", property_name());
writer->WriteLine(" Merge$0$(other.$0$);", property_name());
writer->WriteLine("}");
}
void MessageFieldGenerator::GenerateBuildingCode(Writer* writer) {
// Nothing to do for singular fields
}
void MessageFieldGenerator::GenerateParsingCode(Writer* writer) {
writer->WriteLine("$0$.Builder subBuilder = $0$.CreateBuilder();",
type_name());
writer->WriteLine("if (result.has$0$) {", property_name());
writer->WriteLine(" subBuilder.MergeFrom($0$);", property_name());
writer->WriteLine("}");
if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
writer->WriteLine("input.ReadGroup($0$, subBuilder, extensionRegistry);",
number());
} else {
writer->WriteLine("input.ReadMessage(subBuilder, extensionRegistry);");
}
writer->WriteLine("$0$ = subBuilder.BuildPartial();", property_name());
}
void MessageFieldGenerator::GenerateSerializationCode(Writer* writer) {
writer->WriteLine("if (has$0$) {", property_name());
writer->WriteLine(" output.Write$0$($1$, field_names[$3$], $2$);",
message_or_group(), number(), property_name(),
field_ordinal());
writer->WriteLine("}");
}
void MessageFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
writer->WriteLine("if (has$0$) {", property_name());
writer->WriteLine(" size += pb::CodedOutputStream.Compute$0$Size($1$, $2$);",
message_or_group(), number(), property_name());
writer->WriteLine("}");
}
void MessageFieldGenerator::WriteHash(Writer* writer) {
writer->WriteLine("if (has$0$) hash ^= $1$_.GetHashCode();", property_name(),
name());
}
void MessageFieldGenerator::WriteEquals(Writer* writer) {
writer->WriteLine(
"if (has$0$ != other.has$0$ || (has$0$ && !$1$_.Equals(other.$1$_))) return false;",
property_name(), name());
}
void MessageFieldGenerator::WriteToString(Writer* writer) {
writer->WriteLine("PrintField(\"$2$\", has$0$, $1$_, writer);",
property_name(), name(), GetFieldName(descriptor_));
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,73 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class Writer;
class MessageFieldGenerator : public FieldGeneratorBase {
public:
MessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
~MessageFieldGenerator();
virtual void GenerateMembers(Writer* writer);
virtual void GenerateBuilderMembers(Writer* writer);
virtual void GenerateMergingCode(Writer* writer);
virtual void GenerateBuildingCode(Writer* writer);
virtual void GenerateParsingCode(Writer* writer);
virtual void GenerateSerializationCode(Writer* writer);
virtual void GenerateSerializedSizeCode(Writer* writer);
virtual void WriteHash(Writer* writer);
virtual void WriteEquals(Writer* writer);
virtual void WriteToString(Writer* writer);
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MessageFieldGenerator);
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_MESSAGE_FIELD_H__

@ -0,0 +1,148 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_primitive_field.h>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
PrimitiveFieldGenerator::PrimitiveFieldGenerator(
const FieldDescriptor* descriptor, int fieldOrdinal)
: FieldGeneratorBase(descriptor, fieldOrdinal) {
}
PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {
}
void PrimitiveFieldGenerator::GenerateMembers(Writer* writer) {
writer->WriteLine("private bool has$0$;", property_name());
writer->WriteLine("private $0$ $1$_$2$;", type_name(), name(),
has_default_value() ? " = " + default_value() : "");
AddDeprecatedFlag(writer);
writer->WriteLine("public bool Has$0$ {", property_name());
writer->WriteLine(" get { return has$0$; }", property_name());
writer->WriteLine("}");
AddPublicMemberAttributes(writer);
writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
writer->WriteLine(" get { return $0$_; }", name());
writer->WriteLine("}");
}
void PrimitiveFieldGenerator::GenerateBuilderMembers(Writer* writer) {
AddDeprecatedFlag(writer);
writer->WriteLine("public bool Has$0$ {", property_name());
writer->WriteLine(" get { return result.has$0$; }", property_name());
writer->WriteLine("}");
AddPublicMemberAttributes(writer);
writer->WriteLine("public $0$ $1$ {", type_name(), property_name());
writer->WriteLine(" get { return result.$0$; }", property_name());
writer->WriteLine(" set { Set$0$(value); }", property_name());
writer->WriteLine("}");
AddPublicMemberAttributes(writer);
writer->WriteLine("public Builder Set$0$($1$ value) {", property_name(),
type_name());
AddNullCheck(writer);
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.has$0$ = true;", property_name());
writer->WriteLine(" result.$0$_ = value;", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Clear$0$() {", property_name());
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.has$0$ = false;", property_name());
writer->WriteLine(" result.$0$_ = $1$;", name(), default_value());
writer->WriteLine(" return this;");
writer->WriteLine("}");
}
void PrimitiveFieldGenerator::GenerateMergingCode(Writer* writer) {
writer->WriteLine("if (other.Has$0$) {", property_name());
writer->WriteLine(" $0$ = other.$0$;", property_name());
writer->WriteLine("}");
}
void PrimitiveFieldGenerator::GenerateBuildingCode(Writer* writer) {
// Nothing to do here for primitive types
}
void PrimitiveFieldGenerator::GenerateParsingCode(Writer* writer) {
writer->WriteLine("result.has$0$ = input.Read$1$(ref result.$2$_);",
property_name(), capitalized_type_name(), name());
}
void PrimitiveFieldGenerator::GenerateSerializationCode(Writer* writer) {
writer->WriteLine("if (has$0$) {", property_name());
writer->WriteLine(" output.Write$0$($1$, field_names[$3$], $2$);",
capitalized_type_name(), number(), property_name(),
field_ordinal());
writer->WriteLine("}");
}
void PrimitiveFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
writer->WriteLine("if (has$0$) {", property_name());
writer->WriteLine(" size += pb::CodedOutputStream.Compute$0$Size($1$, $2$);",
capitalized_type_name(), number(), property_name());
writer->WriteLine("}");
}
void PrimitiveFieldGenerator::WriteHash(Writer* writer) {
writer->WriteLine("if (has$0$) hash ^= $1$_.GetHashCode();", property_name(),
name());
}
void PrimitiveFieldGenerator::WriteEquals(Writer* writer) {
writer->WriteLine(
"if (has$0$ != other.has$0$ || (has$0$ && !$1$_.Equals(other.$1$_))) return false;",
property_name(), name());
}
void PrimitiveFieldGenerator::WriteToString(Writer* writer) {
writer->WriteLine("PrintField(\"$0$\", has$1$, $2$_, writer);",
descriptor_->name(), property_name(), name());
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,73 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class Writer;
class PrimitiveFieldGenerator : public FieldGeneratorBase {
public:
PrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
~PrimitiveFieldGenerator();
virtual void GenerateMembers(Writer* writer);
virtual void GenerateBuilderMembers(Writer* writer);
virtual void GenerateMergingCode(Writer* writer);
virtual void GenerateBuildingCode(Writer* writer);
virtual void GenerateParsingCode(Writer* writer);
virtual void GenerateSerializationCode(Writer* writer);
virtual void GenerateSerializedSizeCode(Writer* writer);
virtual void WriteHash(Writer* writer);
virtual void WriteEquals(Writer* writer);
virtual void WriteToString(Writer* writer);
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PrimitiveFieldGenerator);
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_PRIMITIVE_FIELD_H__

@ -0,0 +1,226 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator(
const FieldDescriptor* descriptor, int fieldOrdinal)
: FieldGeneratorBase(descriptor, fieldOrdinal) {
}
RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {
}
void RepeatedEnumFieldGenerator::GenerateMembers(Writer* writer) {
if (descriptor_->is_packed() && optimize_speed()) {
writer->WriteLine("private int $0$MemoizedSerializedSize;", name());
}
writer->WriteLine(
"private pbc::PopsicleList<$0$> $1$_ = new pbc::PopsicleList<$0$>();",
type_name(), name());
AddDeprecatedFlag(writer);
writer->WriteLine("public scg::IList<$0$> $1$List {", type_name(),
property_name());
writer->WriteLine(" get { return pbc::Lists.AsReadOnly($0$_); }", name());
writer->WriteLine("}");
// TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
AddDeprecatedFlag(writer);
writer->WriteLine("public int $0$Count {", property_name());
writer->WriteLine(" get { return $0$_.Count; }", name());
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public $0$ Get$1$(int index) {", type_name(),
property_name());
writer->WriteLine(" return $0$_[index];", name());
writer->WriteLine("}");
}
void RepeatedEnumFieldGenerator::GenerateBuilderMembers(Writer* writer) {
// Note: We can return the original list here, because we make it unmodifiable when we build
// We return it via IPopsicleList so that collection initializers work more pleasantly.
AddDeprecatedFlag(writer);
writer->WriteLine("public pbc::IPopsicleList<$0$> $1$List {", type_name(),
property_name());
writer->WriteLine(" get { return PrepareBuilder().$0$_; }", name());
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public int $0$Count {", property_name());
writer->WriteLine(" get { return result.$0$Count; }", property_name());
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public $0$ Get$1$(int index) {", type_name(),
property_name());
writer->WriteLine(" return result.Get$0$(index);", property_name());
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Set$0$(int index, $1$ value) {",
property_name(), type_name());
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_[index] = value;", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Add$0$($1$ value) {", property_name(),
type_name());
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_.Add(value);", name(), type_name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine(
"public Builder AddRange$0$(scg::IEnumerable<$1$> values) {",
property_name(), type_name());
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_.Add(values);", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Clear$0$() {", property_name());
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_.Clear();", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
}
void RepeatedEnumFieldGenerator::GenerateMergingCode(Writer* writer) {
writer->WriteLine("if (other.$0$_.Count != 0) {", name());
writer->WriteLine(" result.$0$_.Add(other.$0$_);", name());
writer->WriteLine("}");
}
void RepeatedEnumFieldGenerator::GenerateBuildingCode(Writer* writer) {
writer->WriteLine("$0$_.MakeReadOnly();", name());
}
void RepeatedEnumFieldGenerator::GenerateParsingCode(Writer* writer) {
writer->WriteLine("scg::ICollection<object> unknownItems;");
writer->WriteLine(
"input.ReadEnumArray<$0$>(tag, field_name, result.$1$_, out unknownItems);",
type_name(), name());
if (!use_lite_runtime()) {
writer->WriteLine("if (unknownItems != null) {");
writer->WriteLine(" if (unknownFields == null) {");
writer->WriteLine(
" unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");
writer->WriteLine(" }");
writer->WriteLine(" foreach (object rawValue in unknownItems)");
writer->WriteLine(" if (rawValue is int)");
writer->WriteLine(
" unknownFields.MergeVarintField($0$, (ulong)(int)rawValue);",
number());
writer->WriteLine("}");
}
}
void RepeatedEnumFieldGenerator::GenerateSerializationCode(Writer* writer) {
writer->WriteLine("if ($0$_.Count > 0) {", name());
writer->Indent();
if (descriptor_->is_packed()) {
writer->WriteLine(
"output.WritePackedEnumArray($0$, field_names[$2$], $1$MemoizedSerializedSize, $1$_);",
number(), name(), field_ordinal());
} else {
writer->WriteLine("output.WriteEnumArray($0$, field_names[$2$], $1$_);",
number(), name(), field_ordinal());
}
writer->Outdent();
writer->WriteLine("}");
}
void RepeatedEnumFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
writer->WriteLine("{");
writer->Indent();
writer->WriteLine("int dataSize = 0;");
writer->WriteLine("if ($0$_.Count > 0) {", name());
writer->Indent();
writer->WriteLine("foreach ($0$ element in $1$_) {", type_name(), name());
writer->WriteLine(
" dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);");
writer->WriteLine("}");
writer->WriteLine("size += dataSize;");
int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type());
if (descriptor_->is_packed()) {
writer->WriteLine("size += $0$;", SimpleItoa(tagSize));
writer->WriteLine(
"size += pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);");
} else {
writer->WriteLine("size += $0$ * $1$_.Count;", SimpleItoa(tagSize), name());
}
writer->Outdent();
writer->WriteLine("}");
// cache the data size for packed fields.
if (descriptor_->is_packed()) {
writer->WriteLine("$0$MemoizedSerializedSize = dataSize;", name());
}
writer->Outdent();
writer->WriteLine("}");
}
void RepeatedEnumFieldGenerator::WriteHash(Writer* writer) {
writer->WriteLine("foreach($0$ i in $1$_)", type_name(), name());
writer->WriteLine(" hash ^= i.GetHashCode();");
}
void RepeatedEnumFieldGenerator::WriteEquals(Writer* writer) {
writer->WriteLine("if($0$_.Count != other.$0$_.Count) return false;", name());
writer->WriteLine("for(int ix=0; ix < $0$_.Count; ix++)", name());
writer->WriteLine(" if(!$0$_[ix].Equals(other.$0$_[ix])) return false;",
name());
}
void RepeatedEnumFieldGenerator::WriteToString(Writer* writer) {
writer->WriteLine("PrintField(\"$0$\", $1$_, writer);", descriptor_->name(),
name());
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,73 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class Writer;
class RepeatedEnumFieldGenerator : public FieldGeneratorBase {
public:
RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
~RepeatedEnumFieldGenerator();
virtual void GenerateMembers(Writer* writer);
virtual void GenerateBuilderMembers(Writer* writer);
virtual void GenerateMergingCode(Writer* writer);
virtual void GenerateBuildingCode(Writer* writer);
virtual void GenerateParsingCode(Writer* writer);
virtual void GenerateSerializationCode(Writer* writer);
virtual void GenerateSerializedSizeCode(Writer* writer);
virtual void WriteHash(Writer* writer);
virtual void WriteEquals(Writer* writer);
virtual void WriteToString(Writer* writer);
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedEnumFieldGenerator);
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_ENUM_FIELD_H__

@ -0,0 +1,201 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator(
const FieldDescriptor* descriptor, int fieldOrdinal)
: FieldGeneratorBase(descriptor, fieldOrdinal) {
}
RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {
}
void RepeatedMessageFieldGenerator::GenerateMembers(Writer* writer) {
writer->WriteLine(
"private pbc::PopsicleList<$0$> $1$_ = new pbc::PopsicleList<$0$>();",
type_name(), name());
AddDeprecatedFlag(writer);
writer->WriteLine("public scg::IList<$0$> $1$List {", type_name(),
property_name());
writer->WriteLine(" get { return $0$_; }", name());
writer->WriteLine("}");
// TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
AddDeprecatedFlag(writer);
writer->WriteLine("public int $0$Count {", property_name());
writer->WriteLine(" get { return $0$_.Count; }", name());
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public $0$ Get$1$(int index) {", type_name(),
property_name());
writer->WriteLine(" return $0$_[index];", name());
writer->WriteLine("}");
}
void RepeatedMessageFieldGenerator::GenerateBuilderMembers(Writer* writer) {
// Note: We can return the original list here, because we make it unmodifiable when we build
// We return it via IPopsicleList so that collection initializers work more pleasantly.
AddDeprecatedFlag(writer);
writer->WriteLine("public pbc::IPopsicleList<$0$> $1$List {", type_name(),
property_name());
writer->WriteLine(" get { return PrepareBuilder().$0$_; }", name());
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public int $0$Count {", property_name());
writer->WriteLine(" get { return result.$0$Count; }", property_name());
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public $0$ Get$1$(int index) {", type_name(),
property_name());
writer->WriteLine(" return result.Get$0$(index);", property_name());
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Set$0$(int index, $1$ value) {",
property_name(), type_name());
AddNullCheck(writer);
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_[index] = value;", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
// Extra overload for builder (just on messages)
AddDeprecatedFlag(writer);
writer->WriteLine(
"public Builder Set$0$(int index, $1$.Builder builderForValue) {",
property_name(), type_name());
AddNullCheck(writer, "builderForValue");
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_[index] = builderForValue.Build();", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Add$0$($1$ value) {", property_name(),
type_name());
AddNullCheck(writer);
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_.Add(value);", name(), type_name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
// Extra overload for builder (just on messages)
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Add$0$($1$.Builder builderForValue) {",
property_name(), type_name());
AddNullCheck(writer, "builderForValue");
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_.Add(builderForValue.Build());", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine(
"public Builder AddRange$0$(scg::IEnumerable<$1$> values) {",
property_name(), type_name());
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_.Add(values);", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Clear$0$() {", property_name());
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_.Clear();", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
}
void RepeatedMessageFieldGenerator::GenerateMergingCode(Writer* writer) {
writer->WriteLine("if (other.$0$_.Count != 0) {", name());
writer->WriteLine(" result.$0$_.Add(other.$0$_);", name());
writer->WriteLine("}");
}
void RepeatedMessageFieldGenerator::GenerateBuildingCode(Writer* writer) {
writer->WriteLine("$0$_.MakeReadOnly();", name());
}
void RepeatedMessageFieldGenerator::GenerateParsingCode(Writer* writer) {
writer->WriteLine(
"input.Read$0$Array(tag, field_name, result.$1$_, $2$.DefaultInstance, extensionRegistry);",
message_or_group(), name(), type_name());
}
void RepeatedMessageFieldGenerator::GenerateSerializationCode(Writer* writer) {
writer->WriteLine("if ($0$_.Count > 0) {", name());
writer->Indent();
writer->WriteLine("output.Write$0$Array($1$, field_names[$3$], $2$_);",
message_or_group(), number(), name(), field_ordinal());
writer->Outdent();
writer->WriteLine("}");
}
void RepeatedMessageFieldGenerator::GenerateSerializedSizeCode(Writer* writer) {
writer->WriteLine("foreach ($0$ element in $1$List) {", type_name(),
property_name());
writer->WriteLine(
" size += pb::CodedOutputStream.Compute$0$Size($1$, element);",
message_or_group(), number());
writer->WriteLine("}");
}
void RepeatedMessageFieldGenerator::WriteHash(Writer* writer) {
writer->WriteLine("foreach($0$ i in $1$_)", type_name(), name());
writer->WriteLine(" hash ^= i.GetHashCode();");
}
void RepeatedMessageFieldGenerator::WriteEquals(Writer* writer) {
writer->WriteLine("if($0$_.Count != other.$0$_.Count) return false;", name());
writer->WriteLine("for(int ix=0; ix < $0$_.Count; ix++)", name());
writer->WriteLine(" if(!$0$_[ix].Equals(other.$0$_[ix])) return false;",
name());
}
void RepeatedMessageFieldGenerator::WriteToString(Writer* writer) {
writer->WriteLine("PrintField(\"$0$\", $1$_, writer);",
GetFieldName(descriptor_), name());
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,73 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class Writer;
class RepeatedMessageFieldGenerator : public FieldGeneratorBase {
public:
RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
~RepeatedMessageFieldGenerator();
virtual void GenerateMembers(Writer* writer);
virtual void GenerateBuilderMembers(Writer* writer);
virtual void GenerateMergingCode(Writer* writer);
virtual void GenerateBuildingCode(Writer* writer);
virtual void GenerateParsingCode(Writer* writer);
virtual void GenerateSerializationCode(Writer* writer);
virtual void GenerateSerializedSizeCode(Writer* writer);
virtual void WriteHash(Writer* writer);
virtual void WriteEquals(Writer* writer);
virtual void WriteToString(Writer* writer);
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedMessageFieldGenerator);
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_MESSAGE_FIELD_H__

@ -0,0 +1,219 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator(
const FieldDescriptor* descriptor, int fieldOrdinal)
: FieldGeneratorBase(descriptor, fieldOrdinal) {
}
RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {
}
void RepeatedPrimitiveFieldGenerator::GenerateMembers(Writer* writer) {
if (descriptor_->is_packed() && optimize_speed()) {
writer->WriteLine("private int $0$MemoizedSerializedSize;", name());
}
writer->WriteLine(
"private pbc::PopsicleList<$0$> $1$_ = new pbc::PopsicleList<$0$>();",
type_name(), name());
AddPublicMemberAttributes(writer);
writer->WriteLine("public scg::IList<$0$> $1$List {", type_name(),
property_name());
writer->WriteLine(" get { return pbc::Lists.AsReadOnly($0$_); }", name());
writer->WriteLine("}");
// TODO(jonskeet): Redundant API calls? Possibly - include for portability though. Maybe create an option.
AddDeprecatedFlag(writer);
writer->WriteLine("public int $0$Count {", property_name());
writer->WriteLine(" get { return $0$_.Count; }", name());
writer->WriteLine("}");
AddPublicMemberAttributes(writer);
writer->WriteLine("public $0$ Get$1$(int index) {", type_name(),
property_name());
writer->WriteLine(" return $0$_[index];", name());
writer->WriteLine("}");
}
void RepeatedPrimitiveFieldGenerator::GenerateBuilderMembers(Writer* writer) {
// Note: We can return the original list here, because we make it unmodifiable when we build
// We return it via IPopsicleList so that collection initializers work more pleasantly.
AddPublicMemberAttributes(writer);
writer->WriteLine("public pbc::IPopsicleList<$0$> $1$List {", type_name(),
property_name());
writer->WriteLine(" get { return PrepareBuilder().$0$_; }", name());
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public int $0$Count {", property_name());
writer->WriteLine(" get { return result.$0$Count; }", property_name());
writer->WriteLine("}");
AddPublicMemberAttributes(writer);
writer->WriteLine("public $0$ Get$1$(int index) {", type_name(),
property_name());
writer->WriteLine(" return result.Get$0$(index);", property_name());
writer->WriteLine("}");
AddPublicMemberAttributes(writer);
writer->WriteLine("public Builder Set$0$(int index, $1$ value) {",
property_name(), type_name());
AddNullCheck(writer);
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_[index] = value;", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddPublicMemberAttributes(writer);
writer->WriteLine("public Builder Add$0$($1$ value) {", property_name(),
type_name());
AddNullCheck(writer);
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_.Add(value);", name(), type_name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddPublicMemberAttributes(writer);
writer->WriteLine(
"public Builder AddRange$0$(scg::IEnumerable<$1$> values) {",
property_name(), type_name());
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_.Add(values);", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
AddDeprecatedFlag(writer);
writer->WriteLine("public Builder Clear$0$() {", property_name());
writer->WriteLine(" PrepareBuilder();");
writer->WriteLine(" result.$0$_.Clear();", name());
writer->WriteLine(" return this;");
writer->WriteLine("}");
}
void RepeatedPrimitiveFieldGenerator::GenerateMergingCode(Writer* writer) {
writer->WriteLine("if (other.$0$_.Count != 0) {", name());
writer->WriteLine(" result.$0$_.Add(other.$0$_);", name());
writer->WriteLine("}");
}
void RepeatedPrimitiveFieldGenerator::GenerateBuildingCode(Writer* writer) {
writer->WriteLine("$0$_.MakeReadOnly();", name());
}
void RepeatedPrimitiveFieldGenerator::GenerateParsingCode(Writer* writer) {
writer->WriteLine("input.Read$0$Array(tag, field_name, result.$1$_);",
capitalized_type_name(), name());
}
void RepeatedPrimitiveFieldGenerator::GenerateSerializationCode(
Writer* writer) {
writer->WriteLine("if ($0$_.Count > 0) {", name());
writer->Indent();
if (descriptor_->is_packed()) {
writer->WriteLine(
"output.WritePacked$0$Array($1$, field_names[$3$], $2$MemoizedSerializedSize, $2$_);",
capitalized_type_name(), number(), name(), field_ordinal());
} else {
writer->WriteLine("output.Write$0$Array($1$, field_names[$3$], $2$_);",
capitalized_type_name(), number(), name(),
field_ordinal());
}
writer->Outdent();
writer->WriteLine("}");
}
void RepeatedPrimitiveFieldGenerator::GenerateSerializedSizeCode(
Writer* writer) {
writer->WriteLine("{");
writer->Indent();
writer->WriteLine("int dataSize = 0;");
int fixedSize = GetFixedSize(descriptor_->type());
if (fixedSize == -1) {
writer->WriteLine("foreach ($0$ element in $1$List) {", type_name(),
property_name());
writer->WriteLine(
" dataSize += pb::CodedOutputStream.Compute$0$SizeNoTag(element);",
capitalized_type_name(), number());
writer->WriteLine("}");
} else {
writer->WriteLine("dataSize = $0$ * $1$_.Count;", SimpleItoa(fixedSize), name());
}
writer->WriteLine("size += dataSize;");
int tagSize = internal::WireFormat::TagSize(descriptor_->number(), descriptor_->type());
if (descriptor_->is_packed()) {
writer->WriteLine("if ($0$_.Count != 0) {", name());
writer->WriteLine(
" size += $0$ + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);",
SimpleItoa(tagSize));
writer->WriteLine("}");
} else {
writer->WriteLine("size += $0$ * $1$_.Count;", SimpleItoa(tagSize), name());
}
// cache the data size for packed fields.
if (descriptor_->is_packed()) {
writer->WriteLine("$0$MemoizedSerializedSize = dataSize;", name());
}
writer->Outdent();
writer->WriteLine("}");
}
void RepeatedPrimitiveFieldGenerator::WriteHash(Writer* writer) {
writer->WriteLine("foreach($0$ i in $1$_)", type_name(), name());
writer->WriteLine(" hash ^= i.GetHashCode();");
}
void RepeatedPrimitiveFieldGenerator::WriteEquals(Writer* writer) {
writer->WriteLine("if($0$_.Count != other.$0$_.Count) return false;", name());
writer->WriteLine("for(int ix=0; ix < $0$_.Count; ix++)", name());
writer->WriteLine(" if(!$0$_[ix].Equals(other.$0$_[ix])) return false;",
name());
}
void RepeatedPrimitiveFieldGenerator::WriteToString(Writer* writer) {
writer->WriteLine("PrintField(\"$0$\", $1$_, writer);", descriptor_->name(),
name());
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,73 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class Writer;
class RepeatedPrimitiveFieldGenerator : public FieldGeneratorBase {
public:
RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, int fieldOrdinal);
~RepeatedPrimitiveFieldGenerator();
virtual void GenerateMembers(Writer* writer);
virtual void GenerateBuilderMembers(Writer* writer);
virtual void GenerateMergingCode(Writer* writer);
virtual void GenerateBuildingCode(Writer* writer);
virtual void GenerateParsingCode(Writer* writer);
virtual void GenerateSerializationCode(Writer* writer);
virtual void GenerateSerializedSizeCode(Writer* writer);
virtual void WriteHash(Writer* writer);
virtual void WriteEquals(Writer* writer);
virtual void WriteToString(Writer* writer);
private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(RepeatedPrimitiveFieldGenerator);
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_REPEATED_PRIMITIVE_FIELD_H__

@ -0,0 +1,82 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
SourceGeneratorBase::SourceGeneratorBase(const FileDescriptor* descriptor)
: descriptor_(descriptor) {
optimizeSize_ = (descriptor->options().optimize_for()
== FileOptions::CODE_SIZE);
optimizeSpeed_ = (descriptor->options().optimize_for() == FileOptions::SPEED);
useLiteRuntime_ = (descriptor->options().optimize_for()
== FileOptions::LITE_RUNTIME);
optimizeSpeed_ |= useLiteRuntime_;
runtimeSuffix_ = useLiteRuntime_ ? "Lite" : "";
}
SourceGeneratorBase::~SourceGeneratorBase() {
}
void SourceGeneratorBase::WriteGeneratedCodeAttributes(Writer* writer) {
// TODO(jtattermusch):
//if (descriptor.File.CSharpOptions.GeneratedCodeAttributes)
// {
// writer.WriteLine("[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]");
// writer.WriteLine("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"{0}\", \"{1}\")]",
// GetType().Assembly.GetName().Name, GetType().Assembly.GetName().Version);
// }
}
std::string SourceGeneratorBase::class_access_level() {
// TODO(jtattermusch): implement this
return "public";
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,83 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_SOURCE_GENERATOR_BASE_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_SOURCE_GENERATOR_BASE_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class Writer;
class SourceGeneratorBase {
protected:
SourceGeneratorBase(const FileDescriptor* descriptor);
virtual ~SourceGeneratorBase();
std::string class_access_level();
bool optimize_size() {
return optimizeSize_;
}
bool optimize_speed() {
return optimizeSpeed_;
}
bool use_lite_runtime() {
return useLiteRuntime_;
}
std::string runtime_suffix() {
return runtimeSuffix_;
}
void WriteGeneratedCodeAttributes(Writer* writer);
private:
const FileDescriptor* descriptor_;
bool optimizeSize_;
bool optimizeSpeed_;
bool useLiteRuntime_;
std::string runtimeSuffix_;
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SourceGeneratorBase);
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_SOURCE_GENERATOR_BASE_H__

@ -0,0 +1,297 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <sstream>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/compiler/csharp/csharp_umbrella_class.h>
#include <google/protobuf/compiler/csharp/csharp_enum.h>
#include <google/protobuf/compiler/csharp/csharp_extension.h>
#include <google/protobuf/compiler/csharp/csharp_helpers.h>
#include <google/protobuf/compiler/csharp/csharp_message.h>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
UmbrellaClassGenerator::UmbrellaClassGenerator(const FileDescriptor* file)
: SourceGeneratorBase(file),
file_(file) {
namespace_ = GetFileNamespace(file);
umbrellaClassname_ = GetFileUmbrellaClassname(file);
umbrellaNamespace_ = GetFileUmbrellaNamespace(file);
}
UmbrellaClassGenerator::~UmbrellaClassGenerator() {
}
void UmbrellaClassGenerator::Generate(Writer* writer) {
WriteIntroduction(writer);
WriteExtensionRegistration(writer);
// write children: Extensions
if (file_->extension_count() > 0) {
writer->WriteLine("#region Extensions");
for (int i = 0; i < file_->extension_count(); i++) {
ExtensionGenerator extensionGenerator(file_->extension(i));
extensionGenerator.Generate(writer);
}
writer->WriteLine("#endregion");
writer->WriteLine();
}
writer->WriteLine("#region Static variables");
for (int i = 0; i < file_->message_type_count(); i++) {
MessageGenerator messageGenerator(file_->message_type(i));
messageGenerator.GenerateStaticVariables(writer);
}
writer->WriteLine("#endregion");
if (!use_lite_runtime()) {
WriteDescriptor(writer);
} else {
WriteLiteExtensions(writer);
}
// The class declaration either gets closed before or after the children are written.
if (!file_->options().csharp_nest_classes()) {
writer->Outdent();
writer->WriteLine("}");
// Close the namespace around the umbrella class if defined
if (!file_->options().csharp_nest_classes()
&& !umbrellaNamespace_.empty()) {
writer->Outdent();
writer->WriteLine("}");
}
}
// write children: Enums
if (file_->enum_type_count() > 0) {
writer->WriteLine("#region Enums");
for (int i = 0; i < file_->enum_type_count(); i++) {
EnumGenerator enumGenerator(file_->enum_type(i));
enumGenerator.Generate(writer);
}
writer->WriteLine("#endregion");
writer->WriteLine();
}
// write children: Messages
if (file_->message_type_count() > 0) {
writer->WriteLine("#region Messages");
for (int i = 0; i < file_->message_type_count(); i++) {
MessageGenerator messageGenerator(file_->message_type(i));
messageGenerator.Generate(writer);
}
writer->WriteLine("#endregion");
writer->WriteLine();
}
// TODO(jtattermusch): add support for generating services.
//WriteChildren(writer, "Services", Descriptor.Services);
if (file_->options().csharp_nest_classes()) {
writer->Outdent();
writer->WriteLine("}");
}
if (!namespace_.empty()) {
writer->Outdent();
writer->WriteLine("}");
}
writer->WriteLine();
writer->WriteLine("#endregion Designer generated code");
}
void UmbrellaClassGenerator::WriteIntroduction(Writer* writer) {
writer->WriteLine(
"// Generated by the protocol buffer compiler. DO NOT EDIT!");
writer->WriteLine("// source: $0$", file_->name());
writer->WriteLine("#pragma warning disable 1591, 0612, 3021");
writer->WriteLine("#region Designer generated code");
writer->WriteLine();
writer->WriteLine("using pb = global::Google.ProtocolBuffers;");
writer->WriteLine("using pbc = global::Google.ProtocolBuffers.Collections;");
writer->WriteLine("using pbd = global::Google.ProtocolBuffers.Descriptors;");
writer->WriteLine("using scg = global::System.Collections.Generic;");
if (!namespace_.empty()) {
writer->WriteLine("namespace $0$ {", namespace_);
writer->Indent();
writer->WriteLine();
}
// Add the namespace around the umbrella class if defined
if (!file_->options().csharp_nest_classes() && !umbrellaNamespace_.empty()) {
writer->WriteLine("namespace $0$ {", umbrellaNamespace_);
writer->Indent();
writer->WriteLine();
}
if (file_->options().csharp_code_contracts()) {
writer->WriteLine(
"[global::System.Diagnostics.Contracts.ContractVerificationAttribute(false)]");
}
writer->WriteLine(
"[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]");
WriteGeneratedCodeAttributes(writer);
writer->WriteLine("$0$ static partial class $1$ {", class_access_level(),
umbrellaClassname_);
writer->WriteLine();
writer->Indent();
}
void UmbrellaClassGenerator::WriteExtensionRegistration(Writer* writer) {
writer->WriteLine("#region Extension registration");
writer->WriteLine(
"public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {");
writer->Indent();
for (int i = 0; i < file_->extension_count(); i++) {
ExtensionGenerator extensionGenerator(file_->extension(i));
extensionGenerator.GenerateExtensionRegistrationCode(writer);
}
for (int i = 0; i < file_->message_type_count(); i++) {
MessageGenerator messageGenerator(file_->message_type(i));
messageGenerator.GenerateExtensionRegistrationCode(writer);
}
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine("#endregion");
}
void UmbrellaClassGenerator::WriteDescriptor(Writer* writer) {
writer->WriteLine("#region Descriptor");
writer->WriteLine("public static pbd::FileDescriptor Descriptor {");
writer->WriteLine(" get { return descriptor; }");
writer->WriteLine("}");
writer->WriteLine("private static pbd::FileDescriptor descriptor;");
writer->WriteLine();
writer->WriteLine("static $0$() {", umbrellaClassname_);
writer->Indent();
writer->WriteLine(
"byte[] descriptorData = global::System.Convert.FromBase64String(");
writer->Indent();
writer->Indent();
writer->WriteLine("string.Concat(");
writer->Indent();
// TODO(jonskeet): Consider a C#-escaping format here instead of just Base64.
std::string base64 = FileDescriptorToBase64(file_);
while (base64.size() > 60) {
writer->WriteLine("\"$0$\", ", base64.substr(0, 60));
base64 = base64.substr(60);
}
writer->Outdent();
writer->WriteLine("\"$0$\"));", base64);
writer->Outdent();
writer->Outdent();
writer->WriteLine(
"pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {");
writer->Indent();
writer->WriteLine("descriptor = root;");
for (int i = 0; i < file_->message_type_count(); i++) {
MessageGenerator messageGenerator(file_->message_type(i));
messageGenerator.GenerateStaticVariableInitializers(writer);
}
for (int i = 0; i < file_->extension_count(); i++) {
ExtensionGenerator extensionGenerator(file_->extension(i));
extensionGenerator.GenerateStaticVariableInitializers(writer);
}
if (uses_extensions()) {
// Must construct an ExtensionRegistry containing all possible extensions
// and return it.
writer->WriteLine(
"pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();");
writer->WriteLine("RegisterAllExtensions(registry);");
for (int i = 0; i < file_->dependency_count(); i++) {
writer->WriteLine("$0$.RegisterAllExtensions(registry);",
GetFullUmbrellaClassName(file_->dependency(i)));
}
writer->WriteLine("return registry;");
} else {
writer->WriteLine("return null;");
}
writer->Outdent();
writer->WriteLine("};");
// -----------------------------------------------------------------
// Invoke internalBuildGeneratedFileFrom() to build the file.
writer->WriteLine(
"pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,");
writer->WriteLine(" new pbd::FileDescriptor[] {");
for (int i = 0; i < file_->dependency_count(); i++) {
writer->WriteLine(" $0$.Descriptor, ",
GetFullUmbrellaClassName(file_->dependency(i)));
}
writer->WriteLine(" }, assigner);");
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine("#endregion");
writer->WriteLine();
}
void UmbrellaClassGenerator::WriteLiteExtensions(Writer* writer) {
writer->WriteLine("#region Extensions");
writer->WriteLine("internal static readonly object Descriptor;");
writer->WriteLine("static $0$() {", umbrellaClassname_);
writer->Indent();
writer->WriteLine("Descriptor = null;");
for (int i = 0; i < file_->message_type_count(); i++) {
MessageGenerator messageGenerator(file_->message_type(i));
messageGenerator.GenerateStaticVariableInitializers(writer);
}
for (int i = 0; i < file_->extension_count(); i++) {
ExtensionGenerator extensionGenerator(file_->extension(i));
extensionGenerator.GenerateStaticVariableInitializers(writer);
}
writer->Outdent();
writer->WriteLine("}");
writer->WriteLine("#endregion");
writer->WriteLine();
}
bool UmbrellaClassGenerator::uses_extensions() {
// TODO(jtattermusch): implement recursive descent that looks for extensions.
// For now, we conservatively assume that extensions are used.
return true;
}
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,76 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_UMBRELLA_CLASS_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_UMBRELLA_CLASS_H__
#include <string>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/csharp/csharp_source_generator_base.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
class Writer;
class UmbrellaClassGenerator : public SourceGeneratorBase {
public:
UmbrellaClassGenerator(const FileDescriptor* file);
~UmbrellaClassGenerator();
void Generate(Writer* write);
private:
const FileDescriptor* file_;
std::string namespace_;
std::string umbrellaClassname_;
std::string umbrellaNamespace_;
void WriteIntroduction(Writer* writer);
void WriteExtensionRegistration(Writer* writer);
void WriteDescriptor(Writer* writer);
void WriteLiteExtensions(Writer* write);
bool uses_extensions();
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(UmbrellaClassGenerator);
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_UMBRELLA_CLASS_H__

@ -0,0 +1,136 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#include <algorithm>
#include <google/protobuf/stubs/hash.h>
#include <limits>
#include <vector>
#include <google/protobuf/compiler/csharp/csharp_writer.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/wire_format.h>
#include <google/protobuf/stubs/strutil.h>
#include <google/protobuf/stubs/substitute.h>
#include <google/protobuf/compiler/csharp/csharp_field_base.h>
#include <google/protobuf/compiler/csharp/csharp_enum_field.h>
#include <google/protobuf/compiler/csharp/csharp_message_field.h>
#include <google/protobuf/compiler/csharp/csharp_primitive_field.h>
#include <google/protobuf/compiler/csharp/csharp_repeated_enum_field.h>
#include <google/protobuf/compiler/csharp/csharp_repeated_message_field.h>
#include <google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
Writer::Writer(google::protobuf::io::Printer* printer)
: printer_(printer),
newline_("\n") {
// TODO(jtattermusch): make newline customizable.
}
Writer::~Writer() {
}
void Writer::Indent() {
printer_->Indent();
}
void Writer::Outdent() {
printer_->Outdent();
}
void Writer::Write(const char* text) {
printer_->Print(text);
}
void Writer::Write(const char* text, const string& value0) {
printer_->Print(text, "0", value0);
}
void Writer::Write(const char* text, const string& value0,
const string& value1) {
printer_->Print(text, "0", value0, "1", value1);
}
void Writer::Write(const char* text, const string& value0, const string& value1,
const string& value2) {
printer_->Print(text, "0", value0, "1", value1, "2", value2);
}
void Writer::Write(const char* text, const string& value0, const string& value1,
const string& value2, const string& value3) {
printer_->Print(text, "0", value0, "1", value1, "2", value2, "3", value3);
}
void Writer::WriteLine() {
printer_->Print(newline_);
}
void Writer::WriteLine(const char* text) {
Write(text);
WriteLine();
}
void Writer::WriteLine(const char* text, const string& value0) {
Write(text, value0);
WriteLine();
}
void Writer::WriteLine(const char* text, const string& value0,
const string& value1) {
Write(text, value0, value1);
WriteLine();
}
void Writer::WriteLine(const char* text, const string& value0,
const string& value1, const string& value2) {
Write(text, value0, value1, value2);
WriteLine();
}
void Writer::WriteLine(const char* text, const string& value0,
const string& value1, const string& value2,
const string& value3) {
Write(text, value0, value1, value2, value3);
WriteLine();
}
} // namespace java
} // namespace compiler
} // namespace protobuf
} // namespace google

@ -0,0 +1,93 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Author: kenton@google.com (Kenton Varda)
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
#ifndef GOOGLE_PROTOBUF_COMPILER_CSHARP_WRITER_H__
#define GOOGLE_PROTOBUF_COMPILER_CSHARP_WRITER_H__
#include <string>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/io/printer.h>
namespace google {
namespace protobuf {
namespace compiler {
namespace csharp {
// Simple wrapper around Printer that supports customizable line endings
// and number-based variables (e.g. $0$).
class Writer {
public:
Writer(io::Printer* printer);
~Writer();
void Indent();
void Outdent();
void Write(const char* text);
void Write(const char* text, const string& value0);
void Write(const char* text, const string& value0, const string& value1);
void Write(const char* text, const string& value0, const string& value1,
const string& value2);
void Write(const char* text, const string& value0, const string& value1,
const string& value2, const string& value3);
void WriteLine();
void WriteLine(const char* text);
void WriteLine(const char* text, const string& value0);
void WriteLine(const char* text, const string& value0, const string& value1);
void WriteLine(const char* text, const string& value0, const string& value1,
const string& value2);
void WriteLine(const char* text, const string& value0, const string& value1,
const string& value2, const string& value3);
private:
io::Printer* printer_;
const char* newline_;
};
} // namespace csharp
} // namespace compiler
} // namespace protobuf
} // namespace google
#endif // GOOGLE_PROTOBUF_COMPILER_CSHARP_WRITER_H__

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

File diff suppressed because it is too large Load Diff

@ -1837,6 +1837,117 @@ 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);
// optional string csharp_umbrella_classname = 38;
bool has_csharp_umbrella_classname() const;
void clear_csharp_umbrella_classname();
static const int kCsharpUmbrellaClassnameFieldNumber = 38;
const ::std::string& csharp_umbrella_classname() const;
void set_csharp_umbrella_classname(const ::std::string& value);
void set_csharp_umbrella_classname(const char* value);
void set_csharp_umbrella_classname(const char* value, size_t size);
::std::string* mutable_csharp_umbrella_classname();
::std::string* release_csharp_umbrella_classname();
void set_allocated_csharp_umbrella_classname(::std::string* csharp_umbrella_classname);
// optional bool csharp_public_classes = 39 [default = true];
bool has_csharp_public_classes() const;
void clear_csharp_public_classes();
static const int kCsharpPublicClassesFieldNumber = 39;
bool csharp_public_classes() const;
void set_csharp_public_classes(bool value);
// optional bool csharp_multiple_files = 40;
bool has_csharp_multiple_files() const;
void clear_csharp_multiple_files();
static const int kCsharpMultipleFilesFieldNumber = 40;
bool csharp_multiple_files() const;
void set_csharp_multiple_files(bool value);
// optional bool csharp_nest_classes = 41;
bool has_csharp_nest_classes() const;
void clear_csharp_nest_classes();
static const int kCsharpNestClassesFieldNumber = 41;
bool csharp_nest_classes() const;
void set_csharp_nest_classes(bool value);
// optional bool csharp_code_contracts = 42;
bool has_csharp_code_contracts() const;
void clear_csharp_code_contracts();
static const int kCsharpCodeContractsFieldNumber = 42;
bool csharp_code_contracts() const;
void set_csharp_code_contracts(bool value);
// optional bool csharp_expand_namespace_directories = 43;
bool has_csharp_expand_namespace_directories() const;
void clear_csharp_expand_namespace_directories();
static const int kCsharpExpandNamespaceDirectoriesFieldNumber = 43;
bool csharp_expand_namespace_directories() const;
void set_csharp_expand_namespace_directories(bool value);
// optional bool csharp_cls_compliance = 44 [default = true];
bool has_csharp_cls_compliance() const;
void clear_csharp_cls_compliance();
static const int kCsharpClsComplianceFieldNumber = 44;
bool csharp_cls_compliance() const;
void set_csharp_cls_compliance(bool value);
// optional bool csharp_add_serializable = 45 [default = false];
bool has_csharp_add_serializable() const;
void clear_csharp_add_serializable();
static const int kCsharpAddSerializableFieldNumber = 45;
bool csharp_add_serializable() const;
void set_csharp_add_serializable(bool value);
// optional bool csharp_generate_private_ctor = 46 [default = true];
bool has_csharp_generate_private_ctor() const;
void clear_csharp_generate_private_ctor();
static const int kCsharpGeneratePrivateCtorFieldNumber = 46;
bool csharp_generate_private_ctor() const;
void set_csharp_generate_private_ctor(bool value);
// optional string csharp_file_extension = 47 [default = ".cs"];
bool has_csharp_file_extension() const;
void clear_csharp_file_extension();
static const int kCsharpFileExtensionFieldNumber = 47;
const ::std::string& csharp_file_extension() const;
void set_csharp_file_extension(const ::std::string& value);
void set_csharp_file_extension(const char* value);
void set_csharp_file_extension(const char* value, size_t size);
::std::string* mutable_csharp_file_extension();
::std::string* release_csharp_file_extension();
void set_allocated_csharp_file_extension(::std::string* csharp_file_extension);
// optional string csharp_umbrella_namespace = 48;
bool has_csharp_umbrella_namespace() const;
void clear_csharp_umbrella_namespace();
static const int kCsharpUmbrellaNamespaceFieldNumber = 48;
const ::std::string& csharp_umbrella_namespace() const;
void set_csharp_umbrella_namespace(const ::std::string& value);
void set_csharp_umbrella_namespace(const char* value);
void set_csharp_umbrella_namespace(const char* value, size_t size);
::std::string* mutable_csharp_umbrella_namespace();
::std::string* release_csharp_umbrella_namespace();
void set_allocated_csharp_umbrella_namespace(::std::string* csharp_umbrella_namespace);
// optional bool csharp_generated_code_attributes = 49 [default = false];
bool has_csharp_generated_code_attributes() const;
void clear_csharp_generated_code_attributes();
static const int kCsharpGeneratedCodeAttributesFieldNumber = 49;
bool csharp_generated_code_attributes() const;
void set_csharp_generated_code_attributes(bool value);
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
int uninterpreted_option_size() const;
void clear_uninterpreted_option();
@ -1878,6 +1989,32 @@ 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();
inline void set_has_csharp_umbrella_classname();
inline void clear_has_csharp_umbrella_classname();
inline void set_has_csharp_public_classes();
inline void clear_has_csharp_public_classes();
inline void set_has_csharp_multiple_files();
inline void clear_has_csharp_multiple_files();
inline void set_has_csharp_nest_classes();
inline void clear_has_csharp_nest_classes();
inline void set_has_csharp_code_contracts();
inline void clear_has_csharp_code_contracts();
inline void set_has_csharp_expand_namespace_directories();
inline void clear_has_csharp_expand_namespace_directories();
inline void set_has_csharp_cls_compliance();
inline void clear_has_csharp_cls_compliance();
inline void set_has_csharp_add_serializable();
inline void clear_has_csharp_add_serializable();
inline void set_has_csharp_generate_private_ctor();
inline void clear_has_csharp_generate_private_ctor();
inline void set_has_csharp_file_extension();
inline void clear_has_csharp_file_extension();
inline void set_has_csharp_umbrella_namespace();
inline void clear_has_csharp_umbrella_namespace();
inline void set_has_csharp_generated_code_attributes();
inline void clear_has_csharp_generated_code_attributes();
::google::protobuf::internal::ExtensionSet _extensions_;
@ -1893,11 +2030,25 @@ 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::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
::google::protobuf::internal::ArenaStringPtr csharp_namespace_;
bool java_generic_services_;
bool py_generic_services_;
bool deprecated_;
bool cc_enable_arenas_;
bool csharp_public_classes_;
bool csharp_multiple_files_;
bool csharp_nest_classes_;
bool csharp_code_contracts_;
::google::protobuf::internal::ArenaStringPtr csharp_umbrella_classname_;
bool csharp_expand_namespace_directories_;
bool csharp_cls_compliance_;
bool csharp_add_serializable_;
bool csharp_generate_private_ctor_;
bool csharp_generated_code_attributes_;
static ::std::string* _default_csharp_file_extension_;
::google::protobuf::internal::ArenaStringPtr csharp_file_extension_;
::google::protobuf::internal::ArenaStringPtr csharp_umbrella_namespace_;
::google::protobuf::RepeatedPtrField< ::google::protobuf::UninterpretedOption > uninterpreted_option_;
friend void LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
friend void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto();
@ -5502,6 +5653,434 @@ 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)
}
// optional string csharp_umbrella_classname = 38;
inline bool FileOptions::has_csharp_umbrella_classname() const {
return (_has_bits_[0] & 0x00004000u) != 0;
}
inline void FileOptions::set_has_csharp_umbrella_classname() {
_has_bits_[0] |= 0x00004000u;
}
inline void FileOptions::clear_has_csharp_umbrella_classname() {
_has_bits_[0] &= ~0x00004000u;
}
inline void FileOptions::clear_csharp_umbrella_classname() {
csharp_umbrella_classname_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
clear_has_csharp_umbrella_classname();
}
inline const ::std::string& FileOptions::csharp_umbrella_classname() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_umbrella_classname)
return csharp_umbrella_classname_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FileOptions::set_csharp_umbrella_classname(const ::std::string& value) {
set_has_csharp_umbrella_classname();
csharp_umbrella_classname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_umbrella_classname)
}
inline void FileOptions::set_csharp_umbrella_classname(const char* value) {
set_has_csharp_umbrella_classname();
csharp_umbrella_classname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
// @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_umbrella_classname)
}
inline void FileOptions::set_csharp_umbrella_classname(const char* value, size_t size) {
set_has_csharp_umbrella_classname();
csharp_umbrella_classname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
::std::string(reinterpret_cast<const char*>(value), size));
// @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.csharp_umbrella_classname)
}
inline ::std::string* FileOptions::mutable_csharp_umbrella_classname() {
set_has_csharp_umbrella_classname();
// @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_umbrella_classname)
return csharp_umbrella_classname_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileOptions::release_csharp_umbrella_classname() {
clear_has_csharp_umbrella_classname();
return csharp_umbrella_classname_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FileOptions::set_allocated_csharp_umbrella_classname(::std::string* csharp_umbrella_classname) {
if (csharp_umbrella_classname != NULL) {
set_has_csharp_umbrella_classname();
} else {
clear_has_csharp_umbrella_classname();
}
csharp_umbrella_classname_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), csharp_umbrella_classname);
// @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_umbrella_classname)
}
// optional bool csharp_public_classes = 39 [default = true];
inline bool FileOptions::has_csharp_public_classes() const {
return (_has_bits_[0] & 0x00008000u) != 0;
}
inline void FileOptions::set_has_csharp_public_classes() {
_has_bits_[0] |= 0x00008000u;
}
inline void FileOptions::clear_has_csharp_public_classes() {
_has_bits_[0] &= ~0x00008000u;
}
inline void FileOptions::clear_csharp_public_classes() {
csharp_public_classes_ = true;
clear_has_csharp_public_classes();
}
inline bool FileOptions::csharp_public_classes() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_public_classes)
return csharp_public_classes_;
}
inline void FileOptions::set_csharp_public_classes(bool value) {
set_has_csharp_public_classes();
csharp_public_classes_ = value;
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_public_classes)
}
// optional bool csharp_multiple_files = 40;
inline bool FileOptions::has_csharp_multiple_files() const {
return (_has_bits_[0] & 0x00010000u) != 0;
}
inline void FileOptions::set_has_csharp_multiple_files() {
_has_bits_[0] |= 0x00010000u;
}
inline void FileOptions::clear_has_csharp_multiple_files() {
_has_bits_[0] &= ~0x00010000u;
}
inline void FileOptions::clear_csharp_multiple_files() {
csharp_multiple_files_ = false;
clear_has_csharp_multiple_files();
}
inline bool FileOptions::csharp_multiple_files() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_multiple_files)
return csharp_multiple_files_;
}
inline void FileOptions::set_csharp_multiple_files(bool value) {
set_has_csharp_multiple_files();
csharp_multiple_files_ = value;
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_multiple_files)
}
// optional bool csharp_nest_classes = 41;
inline bool FileOptions::has_csharp_nest_classes() const {
return (_has_bits_[0] & 0x00020000u) != 0;
}
inline void FileOptions::set_has_csharp_nest_classes() {
_has_bits_[0] |= 0x00020000u;
}
inline void FileOptions::clear_has_csharp_nest_classes() {
_has_bits_[0] &= ~0x00020000u;
}
inline void FileOptions::clear_csharp_nest_classes() {
csharp_nest_classes_ = false;
clear_has_csharp_nest_classes();
}
inline bool FileOptions::csharp_nest_classes() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_nest_classes)
return csharp_nest_classes_;
}
inline void FileOptions::set_csharp_nest_classes(bool value) {
set_has_csharp_nest_classes();
csharp_nest_classes_ = value;
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_nest_classes)
}
// optional bool csharp_code_contracts = 42;
inline bool FileOptions::has_csharp_code_contracts() const {
return (_has_bits_[0] & 0x00040000u) != 0;
}
inline void FileOptions::set_has_csharp_code_contracts() {
_has_bits_[0] |= 0x00040000u;
}
inline void FileOptions::clear_has_csharp_code_contracts() {
_has_bits_[0] &= ~0x00040000u;
}
inline void FileOptions::clear_csharp_code_contracts() {
csharp_code_contracts_ = false;
clear_has_csharp_code_contracts();
}
inline bool FileOptions::csharp_code_contracts() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_code_contracts)
return csharp_code_contracts_;
}
inline void FileOptions::set_csharp_code_contracts(bool value) {
set_has_csharp_code_contracts();
csharp_code_contracts_ = value;
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_code_contracts)
}
// optional bool csharp_expand_namespace_directories = 43;
inline bool FileOptions::has_csharp_expand_namespace_directories() const {
return (_has_bits_[0] & 0x00080000u) != 0;
}
inline void FileOptions::set_has_csharp_expand_namespace_directories() {
_has_bits_[0] |= 0x00080000u;
}
inline void FileOptions::clear_has_csharp_expand_namespace_directories() {
_has_bits_[0] &= ~0x00080000u;
}
inline void FileOptions::clear_csharp_expand_namespace_directories() {
csharp_expand_namespace_directories_ = false;
clear_has_csharp_expand_namespace_directories();
}
inline bool FileOptions::csharp_expand_namespace_directories() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_expand_namespace_directories)
return csharp_expand_namespace_directories_;
}
inline void FileOptions::set_csharp_expand_namespace_directories(bool value) {
set_has_csharp_expand_namespace_directories();
csharp_expand_namespace_directories_ = value;
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_expand_namespace_directories)
}
// optional bool csharp_cls_compliance = 44 [default = true];
inline bool FileOptions::has_csharp_cls_compliance() const {
return (_has_bits_[0] & 0x00100000u) != 0;
}
inline void FileOptions::set_has_csharp_cls_compliance() {
_has_bits_[0] |= 0x00100000u;
}
inline void FileOptions::clear_has_csharp_cls_compliance() {
_has_bits_[0] &= ~0x00100000u;
}
inline void FileOptions::clear_csharp_cls_compliance() {
csharp_cls_compliance_ = true;
clear_has_csharp_cls_compliance();
}
inline bool FileOptions::csharp_cls_compliance() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_cls_compliance)
return csharp_cls_compliance_;
}
inline void FileOptions::set_csharp_cls_compliance(bool value) {
set_has_csharp_cls_compliance();
csharp_cls_compliance_ = value;
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_cls_compliance)
}
// optional bool csharp_add_serializable = 45 [default = false];
inline bool FileOptions::has_csharp_add_serializable() const {
return (_has_bits_[0] & 0x00200000u) != 0;
}
inline void FileOptions::set_has_csharp_add_serializable() {
_has_bits_[0] |= 0x00200000u;
}
inline void FileOptions::clear_has_csharp_add_serializable() {
_has_bits_[0] &= ~0x00200000u;
}
inline void FileOptions::clear_csharp_add_serializable() {
csharp_add_serializable_ = false;
clear_has_csharp_add_serializable();
}
inline bool FileOptions::csharp_add_serializable() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_add_serializable)
return csharp_add_serializable_;
}
inline void FileOptions::set_csharp_add_serializable(bool value) {
set_has_csharp_add_serializable();
csharp_add_serializable_ = value;
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_add_serializable)
}
// optional bool csharp_generate_private_ctor = 46 [default = true];
inline bool FileOptions::has_csharp_generate_private_ctor() const {
return (_has_bits_[0] & 0x00400000u) != 0;
}
inline void FileOptions::set_has_csharp_generate_private_ctor() {
_has_bits_[0] |= 0x00400000u;
}
inline void FileOptions::clear_has_csharp_generate_private_ctor() {
_has_bits_[0] &= ~0x00400000u;
}
inline void FileOptions::clear_csharp_generate_private_ctor() {
csharp_generate_private_ctor_ = true;
clear_has_csharp_generate_private_ctor();
}
inline bool FileOptions::csharp_generate_private_ctor() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_generate_private_ctor)
return csharp_generate_private_ctor_;
}
inline void FileOptions::set_csharp_generate_private_ctor(bool value) {
set_has_csharp_generate_private_ctor();
csharp_generate_private_ctor_ = value;
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_generate_private_ctor)
}
// optional string csharp_file_extension = 47 [default = ".cs"];
inline bool FileOptions::has_csharp_file_extension() const {
return (_has_bits_[0] & 0x00800000u) != 0;
}
inline void FileOptions::set_has_csharp_file_extension() {
_has_bits_[0] |= 0x00800000u;
}
inline void FileOptions::clear_has_csharp_file_extension() {
_has_bits_[0] &= ~0x00800000u;
}
inline void FileOptions::clear_csharp_file_extension() {
csharp_file_extension_.ClearToDefaultNoArena(_default_csharp_file_extension_);
clear_has_csharp_file_extension();
}
inline const ::std::string& FileOptions::csharp_file_extension() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_file_extension)
return csharp_file_extension_.GetNoArena(_default_csharp_file_extension_);
}
inline void FileOptions::set_csharp_file_extension(const ::std::string& value) {
set_has_csharp_file_extension();
csharp_file_extension_.SetNoArena(_default_csharp_file_extension_, value);
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_file_extension)
}
inline void FileOptions::set_csharp_file_extension(const char* value) {
set_has_csharp_file_extension();
csharp_file_extension_.SetNoArena(_default_csharp_file_extension_, ::std::string(value));
// @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_file_extension)
}
inline void FileOptions::set_csharp_file_extension(const char* value, size_t size) {
set_has_csharp_file_extension();
csharp_file_extension_.SetNoArena(_default_csharp_file_extension_,
::std::string(reinterpret_cast<const char*>(value), size));
// @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.csharp_file_extension)
}
inline ::std::string* FileOptions::mutable_csharp_file_extension() {
set_has_csharp_file_extension();
// @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_file_extension)
return csharp_file_extension_.MutableNoArena(_default_csharp_file_extension_);
}
inline ::std::string* FileOptions::release_csharp_file_extension() {
clear_has_csharp_file_extension();
return csharp_file_extension_.ReleaseNoArena(_default_csharp_file_extension_);
}
inline void FileOptions::set_allocated_csharp_file_extension(::std::string* csharp_file_extension) {
if (csharp_file_extension != NULL) {
set_has_csharp_file_extension();
} else {
clear_has_csharp_file_extension();
}
csharp_file_extension_.SetAllocatedNoArena(_default_csharp_file_extension_, csharp_file_extension);
// @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_file_extension)
}
// optional string csharp_umbrella_namespace = 48;
inline bool FileOptions::has_csharp_umbrella_namespace() const {
return (_has_bits_[0] & 0x01000000u) != 0;
}
inline void FileOptions::set_has_csharp_umbrella_namespace() {
_has_bits_[0] |= 0x01000000u;
}
inline void FileOptions::clear_has_csharp_umbrella_namespace() {
_has_bits_[0] &= ~0x01000000u;
}
inline void FileOptions::clear_csharp_umbrella_namespace() {
csharp_umbrella_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
clear_has_csharp_umbrella_namespace();
}
inline const ::std::string& FileOptions::csharp_umbrella_namespace() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_umbrella_namespace)
return csharp_umbrella_namespace_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FileOptions::set_csharp_umbrella_namespace(const ::std::string& value) {
set_has_csharp_umbrella_namespace();
csharp_umbrella_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_umbrella_namespace)
}
inline void FileOptions::set_csharp_umbrella_namespace(const char* value) {
set_has_csharp_umbrella_namespace();
csharp_umbrella_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
// @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_umbrella_namespace)
}
inline void FileOptions::set_csharp_umbrella_namespace(const char* value, size_t size) {
set_has_csharp_umbrella_namespace();
csharp_umbrella_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
::std::string(reinterpret_cast<const char*>(value), size));
// @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.csharp_umbrella_namespace)
}
inline ::std::string* FileOptions::mutable_csharp_umbrella_namespace() {
set_has_csharp_umbrella_namespace();
// @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_umbrella_namespace)
return csharp_umbrella_namespace_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* FileOptions::release_csharp_umbrella_namespace() {
clear_has_csharp_umbrella_namespace();
return csharp_umbrella_namespace_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void FileOptions::set_allocated_csharp_umbrella_namespace(::std::string* csharp_umbrella_namespace) {
if (csharp_umbrella_namespace != NULL) {
set_has_csharp_umbrella_namespace();
} else {
clear_has_csharp_umbrella_namespace();
}
csharp_umbrella_namespace_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), csharp_umbrella_namespace);
// @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_umbrella_namespace)
}
// optional bool csharp_generated_code_attributes = 49 [default = false];
inline bool FileOptions::has_csharp_generated_code_attributes() const {
return (_has_bits_[0] & 0x02000000u) != 0;
}
inline void FileOptions::set_has_csharp_generated_code_attributes() {
_has_bits_[0] |= 0x02000000u;
}
inline void FileOptions::clear_has_csharp_generated_code_attributes() {
_has_bits_[0] &= ~0x02000000u;
}
inline void FileOptions::clear_csharp_generated_code_attributes() {
csharp_generated_code_attributes_ = false;
clear_has_csharp_generated_code_attributes();
}
inline bool FileOptions::csharp_generated_code_attributes() const {
// @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_generated_code_attributes)
return csharp_generated_code_attributes_;
}
inline void FileOptions::set_csharp_generated_code_attributes(bool value) {
set_has_csharp_generated_code_attributes();
csharp_generated_code_attributes_ = value;
// @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_generated_code_attributes)
}
// repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
inline int FileOptions::uninterpreted_option_size() const {
return uninterpreted_option_.size();

@ -351,6 +351,58 @@ 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;
// Name of the "umbrella" class used for metadata about all
// the messages within this file. Default is based on the name
// of the file.
optional string csharp_umbrella_classname = 38;
// Whether classes should be public (true) or internal (false)
optional bool csharp_public_classes = 39 [default = true];
// Whether to generate a single file for everything within the
// .proto file (false), or one file per message (true).
// This option is not currently honored; please log a feature
// request if you really want it.
optional bool csharp_multiple_files = 40;
// Whether to nest messages within a single umbrella class (true)
// or create the umbrella class as a peer, with messages as
// top-level classes in the namespace (false)
optional bool csharp_nest_classes = 41;
// Generate appropriate support for Code Contracts
// (Ongoing; support should improve over time)
optional bool csharp_code_contracts = 42;
// Create subdirectories for namespaces, e.g. namespace "Foo.Bar"
// would generate files within [output directory]/Foo/Bar
optional bool csharp_expand_namespace_directories = 43;
// Generate attributes indicating non-CLS-compliance
optional bool csharp_cls_compliance = 44 [default = true];
// Generate messages/builders with the [Serializable] attribute
optional bool csharp_add_serializable = 45 [default = false];
// Generates a private ctor for Message types
optional bool csharp_generate_private_ctor = 46 [default = true];
// The extension that should be appended to the umbrella_classname when creating files.
optional string csharp_file_extension = 47 [default = ".cs"];
// A nested namespace for the umbrella class. Helpful for name collisions caused by
// umbrella_classname conflicting with an existing type. This will be automatically
// set to 'Proto' if a collision is detected with types being generated. This value
// is ignored when nest_classes == true
optional string csharp_umbrella_namespace = 48;
// Used to add the System.Runtime.CompilerServices.CompilerGeneratedAttribute and
// System.CodeDom.Compiler.GeneratedCodeAttribute attributes to generated code.
optional bool csharp_generated_code_attributes = 49 [default = false];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;

Loading…
Cancel
Save