浏览代码

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

Jan Tattermusch 10 年之前
父节点
当前提交
685ae36ca2
共有 36 个文件被更改,包括 6640 次插入49 次删除
  1. 19 2
      src/Makefile.am
  2. 79 0
      src/google/protobuf/compiler/csharp/csharp_enum.cc
  3. 65 0
      src/google/protobuf/compiler/csharp/csharp_enum.h
  4. 160 0
      src/google/protobuf/compiler/csharp/csharp_enum_field.cc
  5. 73 0
      src/google/protobuf/compiler/csharp/csharp_enum_field.h
  6. 170 0
      src/google/protobuf/compiler/csharp/csharp_extension.cc
  7. 80 0
      src/google/protobuf/compiler/csharp/csharp_extension.h
  8. 394 0
      src/google/protobuf/compiler/csharp/csharp_field_base.cc
  9. 100 0
      src/google/protobuf/compiler/csharp/csharp_field_base.h
  10. 82 0
      src/google/protobuf/compiler/csharp/csharp_generator.cc
  11. 58 0
      src/google/protobuf/compiler/csharp/csharp_generator.h
  12. 54 0
      src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc
  13. 383 0
      src/google/protobuf/compiler/csharp/csharp_helpers.cc
  14. 108 0
      src/google/protobuf/compiler/csharp/csharp_helpers.h
  15. 900 0
      src/google/protobuf/compiler/csharp/csharp_message.cc
  16. 98 0
      src/google/protobuf/compiler/csharp/csharp_message.h
  17. 183 0
      src/google/protobuf/compiler/csharp/csharp_message_field.cc
  18. 73 0
      src/google/protobuf/compiler/csharp/csharp_message_field.h
  19. 148 0
      src/google/protobuf/compiler/csharp/csharp_primitive_field.cc
  20. 73 0
      src/google/protobuf/compiler/csharp/csharp_primitive_field.h
  21. 226 0
      src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc
  22. 73 0
      src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h
  23. 201 0
      src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc
  24. 73 0
      src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h
  25. 219 0
      src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc
  26. 73 0
      src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h
  27. 82 0
      src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc
  28. 83 0
      src/google/protobuf/compiler/csharp/csharp_source_generator_base.h
  29. 297 0
      src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc
  30. 76 0
      src/google/protobuf/compiler/csharp/csharp_umbrella_class.h
  31. 136 0
      src/google/protobuf/compiler/csharp/csharp_writer.cc
  32. 93 0
      src/google/protobuf/compiler/csharp/csharp_writer.h
  33. 6 0
      src/google/protobuf/compiler/main.cc
  34. 1070 46
      src/google/protobuf/descriptor.pb.cc
  35. 580 1
      src/google/protobuf/descriptor.pb.h
  36. 52 0
      src/google/protobuf/descriptor.proto

+ 19 - 2
src/Makefile.am

@@ -126,7 +126,8 @@ nobase_include_HEADERS =                                        \
   google/protobuf/compiler/java/java_names.h                    \
   google/protobuf/compiler/java/java_names.h                    \
   google/protobuf/compiler/javanano/javanano_generator.h        \
   google/protobuf/compiler/javanano/javanano_generator.h        \
   google/protobuf/compiler/python/python_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 =                                 \
 nobase_nodist_include_HEADERS =                                 \
   $(public_config)
   $(public_config)
@@ -288,7 +289,22 @@ libprotoc_la_SOURCES =                                         \
   google/protobuf/compiler/javanano/javanano_primitive_field.cc \
   google/protobuf/compiler/javanano/javanano_primitive_field.cc \
   google/protobuf/compiler/javanano/javanano_primitive_field.h \
   google/protobuf/compiler/javanano/javanano_primitive_field.h \
   google/protobuf/compiler/python/python_generator.cc          \
   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
 bin_PROGRAMS = protoc
 protoc_LDADD = $(PTHREAD_LIBS) libprotobuf.la libprotoc.la
 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/java/java_doc_comment_unittest.cc   \
   google/protobuf/compiler/python/python_plugin_unittest.cc    \
   google/protobuf/compiler/python/python_plugin_unittest.cc    \
   google/protobuf/compiler/ruby/ruby_generator_unittest.cc     \
   google/protobuf/compiler/ruby/ruby_generator_unittest.cc     \
+  google/protobuf/compiler/csharp/csharp_generator_unittest.cc \
   $(COMMON_TEST_SOURCES)
   $(COMMON_TEST_SOURCES)
 nodist_protobuf_test_SOURCES = $(protoc_outputs)
 nodist_protobuf_test_SOURCES = $(protoc_outputs)
 
 

+ 79 - 0
src/google/protobuf/compiler/csharp/csharp_enum.cc

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

+ 65 - 0
src/google/protobuf/compiler/csharp/csharp_enum.h

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

+ 160 - 0
src/google/protobuf/compiler/csharp/csharp_enum_field.cc

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

+ 73 - 0
src/google/protobuf/compiler/csharp/csharp_enum_field.h

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

+ 170 - 0
src/google/protobuf/compiler/csharp/csharp_extension.cc

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

+ 80 - 0
src/google/protobuf/compiler/csharp/csharp_extension.h

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

+ 394 - 0
src/google/protobuf/compiler/csharp/csharp_field_base.cc

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

+ 100 - 0
src/google/protobuf/compiler/csharp/csharp_field_base.h

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

+ 82 - 0
src/google/protobuf/compiler/csharp/csharp_generator.cc

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

+ 58 - 0
src/google/protobuf/compiler/csharp/csharp_generator.h

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

+ 54 - 0
src/google/protobuf/compiler/csharp/csharp_generator_unittest.cc

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

+ 383 - 0
src/google/protobuf/compiler/csharp/csharp_helpers.cc

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

+ 108 - 0
src/google/protobuf/compiler/csharp/csharp_helpers.h

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

+ 900 - 0
src/google/protobuf/compiler/csharp/csharp_message.cc

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

+ 98 - 0
src/google/protobuf/compiler/csharp/csharp_message.h

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

+ 183 - 0
src/google/protobuf/compiler/csharp/csharp_message_field.cc

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

+ 73 - 0
src/google/protobuf/compiler/csharp/csharp_message_field.h

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

+ 148 - 0
src/google/protobuf/compiler/csharp/csharp_primitive_field.cc

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

+ 73 - 0
src/google/protobuf/compiler/csharp/csharp_primitive_field.h

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

+ 226 - 0
src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc

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

+ 73 - 0
src/google/protobuf/compiler/csharp/csharp_repeated_enum_field.h

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

+ 201 - 0
src/google/protobuf/compiler/csharp/csharp_repeated_message_field.cc

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

+ 73 - 0
src/google/protobuf/compiler/csharp/csharp_repeated_message_field.h

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

+ 219 - 0
src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc

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

+ 73 - 0
src/google/protobuf/compiler/csharp/csharp_repeated_primitive_field.h

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

+ 82 - 0
src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc

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

+ 83 - 0
src/google/protobuf/compiler/csharp/csharp_source_generator_base.h

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

+ 297 - 0
src/google/protobuf/compiler/csharp/csharp_umbrella_class.cc

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

+ 76 - 0
src/google/protobuf/compiler/csharp/csharp_umbrella_class.h

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

+ 136 - 0
src/google/protobuf/compiler/csharp/csharp_writer.cc

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

+ 93 - 0
src/google/protobuf/compiler/csharp/csharp_writer.h

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

+ 6 - 0
src/google/protobuf/compiler/main.cc

@@ -36,6 +36,7 @@
 #include <google/protobuf/compiler/java/java_generator.h>
 #include <google/protobuf/compiler/java/java_generator.h>
 #include <google/protobuf/compiler/javanano/javanano_generator.h>
 #include <google/protobuf/compiler/javanano/javanano_generator.h>
 #include <google/protobuf/compiler/ruby/ruby_generator.h>
 #include <google/protobuf/compiler/ruby/ruby_generator.h>
+#include <google/protobuf/compiler/csharp/csharp_generator.h>
 
 
 int main(int argc, char* argv[]) {
 int main(int argc, char* argv[]) {
 
 
@@ -68,5 +69,10 @@ int main(int argc, char* argv[]) {
   cli.RegisterGenerator("--ruby_out", &rb_generator,
   cli.RegisterGenerator("--ruby_out", &rb_generator,
                         "Generate Ruby source file.");
                         "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);
   return cli.Run(argc, argv);
 }
 }

+ 1070 - 46
src/google/protobuf/descriptor.pb.cc

@@ -289,7 +289,7 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _internal_metadata_),
       GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _internal_metadata_),
       -1);
       -1);
   FileOptions_descriptor_ = file->message_type(9);
   FileOptions_descriptor_ = file->message_type(9);
-  static const int FileOptions_offsets_[14] = {
+  static const int FileOptions_offsets_[27] = {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_),
@@ -303,6 +303,19 @@ void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, deprecated_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, deprecated_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_enable_arenas_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_enable_arenas_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, objc_class_prefix_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, objc_class_prefix_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_namespace_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_umbrella_classname_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_public_classes_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_multiple_files_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_nest_classes_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_code_contracts_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_expand_namespace_directories_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_cls_compliance_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_add_serializable_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_generate_private_ctor_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_file_extension_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_umbrella_namespace_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, csharp_generated_code_attributes_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_),
     GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_),
   };
   };
   FileOptions_reflection_ =
   FileOptions_reflection_ =
@@ -574,6 +587,7 @@ void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() {
   delete MethodDescriptorProto_reflection_;
   delete MethodDescriptorProto_reflection_;
   delete FileOptions::default_instance_;
   delete FileOptions::default_instance_;
   delete FileOptions_reflection_;
   delete FileOptions_reflection_;
+  delete FileOptions::_default_csharp_file_extension_;
   delete MessageOptions::default_instance_;
   delete MessageOptions::default_instance_;
   delete MessageOptions_reflection_;
   delete MessageOptions_reflection_;
   delete FieldOptions::default_instance_;
   delete FieldOptions::default_instance_;
@@ -663,7 +677,7 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
     "t_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google.p"
     "t_type\030\003 \001(\t\022/\n\007options\030\004 \001(\0132\036.google.p"
     "rotobuf.MethodOptions\022\037\n\020client_streamin"
     "rotobuf.MethodOptions\022\037\n\020client_streamin"
     "g\030\005 \001(\010:\005false\022\037\n\020server_streaming\030\006 \001(\010"
     "g\030\005 \001(\010:\005false\022\037\n\020server_streaming\030\006 \001(\010"
-    ":\005false\"\347\004\n\013FileOptions\022\024\n\014java_package\030"
+    ":\005false\"\302\010\n\013FileOptions\022\024\n\014java_package\030"
     "\001 \001(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023j"
     "\001 \001(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023j"
     "ava_multiple_files\030\n \001(\010:\005false\022,\n\035java_"
     "ava_multiple_files\030\n \001(\010:\005false\022,\n\035java_"
     "generate_equals_and_hash\030\024 \001(\010:\005false\022%\n"
     "generate_equals_and_hash\030\024 \001(\010:\005false\022%\n"
@@ -675,50 +689,62 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
     "se\022\"\n\023py_generic_services\030\022 \001(\010:\005false\022\031"
     "se\022\"\n\023py_generic_services\030\022 \001(\010:\005false\022\031"
     "\n\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_enable_a"
     "\n\ndeprecated\030\027 \001(\010:\005false\022\037\n\020cc_enable_a"
     "renas\030\037 \001(\010:\005false\022\031\n\021objc_class_prefix\030"
     "renas\030\037 \001(\010:\005false\022\031\n\021objc_class_prefix\030"
-    "$ \001(\t\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g"
-    "oogle.protobuf.UninterpretedOption\":\n\014Op"
-    "timizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014"
-    "LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\346\001\n\016MessageOpt"
-    "ions\022&\n\027message_set_wire_format\030\001 \001(\010:\005f"
-    "alse\022.\n\037no_standard_descriptor_accessor\030"
-    "\002 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022"
-    "\021\n\tmap_entry\030\007 \001(\010\022C\n\024uninterpreted_opti"
-    "on\030\347\007 \003(\0132$.google.protobuf.Uninterprete"
-    "dOption*\t\010\350\007\020\200\200\200\200\002\"\240\002\n\014FieldOptions\022:\n\005c"
-    "type\030\001 \001(\0162#.google.protobuf.FieldOption"
-    "s.CType:\006STRING\022\016\n\006packed\030\002 \001(\010\022\023\n\004lazy\030"
-    "\005 \001(\010:\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022"
-    "\023\n\004weak\030\n \001(\010:\005false\022C\n\024uninterpreted_op"
-    "tion\030\347\007 \003(\0132$.google.protobuf.Uninterpre"
-    "tedOption\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001"
-    "\022\020\n\014STRING_PIECE\020\002*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013EnumOp"
-    "tions\022\023\n\013allow_alias\030\002 \001(\010\022\031\n\ndeprecated"
-    "\030\003 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007"
+    "$ \001(\t\022\030\n\020csharp_namespace\030% \001(\t\022!\n\031cshar"
+    "p_umbrella_classname\030& \001(\t\022#\n\025csharp_pub"
+    "lic_classes\030\' \001(\010:\004true\022\035\n\025csharp_multip"
+    "le_files\030( \001(\010\022\033\n\023csharp_nest_classes\030) "
+    "\001(\010\022\035\n\025csharp_code_contracts\030* \001(\010\022+\n#cs"
+    "harp_expand_namespace_directories\030+ \001(\010\022"
+    "#\n\025csharp_cls_compliance\030, \001(\010:\004true\022&\n\027"
+    "csharp_add_serializable\030- \001(\010:\005false\022*\n\034"
+    "csharp_generate_private_ctor\030. \001(\010:\004true"
+    "\022\"\n\025csharp_file_extension\030/ \001(\t:\003.cs\022!\n\031"
+    "csharp_umbrella_namespace\0300 \001(\t\022/\n cshar"
+    "p_generated_code_attributes\0301 \001(\010:\005false"
+    "\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.google"
+    ".protobuf.UninterpretedOption\":\n\014Optimiz"
+    "eMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_"
+    "RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\346\001\n\016MessageOptions\022"
+    "&\n\027message_set_wire_format\030\001 \001(\010:\005false\022"
+    ".\n\037no_standard_descriptor_accessor\030\002 \001(\010"
+    ":\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\021\n\tma"
+    "p_entry\030\007 \001(\010\022C\n\024uninterpreted_option\030\347\007"
     " \003(\0132$.google.protobuf.UninterpretedOpti"
     " \003(\0132$.google.protobuf.UninterpretedOpti"
-    "on*\t\010\350\007\020\200\200\200\200\002\"}\n\020EnumValueOptions\022\031\n\ndep"
-    "recated\030\001 \001(\010:\005false\022C\n\024uninterpreted_op"
+    "on*\t\010\350\007\020\200\200\200\200\002\"\240\002\n\014FieldOptions\022:\n\005ctype\030"
+    "\001 \001(\0162#.google.protobuf.FieldOptions.CTy"
+    "pe:\006STRING\022\016\n\006packed\030\002 \001(\010\022\023\n\004lazy\030\005 \001(\010"
+    ":\005false\022\031\n\ndeprecated\030\003 \001(\010:\005false\022\023\n\004we"
+    "ak\030\n \001(\010:\005false\022C\n\024uninterpreted_option\030"
+    "\347\007 \003(\0132$.google.protobuf.UninterpretedOp"
+    "tion\"/\n\005CType\022\n\n\006STRING\020\000\022\010\n\004CORD\020\001\022\020\n\014S"
+    "TRING_PIECE\020\002*\t\010\350\007\020\200\200\200\200\002\"\215\001\n\013EnumOptions"
+    "\022\023\n\013allow_alias\030\002 \001(\010\022\031\n\ndeprecated\030\003 \001("
+    "\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003(\0132"
+    "$.google.protobuf.UninterpretedOption*\t\010"
+    "\350\007\020\200\200\200\200\002\"}\n\020EnumValueOptions\022\031\n\ndeprecat"
+    "ed\030\001 \001(\010:\005false\022C\n\024uninterpreted_option\030"
+    "\347\007 \003(\0132$.google.protobuf.UninterpretedOp"
+    "tion*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031\n\ndep"
+    "recated\030! \001(\010:\005false\022C\n\024uninterpreted_op"
     "tion\030\347\007 \003(\0132$.google.protobuf.Uninterpre"
     "tion\030\347\007 \003(\0132$.google.protobuf.Uninterpre"
-    "tedOption*\t\010\350\007\020\200\200\200\200\002\"{\n\016ServiceOptions\022\031"
-    "\n\ndeprecated\030! \001(\010:\005false\022C\n\024uninterpret"
-    "ed_option\030\347\007 \003(\0132$.google.protobuf.Unint"
-    "erpretedOption*\t\010\350\007\020\200\200\200\200\002\"z\n\rMethodOptio"
-    "ns\022\031\n\ndeprecated\030! \001(\010:\005false\022C\n\024uninter"
-    "preted_option\030\347\007 \003(\0132$.google.protobuf.U"
-    "ninterpretedOption*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023Uninte"
-    "rpretedOption\022;\n\004name\030\002 \003(\0132-.google.pro"
-    "tobuf.UninterpretedOption.NamePart\022\030\n\020id"
-    "entifier_value\030\003 \001(\t\022\032\n\022positive_int_val"
-    "ue\030\004 \001(\004\022\032\n\022negative_int_value\030\005 \001(\003\022\024\n\014"
-    "double_value\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014"
-    "\022\027\n\017aggregate_value\030\010 \001(\t\0323\n\010NamePart\022\021\n"
-    "\tname_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010\"\325"
-    "\001\n\016SourceCodeInfo\022:\n\010location\030\001 \003(\0132(.go"
-    "ogle.protobuf.SourceCodeInfo.Location\032\206\001"
-    "\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003"
-    "(\005B\002\020\001\022\030\n\020leading_comments\030\003 \001(\t\022\031\n\021trai"
-    "ling_comments\030\004 \001(\t\022!\n\031leading_detached_"
-    "comments\030\006 \003(\tB)\n\023com.google.protobufB\020D"
-    "escriptorProtosH\001", 4617);
+    "tedOption*\t\010\350\007\020\200\200\200\200\002\"z\n\rMethodOptions\022\031\n"
+    "\ndeprecated\030! \001(\010:\005false\022C\n\024uninterprete"
+    "d_option\030\347\007 \003(\0132$.google.protobuf.Uninte"
+    "rpretedOption*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023Uninterpret"
+    "edOption\022;\n\004name\030\002 \003(\0132-.google.protobuf"
+    ".UninterpretedOption.NamePart\022\030\n\020identif"
+    "ier_value\030\003 \001(\t\022\032\n\022positive_int_value\030\004 "
+    "\001(\004\022\032\n\022negative_int_value\030\005 \001(\003\022\024\n\014doubl"
+    "e_value\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014\022\027\n\017a"
+    "ggregate_value\030\010 \001(\t\0323\n\010NamePart\022\021\n\tname"
+    "_part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010\"\325\001\n\016So"
+    "urceCodeInfo\022:\n\010location\030\001 \003(\0132(.google."
+    "protobuf.SourceCodeInfo.Location\032\206\001\n\010Loc"
+    "ation\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020"
+    "\001\022\030\n\020leading_comments\030\003 \001(\t\022\031\n\021trailing_"
+    "comments\030\004 \001(\t\022!\n\031leading_detached_comme"
+    "nts\030\006 \003(\tB)\n\023com.google.protobufB\020Descri"
+    "ptorProtosH\001", 5092);
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
   ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
     "google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
     "google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
   FileDescriptorSet::default_instance_ = new FileDescriptorSet();
   FileDescriptorSet::default_instance_ = new FileDescriptorSet();
@@ -731,6 +757,8 @@ void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
   EnumValueDescriptorProto::default_instance_ = new EnumValueDescriptorProto();
   EnumValueDescriptorProto::default_instance_ = new EnumValueDescriptorProto();
   ServiceDescriptorProto::default_instance_ = new ServiceDescriptorProto();
   ServiceDescriptorProto::default_instance_ = new ServiceDescriptorProto();
   MethodDescriptorProto::default_instance_ = new MethodDescriptorProto();
   MethodDescriptorProto::default_instance_ = new MethodDescriptorProto();
+  FileOptions::_default_csharp_file_extension_ =
+      new ::std::string(".cs", 3);
   FileOptions::default_instance_ = new FileOptions();
   FileOptions::default_instance_ = new FileOptions();
   MessageOptions::default_instance_ = new MessageOptions();
   MessageOptions::default_instance_ = new MessageOptions();
   FieldOptions::default_instance_ = new FieldOptions();
   FieldOptions::default_instance_ = new FieldOptions();
@@ -7002,6 +7030,7 @@ const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN;
 const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
 const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
 const int FileOptions::OptimizeMode_ARRAYSIZE;
 const int FileOptions::OptimizeMode_ARRAYSIZE;
 #endif  // _MSC_VER
 #endif  // _MSC_VER
+::std::string* FileOptions::_default_csharp_file_extension_ = NULL;
 #ifndef _MSC_VER
 #ifndef _MSC_VER
 const int FileOptions::kJavaPackageFieldNumber;
 const int FileOptions::kJavaPackageFieldNumber;
 const int FileOptions::kJavaOuterClassnameFieldNumber;
 const int FileOptions::kJavaOuterClassnameFieldNumber;
@@ -7016,6 +7045,19 @@ const int FileOptions::kPyGenericServicesFieldNumber;
 const int FileOptions::kDeprecatedFieldNumber;
 const int FileOptions::kDeprecatedFieldNumber;
 const int FileOptions::kCcEnableArenasFieldNumber;
 const int FileOptions::kCcEnableArenasFieldNumber;
 const int FileOptions::kObjcClassPrefixFieldNumber;
 const int FileOptions::kObjcClassPrefixFieldNumber;
+const int FileOptions::kCsharpNamespaceFieldNumber;
+const int FileOptions::kCsharpUmbrellaClassnameFieldNumber;
+const int FileOptions::kCsharpPublicClassesFieldNumber;
+const int FileOptions::kCsharpMultipleFilesFieldNumber;
+const int FileOptions::kCsharpNestClassesFieldNumber;
+const int FileOptions::kCsharpCodeContractsFieldNumber;
+const int FileOptions::kCsharpExpandNamespaceDirectoriesFieldNumber;
+const int FileOptions::kCsharpClsComplianceFieldNumber;
+const int FileOptions::kCsharpAddSerializableFieldNumber;
+const int FileOptions::kCsharpGeneratePrivateCtorFieldNumber;
+const int FileOptions::kCsharpFileExtensionFieldNumber;
+const int FileOptions::kCsharpUmbrellaNamespaceFieldNumber;
+const int FileOptions::kCsharpGeneratedCodeAttributesFieldNumber;
 const int FileOptions::kUninterpretedOptionFieldNumber;
 const int FileOptions::kUninterpretedOptionFieldNumber;
 #endif  // !_MSC_VER
 #endif  // !_MSC_VER
 
 
@@ -7052,6 +7094,19 @@ void FileOptions::SharedCtor() {
   deprecated_ = false;
   deprecated_ = false;
   cc_enable_arenas_ = false;
   cc_enable_arenas_ = false;
   objc_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   objc_class_prefix_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  csharp_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  csharp_umbrella_classname_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  csharp_public_classes_ = true;
+  csharp_multiple_files_ = false;
+  csharp_nest_classes_ = false;
+  csharp_code_contracts_ = false;
+  csharp_expand_namespace_directories_ = false;
+  csharp_cls_compliance_ = true;
+  csharp_add_serializable_ = false;
+  csharp_generate_private_ctor_ = true;
+  csharp_file_extension_.UnsafeSetDefault(_default_csharp_file_extension_);
+  csharp_umbrella_namespace_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  csharp_generated_code_attributes_ = false;
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
   ::memset(_has_bits_, 0, sizeof(_has_bits_));
 }
 }
 
 
@@ -7065,6 +7120,10 @@ void FileOptions::SharedDtor() {
   java_outer_classname_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   java_outer_classname_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   go_package_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   go_package_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   objc_class_prefix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   objc_class_prefix_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  csharp_namespace_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  csharp_umbrella_classname_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  csharp_file_extension_.DestroyNoArena(_default_csharp_file_extension_);
+  csharp_umbrella_namespace_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
   if (this != default_instance_) {
   if (this != default_instance_) {
   }
   }
 }
 }
@@ -7117,11 +7176,34 @@ void FileOptions::Clear() {
       go_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       go_package_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
     }
     }
   }
   }
-  if (_has_bits_[8 / 32] & 7936) {
+  if (_has_bits_[8 / 32] & 65280) {
     ZR_(java_generic_services_, cc_enable_arenas_);
     ZR_(java_generic_services_, cc_enable_arenas_);
     if (has_objc_class_prefix()) {
     if (has_objc_class_prefix()) {
       objc_class_prefix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
       objc_class_prefix_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
     }
     }
+    if (has_csharp_namespace()) {
+      csharp_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    }
+    if (has_csharp_umbrella_classname()) {
+      csharp_umbrella_classname_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    }
+    csharp_public_classes_ = true;
+  }
+  if (_has_bits_[16 / 32] & 16711680) {
+    ZR_(csharp_multiple_files_, csharp_code_contracts_);
+    csharp_expand_namespace_directories_ = false;
+    csharp_cls_compliance_ = true;
+    csharp_add_serializable_ = false;
+    csharp_generate_private_ctor_ = true;
+    if (has_csharp_file_extension()) {
+      csharp_file_extension_.ClearToDefaultNoArena(_default_csharp_file_extension_);
+    }
+  }
+  if (_has_bits_[24 / 32] & 50331648) {
+    if (has_csharp_umbrella_namespace()) {
+      csharp_umbrella_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    }
+    csharp_generated_code_attributes_ = false;
   }
   }
 
 
 #undef ZR_HELPER_
 #undef ZR_HELPER_
@@ -7347,6 +7429,209 @@ bool FileOptions::MergePartialFromCodedStream(
         } else {
         } else {
           goto handle_unusual;
           goto handle_unusual;
         }
         }
+        if (input->ExpectTag(298)) goto parse_csharp_namespace;
+        break;
+      }
+
+      // optional string csharp_namespace = 37;
+      case 37: {
+        if (tag == 298) {
+         parse_csharp_namespace:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_csharp_namespace()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->csharp_namespace().data(), this->csharp_namespace().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "google.protobuf.FileOptions.csharp_namespace");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(306)) goto parse_csharp_umbrella_classname;
+        break;
+      }
+
+      // optional string csharp_umbrella_classname = 38;
+      case 38: {
+        if (tag == 306) {
+         parse_csharp_umbrella_classname:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_csharp_umbrella_classname()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->csharp_umbrella_classname().data(), this->csharp_umbrella_classname().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "google.protobuf.FileOptions.csharp_umbrella_classname");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(312)) goto parse_csharp_public_classes;
+        break;
+      }
+
+      // optional bool csharp_public_classes = 39 [default = true];
+      case 39: {
+        if (tag == 312) {
+         parse_csharp_public_classes:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &csharp_public_classes_)));
+          set_has_csharp_public_classes();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(320)) goto parse_csharp_multiple_files;
+        break;
+      }
+
+      // optional bool csharp_multiple_files = 40;
+      case 40: {
+        if (tag == 320) {
+         parse_csharp_multiple_files:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &csharp_multiple_files_)));
+          set_has_csharp_multiple_files();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(328)) goto parse_csharp_nest_classes;
+        break;
+      }
+
+      // optional bool csharp_nest_classes = 41;
+      case 41: {
+        if (tag == 328) {
+         parse_csharp_nest_classes:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &csharp_nest_classes_)));
+          set_has_csharp_nest_classes();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(336)) goto parse_csharp_code_contracts;
+        break;
+      }
+
+      // optional bool csharp_code_contracts = 42;
+      case 42: {
+        if (tag == 336) {
+         parse_csharp_code_contracts:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &csharp_code_contracts_)));
+          set_has_csharp_code_contracts();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(344)) goto parse_csharp_expand_namespace_directories;
+        break;
+      }
+
+      // optional bool csharp_expand_namespace_directories = 43;
+      case 43: {
+        if (tag == 344) {
+         parse_csharp_expand_namespace_directories:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &csharp_expand_namespace_directories_)));
+          set_has_csharp_expand_namespace_directories();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(352)) goto parse_csharp_cls_compliance;
+        break;
+      }
+
+      // optional bool csharp_cls_compliance = 44 [default = true];
+      case 44: {
+        if (tag == 352) {
+         parse_csharp_cls_compliance:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &csharp_cls_compliance_)));
+          set_has_csharp_cls_compliance();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(360)) goto parse_csharp_add_serializable;
+        break;
+      }
+
+      // optional bool csharp_add_serializable = 45 [default = false];
+      case 45: {
+        if (tag == 360) {
+         parse_csharp_add_serializable:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &csharp_add_serializable_)));
+          set_has_csharp_add_serializable();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(368)) goto parse_csharp_generate_private_ctor;
+        break;
+      }
+
+      // optional bool csharp_generate_private_ctor = 46 [default = true];
+      case 46: {
+        if (tag == 368) {
+         parse_csharp_generate_private_ctor:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &csharp_generate_private_ctor_)));
+          set_has_csharp_generate_private_ctor();
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(378)) goto parse_csharp_file_extension;
+        break;
+      }
+
+      // optional string csharp_file_extension = 47 [default = ".cs"];
+      case 47: {
+        if (tag == 378) {
+         parse_csharp_file_extension:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_csharp_file_extension()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->csharp_file_extension().data(), this->csharp_file_extension().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "google.protobuf.FileOptions.csharp_file_extension");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(386)) goto parse_csharp_umbrella_namespace;
+        break;
+      }
+
+      // optional string csharp_umbrella_namespace = 48;
+      case 48: {
+        if (tag == 386) {
+         parse_csharp_umbrella_namespace:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_csharp_umbrella_namespace()));
+          ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+            this->csharp_umbrella_namespace().data(), this->csharp_umbrella_namespace().length(),
+            ::google::protobuf::internal::WireFormat::PARSE,
+            "google.protobuf.FileOptions.csharp_umbrella_namespace");
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(392)) goto parse_csharp_generated_code_attributes;
+        break;
+      }
+
+      // optional bool csharp_generated_code_attributes = 49 [default = false];
+      case 49: {
+        if (tag == 392) {
+         parse_csharp_generated_code_attributes:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
+                 input, &csharp_generated_code_attributes_)));
+          set_has_csharp_generated_code_attributes();
+        } else {
+          goto handle_unusual;
+        }
         if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
         if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
         break;
         break;
       }
       }
@@ -7481,6 +7766,91 @@ void FileOptions::SerializeWithCachedSizes(
       36, this->objc_class_prefix(), output);
       36, this->objc_class_prefix(), output);
   }
   }
 
 
+  // optional string csharp_namespace = 37;
+  if (has_csharp_namespace()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->csharp_namespace().data(), this->csharp_namespace().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.FileOptions.csharp_namespace");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      37, this->csharp_namespace(), output);
+  }
+
+  // optional string csharp_umbrella_classname = 38;
+  if (has_csharp_umbrella_classname()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->csharp_umbrella_classname().data(), this->csharp_umbrella_classname().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.FileOptions.csharp_umbrella_classname");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      38, this->csharp_umbrella_classname(), output);
+  }
+
+  // optional bool csharp_public_classes = 39 [default = true];
+  if (has_csharp_public_classes()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(39, this->csharp_public_classes(), output);
+  }
+
+  // optional bool csharp_multiple_files = 40;
+  if (has_csharp_multiple_files()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(40, this->csharp_multiple_files(), output);
+  }
+
+  // optional bool csharp_nest_classes = 41;
+  if (has_csharp_nest_classes()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(41, this->csharp_nest_classes(), output);
+  }
+
+  // optional bool csharp_code_contracts = 42;
+  if (has_csharp_code_contracts()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(42, this->csharp_code_contracts(), output);
+  }
+
+  // optional bool csharp_expand_namespace_directories = 43;
+  if (has_csharp_expand_namespace_directories()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(43, this->csharp_expand_namespace_directories(), output);
+  }
+
+  // optional bool csharp_cls_compliance = 44 [default = true];
+  if (has_csharp_cls_compliance()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(44, this->csharp_cls_compliance(), output);
+  }
+
+  // optional bool csharp_add_serializable = 45 [default = false];
+  if (has_csharp_add_serializable()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(45, this->csharp_add_serializable(), output);
+  }
+
+  // optional bool csharp_generate_private_ctor = 46 [default = true];
+  if (has_csharp_generate_private_ctor()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(46, this->csharp_generate_private_ctor(), output);
+  }
+
+  // optional string csharp_file_extension = 47 [default = ".cs"];
+  if (has_csharp_file_extension()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->csharp_file_extension().data(), this->csharp_file_extension().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.FileOptions.csharp_file_extension");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      47, this->csharp_file_extension(), output);
+  }
+
+  // optional string csharp_umbrella_namespace = 48;
+  if (has_csharp_umbrella_namespace()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->csharp_umbrella_namespace().data(), this->csharp_umbrella_namespace().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.FileOptions.csharp_umbrella_namespace");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      48, this->csharp_umbrella_namespace(), output);
+  }
+
+  // optional bool csharp_generated_code_attributes = 49 [default = false];
+  if (has_csharp_generated_code_attributes()) {
+    ::google::protobuf::internal::WireFormatLite::WriteBool(49, this->csharp_generated_code_attributes(), output);
+  }
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
   for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
     ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
@@ -7591,6 +7961,95 @@ void FileOptions::SerializeWithCachedSizes(
         36, this->objc_class_prefix(), target);
         36, this->objc_class_prefix(), target);
   }
   }
 
 
+  // optional string csharp_namespace = 37;
+  if (has_csharp_namespace()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->csharp_namespace().data(), this->csharp_namespace().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.FileOptions.csharp_namespace");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        37, this->csharp_namespace(), target);
+  }
+
+  // optional string csharp_umbrella_classname = 38;
+  if (has_csharp_umbrella_classname()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->csharp_umbrella_classname().data(), this->csharp_umbrella_classname().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.FileOptions.csharp_umbrella_classname");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        38, this->csharp_umbrella_classname(), target);
+  }
+
+  // optional bool csharp_public_classes = 39 [default = true];
+  if (has_csharp_public_classes()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(39, this->csharp_public_classes(), target);
+  }
+
+  // optional bool csharp_multiple_files = 40;
+  if (has_csharp_multiple_files()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(40, this->csharp_multiple_files(), target);
+  }
+
+  // optional bool csharp_nest_classes = 41;
+  if (has_csharp_nest_classes()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(41, this->csharp_nest_classes(), target);
+  }
+
+  // optional bool csharp_code_contracts = 42;
+  if (has_csharp_code_contracts()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(42, this->csharp_code_contracts(), target);
+  }
+
+  // optional bool csharp_expand_namespace_directories = 43;
+  if (has_csharp_expand_namespace_directories()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(43, this->csharp_expand_namespace_directories(), target);
+  }
+
+  // optional bool csharp_cls_compliance = 44 [default = true];
+  if (has_csharp_cls_compliance()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(44, this->csharp_cls_compliance(), target);
+  }
+
+  // optional bool csharp_add_serializable = 45 [default = false];
+  if (has_csharp_add_serializable()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(45, this->csharp_add_serializable(), target);
+  }
+
+  // optional bool csharp_generate_private_ctor = 46 [default = true];
+  if (has_csharp_generate_private_ctor()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(46, this->csharp_generate_private_ctor(), target);
+  }
+
+  // optional string csharp_file_extension = 47 [default = ".cs"];
+  if (has_csharp_file_extension()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->csharp_file_extension().data(), this->csharp_file_extension().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.FileOptions.csharp_file_extension");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        47, this->csharp_file_extension(), target);
+  }
+
+  // optional string csharp_umbrella_namespace = 48;
+  if (has_csharp_umbrella_namespace()) {
+    ::google::protobuf::internal::WireFormat::VerifyUTF8StringNamedField(
+      this->csharp_umbrella_namespace().data(), this->csharp_umbrella_namespace().length(),
+      ::google::protobuf::internal::WireFormat::SERIALIZE,
+      "google.protobuf.FileOptions.csharp_umbrella_namespace");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        48, this->csharp_umbrella_namespace(), target);
+  }
+
+  // optional bool csharp_generated_code_attributes = 49 [default = false];
+  if (has_csharp_generated_code_attributes()) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(49, this->csharp_generated_code_attributes(), target);
+  }
+
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
   for (unsigned int i = 0, n = this->uninterpreted_option_size(); i < n; i++) {
     target = ::google::protobuf::internal::WireFormatLite::
     target = ::google::protobuf::internal::WireFormatLite::
@@ -7662,7 +8121,7 @@ int FileOptions::ByteSize() const {
     }
     }
 
 
   }
   }
-  if (_has_bits_[8 / 32] & 7936) {
+  if (_has_bits_[8 / 32] & 65280) {
     // optional bool java_generic_services = 17 [default = false];
     // optional bool java_generic_services = 17 [default = false];
     if (has_java_generic_services()) {
     if (has_java_generic_services()) {
       total_size += 2 + 1;
       total_size += 2 + 1;
@@ -7690,6 +8149,83 @@ int FileOptions::ByteSize() const {
           this->objc_class_prefix());
           this->objc_class_prefix());
     }
     }
 
 
+    // optional string csharp_namespace = 37;
+    if (has_csharp_namespace()) {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->csharp_namespace());
+    }
+
+    // optional string csharp_umbrella_classname = 38;
+    if (has_csharp_umbrella_classname()) {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->csharp_umbrella_classname());
+    }
+
+    // optional bool csharp_public_classes = 39 [default = true];
+    if (has_csharp_public_classes()) {
+      total_size += 2 + 1;
+    }
+
+  }
+  if (_has_bits_[16 / 32] & 16711680) {
+    // optional bool csharp_multiple_files = 40;
+    if (has_csharp_multiple_files()) {
+      total_size += 2 + 1;
+    }
+
+    // optional bool csharp_nest_classes = 41;
+    if (has_csharp_nest_classes()) {
+      total_size += 2 + 1;
+    }
+
+    // optional bool csharp_code_contracts = 42;
+    if (has_csharp_code_contracts()) {
+      total_size += 2 + 1;
+    }
+
+    // optional bool csharp_expand_namespace_directories = 43;
+    if (has_csharp_expand_namespace_directories()) {
+      total_size += 2 + 1;
+    }
+
+    // optional bool csharp_cls_compliance = 44 [default = true];
+    if (has_csharp_cls_compliance()) {
+      total_size += 2 + 1;
+    }
+
+    // optional bool csharp_add_serializable = 45 [default = false];
+    if (has_csharp_add_serializable()) {
+      total_size += 2 + 1;
+    }
+
+    // optional bool csharp_generate_private_ctor = 46 [default = true];
+    if (has_csharp_generate_private_ctor()) {
+      total_size += 2 + 1;
+    }
+
+    // optional string csharp_file_extension = 47 [default = ".cs"];
+    if (has_csharp_file_extension()) {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->csharp_file_extension());
+    }
+
+  }
+  if (_has_bits_[24 / 32] & 50331648) {
+    // optional string csharp_umbrella_namespace = 48;
+    if (has_csharp_umbrella_namespace()) {
+      total_size += 2 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->csharp_umbrella_namespace());
+    }
+
+    // optional bool csharp_generated_code_attributes = 49 [default = false];
+    if (has_csharp_generated_code_attributes()) {
+      total_size += 2 + 1;
+    }
+
   }
   }
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   total_size += 2 * this->uninterpreted_option_size();
   total_size += 2 * this->uninterpreted_option_size();
@@ -7773,6 +8309,53 @@ void FileOptions::MergeFrom(const FileOptions& from) {
       set_has_objc_class_prefix();
       set_has_objc_class_prefix();
       objc_class_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.objc_class_prefix_);
       objc_class_prefix_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.objc_class_prefix_);
     }
     }
+    if (from.has_csharp_namespace()) {
+      set_has_csharp_namespace();
+      csharp_namespace_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.csharp_namespace_);
+    }
+    if (from.has_csharp_umbrella_classname()) {
+      set_has_csharp_umbrella_classname();
+      csharp_umbrella_classname_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.csharp_umbrella_classname_);
+    }
+    if (from.has_csharp_public_classes()) {
+      set_csharp_public_classes(from.csharp_public_classes());
+    }
+  }
+  if (from._has_bits_[16 / 32] & (0xffu << (16 % 32))) {
+    if (from.has_csharp_multiple_files()) {
+      set_csharp_multiple_files(from.csharp_multiple_files());
+    }
+    if (from.has_csharp_nest_classes()) {
+      set_csharp_nest_classes(from.csharp_nest_classes());
+    }
+    if (from.has_csharp_code_contracts()) {
+      set_csharp_code_contracts(from.csharp_code_contracts());
+    }
+    if (from.has_csharp_expand_namespace_directories()) {
+      set_csharp_expand_namespace_directories(from.csharp_expand_namespace_directories());
+    }
+    if (from.has_csharp_cls_compliance()) {
+      set_csharp_cls_compliance(from.csharp_cls_compliance());
+    }
+    if (from.has_csharp_add_serializable()) {
+      set_csharp_add_serializable(from.csharp_add_serializable());
+    }
+    if (from.has_csharp_generate_private_ctor()) {
+      set_csharp_generate_private_ctor(from.csharp_generate_private_ctor());
+    }
+    if (from.has_csharp_file_extension()) {
+      set_has_csharp_file_extension();
+      csharp_file_extension_.AssignWithDefault(_default_csharp_file_extension_, from.csharp_file_extension_);
+    }
+  }
+  if (from._has_bits_[24 / 32] & (0xffu << (24 % 32))) {
+    if (from.has_csharp_umbrella_namespace()) {
+      set_has_csharp_umbrella_namespace();
+      csharp_umbrella_namespace_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.csharp_umbrella_namespace_);
+    }
+    if (from.has_csharp_generated_code_attributes()) {
+      set_csharp_generated_code_attributes(from.csharp_generated_code_attributes());
+    }
   }
   }
   _extensions_.MergeFrom(from._extensions_);
   _extensions_.MergeFrom(from._extensions_);
   if (from._internal_metadata_.have_unknown_fields()) {
   if (from._internal_metadata_.have_unknown_fields()) {
@@ -7817,6 +8400,19 @@ void FileOptions::InternalSwap(FileOptions* other) {
   std::swap(deprecated_, other->deprecated_);
   std::swap(deprecated_, other->deprecated_);
   std::swap(cc_enable_arenas_, other->cc_enable_arenas_);
   std::swap(cc_enable_arenas_, other->cc_enable_arenas_);
   objc_class_prefix_.Swap(&other->objc_class_prefix_);
   objc_class_prefix_.Swap(&other->objc_class_prefix_);
+  csharp_namespace_.Swap(&other->csharp_namespace_);
+  csharp_umbrella_classname_.Swap(&other->csharp_umbrella_classname_);
+  std::swap(csharp_public_classes_, other->csharp_public_classes_);
+  std::swap(csharp_multiple_files_, other->csharp_multiple_files_);
+  std::swap(csharp_nest_classes_, other->csharp_nest_classes_);
+  std::swap(csharp_code_contracts_, other->csharp_code_contracts_);
+  std::swap(csharp_expand_namespace_directories_, other->csharp_expand_namespace_directories_);
+  std::swap(csharp_cls_compliance_, other->csharp_cls_compliance_);
+  std::swap(csharp_add_serializable_, other->csharp_add_serializable_);
+  std::swap(csharp_generate_private_ctor_, other->csharp_generate_private_ctor_);
+  csharp_file_extension_.Swap(&other->csharp_file_extension_);
+  csharp_umbrella_namespace_.Swap(&other->csharp_umbrella_namespace_);
+  std::swap(csharp_generated_code_attributes_, other->csharp_generated_code_attributes_);
   uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
   uninterpreted_option_.UnsafeArenaSwap(&other->uninterpreted_option_);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   std::swap(_has_bits_[0], other->_has_bits_[0]);
   _internal_metadata_.Swap(&other->_internal_metadata_);
   _internal_metadata_.Swap(&other->_internal_metadata_);
@@ -8264,6 +8860,434 @@ void FileOptions::InternalSwap(FileOptions* other) {
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix)
   // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.objc_class_prefix)
 }
 }
 
 
+// optional string csharp_namespace = 37;
+ bool FileOptions::has_csharp_namespace() const {
+  return (_has_bits_[0] & 0x00002000u) != 0;
+}
+ void FileOptions::set_has_csharp_namespace() {
+  _has_bits_[0] |= 0x00002000u;
+}
+ void FileOptions::clear_has_csharp_namespace() {
+  _has_bits_[0] &= ~0x00002000u;
+}
+ void FileOptions::clear_csharp_namespace() {
+  csharp_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_csharp_namespace();
+}
+ const ::std::string& FileOptions::csharp_namespace() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_namespace)
+  return csharp_namespace_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileOptions::set_csharp_namespace(const ::std::string& value) {
+  set_has_csharp_namespace();
+  csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:google.protobuf.FileOptions.csharp_namespace)
+}
+ void FileOptions::set_csharp_namespace(const char* value) {
+  set_has_csharp_namespace();
+  csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:google.protobuf.FileOptions.csharp_namespace)
+}
+ void FileOptions::set_csharp_namespace(const char* value, size_t size) {
+  set_has_csharp_namespace();
+  csharp_namespace_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:google.protobuf.FileOptions.csharp_namespace)
+}
+ ::std::string* FileOptions::mutable_csharp_namespace() {
+  set_has_csharp_namespace();
+  // @@protoc_insertion_point(field_mutable:google.protobuf.FileOptions.csharp_namespace)
+  return csharp_namespace_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* FileOptions::release_csharp_namespace() {
+  clear_has_csharp_namespace();
+  return csharp_namespace_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void FileOptions::set_allocated_csharp_namespace(::std::string* csharp_namespace) {
+  if (csharp_namespace != NULL) {
+    set_has_csharp_namespace();
+  } else {
+    clear_has_csharp_namespace();
+  }
+  csharp_namespace_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), csharp_namespace);
+  // @@protoc_insertion_point(field_set_allocated:google.protobuf.FileOptions.csharp_namespace)
+}
+
+// optional string csharp_umbrella_classname = 38;
+ bool FileOptions::has_csharp_umbrella_classname() const {
+  return (_has_bits_[0] & 0x00004000u) != 0;
+}
+ void FileOptions::set_has_csharp_umbrella_classname() {
+  _has_bits_[0] |= 0x00004000u;
+}
+ void FileOptions::clear_has_csharp_umbrella_classname() {
+  _has_bits_[0] &= ~0x00004000u;
+}
+ void FileOptions::clear_csharp_umbrella_classname() {
+  csharp_umbrella_classname_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_csharp_umbrella_classname();
+}
+ 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());
+}
+ 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)
+}
+ 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)
+}
+ 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)
+}
+ ::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());
+}
+ ::std::string* FileOptions::release_csharp_umbrella_classname() {
+  clear_has_csharp_umbrella_classname();
+  return csharp_umbrella_classname_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ 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];
+ bool FileOptions::has_csharp_public_classes() const {
+  return (_has_bits_[0] & 0x00008000u) != 0;
+}
+ void FileOptions::set_has_csharp_public_classes() {
+  _has_bits_[0] |= 0x00008000u;
+}
+ void FileOptions::clear_has_csharp_public_classes() {
+  _has_bits_[0] &= ~0x00008000u;
+}
+ void FileOptions::clear_csharp_public_classes() {
+  csharp_public_classes_ = true;
+  clear_has_csharp_public_classes();
+}
+ bool FileOptions::csharp_public_classes() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_public_classes)
+  return csharp_public_classes_;
+}
+ 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;
+ bool FileOptions::has_csharp_multiple_files() const {
+  return (_has_bits_[0] & 0x00010000u) != 0;
+}
+ void FileOptions::set_has_csharp_multiple_files() {
+  _has_bits_[0] |= 0x00010000u;
+}
+ void FileOptions::clear_has_csharp_multiple_files() {
+  _has_bits_[0] &= ~0x00010000u;
+}
+ void FileOptions::clear_csharp_multiple_files() {
+  csharp_multiple_files_ = false;
+  clear_has_csharp_multiple_files();
+}
+ bool FileOptions::csharp_multiple_files() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_multiple_files)
+  return csharp_multiple_files_;
+}
+ 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;
+ bool FileOptions::has_csharp_nest_classes() const {
+  return (_has_bits_[0] & 0x00020000u) != 0;
+}
+ void FileOptions::set_has_csharp_nest_classes() {
+  _has_bits_[0] |= 0x00020000u;
+}
+ void FileOptions::clear_has_csharp_nest_classes() {
+  _has_bits_[0] &= ~0x00020000u;
+}
+ void FileOptions::clear_csharp_nest_classes() {
+  csharp_nest_classes_ = false;
+  clear_has_csharp_nest_classes();
+}
+ bool FileOptions::csharp_nest_classes() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_nest_classes)
+  return csharp_nest_classes_;
+}
+ 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;
+ bool FileOptions::has_csharp_code_contracts() const {
+  return (_has_bits_[0] & 0x00040000u) != 0;
+}
+ void FileOptions::set_has_csharp_code_contracts() {
+  _has_bits_[0] |= 0x00040000u;
+}
+ void FileOptions::clear_has_csharp_code_contracts() {
+  _has_bits_[0] &= ~0x00040000u;
+}
+ void FileOptions::clear_csharp_code_contracts() {
+  csharp_code_contracts_ = false;
+  clear_has_csharp_code_contracts();
+}
+ bool FileOptions::csharp_code_contracts() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_code_contracts)
+  return csharp_code_contracts_;
+}
+ 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;
+ bool FileOptions::has_csharp_expand_namespace_directories() const {
+  return (_has_bits_[0] & 0x00080000u) != 0;
+}
+ void FileOptions::set_has_csharp_expand_namespace_directories() {
+  _has_bits_[0] |= 0x00080000u;
+}
+ void FileOptions::clear_has_csharp_expand_namespace_directories() {
+  _has_bits_[0] &= ~0x00080000u;
+}
+ void FileOptions::clear_csharp_expand_namespace_directories() {
+  csharp_expand_namespace_directories_ = false;
+  clear_has_csharp_expand_namespace_directories();
+}
+ bool FileOptions::csharp_expand_namespace_directories() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_expand_namespace_directories)
+  return csharp_expand_namespace_directories_;
+}
+ 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];
+ bool FileOptions::has_csharp_cls_compliance() const {
+  return (_has_bits_[0] & 0x00100000u) != 0;
+}
+ void FileOptions::set_has_csharp_cls_compliance() {
+  _has_bits_[0] |= 0x00100000u;
+}
+ void FileOptions::clear_has_csharp_cls_compliance() {
+  _has_bits_[0] &= ~0x00100000u;
+}
+ void FileOptions::clear_csharp_cls_compliance() {
+  csharp_cls_compliance_ = true;
+  clear_has_csharp_cls_compliance();
+}
+ bool FileOptions::csharp_cls_compliance() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_cls_compliance)
+  return csharp_cls_compliance_;
+}
+ 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];
+ bool FileOptions::has_csharp_add_serializable() const {
+  return (_has_bits_[0] & 0x00200000u) != 0;
+}
+ void FileOptions::set_has_csharp_add_serializable() {
+  _has_bits_[0] |= 0x00200000u;
+}
+ void FileOptions::clear_has_csharp_add_serializable() {
+  _has_bits_[0] &= ~0x00200000u;
+}
+ void FileOptions::clear_csharp_add_serializable() {
+  csharp_add_serializable_ = false;
+  clear_has_csharp_add_serializable();
+}
+ bool FileOptions::csharp_add_serializable() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_add_serializable)
+  return csharp_add_serializable_;
+}
+ 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];
+ bool FileOptions::has_csharp_generate_private_ctor() const {
+  return (_has_bits_[0] & 0x00400000u) != 0;
+}
+ void FileOptions::set_has_csharp_generate_private_ctor() {
+  _has_bits_[0] |= 0x00400000u;
+}
+ void FileOptions::clear_has_csharp_generate_private_ctor() {
+  _has_bits_[0] &= ~0x00400000u;
+}
+ void FileOptions::clear_csharp_generate_private_ctor() {
+  csharp_generate_private_ctor_ = true;
+  clear_has_csharp_generate_private_ctor();
+}
+ bool FileOptions::csharp_generate_private_ctor() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_generate_private_ctor)
+  return csharp_generate_private_ctor_;
+}
+ 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"];
+ bool FileOptions::has_csharp_file_extension() const {
+  return (_has_bits_[0] & 0x00800000u) != 0;
+}
+ void FileOptions::set_has_csharp_file_extension() {
+  _has_bits_[0] |= 0x00800000u;
+}
+ void FileOptions::clear_has_csharp_file_extension() {
+  _has_bits_[0] &= ~0x00800000u;
+}
+ void FileOptions::clear_csharp_file_extension() {
+  csharp_file_extension_.ClearToDefaultNoArena(_default_csharp_file_extension_);
+  clear_has_csharp_file_extension();
+}
+ 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_);
+}
+ 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)
+}
+ 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)
+}
+ 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)
+}
+ ::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_);
+}
+ ::std::string* FileOptions::release_csharp_file_extension() {
+  clear_has_csharp_file_extension();
+  return csharp_file_extension_.ReleaseNoArena(_default_csharp_file_extension_);
+}
+ 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;
+ bool FileOptions::has_csharp_umbrella_namespace() const {
+  return (_has_bits_[0] & 0x01000000u) != 0;
+}
+ void FileOptions::set_has_csharp_umbrella_namespace() {
+  _has_bits_[0] |= 0x01000000u;
+}
+ void FileOptions::clear_has_csharp_umbrella_namespace() {
+  _has_bits_[0] &= ~0x01000000u;
+}
+ void FileOptions::clear_csharp_umbrella_namespace() {
+  csharp_umbrella_namespace_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_csharp_umbrella_namespace();
+}
+ 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());
+}
+ 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)
+}
+ 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)
+}
+ 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)
+}
+ ::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());
+}
+ ::std::string* FileOptions::release_csharp_umbrella_namespace() {
+  clear_has_csharp_umbrella_namespace();
+  return csharp_umbrella_namespace_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ 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];
+ bool FileOptions::has_csharp_generated_code_attributes() const {
+  return (_has_bits_[0] & 0x02000000u) != 0;
+}
+ void FileOptions::set_has_csharp_generated_code_attributes() {
+  _has_bits_[0] |= 0x02000000u;
+}
+ void FileOptions::clear_has_csharp_generated_code_attributes() {
+  _has_bits_[0] &= ~0x02000000u;
+}
+ void FileOptions::clear_csharp_generated_code_attributes() {
+  csharp_generated_code_attributes_ = false;
+  clear_has_csharp_generated_code_attributes();
+}
+ bool FileOptions::csharp_generated_code_attributes() const {
+  // @@protoc_insertion_point(field_get:google.protobuf.FileOptions.csharp_generated_code_attributes)
+  return csharp_generated_code_attributes_;
+}
+ 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;
 // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  int FileOptions::uninterpreted_option_size() const {
  int FileOptions::uninterpreted_option_size() const {
   return uninterpreted_option_.size();
   return uninterpreted_option_.size();

+ 580 - 1
src/google/protobuf/descriptor.pb.h

@@ -1837,6 +1837,117 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
   ::std::string* release_objc_class_prefix();
   ::std::string* release_objc_class_prefix();
   void set_allocated_objc_class_prefix(::std::string* 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;
   // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
   int uninterpreted_option_size() const;
   int uninterpreted_option_size() const;
   void clear_uninterpreted_option();
   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 clear_has_cc_enable_arenas();
   inline void set_has_objc_class_prefix();
   inline void set_has_objc_class_prefix();
   inline void clear_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_;
   ::google::protobuf::internal::ExtensionSet _extensions_;
 
 
@@ -1893,11 +2030,25 @@ class LIBPROTOBUF_EXPORT FileOptions : public ::google::protobuf::Message {
   int optimize_for_;
   int optimize_for_;
   ::google::protobuf::internal::ArenaStringPtr go_package_;
   ::google::protobuf::internal::ArenaStringPtr go_package_;
   ::google::protobuf::internal::ArenaStringPtr objc_class_prefix_;
   ::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 java_generic_services_;
   bool py_generic_services_;
   bool py_generic_services_;
   bool deprecated_;
   bool deprecated_;
   bool cc_enable_arenas_;
   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 LIBPROTOBUF_EXPORT protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
   friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
   friend void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto();
   friend void protobuf_ShutdownFile_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)
   // @@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;
 // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
 inline int FileOptions::uninterpreted_option_size() const {
 inline int FileOptions::uninterpreted_option_size() const {
   return uninterpreted_option_.size();
   return uninterpreted_option_.size();

+ 52 - 0
src/google/protobuf/descriptor.proto

@@ -351,6 +351,58 @@ message FileOptions {
   // generated classes from this .proto. There is no default.
   // generated classes from this .proto. There is no default.
   optional string objc_class_prefix = 36;
   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.
   // The parser stores options it doesn't recognize here. See above.
   repeated UninterpretedOption uninterpreted_option = 999;
   repeated UninterpretedOption uninterpreted_option = 999;