Merge pull request #1675 from jtattermusch/csharp_codegen_improvements

grpc_csharp_plugin improvements
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index 82dd06b..5dd078b 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -51,20 +51,49 @@
 using grpc_generator::METHODTYPE_CLIENT_STREAMING;
 using grpc_generator::METHODTYPE_SERVER_STREAMING;
 using grpc_generator::METHODTYPE_BIDI_STREAMING;
+using grpc_generator::StringReplace;
 using std::map;
 using std::vector;
 
 namespace grpc_csharp_generator {
 namespace {
 
-std::string GetCSharpNamespace(const FileDescriptor* file) {
-  // TODO(jtattermusch): this should be based on csharp_namespace option
+// TODO(jtattermusch): make GetFileNamespace part of libprotoc public API.
+// NOTE: Implementation needs to match exactly to GetFileNamespace
+// defined in csharp_helpers.h in protoc csharp plugin.
+// We cannot reference it directly because google3 protobufs
+// don't have a csharp protoc plugin.
+std::string GetFileNamespace(const FileDescriptor* file) {
+  if (file->options().has_csharp_namespace()) {
+    return file->options().csharp_namespace();
+  }
   return file->package();
 }
 
-std::string GetMessageType(const Descriptor* message) {
-  // TODO(jtattermusch): this has to match with C# protobuf generator
-  return message->name();
+std::string ToCSharpName(const std::string& name, const FileDescriptor* file) {
+  std::string result = GetFileNamespace(file);
+  if (result != "") {
+    result += '.';
+  }
+  std::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;
+}
+
+// TODO(jtattermusch): make GetClassName part of libprotoc public API.
+// NOTE: Implementation needs to match exactly to GetClassName
+// defined in csharp_helpers.h in protoc csharp plugin.
+// We cannot reference it directly because google3 protobufs
+// don't have a csharp protoc plugin.
+std::string GetClassName(const Descriptor* message) {
+  return ToCSharpName(message->full_name(), message->file());
 }
 
 std::string GetServiceClassName(const ServiceDescriptor* service) {
@@ -114,22 +143,22 @@
   if (method->client_streaming()) {
     return "";
   }
-  return GetMessageType(method->input_type()) + " request, ";
+  return GetClassName(method->input_type()) + " request, ";
 }
 
 std::string GetMethodReturnTypeClient(const MethodDescriptor *method) {
   switch (GetMethodType(method)) {
     case METHODTYPE_NO_STREAMING:
-      return "Task<" + GetMessageType(method->output_type()) + ">";
+      return "Task<" + GetClassName(method->output_type()) + ">";
     case METHODTYPE_CLIENT_STREAMING:
-      return "AsyncClientStreamingCall<" + GetMessageType(method->input_type())
-          + ", " + GetMessageType(method->output_type()) + ">";
+      return "AsyncClientStreamingCall<" + GetClassName(method->input_type())
+          + ", " + GetClassName(method->output_type()) + ">";
     case METHODTYPE_SERVER_STREAMING:
-      return "AsyncServerStreamingCall<" + GetMessageType(method->output_type())
+      return "AsyncServerStreamingCall<" + GetClassName(method->output_type())
           + ">";
     case METHODTYPE_BIDI_STREAMING:
-      return "AsyncDuplexStreamingCall<" + GetMessageType(method->input_type())
-          + ", " + GetMessageType(method->output_type()) + ">";
+      return "AsyncDuplexStreamingCall<" + GetClassName(method->input_type())
+          + ", " + GetClassName(method->output_type()) + ">";
   }
   GOOGLE_LOG(FATAL)<< "Can't get here.";
   return "";
@@ -139,10 +168,10 @@
   switch (GetMethodType(method)) {
     case METHODTYPE_NO_STREAMING:
     case METHODTYPE_SERVER_STREAMING:
-      return GetMessageType(method->input_type()) + " request";
+      return GetClassName(method->input_type()) + " request";
     case METHODTYPE_CLIENT_STREAMING:
     case METHODTYPE_BIDI_STREAMING:
-      return "IAsyncStreamReader<" + GetMessageType(method->input_type())
+      return "IAsyncStreamReader<" + GetClassName(method->input_type())
           + "> requestStream";
   }
   GOOGLE_LOG(FATAL)<< "Can't get here.";
@@ -153,7 +182,7 @@
   switch (GetMethodType(method)) {
     case METHODTYPE_NO_STREAMING:
     case METHODTYPE_CLIENT_STREAMING:
-      return "Task<" + GetMessageType(method->output_type()) + ">";
+      return "Task<" + GetClassName(method->output_type()) + ">";
     case METHODTYPE_SERVER_STREAMING:
     case METHODTYPE_BIDI_STREAMING:
       return "Task";
@@ -169,7 +198,7 @@
       return "";
     case METHODTYPE_SERVER_STREAMING:
     case METHODTYPE_BIDI_STREAMING:
-      return ", IServerStreamWriter<" + GetMessageType(method->output_type())
+      return ", IServerStreamWriter<" + GetClassName(method->output_type())
           + "> responseStream";
   }
   GOOGLE_LOG(FATAL)<< "Can't get here.";
@@ -202,7 +231,7 @@
     out->Print(
         "static readonly Marshaller<$type$> $fieldname$ = Marshallers.Create((arg) => arg.ToByteArray(), $type$.ParseFrom);\n",
         "fieldname", GetMarshallerFieldName(message), "type",
-        GetMessageType(message));
+        GetClassName(message));
   }
   out->Print("\n");
 }
@@ -211,8 +240,8 @@
   out->Print(
       "static readonly Method<$request$, $response$> $fieldname$ = new Method<$request$, $response$>(\n",
       "fieldname", GetMethodFieldName(method), "request",
-      GetMessageType(method->input_type()), "response",
-      GetMessageType(method->output_type()));
+      GetClassName(method->input_type()), "response",
+      GetClassName(method->output_type()));
   out->Indent();
   out->Indent();
   out->Print("$methodtype$,\n", "methodtype",
@@ -242,8 +271,8 @@
       out->Print(
           "$response$ $methodname$($request$ request, CancellationToken token = default(CancellationToken));\n",
           "methodname", method->name(), "request",
-          GetMessageType(method->input_type()), "response",
-          GetMessageType(method->output_type()));
+          GetClassName(method->input_type()), "response",
+          GetClassName(method->output_type()));
     }
 
     std::string method_name = method->name();
@@ -310,8 +339,8 @@
       out->Print(
           "public $response$ $methodname$($request$ request, CancellationToken token = default(CancellationToken))\n",
           "methodname", method->name(), "request",
-          GetMessageType(method->input_type()), "response",
-          GetMessageType(method->output_type()));
+          GetClassName(method->input_type()), "response",
+          GetClassName(method->output_type()));
       out->Print("{\n");
       out->Indent();
       out->Print("var call = CreateCall($servicenamefield$, $methodfield$);\n",
@@ -466,7 +495,7 @@
   // TODO(jtattermusch): add using for protobuf message classes
   out.Print("\n");
 
-  out.Print("namespace $namespace$ {\n", "namespace", GetCSharpNamespace(file));
+  out.Print("namespace $namespace$ {\n", "namespace", GetFileNamespace(file));
   out.Indent();
   for (int i = 0; i < file->service_count(); i++) {
     GenerateService(&out, file->service(i));
diff --git a/src/compiler/generator_helpers.h b/src/compiler/generator_helpers.h
index a232fcc..7bdaff1 100644
--- a/src/compiler/generator_helpers.h
+++ b/src/compiler/generator_helpers.h
@@ -60,21 +60,26 @@
 }
 
 inline grpc::string StringReplace(grpc::string str, const grpc::string &from,
-                                  const grpc::string &to) {
+                                  const grpc::string &to, bool replace_all) {
   size_t pos = 0;
 
-  for (;;) {
+  do {
     pos = str.find(from, pos);
     if (pos == grpc::string::npos) {
       break;
     }
     str.replace(pos, from.length(), to);
     pos += to.length();
-  }
+  } while(replace_all);
 
   return str;
 }
 
+inline grpc::string StringReplace(grpc::string str, const grpc::string &from,
+                                  const grpc::string &to) {
+  return StringReplace(str, from, to, true);
+}
+
 inline std::vector<grpc::string> tokenize(const grpc::string &input,
                                           const grpc::string &delimiters) {
   std::vector<grpc::string> tokens;
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index 2546fd2..b9efc44 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -12,30 +12,30 @@
   {
     static readonly string __ServiceName = "math.Math";
 
-    static readonly Marshaller<DivArgs> __Marshaller_DivArgs = Marshallers.Create((arg) => arg.ToByteArray(), DivArgs.ParseFrom);
-    static readonly Marshaller<DivReply> __Marshaller_DivReply = Marshallers.Create((arg) => arg.ToByteArray(), DivReply.ParseFrom);
-    static readonly Marshaller<FibArgs> __Marshaller_FibArgs = Marshallers.Create((arg) => arg.ToByteArray(), FibArgs.ParseFrom);
-    static readonly Marshaller<Num> __Marshaller_Num = Marshallers.Create((arg) => arg.ToByteArray(), Num.ParseFrom);
+    static readonly Marshaller<global::math.DivArgs> __Marshaller_DivArgs = Marshallers.Create((arg) => arg.ToByteArray(), global::math.DivArgs.ParseFrom);
+    static readonly Marshaller<global::math.DivReply> __Marshaller_DivReply = Marshallers.Create((arg) => arg.ToByteArray(), global::math.DivReply.ParseFrom);
+    static readonly Marshaller<global::math.FibArgs> __Marshaller_FibArgs = Marshallers.Create((arg) => arg.ToByteArray(), global::math.FibArgs.ParseFrom);
+    static readonly Marshaller<global::math.Num> __Marshaller_Num = Marshallers.Create((arg) => arg.ToByteArray(), global::math.Num.ParseFrom);
 
-    static readonly Method<DivArgs, DivReply> __Method_Div = new Method<DivArgs, DivReply>(
+    static readonly Method<global::math.DivArgs, global::math.DivReply> __Method_Div = new Method<global::math.DivArgs, global::math.DivReply>(
         MethodType.Unary,
         "Div",
         __Marshaller_DivArgs,
         __Marshaller_DivReply);
 
-    static readonly Method<DivArgs, DivReply> __Method_DivMany = new Method<DivArgs, DivReply>(
+    static readonly Method<global::math.DivArgs, global::math.DivReply> __Method_DivMany = new Method<global::math.DivArgs, global::math.DivReply>(
         MethodType.DuplexStreaming,
         "DivMany",
         __Marshaller_DivArgs,
         __Marshaller_DivReply);
 
-    static readonly Method<FibArgs, Num> __Method_Fib = new Method<FibArgs, Num>(
+    static readonly Method<global::math.FibArgs, global::math.Num> __Method_Fib = new Method<global::math.FibArgs, global::math.Num>(
         MethodType.ServerStreaming,
         "Fib",
         __Marshaller_FibArgs,
         __Marshaller_Num);
 
-    static readonly Method<Num, Num> __Method_Sum = new Method<Num, Num>(
+    static readonly Method<global::math.Num, global::math.Num> __Method_Sum = new Method<global::math.Num, global::math.Num>(
         MethodType.ClientStreaming,
         "Sum",
         __Marshaller_Num,
@@ -44,20 +44,20 @@
     // client-side stub interface
     public interface IMathClient
     {
-      DivReply Div(DivArgs request, CancellationToken token = default(CancellationToken));
-      Task<DivReply> DivAsync(DivArgs request, CancellationToken token = default(CancellationToken));
-      AsyncDuplexStreamingCall<DivArgs, DivReply> DivMany(CancellationToken token = default(CancellationToken));
-      AsyncServerStreamingCall<Num> Fib(FibArgs request, CancellationToken token = default(CancellationToken));
-      AsyncClientStreamingCall<Num, Num> Sum(CancellationToken token = default(CancellationToken));
+      global::math.DivReply Div(global::math.DivArgs request, CancellationToken token = default(CancellationToken));
+      Task<global::math.DivReply> DivAsync(global::math.DivArgs request, CancellationToken token = default(CancellationToken));
+      AsyncDuplexStreamingCall<global::math.DivArgs, global::math.DivReply> DivMany(CancellationToken token = default(CancellationToken));
+      AsyncServerStreamingCall<global::math.Num> Fib(global::math.FibArgs request, CancellationToken token = default(CancellationToken));
+      AsyncClientStreamingCall<global::math.Num, global::math.Num> Sum(CancellationToken token = default(CancellationToken));
     }
 
     // server-side interface
     public interface IMath
     {
-      Task<DivReply> Div(ServerCallContext context, DivArgs request);
-      Task DivMany(ServerCallContext context, IAsyncStreamReader<DivArgs> requestStream, IServerStreamWriter<DivReply> responseStream);
-      Task Fib(ServerCallContext context, FibArgs request, IServerStreamWriter<Num> responseStream);
-      Task<Num> Sum(ServerCallContext context, IAsyncStreamReader<Num> requestStream);
+      Task<global::math.DivReply> Div(ServerCallContext context, global::math.DivArgs request);
+      Task DivMany(ServerCallContext context, IAsyncStreamReader<global::math.DivArgs> requestStream, IServerStreamWriter<global::math.DivReply> responseStream);
+      Task Fib(ServerCallContext context, global::math.FibArgs request, IServerStreamWriter<global::math.Num> responseStream);
+      Task<global::math.Num> Sum(ServerCallContext context, IAsyncStreamReader<global::math.Num> requestStream);
     }
 
     // client stub
@@ -69,27 +69,27 @@
       public MathClient(Channel channel, StubConfiguration config) : base(channel, config)
       {
       }
-      public DivReply Div(DivArgs request, CancellationToken token = default(CancellationToken))
+      public global::math.DivReply Div(global::math.DivArgs request, CancellationToken token = default(CancellationToken))
       {
         var call = CreateCall(__ServiceName, __Method_Div);
         return Calls.BlockingUnaryCall(call, request, token);
       }
-      public Task<DivReply> DivAsync(DivArgs request, CancellationToken token = default(CancellationToken))
+      public Task<global::math.DivReply> DivAsync(global::math.DivArgs request, CancellationToken token = default(CancellationToken))
       {
         var call = CreateCall(__ServiceName, __Method_Div);
         return Calls.AsyncUnaryCall(call, request, token);
       }
-      public AsyncDuplexStreamingCall<DivArgs, DivReply> DivMany(CancellationToken token = default(CancellationToken))
+      public AsyncDuplexStreamingCall<global::math.DivArgs, global::math.DivReply> DivMany(CancellationToken token = default(CancellationToken))
       {
         var call = CreateCall(__ServiceName, __Method_DivMany);
         return Calls.AsyncDuplexStreamingCall(call, token);
       }
-      public AsyncServerStreamingCall<Num> Fib(FibArgs request, CancellationToken token = default(CancellationToken))
+      public AsyncServerStreamingCall<global::math.Num> Fib(global::math.FibArgs request, CancellationToken token = default(CancellationToken))
       {
         var call = CreateCall(__ServiceName, __Method_Fib);
         return Calls.AsyncServerStreamingCall(call, request, token);
       }
-      public AsyncClientStreamingCall<Num, Num> Sum(CancellationToken token = default(CancellationToken))
+      public AsyncClientStreamingCall<global::math.Num, global::math.Num> Sum(CancellationToken token = default(CancellationToken))
       {
         var call = CreateCall(__ServiceName, __Method_Sum);
         return Calls.AsyncClientStreamingCall(call, token);
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index 679aafb..ee077f9 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -12,45 +12,45 @@
   {
     static readonly string __ServiceName = "grpc.testing.TestService";
 
-    static readonly Marshaller<Empty> __Marshaller_Empty = Marshallers.Create((arg) => arg.ToByteArray(), Empty.ParseFrom);
-    static readonly Marshaller<SimpleRequest> __Marshaller_SimpleRequest = Marshallers.Create((arg) => arg.ToByteArray(), SimpleRequest.ParseFrom);
-    static readonly Marshaller<SimpleResponse> __Marshaller_SimpleResponse = Marshallers.Create((arg) => arg.ToByteArray(), SimpleResponse.ParseFrom);
-    static readonly Marshaller<StreamingOutputCallRequest> __Marshaller_StreamingOutputCallRequest = Marshallers.Create((arg) => arg.ToByteArray(), StreamingOutputCallRequest.ParseFrom);
-    static readonly Marshaller<StreamingOutputCallResponse> __Marshaller_StreamingOutputCallResponse = Marshallers.Create((arg) => arg.ToByteArray(), StreamingOutputCallResponse.ParseFrom);
-    static readonly Marshaller<StreamingInputCallRequest> __Marshaller_StreamingInputCallRequest = Marshallers.Create((arg) => arg.ToByteArray(), StreamingInputCallRequest.ParseFrom);
-    static readonly Marshaller<StreamingInputCallResponse> __Marshaller_StreamingInputCallResponse = Marshallers.Create((arg) => arg.ToByteArray(), StreamingInputCallResponse.ParseFrom);
+    static readonly Marshaller<global::grpc.testing.Empty> __Marshaller_Empty = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.Empty.ParseFrom);
+    static readonly Marshaller<global::grpc.testing.SimpleRequest> __Marshaller_SimpleRequest = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.SimpleRequest.ParseFrom);
+    static readonly Marshaller<global::grpc.testing.SimpleResponse> __Marshaller_SimpleResponse = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.SimpleResponse.ParseFrom);
+    static readonly Marshaller<global::grpc.testing.StreamingOutputCallRequest> __Marshaller_StreamingOutputCallRequest = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.StreamingOutputCallRequest.ParseFrom);
+    static readonly Marshaller<global::grpc.testing.StreamingOutputCallResponse> __Marshaller_StreamingOutputCallResponse = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.StreamingOutputCallResponse.ParseFrom);
+    static readonly Marshaller<global::grpc.testing.StreamingInputCallRequest> __Marshaller_StreamingInputCallRequest = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.StreamingInputCallRequest.ParseFrom);
+    static readonly Marshaller<global::grpc.testing.StreamingInputCallResponse> __Marshaller_StreamingInputCallResponse = Marshallers.Create((arg) => arg.ToByteArray(), global::grpc.testing.StreamingInputCallResponse.ParseFrom);
 
-    static readonly Method<Empty, Empty> __Method_EmptyCall = new Method<Empty, Empty>(
+    static readonly Method<global::grpc.testing.Empty, global::grpc.testing.Empty> __Method_EmptyCall = new Method<global::grpc.testing.Empty, global::grpc.testing.Empty>(
         MethodType.Unary,
         "EmptyCall",
         __Marshaller_Empty,
         __Marshaller_Empty);
 
-    static readonly Method<SimpleRequest, SimpleResponse> __Method_UnaryCall = new Method<SimpleRequest, SimpleResponse>(
+    static readonly Method<global::grpc.testing.SimpleRequest, global::grpc.testing.SimpleResponse> __Method_UnaryCall = new Method<global::grpc.testing.SimpleRequest, global::grpc.testing.SimpleResponse>(
         MethodType.Unary,
         "UnaryCall",
         __Marshaller_SimpleRequest,
         __Marshaller_SimpleResponse);
 
-    static readonly Method<StreamingOutputCallRequest, StreamingOutputCallResponse> __Method_StreamingOutputCall = new Method<StreamingOutputCallRequest, StreamingOutputCallResponse>(
+    static readonly Method<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> __Method_StreamingOutputCall = new Method<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse>(
         MethodType.ServerStreaming,
         "StreamingOutputCall",
         __Marshaller_StreamingOutputCallRequest,
         __Marshaller_StreamingOutputCallResponse);
 
-    static readonly Method<StreamingInputCallRequest, StreamingInputCallResponse> __Method_StreamingInputCall = new Method<StreamingInputCallRequest, StreamingInputCallResponse>(
+    static readonly Method<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse> __Method_StreamingInputCall = new Method<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse>(
         MethodType.ClientStreaming,
         "StreamingInputCall",
         __Marshaller_StreamingInputCallRequest,
         __Marshaller_StreamingInputCallResponse);
 
-    static readonly Method<StreamingOutputCallRequest, StreamingOutputCallResponse> __Method_FullDuplexCall = new Method<StreamingOutputCallRequest, StreamingOutputCallResponse>(
+    static readonly Method<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> __Method_FullDuplexCall = new Method<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse>(
         MethodType.DuplexStreaming,
         "FullDuplexCall",
         __Marshaller_StreamingOutputCallRequest,
         __Marshaller_StreamingOutputCallResponse);
 
-    static readonly Method<StreamingOutputCallRequest, StreamingOutputCallResponse> __Method_HalfDuplexCall = new Method<StreamingOutputCallRequest, StreamingOutputCallResponse>(
+    static readonly Method<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> __Method_HalfDuplexCall = new Method<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse>(
         MethodType.DuplexStreaming,
         "HalfDuplexCall",
         __Marshaller_StreamingOutputCallRequest,
@@ -59,25 +59,25 @@
     // client-side stub interface
     public interface ITestServiceClient
     {
-      Empty EmptyCall(Empty request, CancellationToken token = default(CancellationToken));
-      Task<Empty> EmptyCallAsync(Empty request, CancellationToken token = default(CancellationToken));
-      SimpleResponse UnaryCall(SimpleRequest request, CancellationToken token = default(CancellationToken));
-      Task<SimpleResponse> UnaryCallAsync(SimpleRequest request, CancellationToken token = default(CancellationToken));
-      AsyncServerStreamingCall<StreamingOutputCallResponse> StreamingOutputCall(StreamingOutputCallRequest request, CancellationToken token = default(CancellationToken));
-      AsyncClientStreamingCall<StreamingInputCallRequest, StreamingInputCallResponse> StreamingInputCall(CancellationToken token = default(CancellationToken));
-      AsyncDuplexStreamingCall<StreamingOutputCallRequest, StreamingOutputCallResponse> FullDuplexCall(CancellationToken token = default(CancellationToken));
-      AsyncDuplexStreamingCall<StreamingOutputCallRequest, StreamingOutputCallResponse> HalfDuplexCall(CancellationToken token = default(CancellationToken));
+      global::grpc.testing.Empty EmptyCall(global::grpc.testing.Empty request, CancellationToken token = default(CancellationToken));
+      Task<global::grpc.testing.Empty> EmptyCallAsync(global::grpc.testing.Empty request, CancellationToken token = default(CancellationToken));
+      global::grpc.testing.SimpleResponse UnaryCall(global::grpc.testing.SimpleRequest request, CancellationToken token = default(CancellationToken));
+      Task<global::grpc.testing.SimpleResponse> UnaryCallAsync(global::grpc.testing.SimpleRequest request, CancellationToken token = default(CancellationToken));
+      AsyncServerStreamingCall<global::grpc.testing.StreamingOutputCallResponse> StreamingOutputCall(global::grpc.testing.StreamingOutputCallRequest request, CancellationToken token = default(CancellationToken));
+      AsyncClientStreamingCall<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse> StreamingInputCall(CancellationToken token = default(CancellationToken));
+      AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> FullDuplexCall(CancellationToken token = default(CancellationToken));
+      AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> HalfDuplexCall(CancellationToken token = default(CancellationToken));
     }
 
     // server-side interface
     public interface ITestService
     {
-      Task<Empty> EmptyCall(ServerCallContext context, Empty request);
-      Task<SimpleResponse> UnaryCall(ServerCallContext context, SimpleRequest request);
-      Task StreamingOutputCall(ServerCallContext context, StreamingOutputCallRequest request, IServerStreamWriter<StreamingOutputCallResponse> responseStream);
-      Task<StreamingInputCallResponse> StreamingInputCall(ServerCallContext context, IAsyncStreamReader<StreamingInputCallRequest> requestStream);
-      Task FullDuplexCall(ServerCallContext context, IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream);
-      Task HalfDuplexCall(ServerCallContext context, IAsyncStreamReader<StreamingOutputCallRequest> requestStream, IServerStreamWriter<StreamingOutputCallResponse> responseStream);
+      Task<global::grpc.testing.Empty> EmptyCall(ServerCallContext context, global::grpc.testing.Empty request);
+      Task<global::grpc.testing.SimpleResponse> UnaryCall(ServerCallContext context, global::grpc.testing.SimpleRequest request);
+      Task StreamingOutputCall(ServerCallContext context, global::grpc.testing.StreamingOutputCallRequest request, IServerStreamWriter<global::grpc.testing.StreamingOutputCallResponse> responseStream);
+      Task<global::grpc.testing.StreamingInputCallResponse> StreamingInputCall(ServerCallContext context, IAsyncStreamReader<global::grpc.testing.StreamingInputCallRequest> requestStream);
+      Task FullDuplexCall(ServerCallContext context, IAsyncStreamReader<global::grpc.testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::grpc.testing.StreamingOutputCallResponse> responseStream);
+      Task HalfDuplexCall(ServerCallContext context, IAsyncStreamReader<global::grpc.testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::grpc.testing.StreamingOutputCallResponse> responseStream);
     }
 
     // client stub
@@ -89,42 +89,42 @@
       public TestServiceClient(Channel channel, StubConfiguration config) : base(channel, config)
       {
       }
-      public Empty EmptyCall(Empty request, CancellationToken token = default(CancellationToken))
+      public global::grpc.testing.Empty EmptyCall(global::grpc.testing.Empty request, CancellationToken token = default(CancellationToken))
       {
         var call = CreateCall(__ServiceName, __Method_EmptyCall);
         return Calls.BlockingUnaryCall(call, request, token);
       }
-      public Task<Empty> EmptyCallAsync(Empty request, CancellationToken token = default(CancellationToken))
+      public Task<global::grpc.testing.Empty> EmptyCallAsync(global::grpc.testing.Empty request, CancellationToken token = default(CancellationToken))
       {
         var call = CreateCall(__ServiceName, __Method_EmptyCall);
         return Calls.AsyncUnaryCall(call, request, token);
       }
-      public SimpleResponse UnaryCall(SimpleRequest request, CancellationToken token = default(CancellationToken))
+      public global::grpc.testing.SimpleResponse UnaryCall(global::grpc.testing.SimpleRequest request, CancellationToken token = default(CancellationToken))
       {
         var call = CreateCall(__ServiceName, __Method_UnaryCall);
         return Calls.BlockingUnaryCall(call, request, token);
       }
-      public Task<SimpleResponse> UnaryCallAsync(SimpleRequest request, CancellationToken token = default(CancellationToken))
+      public Task<global::grpc.testing.SimpleResponse> UnaryCallAsync(global::grpc.testing.SimpleRequest request, CancellationToken token = default(CancellationToken))
       {
         var call = CreateCall(__ServiceName, __Method_UnaryCall);
         return Calls.AsyncUnaryCall(call, request, token);
       }
-      public AsyncServerStreamingCall<StreamingOutputCallResponse> StreamingOutputCall(StreamingOutputCallRequest request, CancellationToken token = default(CancellationToken))
+      public AsyncServerStreamingCall<global::grpc.testing.StreamingOutputCallResponse> StreamingOutputCall(global::grpc.testing.StreamingOutputCallRequest request, CancellationToken token = default(CancellationToken))
       {
         var call = CreateCall(__ServiceName, __Method_StreamingOutputCall);
         return Calls.AsyncServerStreamingCall(call, request, token);
       }
-      public AsyncClientStreamingCall<StreamingInputCallRequest, StreamingInputCallResponse> StreamingInputCall(CancellationToken token = default(CancellationToken))
+      public AsyncClientStreamingCall<global::grpc.testing.StreamingInputCallRequest, global::grpc.testing.StreamingInputCallResponse> StreamingInputCall(CancellationToken token = default(CancellationToken))
       {
         var call = CreateCall(__ServiceName, __Method_StreamingInputCall);
         return Calls.AsyncClientStreamingCall(call, token);
       }
-      public AsyncDuplexStreamingCall<StreamingOutputCallRequest, StreamingOutputCallResponse> FullDuplexCall(CancellationToken token = default(CancellationToken))
+      public AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> FullDuplexCall(CancellationToken token = default(CancellationToken))
       {
         var call = CreateCall(__ServiceName, __Method_FullDuplexCall);
         return Calls.AsyncDuplexStreamingCall(call, token);
       }
-      public AsyncDuplexStreamingCall<StreamingOutputCallRequest, StreamingOutputCallResponse> HalfDuplexCall(CancellationToken token = default(CancellationToken))
+      public AsyncDuplexStreamingCall<global::grpc.testing.StreamingOutputCallRequest, global::grpc.testing.StreamingOutputCallResponse> HalfDuplexCall(CancellationToken token = default(CancellationToken))
       {
         var call = CreateCall(__ServiceName, __Method_HalfDuplexCall);
         return Calls.AsyncDuplexStreamingCall(call, token);