Precreate RpcMethod instances
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index bd8bf65..defb44a 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -154,6 +154,7 @@
                                const Parameters &params) {
   grpc::string temp =
       "#include <grpc++/impl/internal_stub.h>\n"
+      "#include <grpc++/impl/rpc_method.h>\n"
       "#include <grpc++/impl/service_type.h>\n"
       "#include <grpc++/status.h>\n"
       "\n"
@@ -264,6 +265,13 @@
   }
 }
 
+void PrintHeaderClientMethodData(grpc::protobuf::io::Printer *printer,
+                                 const grpc::protobuf::MethodDescriptor *method,
+                                 std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
+}
+
 void PrintHeaderServerMethodSync(
     grpc::protobuf::io::Printer *printer,
     const grpc::protobuf::MethodDescriptor *method,
@@ -351,10 +359,17 @@
       "class Stub GRPC_FINAL : public ::grpc::InternalStub {\n"
       " public:\n");
   printer->Indent();
+  printer->Print("Stub();\n");
   for (int i = 0; i < service->method_count(); ++i) {
     PrintHeaderClientMethod(printer, service->method(i), vars);
   }
   printer->Outdent();
+  printer->Print(" private:\n");
+  printer->Indent();
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintHeaderClientMethodData(printer, service->method(i), vars);
+  }
+  printer->Outdent();
   printer->Print("};\n");
   printer->Print(
       "static std::unique_ptr<Stub> NewStub(const std::shared_ptr< "
@@ -479,7 +494,6 @@
   printer.Print(vars, "#include <grpc++/async_unary_call.h>\n");
   printer.Print(vars, "#include <grpc++/channel_interface.h>\n");
   printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
-  printer.Print(vars, "#include <grpc++/impl/rpc_method.h>\n");
   printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
   printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
   printer.Print(vars, "#include <grpc++/stream.h>\n");
@@ -513,8 +527,8 @@
                    "::grpc::ClientContext* context, "
                    "const $Request$& request, $Response$* response) {\n");
     printer->Print(*vars,
-                   "  return ::grpc::BlockingUnaryCall(channel(),"
-                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$]), "
+                   "  return ::grpc::BlockingUnaryCall(channel(), "
+                   "rpcmethod_$Method$_, "
                    "context, request, response);\n"
                    "}\n\n");
     printer->Print(
@@ -528,7 +542,7 @@
                    "::grpc::ClientAsyncResponseReader< $Response$>>(new "
                    "::grpc::ClientAsyncResponseReader< $Response$>("
                    "channel(), cq, "
-                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$]), "
+                   "rpcmethod_$Method$_, "
                    "context, request, tag));\n"
                    "}\n\n");
   } else if (ClientOnlyStreaming(method)) {
@@ -540,8 +554,7 @@
                    "  return std::unique_ptr< ::grpc::ClientWriter< "
                    "$Request$>>(new ::grpc::ClientWriter< $Request$>("
                    "channel(),"
-                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
-                   "::grpc::RpcMethod::RpcType::CLIENT_STREAMING), "
+                   "rpcmethod_$Method$_, "
                    "context, response));\n"
                    "}\n\n");
     printer->Print(*vars,
@@ -553,8 +566,7 @@
                    "  return std::unique_ptr< ::grpc::ClientAsyncWriter< "
                    "$Request$>>(new ::grpc::ClientAsyncWriter< $Request$>("
                    "channel(), cq, "
-                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
-                   "::grpc::RpcMethod::RpcType::CLIENT_STREAMING), "
+                   "rpcmethod_$Method$_, "
                    "context, response, tag));\n"
                    "}\n\n");
   } else if (ServerOnlyStreaming(method)) {
@@ -567,8 +579,7 @@
                    "  return std::unique_ptr< ::grpc::ClientReader< "
                    "$Response$>>(new ::grpc::ClientReader< $Response$>("
                    "channel(),"
-                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
-                   "::grpc::RpcMethod::RpcType::SERVER_STREAMING), "
+                   "rpcmethod_$Method$_, "
                    "context, request));\n"
                    "}\n\n");
     printer->Print(*vars,
@@ -580,8 +591,7 @@
                    "  return std::unique_ptr< ::grpc::ClientAsyncReader< "
                    "$Response$>>(new ::grpc::ClientAsyncReader< $Response$>("
                    "channel(), cq, "
-                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
-                   "::grpc::RpcMethod::RpcType::SERVER_STREAMING), "
+                   "rpcmethod_$Method$_, "
                    "context, request, tag));\n"
                    "}\n\n");
   } else if (BidiStreaming(method)) {
@@ -594,8 +604,7 @@
                    "$Request$, $Response$>>(new ::grpc::ClientReaderWriter< "
                    "$Request$, $Response$>("
                    "channel(),"
-                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
-                   "::grpc::RpcMethod::RpcType::BIDI_STREAMING), "
+                   "rpcmethod_$Method$_, "
                    "context));\n"
                    "}\n\n");
     printer->Print(*vars,
@@ -608,8 +617,7 @@
                    "$Request$, $Response$>>(new "
                    "::grpc::ClientAsyncReaderWriter< $Request$, $Response$>("
                    "channel(), cq, "
-                   "::grpc::RpcMethod($prefix$$Service$_method_names[$Idx$], "
-                   "::grpc::RpcMethod::RpcType::BIDI_STREAMING), "
+                   "rpcmethod_$Method$_, "
                    "context, tag));\n"
                    "}\n\n");
   }
@@ -740,6 +748,30 @@
       "  stub->set_channel(channel);\n"
       "  return stub;\n"
       "}\n\n");
+  printer->Print(*vars, "$ns$$Service$::Stub::Stub()");
+  printer->Indent();
+  for (int i = 0; i < service->method_count(); ++i) {
+    const grpc::protobuf::MethodDescriptor *method = service->method(i);
+    (*vars)["Sep"] = (i==0) ? ":" : ",";
+    (*vars)["Method"] = method->name();
+    (*vars)["Idx"] = as_string(i);
+    if (NoStreaming(method)) {
+      (*vars)["StreamingType"] = "NORMAL_RPC";
+    } else if (ClientOnlyStreaming(method)) {
+      (*vars)["StreamingType"] = "CLIENT_STREAMING";
+    } else if (ServerOnlyStreaming(method)) {
+      (*vars)["StreamingType"] = "SERVER_STREAMING";
+    } else {
+      (*vars)["StreamingType"] = "BIDI_STREAMING";
+    }
+    printer->Print(*vars, "$Sep$ rpcmethod_$Method$_("
+      "$prefix$$Service$_method_names[$Idx$], "
+      "::grpc::RpcMethod::$StreamingType$"
+      ")\n");
+  }
+  printer->Print("{}\n");
+  printer->Outdent();
+
   for (int i = 0; i < service->method_count(); ++i) {
     (*vars)["Idx"] = as_string(i);
     PrintSourceClientMethod(printer, service->method(i), vars);