From c429d7830f2a5a32c9543ee3c362f4061c9f0129 Mon Sep 17 00:00:00 2001
From: Alexander Polcyn <apolcyn@google.com>
Date: Mon, 3 Oct 2016 11:23:20 -0700
Subject: [PATCH] change ruby proto plugin to copy package name conversion from
 protoc

---
 src/compiler/ruby_generator.cc | 36 +++++++++++++++++++++++++++++++++-
 1 file changed, 35 insertions(+), 1 deletion(-)

diff --git a/src/compiler/ruby_generator.cc b/src/compiler/ruby_generator.cc
index 6e5419cb47..3a7b89bf69 100644
--- a/src/compiler/ruby_generator.cc
+++ b/src/compiler/ruby_generator.cc
@@ -124,6 +124,40 @@ grpc::string SnakeCaseToCamelCase(grpc::string input) {
   return output;
 }
 
+// The following functions are copied directly from the source for the protoc ruby generator
+// to ensure compatibility ('int i' changed to 'uint i' is the only change).
+// See https://github.com/google/protobuf/blob/master/src/google/protobuf/compiler/ruby/ruby_generator.cc#L250
+// TODO: keep up to date with protoc code generation, though this behavior isn't expected to change
+bool IsLower(char ch) { return ch >= 'a' && ch <= 'z'; }
+
+char ToUpper(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 (uint i = 0; i < name.size(); i++) {
+    if (name[i] == '_') {
+      next_upper = true;
+    } else {
+      if (next_upper) {
+        result.push_back(ToUpper(name[i]));
+      } else {
+        result.push_back(name[i]);
+      }
+      next_upper = false;
+    }
+  }
+
+  return result;
+}
+// end copying of protoc generator for ruby code
 
 grpc::string GetServices(const FileDescriptor *file) {
   grpc::string output;
@@ -166,7 +200,7 @@ grpc::string GetServices(const FileDescriptor *file) {
     std::vector<grpc::string> modules = Split(file->package(), '.');
     for (size_t i = 0; i < modules.size(); ++i) {
       std::map<grpc::string, grpc::string> module_vars =
-          ListToDict({"module.name", SnakeCaseToCamelCase(modules[i]), });
+          ListToDict({"module.name", PackageToModule(modules[i]), });
       out.Print(module_vars, "module $module.name$\n");
       out.Indent();
     }
-- 
GitLab