aboutsummaryrefslogtreecommitdiff
path: root/NorthstarDedicatedTest/include/protobuf/compiler/ruby
diff options
context:
space:
mode:
Diffstat (limited to 'NorthstarDedicatedTest/include/protobuf/compiler/ruby')
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code.proto70
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_pb.rb79
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2.proto71
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_import.proto5
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb80
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit.proto9
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy.proto9
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy_pb.rb20
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_pb.rb20
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit.proto7
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit_pb.rb20
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.cc575
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.h67
-rw-r--r--NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator_unittest.cc145
14 files changed, 1177 insertions, 0 deletions
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code.proto b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code.proto
new file mode 100644
index 00000000..70ec9f17
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code.proto
@@ -0,0 +1,70 @@
+syntax = "proto3";
+
+package A.B.C;
+
+import "ruby_generated_code_proto2_import.proto";
+
+message TestMessage {
+ int32 optional_int32 = 1;
+ int64 optional_int64 = 2;
+ uint32 optional_uint32 = 3;
+ uint64 optional_uint64 = 4;
+ bool optional_bool = 5;
+ double optional_double = 6;
+ float optional_float = 7;
+ string optional_string = 8;
+ bytes optional_bytes = 9;
+ TestEnum optional_enum = 10;
+ TestMessage optional_msg = 11;
+ TestImportedMessage optional_proto2_submessage = 12;
+
+ repeated int32 repeated_int32 = 21;
+ repeated int64 repeated_int64 = 22;
+ repeated uint32 repeated_uint32 = 23;
+ repeated uint64 repeated_uint64 = 24;
+ repeated bool repeated_bool = 25;
+ repeated double repeated_double = 26;
+ repeated float repeated_float = 27;
+ repeated string repeated_string = 28;
+ repeated bytes repeated_bytes = 29;
+ repeated TestEnum repeated_enum = 30;
+ repeated TestMessage repeated_msg = 31;
+
+ oneof my_oneof {
+ int32 oneof_int32 = 41;
+ int64 oneof_int64 = 42;
+ uint32 oneof_uint32 = 43;
+ uint64 oneof_uint64 = 44;
+ bool oneof_bool = 45;
+ double oneof_double = 46;
+ float oneof_float = 47;
+ string oneof_string = 48;
+ bytes oneof_bytes = 49;
+ TestEnum oneof_enum = 50;
+ TestMessage oneof_msg = 51;
+ }
+
+ map<int32, string> map_int32_string = 61;
+ map<int64, string> map_int64_string = 62;
+ map<uint32, string> map_uint32_string = 63;
+ map<uint64, string> map_uint64_string = 64;
+ map<bool, string> map_bool_string = 65;
+ map<string, string> map_string_string = 66;
+ map<string, TestMessage> map_string_msg = 67;
+ map<string, TestEnum> map_string_enum = 68;
+ map<string, int32> map_string_int32 = 69;
+ map<string, bool> map_string_bool = 70;
+
+ message NestedMessage {
+ int32 foo = 1;
+ }
+
+ NestedMessage nested_message = 80;
+}
+
+enum TestEnum {
+ Default = 0;
+ A = 1;
+ B = 2;
+ C = 3;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_pb.rb b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_pb.rb
new file mode 100644
index 00000000..256ac7c1
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_pb.rb
@@ -0,0 +1,79 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: ruby_generated_code.proto
+
+require 'google/protobuf'
+
+require 'ruby_generated_code_proto2_import_pb'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_file("ruby_generated_code.proto", :syntax => :proto3) do
+ add_message "A.B.C.TestMessage" do
+ optional :optional_int32, :int32, 1
+ optional :optional_int64, :int64, 2
+ optional :optional_uint32, :uint32, 3
+ optional :optional_uint64, :uint64, 4
+ optional :optional_bool, :bool, 5
+ optional :optional_double, :double, 6
+ optional :optional_float, :float, 7
+ optional :optional_string, :string, 8
+ optional :optional_bytes, :bytes, 9
+ optional :optional_enum, :enum, 10, "A.B.C.TestEnum"
+ optional :optional_msg, :message, 11, "A.B.C.TestMessage"
+ optional :optional_proto2_submessage, :message, 12, "A.B.C.TestImportedMessage"
+ repeated :repeated_int32, :int32, 21
+ repeated :repeated_int64, :int64, 22
+ repeated :repeated_uint32, :uint32, 23
+ repeated :repeated_uint64, :uint64, 24
+ repeated :repeated_bool, :bool, 25
+ repeated :repeated_double, :double, 26
+ repeated :repeated_float, :float, 27
+ repeated :repeated_string, :string, 28
+ repeated :repeated_bytes, :bytes, 29
+ repeated :repeated_enum, :enum, 30, "A.B.C.TestEnum"
+ repeated :repeated_msg, :message, 31, "A.B.C.TestMessage"
+ map :map_int32_string, :int32, :string, 61
+ map :map_int64_string, :int64, :string, 62
+ map :map_uint32_string, :uint32, :string, 63
+ map :map_uint64_string, :uint64, :string, 64
+ map :map_bool_string, :bool, :string, 65
+ map :map_string_string, :string, :string, 66
+ map :map_string_msg, :string, :message, 67, "A.B.C.TestMessage"
+ map :map_string_enum, :string, :enum, 68, "A.B.C.TestEnum"
+ map :map_string_int32, :string, :int32, 69
+ map :map_string_bool, :string, :bool, 70
+ optional :nested_message, :message, 80, "A.B.C.TestMessage.NestedMessage"
+ oneof :my_oneof do
+ optional :oneof_int32, :int32, 41
+ optional :oneof_int64, :int64, 42
+ optional :oneof_uint32, :uint32, 43
+ optional :oneof_uint64, :uint64, 44
+ optional :oneof_bool, :bool, 45
+ optional :oneof_double, :double, 46
+ optional :oneof_float, :float, 47
+ optional :oneof_string, :string, 48
+ optional :oneof_bytes, :bytes, 49
+ optional :oneof_enum, :enum, 50, "A.B.C.TestEnum"
+ optional :oneof_msg, :message, 51, "A.B.C.TestMessage"
+ end
+ end
+ add_message "A.B.C.TestMessage.NestedMessage" do
+ optional :foo, :int32, 1
+ end
+ add_enum "A.B.C.TestEnum" do
+ value :Default, 0
+ value :A, 1
+ value :B, 2
+ value :C, 3
+ end
+ end
+end
+
+module A
+ module B
+ module C
+ TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage").msgclass
+ TestMessage::NestedMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.NestedMessage").msgclass
+ TestEnum = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestEnum").enummodule
+ end
+ end
+end
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2.proto b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2.proto
new file mode 100644
index 00000000..ea7f7836
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2.proto
@@ -0,0 +1,71 @@
+syntax = "proto2";
+
+package A.B.C;
+
+import "ruby_generated_code_proto2_import.proto";
+
+message TestMessage {
+ optional int32 optional_int32 = 1 [default = 1];
+ optional int64 optional_int64 = 2 [default = 2];
+ optional uint32 optional_uint32 = 3 [default = 3];
+ optional uint64 optional_uint64 = 4 [default = 4];
+ optional bool optional_bool = 5 [default = true];
+ optional double optional_double = 6 [default = 6.0];
+ optional float optional_float = 7 [default = 7.0];
+ optional string optional_string = 8 [default = "default str"];
+ optional bytes optional_bytes = 9 [default = "\0\1\2\100fubar"];
+ optional TestEnum optional_enum = 10 [default = A];
+ optional TestMessage optional_msg = 11;
+ optional TestImportedMessage optional_proto2_submessage = 12;
+
+ repeated int32 repeated_int32 = 21;
+ repeated int64 repeated_int64 = 22;
+ repeated uint32 repeated_uint32 = 23;
+ repeated uint64 repeated_uint64 = 24;
+ repeated bool repeated_bool = 25;
+ repeated double repeated_double = 26;
+ repeated float repeated_float = 27;
+ repeated string repeated_string = 28;
+ repeated bytes repeated_bytes = 29;
+ repeated TestEnum repeated_enum = 30;
+ repeated TestMessage repeated_msg = 31;
+
+ required int32 required_int32 = 41;
+ required int64 required_int64 = 42;
+ required uint32 required_uint32 = 43;
+ required uint64 required_uint64 = 44;
+ required bool required_bool = 45;
+ required double required_double = 46;
+ required float required_float = 47;
+ required string required_string = 48;
+ required bytes required_bytes = 49;
+ required TestEnum required_enum = 50;
+ required TestMessage required_msg = 51;
+
+ oneof my_oneof {
+ int32 oneof_int32 = 61;
+ int64 oneof_int64 = 62;
+ uint32 oneof_uint32 = 63;
+ uint64 oneof_uint64 = 64;
+ bool oneof_bool = 65;
+ double oneof_double = 66;
+ float oneof_float = 67;
+ string oneof_string = 68;
+ bytes oneof_bytes = 69;
+ TestEnum oneof_enum = 70;
+ TestMessage oneof_msg = 71;
+ }
+
+ message NestedMessage {
+ optional int32 foo = 1;
+ }
+
+ optional NestedMessage nested_message = 80;
+}
+
+enum TestEnum {
+ Default = 0;
+ A = 1;
+ B = 2;
+ C = 3;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_import.proto b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_import.proto
new file mode 100644
index 00000000..9ec07381
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_import.proto
@@ -0,0 +1,5 @@
+syntax = "proto2";
+
+package A.B.C;
+
+message TestImportedMessage {}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb
new file mode 100644
index 00000000..44d31969
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_code_proto2_pb.rb
@@ -0,0 +1,80 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: ruby_generated_code_proto2.proto
+
+require 'google/protobuf'
+
+require 'ruby_generated_code_proto2_import_pb'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_file("ruby_generated_code_proto2.proto", :syntax => :proto2) do
+ add_message "A.B.C.TestMessage" do
+ optional :optional_int32, :int32, 1, default: 1
+ optional :optional_int64, :int64, 2, default: 2
+ optional :optional_uint32, :uint32, 3, default: 3
+ optional :optional_uint64, :uint64, 4, default: 4
+ optional :optional_bool, :bool, 5, default: true
+ optional :optional_double, :double, 6, default: 6
+ optional :optional_float, :float, 7, default: 7
+ optional :optional_string, :string, 8, default: "default str"
+ optional :optional_bytes, :bytes, 9, default: "\x00\x01\x02\x40\x66\x75\x62\x61\x72".force_encoding("ASCII-8BIT")
+ optional :optional_enum, :enum, 10, "A.B.C.TestEnum", default: 1
+ optional :optional_msg, :message, 11, "A.B.C.TestMessage"
+ optional :optional_proto2_submessage, :message, 12, "A.B.C.TestImportedMessage"
+ repeated :repeated_int32, :int32, 21
+ repeated :repeated_int64, :int64, 22
+ repeated :repeated_uint32, :uint32, 23
+ repeated :repeated_uint64, :uint64, 24
+ repeated :repeated_bool, :bool, 25
+ repeated :repeated_double, :double, 26
+ repeated :repeated_float, :float, 27
+ repeated :repeated_string, :string, 28
+ repeated :repeated_bytes, :bytes, 29
+ repeated :repeated_enum, :enum, 30, "A.B.C.TestEnum"
+ repeated :repeated_msg, :message, 31, "A.B.C.TestMessage"
+ required :required_int32, :int32, 41
+ required :required_int64, :int64, 42
+ required :required_uint32, :uint32, 43
+ required :required_uint64, :uint64, 44
+ required :required_bool, :bool, 45
+ required :required_double, :double, 46
+ required :required_float, :float, 47
+ required :required_string, :string, 48
+ required :required_bytes, :bytes, 49
+ required :required_enum, :enum, 50, "A.B.C.TestEnum"
+ required :required_msg, :message, 51, "A.B.C.TestMessage"
+ optional :nested_message, :message, 80, "A.B.C.TestMessage.NestedMessage"
+ oneof :my_oneof do
+ optional :oneof_int32, :int32, 61
+ optional :oneof_int64, :int64, 62
+ optional :oneof_uint32, :uint32, 63
+ optional :oneof_uint64, :uint64, 64
+ optional :oneof_bool, :bool, 65
+ optional :oneof_double, :double, 66
+ optional :oneof_float, :float, 67
+ optional :oneof_string, :string, 68
+ optional :oneof_bytes, :bytes, 69
+ optional :oneof_enum, :enum, 70, "A.B.C.TestEnum"
+ optional :oneof_msg, :message, 71, "A.B.C.TestMessage"
+ end
+ end
+ add_message "A.B.C.TestMessage.NestedMessage" do
+ optional :foo, :int32, 1
+ end
+ add_enum "A.B.C.TestEnum" do
+ value :Default, 0
+ value :A, 1
+ value :B, 2
+ value :C, 3
+ end
+ end
+end
+
+module A
+ module B
+ module C
+ TestMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage").msgclass
+ TestMessage::NestedMessage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestMessage.NestedMessage").msgclass
+ TestEnum = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("A.B.C.TestEnum").enummodule
+ end
+ end
+end
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit.proto b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit.proto
new file mode 100644
index 00000000..8d7c948a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit.proto
@@ -0,0 +1,9 @@
+syntax = "proto3";
+
+package one.two.a_three;
+
+option ruby_package = "A::B::C";
+
+message Four {
+ string a_string = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy.proto b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy.proto
new file mode 100644
index 00000000..7a0d2608
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy.proto
@@ -0,0 +1,9 @@
+syntax = "proto3";
+
+package one.two.a_three.and;
+
+option ruby_package = "AA.BB.CC";
+
+message Four {
+ string another_string = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy_pb.rb b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy_pb.rb
new file mode 100644
index 00000000..cdbbe891
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_legacy_pb.rb
@@ -0,0 +1,20 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: ruby_generated_pkg_explicit_legacy.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_file("ruby_generated_pkg_explicit_legacy.proto", :syntax => :proto3) do
+ add_message "one.two.a_three.and.Four" do
+ optional :another_string, :string, 1
+ end
+ end
+end
+
+module AA
+ module BB
+ module CC
+ Four = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("one.two.a_three.and.Four").msgclass
+ end
+ end
+end
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_pb.rb b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_pb.rb
new file mode 100644
index 00000000..e6d47011
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_explicit_pb.rb
@@ -0,0 +1,20 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: ruby_generated_pkg_explicit.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_file("ruby_generated_pkg_explicit.proto", :syntax => :proto3) do
+ add_message "one.two.a_three.Four" do
+ optional :a_string, :string, 1
+ end
+ end
+end
+
+module A
+ module B
+ module C
+ Four = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("one.two.a_three.Four").msgclass
+ end
+ end
+end
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit.proto b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit.proto
new file mode 100644
index 00000000..544db64d
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit.proto
@@ -0,0 +1,7 @@
+syntax = "proto3";
+
+package one.two.a_three;
+
+message Four {
+ string a_string = 1;
+}
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit_pb.rb b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit_pb.rb
new file mode 100644
index 00000000..1ac0ef7a
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generated_pkg_implicit_pb.rb
@@ -0,0 +1,20 @@
+# Generated by the protocol buffer compiler. DO NOT EDIT!
+# source: ruby_generated_pkg_implicit.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+ add_file("ruby_generated_pkg_implicit.proto", :syntax => :proto3) do
+ add_message "one.two.a_three.Four" do
+ optional :a_string, :string, 1
+ end
+ end
+end
+
+module One
+ module Two
+ module AThree
+ Four = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("one.two.a_three.Four").msgclass
+ end
+ end
+end
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.cc b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.cc
new file mode 100644
index 00000000..7d6d5032
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.cc
@@ -0,0 +1,575 @@
+// 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 <iomanip>
+#include <sstream>
+
+#include <compiler/code_generator.h>
+#include <compiler/plugin.h>
+#include <descriptor.h>
+#include <descriptor.pb.h>
+#include <io/printer.h>
+#include <io/zero_copy_stream.h>
+
+#include <compiler/ruby/ruby_generator.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace ruby {
+
+// Forward decls.
+template <class numeric_type>
+std::string NumberToString(numeric_type value);
+std::string GetRequireName(const std::string& proto_file);
+std::string LabelForField(FieldDescriptor* field);
+std::string TypeName(FieldDescriptor* field);
+bool GenerateMessage(const Descriptor* message, io::Printer* printer,
+ std::string* error);
+void GenerateEnum(const EnumDescriptor* en, io::Printer* printer);
+void GenerateMessageAssignment(const std::string& prefix,
+ const Descriptor* message, io::Printer* printer);
+void GenerateEnumAssignment(const std::string& prefix, const EnumDescriptor* en,
+ io::Printer* printer);
+std::string DefaultValueForField(const FieldDescriptor* field);
+
+template<class numeric_type>
+std::string NumberToString(numeric_type value) {
+ std::ostringstream os;
+ os << value;
+ return os.str();
+}
+
+std::string GetRequireName(const std::string& proto_file) {
+ int lastindex = proto_file.find_last_of(".");
+ return proto_file.substr(0, lastindex) + "_pb";
+}
+
+std::string GetOutputFilename(const std::string& proto_file) {
+ return GetRequireName(proto_file) + ".rb";
+}
+
+std::string LabelForField(const FieldDescriptor* field) {
+ if (field->has_optional_keyword() &&
+ field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3) {
+ return "proto3_optional";
+ }
+ switch (field->label()) {
+ case FieldDescriptor::LABEL_OPTIONAL: return "optional";
+ case FieldDescriptor::LABEL_REQUIRED: return "required";
+ case FieldDescriptor::LABEL_REPEATED: return "repeated";
+ default: assert(false); return "";
+ }
+}
+
+std::string TypeName(const FieldDescriptor* field) {
+ switch (field->type()) {
+ case FieldDescriptor::TYPE_INT32: return "int32";
+ case FieldDescriptor::TYPE_INT64: return "int64";
+ case FieldDescriptor::TYPE_UINT32: return "uint32";
+ case FieldDescriptor::TYPE_UINT64: return "uint64";
+ case FieldDescriptor::TYPE_SINT32: return "sint32";
+ case FieldDescriptor::TYPE_SINT64: return "sint64";
+ case FieldDescriptor::TYPE_FIXED32: return "fixed32";
+ case FieldDescriptor::TYPE_FIXED64: return "fixed64";
+ case FieldDescriptor::TYPE_SFIXED32: return "sfixed32";
+ case FieldDescriptor::TYPE_SFIXED64: return "sfixed64";
+ case FieldDescriptor::TYPE_DOUBLE: return "double";
+ case FieldDescriptor::TYPE_FLOAT: return "float";
+ case FieldDescriptor::TYPE_BOOL: return "bool";
+ case FieldDescriptor::TYPE_ENUM: return "enum";
+ case FieldDescriptor::TYPE_STRING: return "string";
+ case FieldDescriptor::TYPE_BYTES: return "bytes";
+ case FieldDescriptor::TYPE_MESSAGE: return "message";
+ case FieldDescriptor::TYPE_GROUP: return "group";
+ default: assert(false); return "";
+ }
+}
+
+std::string StringifySyntax(FileDescriptor::Syntax syntax) {
+ switch (syntax) {
+ case FileDescriptor::SYNTAX_PROTO2:
+ return "proto2";
+ case FileDescriptor::SYNTAX_PROTO3:
+ return "proto3";
+ case FileDescriptor::SYNTAX_UNKNOWN:
+ default:
+ GOOGLE_LOG(FATAL) << "Unsupported syntax; this generator only supports "
+ "proto2 and proto3 syntax.";
+ return "";
+ }
+}
+
+std::string DefaultValueForField(const FieldDescriptor* field) {
+ switch(field->cpp_type()) {
+ case FieldDescriptor::CPPTYPE_INT32:
+ return NumberToString(field->default_value_int32());
+ case FieldDescriptor::CPPTYPE_INT64:
+ return NumberToString(field->default_value_int64());
+ case FieldDescriptor::CPPTYPE_UINT32:
+ return NumberToString(field->default_value_uint32());
+ case FieldDescriptor::CPPTYPE_UINT64:
+ return NumberToString(field->default_value_uint64());
+ case FieldDescriptor::CPPTYPE_FLOAT:
+ return NumberToString(field->default_value_float());
+ case FieldDescriptor::CPPTYPE_DOUBLE:
+ return NumberToString(field->default_value_double());
+ case FieldDescriptor::CPPTYPE_BOOL:
+ return field->default_value_bool() ? "true" : "false";
+ case FieldDescriptor::CPPTYPE_ENUM:
+ return NumberToString(field->default_value_enum()->number());
+ case FieldDescriptor::CPPTYPE_STRING: {
+ std::ostringstream os;
+ std::string default_str = field->default_value_string();
+
+ if (field->type() == FieldDescriptor::TYPE_STRING) {
+ os << "\"" << default_str << "\"";
+ } else if (field->type() == FieldDescriptor::TYPE_BYTES) {
+ os << "\"";
+
+ os.fill('0');
+ for (int i = 0; i < default_str.length(); ++i) {
+ // Write the hex form of each byte.
+ os << "\\x" << std::hex << std::setw(2)
+ << ((uint16)((unsigned char)default_str.at(i)));
+ }
+ os << "\".force_encoding(\"ASCII-8BIT\")";
+ }
+
+ return os.str();
+ }
+ default: assert(false); return "";
+ }
+}
+
+void GenerateField(const FieldDescriptor* field, io::Printer* printer) {
+ if (field->is_map()) {
+ const FieldDescriptor* key_field =
+ field->message_type()->FindFieldByNumber(1);
+ const FieldDescriptor* value_field =
+ field->message_type()->FindFieldByNumber(2);
+
+ printer->Print(
+ "map :$name$, :$key_type$, :$value_type$, $number$",
+ "name", field->name(),
+ "key_type", TypeName(key_field),
+ "value_type", TypeName(value_field),
+ "number", NumberToString(field->number()));
+
+ if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ printer->Print(
+ ", \"$subtype$\"\n",
+ "subtype", value_field->message_type()->full_name());
+ } else if (value_field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ printer->Print(
+ ", \"$subtype$\"\n",
+ "subtype", value_field->enum_type()->full_name());
+ } else {
+ printer->Print("\n");
+ }
+ } else {
+
+ printer->Print(
+ "$label$ :$name$, ",
+ "label", LabelForField(field),
+ "name", field->name());
+ printer->Print(
+ ":$type$, $number$",
+ "type", TypeName(field),
+ "number", NumberToString(field->number()));
+
+ if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+ printer->Print(
+ ", \"$subtype$\"",
+ "subtype", field->message_type()->full_name());
+ } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
+ printer->Print(
+ ", \"$subtype$\"",
+ "subtype", field->enum_type()->full_name());
+ }
+
+ if (field->has_default_value()) {
+ printer->Print(", default: $default$", "default",
+ DefaultValueForField(field));
+ }
+
+ if (field->has_json_name()) {
+ printer->Print(", json_name: \"$json_name$\"", "json_name",
+ field->json_name());
+ }
+
+ printer->Print("\n");
+ }
+}
+
+void GenerateOneof(const OneofDescriptor* oneof, io::Printer* printer) {
+ printer->Print(
+ "oneof :$name$ do\n",
+ "name", oneof->name());
+ printer->Indent();
+
+ for (int i = 0; i < oneof->field_count(); i++) {
+ const FieldDescriptor* field = oneof->field(i);
+ GenerateField(field, printer);
+ }
+
+ printer->Outdent();
+ printer->Print("end\n");
+}
+
+bool GenerateMessage(const Descriptor* message, io::Printer* printer,
+ std::string* error) {
+ if (message->extension_range_count() > 0 || message->extension_count() > 0) {
+ GOOGLE_LOG(WARNING) << "Extensions are not yet supported for proto2 .proto files.";
+ }
+
+ // Don't generate MapEntry messages -- we use the Ruby extension's native
+ // support for map fields instead.
+ if (message->options().map_entry()) {
+ return true;
+ }
+
+ printer->Print(
+ "add_message \"$name$\" do\n",
+ "name", message->full_name());
+ printer->Indent();
+
+ for (int i = 0; i < message->field_count(); i++) {
+ const FieldDescriptor* field = message->field(i);
+ if (!field->real_containing_oneof()) {
+ GenerateField(field, printer);
+ }
+ }
+
+ for (int i = 0; i < message->real_oneof_decl_count(); i++) {
+ const OneofDescriptor* oneof = message->oneof_decl(i);
+ GenerateOneof(oneof, printer);
+ }
+
+ printer->Outdent();
+ printer->Print("end\n");
+
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ if (!GenerateMessage(message->nested_type(i), printer, error)) {
+ return false;
+ }
+ }
+ for (int i = 0; i < message->enum_type_count(); i++) {
+ GenerateEnum(message->enum_type(i), printer);
+ }
+
+ return true;
+}
+
+void GenerateEnum(const EnumDescriptor* en, io::Printer* printer) {
+ printer->Print(
+ "add_enum \"$name$\" do\n",
+ "name", en->full_name());
+ printer->Indent();
+
+ for (int i = 0; i < en->value_count(); i++) {
+ const EnumValueDescriptor* value = en->value(i);
+ printer->Print(
+ "value :$name$, $number$\n",
+ "name", value->name(),
+ "number", NumberToString(value->number()));
+ }
+
+ printer->Outdent();
+ printer->Print(
+ "end\n");
+}
+
+// Locale-agnostic utility functions.
+bool IsLower(char ch) { return ch >= 'a' && ch <= 'z'; }
+
+bool IsUpper(char ch) { return ch >= 'A' && ch <= 'Z'; }
+
+bool IsAlpha(char ch) { return IsLower(ch) || IsUpper(ch); }
+
+char UpperChar(char ch) { return IsLower(ch) ? (ch - 'a' + 'A') : ch; }
+
+
+// Package names in protobuf are snake_case by convention, but Ruby module
+// names must be PascalCased.
+//
+// foo_bar_baz -> FooBarBaz
+std::string PackageToModule(const std::string& name) {
+ bool next_upper = true;
+ std::string result;
+ result.reserve(name.size());
+
+ for (int i = 0; i < name.size(); i++) {
+ if (name[i] == '_') {
+ next_upper = true;
+ } else {
+ if (next_upper) {
+ result.push_back(UpperChar(name[i]));
+ } else {
+ result.push_back(name[i]);
+ }
+ next_upper = false;
+ }
+ }
+
+ return result;
+}
+
+// Class and enum names in protobuf should be PascalCased by convention, but
+// since there is nothing enforcing this we need to ensure that they are valid
+// Ruby constants. That mainly means making sure that the first character is
+// an upper-case letter.
+std::string RubifyConstant(const std::string& name) {
+ std::string ret = name;
+ if (!ret.empty()) {
+ if (IsLower(ret[0])) {
+ // If it starts with a lowercase letter, capitalize it.
+ ret[0] = UpperChar(ret[0]);
+ } else if (!IsAlpha(ret[0])) {
+ // Otherwise (e.g. if it begins with an underscore), we need to come up
+ // with some prefix that starts with a capital letter. We could be smarter
+ // here, e.g. try to strip leading underscores, but this may cause other
+ // problems if the user really intended the name. So let's just prepend a
+ // well-known suffix.
+ ret = "PB_" + ret;
+ }
+ }
+
+ return ret;
+}
+
+void GenerateMessageAssignment(const std::string& prefix,
+ const Descriptor* message,
+ io::Printer* printer) {
+ // Don't generate MapEntry messages -- we use the Ruby extension's native
+ // support for map fields instead.
+ if (message->options().map_entry()) {
+ return;
+ }
+
+ printer->Print(
+ "$prefix$$name$ = ",
+ "prefix", prefix,
+ "name", RubifyConstant(message->name()));
+ printer->Print(
+ "::Google::Protobuf::DescriptorPool.generated_pool."
+ "lookup(\"$full_name$\").msgclass\n",
+ "full_name", message->full_name());
+
+ std::string nested_prefix = prefix + RubifyConstant(message->name()) + "::";
+ for (int i = 0; i < message->nested_type_count(); i++) {
+ GenerateMessageAssignment(nested_prefix, message->nested_type(i), printer);
+ }
+ for (int i = 0; i < message->enum_type_count(); i++) {
+ GenerateEnumAssignment(nested_prefix, message->enum_type(i), printer);
+ }
+}
+
+void GenerateEnumAssignment(const std::string& prefix, const EnumDescriptor* en,
+ io::Printer* printer) {
+ printer->Print(
+ "$prefix$$name$ = ",
+ "prefix", prefix,
+ "name", RubifyConstant(en->name()));
+ printer->Print(
+ "::Google::Protobuf::DescriptorPool.generated_pool."
+ "lookup(\"$full_name$\").enummodule\n",
+ "full_name", en->full_name());
+}
+
+int GeneratePackageModules(const FileDescriptor* file, io::Printer* printer) {
+ int levels = 0;
+ bool need_change_to_module = true;
+ std::string package_name;
+
+ // Determine the name to use in either format:
+ // proto package: one.two.three
+ // option ruby_package: One::Two::Three
+ if (file->options().has_ruby_package()) {
+ package_name = file->options().ruby_package();
+
+ // If :: is in the package use the Ruby formatted name as-is
+ // -> A::B::C
+ // otherwise, use the dot separator
+ // -> A.B.C
+ if (package_name.find("::") != std::string::npos) {
+ need_change_to_module = false;
+ } else {
+ GOOGLE_LOG(WARNING) << "ruby_package option should be in the form of:"
+ << " 'A::B::C' and not 'A.B.C'";
+ }
+ } else {
+ package_name = file->package();
+ }
+
+ // Use the appropriate delimiter
+ std::string delimiter = need_change_to_module ? "." : "::";
+ int delimiter_size = need_change_to_module ? 1 : 2;
+
+ // Extract each module name and indent
+ while (!package_name.empty()) {
+ size_t dot_index = package_name.find(delimiter);
+ std::string component;
+ if (dot_index == std::string::npos) {
+ component = package_name;
+ package_name = "";
+ } else {
+ component = package_name.substr(0, dot_index);
+ package_name = package_name.substr(dot_index + delimiter_size);
+ }
+ if (need_change_to_module) {
+ component = PackageToModule(component);
+ }
+ printer->Print(
+ "module $name$\n",
+ "name", component);
+ printer->Indent();
+ levels++;
+ }
+ return levels;
+}
+
+void EndPackageModules(int levels, io::Printer* printer) {
+ while (levels > 0) {
+ levels--;
+ printer->Outdent();
+ printer->Print(
+ "end\n");
+ }
+}
+
+bool GenerateDslDescriptor(const FileDescriptor* file, io::Printer* printer,
+ std::string* error) {
+ printer->Print("Google::Protobuf::DescriptorPool.generated_pool.build do\n");
+ printer->Indent();
+ printer->Print("add_file(\"$filename$\", :syntax => :$syntax$) do\n",
+ "filename", file->name(), "syntax",
+ StringifySyntax(file->syntax()));
+ printer->Indent();
+ for (int i = 0; i < file->message_type_count(); i++) {
+ if (!GenerateMessage(file->message_type(i), printer, error)) {
+ return false;
+ }
+ }
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ GenerateEnum(file->enum_type(i), printer);
+ }
+ printer->Outdent();
+ printer->Print("end\n");
+ printer->Outdent();
+ printer->Print(
+ "end\n\n");
+ return true;
+}
+
+bool GenerateBinaryDescriptor(const FileDescriptor* file, io::Printer* printer,
+ std::string* error) {
+ printer->Print(
+ R"(descriptor_data = File.binread(__FILE__).split("\n__END__\n", 2)[1])");
+ printer->Print(
+ "\nGoogle::Protobuf::DescriptorPool.generated_pool.add_serialized_file("
+ "descriptor_data)\n\n");
+ return true;
+}
+
+bool GenerateFile(const FileDescriptor* file, io::Printer* printer,
+ std::string* error) {
+ printer->Print(
+ "# Generated by the protocol buffer compiler. DO NOT EDIT!\n"
+ "# source: $filename$\n"
+ "\n",
+ "filename", file->name());
+
+ printer->Print("require 'google/protobuf'\n\n");
+
+ if (file->dependency_count() != 0) {
+ for (int i = 0; i < file->dependency_count(); i++) {
+ printer->Print("require '$name$'\n", "name", GetRequireName(file->dependency(i)->name()));
+ }
+ printer->Print("\n");
+ }
+
+ // TODO: Remove this when ruby supports extensions for proto2 syntax.
+ if (file->syntax() == FileDescriptor::SYNTAX_PROTO2 &&
+ file->extension_count() > 0) {
+ GOOGLE_LOG(WARNING) << "Extensions are not yet supported for proto2 .proto files.";
+ }
+
+ bool use_raw_descriptor = file->name() == "google/protobuf/descriptor.proto";
+
+ if (use_raw_descriptor) {
+ GenerateBinaryDescriptor(file, printer, error);
+ } else {
+ GenerateDslDescriptor(file, printer, error);
+ }
+
+ int levels = GeneratePackageModules(file, printer);
+ for (int i = 0; i < file->message_type_count(); i++) {
+ GenerateMessageAssignment("", file->message_type(i), printer);
+ }
+ for (int i = 0; i < file->enum_type_count(); i++) {
+ GenerateEnumAssignment("", file->enum_type(i), printer);
+ }
+ EndPackageModules(levels, printer);
+
+ if (use_raw_descriptor) {
+ printer->Print("\n__END__\n");
+ FileDescriptorProto file_proto;
+ file->CopyTo(&file_proto);
+ std::string file_data;
+ file_proto.SerializeToString(&file_data);
+ printer->Print("$raw_descriptor$", "raw_descriptor", file_data);
+ }
+ return true;
+}
+
+bool Generator::Generate(
+ const FileDescriptor* file,
+ const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const {
+
+ if (file->syntax() != FileDescriptor::SYNTAX_PROTO3 &&
+ file->syntax() != FileDescriptor::SYNTAX_PROTO2) {
+ *error = "Invalid or unsupported proto syntax";
+ return false;
+ }
+
+ std::unique_ptr<io::ZeroCopyOutputStream> output(
+ generator_context->Open(GetOutputFilename(file->name())));
+ io::Printer printer(output.get(), '$');
+
+ return GenerateFile(file, &printer, error);
+}
+
+} // namespace ruby
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.h b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.h
new file mode 100644
index 00000000..e8e6e566
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator.h
@@ -0,0 +1,67 @@
+// 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.
+
+// Generates Ruby code for a given .proto file.
+
+#ifndef GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__
+#define GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__
+
+#include <string>
+
+#include <compiler/code_generator.h>
+
+#include <port_def.inc>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace ruby {
+
+// CodeGenerator implementation for generated Ruby protocol buffer classes.
+// If you create your own protocol compiler binary and you want it to support
+// Ruby output, you can do so by registering an instance of this
+// CodeGenerator with the CommandLineInterface in your main() function.
+class PROTOC_EXPORT Generator : public CodeGenerator {
+ bool Generate(const FileDescriptor* file, const std::string& parameter,
+ GeneratorContext* generator_context,
+ std::string* error) const override;
+ uint64_t GetSupportedFeatures() const override {
+ return FEATURE_PROTO3_OPTIONAL;
+ }
+};
+
+} // namespace ruby
+} // namespace compiler
+} // namespace protobuf
+} // namespace google
+
+#include <port_undef.inc>
+
+#endif // GOOGLE_PROTOBUF_COMPILER_RUBY_GENERATOR_H__
diff --git a/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator_unittest.cc b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator_unittest.cc
new file mode 100644
index 00000000..cc72c1e6
--- /dev/null
+++ b/NorthstarDedicatedTest/include/protobuf/compiler/ruby/ruby_generator_unittest.cc
@@ -0,0 +1,145 @@
+// 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 <list>
+
+#include <compiler/ruby/ruby_generator.h>
+#include <compiler/command_line_interface.h>
+#include <io/zero_copy_stream.h>
+#include <io/printer.h>
+
+#include <testing/googletest.h>
+#include <gtest/gtest.h>
+#include <testing/file.h>
+
+namespace google {
+namespace protobuf {
+namespace compiler {
+namespace ruby {
+namespace {
+
+std::string FindRubyTestDir() {
+ return TestSourceDir() + "/google/protobuf/compiler/ruby";
+}
+
+// This test is a simple golden-file test over the output of the Ruby code
+// generator. When we make changes to the Ruby extension and alter the Ruby code
+// generator to use those changes, we should (i) manually test the output of the
+// code generator with the extension, and (ii) update the golden output above.
+// Some day, we may integrate build systems between protoc and the language
+// extensions to the point where we can do this test in a more automated way.
+
+void RubyTest(string proto_file, string import_proto_file = "") {
+ std::string ruby_tests = FindRubyTestDir();
+
+ google::protobuf::compiler::CommandLineInterface cli;
+ cli.SetInputsAreProtoPathRelative(true);
+
+ ruby::Generator ruby_generator;
+ cli.RegisterGenerator("--ruby_out", &ruby_generator, "");
+
+ // Copy generated_code.proto to the temporary test directory.
+ std::string test_input;
+ GOOGLE_CHECK_OK(File::GetContents(
+ ruby_tests + proto_file + ".proto",
+ &test_input,
+ true));
+ GOOGLE_CHECK_OK(File::SetContents(
+ TestTempDir() + proto_file + ".proto",
+ test_input,
+ true));
+
+ // Copy generated_code_import.proto to the temporary test directory.
+ std::string test_import;
+ if (!import_proto_file.empty()) {
+ GOOGLE_CHECK_OK(File::GetContents(
+ ruby_tests + import_proto_file + ".proto",
+ &test_import,
+ true));
+ GOOGLE_CHECK_OK(File::SetContents(
+ TestTempDir() + import_proto_file + ".proto",
+ test_import,
+ true));
+ }
+
+ // Invoke the proto compiler (we will be inside TestTempDir() at this point).
+ std::string ruby_out = "--ruby_out=" + TestTempDir();
+ std::string proto_path = "--proto_path=" + TestTempDir();
+
+ std::string proto_target = TestTempDir() + proto_file + ".proto";
+ const char* argv[] = {
+ "protoc",
+ ruby_out.c_str(),
+ proto_path.c_str(),
+ proto_target.c_str(),
+ };
+
+ EXPECT_EQ(0, cli.Run(4, argv));
+
+ // Load the generated output and compare to the expected result.
+ std::string output;
+ GOOGLE_CHECK_OK(File::GetContentsAsText(
+ TestTempDir() + proto_file + "_pb.rb",
+ &output,
+ true));
+ std::string expected_output;
+ GOOGLE_CHECK_OK(File::GetContentsAsText(
+ ruby_tests + proto_file + "_pb.rb",
+ &expected_output,
+ true));
+ EXPECT_EQ(expected_output, output);
+}
+
+TEST(RubyGeneratorTest, Proto3GeneratorTest) {
+ RubyTest("/ruby_generated_code", "/ruby_generated_code_proto2_import");
+}
+
+TEST(RubyGeneratorTest, Proto2GeneratorTest) {
+ RubyTest("/ruby_generated_code_proto2", "/ruby_generated_code_proto2_import");
+}
+
+TEST(RubyGeneratorTest, Proto3ImplicitPackageTest) {
+ RubyTest("/ruby_generated_pkg_implicit");
+}
+
+TEST(RubyGeneratorTest, Proto3ExplictPackageTest) {
+ RubyTest("/ruby_generated_pkg_explicit");
+}
+
+TEST(RubyGeneratorTest, Proto3ExplictLegacyPackageTest) {
+ RubyTest("/ruby_generated_pkg_explicit_legacy");
+}
+
+} // namespace
+} // namespace ruby
+} // namespace compiler
+} // namespace protobuf
+} // namespace google