/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include "src/compiler/csharp_generator.h"

#include <cctype>
#include <map>
#include <sstream>
#include <vector>

#include "src/compiler/config.h"
#include "src/compiler/csharp_generator_helpers.h"

using grpc::protobuf::Descriptor;
using grpc::protobuf::FileDescriptor;
using grpc::protobuf::MethodDescriptor;
using grpc::protobuf::ServiceDescriptor;
using grpc::protobuf::io::Printer;
using grpc::protobuf::io::StringOutputStream;
using grpc_generator::StringReplace;
using std::vector;

namespace grpc_csharp_generator {
namespace {

// This function is a massaged version of
// https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc
// Currently, we cannot easily reuse the functionality as
// google/protobuf/compiler/csharp/csharp_doc_comment.h is not a public header.
// TODO(jtattermusch): reuse the functionality from google/protobuf.
bool GenerateDocCommentBodyImpl(grpc::protobuf::io::Printer* printer,
                                grpc::protobuf::SourceLocation location) {
  std::string comments = location.leading_comments.empty()
                             ? location.trailing_comments
                             : location.leading_comments;
  if (comments.empty()) {
    return false;
  }
  // XML escaping... no need for apostrophes etc as the whole text is going to
  // be a child
  // node of a summary element, not part of an attribute.
  comments = grpc_generator::StringReplace(comments, "&", "&amp;", true);
  comments = grpc_generator::StringReplace(comments, "<", "&lt;", true);

  std::vector<std::string> lines;
  grpc_generator::Split(comments, '\n', &lines);
  // TODO: We really should work out which part to put in the summary and which
  // to put in the remarks...
  // but that needs to be part of a bigger effort to understand the markdown
  // better anyway.
  printer->Print("/// <summary>\n");
  bool last_was_empty = false;
  // We squash multiple blank lines down to one, and remove any trailing blank
  // lines. We need
  // to preserve the blank lines themselves, as this is relevant in the
  // markdown.
  // Note that we can't remove leading or trailing whitespace as *that's*
  // relevant in markdown too.
  // (We don't skip "just whitespace" lines, either.)
  for (std::vector<std::string>::iterator it = lines.begin(); it != lines.end();
       ++it) {
    std::string line = *it;
    if (line.empty()) {
      last_was_empty = true;
    } else {
      if (last_was_empty) {
        printer->Print("///\n");
      }
      last_was_empty = false;
      // If the comment has an extra slash at the start then this can cause the
      // C# compiler to complain when generating the XML documentation Issue
      // [https://github.com/grpc/grpc/issues/35905](https://www.google.com/url?q=https://github.com/grpc/grpc/issues/35905&sa=D)
      if (line[0] == '/') {
        line.replace(0, 1, "&#x2F;");
      }
      printer->Print("///$line$\n", "line", line);
    }
  }
  printer->Print("/// </summary>\n");
  return true;
}

void GenerateGeneratedCodeAttribute(grpc::protobuf::io::Printer* printer) {
  // Mark the code as generated using the [GeneratedCode] attribute.
  // We don't provide plugin version info in attribute the because:
  // * the version information is not readily available from the plugin's code.
  // * it would cause a lot of churn in the pre-generated code
  //   in this repository every time the version is updated.
  printer->Print(
      "[global::System.CodeDom.Compiler.GeneratedCode(\"grpc_csharp_plugin\", "
      "null)]\n");
}

void GenerateObsoleteAttribute(grpc::protobuf::io::Printer* printer,
                               bool is_deprecated) {
  // Mark the code deprecated using the [ObsoleteAttribute] attribute.
  if (is_deprecated) {
    printer->Print("[global::System.ObsoleteAttribute]\n");
  }
}

template <typename DescriptorType>
bool GenerateDocCommentBody(grpc::protobuf::io::Printer* printer,
                            const DescriptorType* descriptor) {
  grpc::protobuf::SourceLocation location;
  if (!descriptor->GetSourceLocation(&location)) {
    return false;
  }
  return GenerateDocCommentBodyImpl(printer, location);
}

void GenerateDocCommentServerMethod(grpc::protobuf::io::Printer* printer,
                                    const MethodDescriptor* method) {
  if (GenerateDocCommentBody(printer, method)) {
    if (method->client_streaming()) {
      printer->Print(
          "/// <param name=\"requestStream\">Used for reading requests from "
          "the client.</param>\n");
    } else {
      printer->Print(
          "/// <param name=\"request\">The request received from the "
          "client.</param>\n");
    }
    if (method->server_streaming()) {
      printer->Print(
          "/// <param name=\"responseStream\">Used for sending responses back "
          "to the client.</param>\n");
    }
    printer->Print(
        "/// <param name=\"context\">The context of the server-side call "
        "handler being invoked.</param>\n");
    if (method->server_streaming()) {
      printer->Print(
          "/// <returns>A task indicating completion of the "
          "handler.</returns>\n");
    } else {
      printer->Print(
          "/// <returns>The response to send back to the client (wrapped by a "
          "task).</returns>\n");
    }
  }
}

void GenerateDocCommentClientMethod(grpc::protobuf::io::Printer* printer,
                                    const MethodDescriptor* method,
                                    bool is_sync, bool use_call_options) {
  if (GenerateDocCommentBody(printer, method)) {
    if (!method->client_streaming()) {
      printer->Print(
          "/// <param name=\"request\">The request to send to the "
          "server.</param>\n");
    }
    if (!use_call_options) {
      printer->Print(
          "/// <param name=\"headers\">The initial metadata to send with the "
          "call. This parameter is optional.</param>\n");
      printer->Print(
          "/// <param name=\"deadline\">An optional deadline for the call. The "
          "call will be cancelled if deadline is hit.</param>\n");
      printer->Print(
          "/// <param name=\"cancellationToken\">An optional token for "
          "canceling the call.</param>\n");
    } else {
      printer->Print(
          "/// <param name=\"options\">The options for the call.</param>\n");
    }
    if (is_sync) {
      printer->Print(
          "/// <returns>The response received from the server.</returns>\n");
    } else {
      printer->Print("/// <returns>The call object.</returns>\n");
    }
  }
}

std::string GetServiceClassName(const ServiceDescriptor* service) {
  return service->name();
}

std::string GetClientClassName(const ServiceDescriptor* service) {
  return service->name() + "Client";
}

std::string GetServerClassName(const ServiceDescriptor* service) {
  return service->name() + "Base";
}

std::string GetCSharpMethodType(const MethodDescriptor* method) {
  if (method->client_streaming()) {
    if (method->server_streaming()) {
      return "grpc::MethodType.DuplexStreaming";
    } else {
      return "grpc::MethodType.ClientStreaming";
    }
  } else {
    if (method->server_streaming()) {
      return "grpc::MethodType.ServerStreaming";
    } else {
      return "grpc::MethodType.Unary";
    }
  }
}

std::string GetCSharpServerMethodType(const MethodDescriptor* method) {
  if (method->client_streaming()) {
    if (method->server_streaming()) {
      return "grpc::DuplexStreamingServerMethod";
    } else {
      return "grpc::ClientStreamingServerMethod";
    }
  } else {
    if (method->server_streaming()) {
      return "grpc::ServerStreamingServerMethod";
    } else {
      return "grpc::UnaryServerMethod";
    }
  }
}

std::string GetServiceNameFieldName() { return "__ServiceName"; }

std::string GetMarshallerFieldName(const Descriptor* message) {
  return "__Marshaller_" +
         grpc_generator::StringReplace(message->full_name(), ".", "_", true);
}

std::string GetMethodFieldName(const MethodDescriptor* method) {
  return "__Method_" + method->name();
}

std::string GetMethodRequestParamMaybe(const MethodDescriptor* method,
                                       bool invocation_param = false) {
  if (method->client_streaming()) {
    return "";
  }
  if (invocation_param) {
    return "request, ";
  }
  return GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->input_type()) + " request, ";
}

std::string GetAccessLevel(bool internal_access) {
  return internal_access ? "internal" : "public";
}

std::string GetMethodReturnTypeClient(const MethodDescriptor* method) {
  if (method->client_streaming()) {
    if (method->server_streaming()) {
      return "grpc::AsyncDuplexStreamingCall<" +
             GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->input_type()) + ", " +
             GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->output_type()) + ">";
    } else {
      return "grpc::AsyncClientStreamingCall<" +
             GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->input_type()) + ", " +
             GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->output_type()) + ">";
    }
  } else {
    if (method->server_streaming()) {
      return "grpc::AsyncServerStreamingCall<" +
             GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->output_type()) + ">";
    } else {
      return "grpc::AsyncUnaryCall<" +
             GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->output_type()) + ">";
    }
  }
}

std::string GetMethodRequestParamServer(const MethodDescriptor* method) {
  if (method->client_streaming()) {
    return "grpc::IAsyncStreamReader<" +
           GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->input_type()) +
           "> requestStream";
  }
  return GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->input_type()) + " request";
}

std::string GetMethodReturnTypeServer(const MethodDescriptor* method) {
  if (method->server_streaming()) {
    return "global::System.Threading.Tasks.Task";
  }
  return "global::System.Threading.Tasks.Task<" +
         GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->output_type()) + ">";
}

std::string GetMethodResponseStreamMaybe(const MethodDescriptor* method) {
  if (method->server_streaming()) {
    return ", grpc::IServerStreamWriter<" +
           GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->output_type()) +
           "> responseStream";
  }
  return "";
}

// Gets vector of all messages used as input or output types.
std::vector<const Descriptor*> GetUsedMessages(
    const ServiceDescriptor* service) {
  std::set<const Descriptor*> descriptor_set;
  std::vector<const Descriptor*>
      result;  // vector is to maintain stable ordering
  for (int i = 0; i < service->method_count(); i++) {
    const MethodDescriptor* method = service->method(i);
    if (descriptor_set.find(method->input_type()) == descriptor_set.end()) {
      descriptor_set.insert(method->input_type());
      result.push_back(method->input_type());
    }
    if (descriptor_set.find(method->output_type()) == descriptor_set.end()) {
      descriptor_set.insert(method->output_type());
      result.push_back(method->output_type());
    }
  }
  return result;
}

void GenerateMarshallerFields(Printer* out, const ServiceDescriptor* service) {
  std::vector<const Descriptor*> used_messages = GetUsedMessages(service);
  if (used_messages.size() != 0) {
    // Generate static helper methods for serialization/deserialization
    GenerateGeneratedCodeAttribute(out);
    out->Print(
        "static void __Helper_SerializeMessage("
        "global::Google.Protobuf.IMessage message, "
        "grpc::SerializationContext context)\n"
        "{\n");
    out->Indent();
    out->Print(
        "#if !GRPC_DISABLE_PROTOBUF_BUFFER_SERIALIZATION\n"
        "if (message is global::Google.Protobuf.IBufferMessage)\n"
        "{\n");
    out->Indent();
    out->Print(
        "context.SetPayloadLength(message.CalculateSize());\n"
        "global::Google.Protobuf.MessageExtensions.WriteTo(message, "
        "context.GetBufferWriter());\n"
        "context.Complete();\n"
        "return;\n");
    out->Outdent();
    out->Print(
        "}\n"
        "#endif\n");
    out->Print(
        "context.Complete("
        "global::Google.Protobuf.MessageExtensions.ToByteArray(message));\n");
    out->Outdent();
    out->Print("}\n\n");

    GenerateGeneratedCodeAttribute(out);
    out->Print(
        "static class __Helper_MessageCache<T>\n"
        "{\n");
    out->Indent();
    out->Print(
        "public static readonly bool IsBufferMessage = "
        "global::System.Reflection.IntrospectionExtensions.GetTypeInfo(typeof("
        "global::Google.Protobuf.IBufferMessage)).IsAssignableFrom(typeof(T));"
        "\n");
    out->Outdent();
    out->Print("}\n\n");

    GenerateGeneratedCodeAttribute(out);
    out->Print(
        "static T __Helper_DeserializeMessage<T>("
        "grpc::DeserializationContext context, "
        "global::Google.Protobuf.MessageParser<T> parser) "
        "where T : global::Google.Protobuf.IMessage<T>\n"
        "{\n");
    out->Indent();
    out->Print(
        "#if !GRPC_DISABLE_PROTOBUF_BUFFER_SERIALIZATION\n"
        "if (__Helper_MessageCache<T>.IsBufferMessage)\n"
        "{\n");
    out->Indent();
    out->Print(
        "return parser.ParseFrom(context.PayloadAsReadOnlySequence());\n");
    out->Outdent();
    out->Print(
        "}\n"
        "#endif\n");
    out->Print("return parser.ParseFrom(context.PayloadAsNewBuffer());\n");
    out->Outdent();
    out->Print("}\n\n");
  }

  for (size_t i = 0; i < used_messages.size(); i++) {
    const Descriptor* message = used_messages[i];
    GenerateGeneratedCodeAttribute(out);
    out->Print(
        "static readonly grpc::Marshaller<$type$> $fieldname$ = "
        "grpc::Marshallers.Create(__Helper_SerializeMessage, "
        "context => __Helper_DeserializeMessage(context, $type$.Parser));\n",
        "fieldname", GetMarshallerFieldName(message), "type",
        GRPC_CUSTOM_CSHARP_GETCLASSNAME(message));
  }
  out->Print("\n");
}

void GenerateStaticMethodField(Printer* out, const MethodDescriptor* method) {
  GenerateGeneratedCodeAttribute(out);
  out->Print(
      "static readonly grpc::Method<$request$, $response$> $fieldname$ = new "
      "grpc::Method<$request$, $response$>(\n",
      "fieldname", GetMethodFieldName(method), "request",
      GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->input_type()), "response",
      GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->output_type()));
  out->Indent();
  out->Indent();
  out->Print("$methodtype$,\n", "methodtype", GetCSharpMethodType(method));
  out->Print("$servicenamefield$,\n", "servicenamefield",
             GetServiceNameFieldName());
  out->Print("\"$methodname$\",\n", "methodname", method->name());
  out->Print("$requestmarshaller$,\n", "requestmarshaller",
             GetMarshallerFieldName(method->input_type()));
  out->Print("$responsemarshaller$);\n", "responsemarshaller",
             GetMarshallerFieldName(method->output_type()));
  out->Print("\n");
  out->Outdent();
  out->Outdent();
}

void GenerateServiceDescriptorProperty(Printer* out,
                                       const ServiceDescriptor* service) {
  std::ostringstream index;
  index << service->index();
  out->Print("/// <summary>Service descriptor</summary>\n");
  out->Print(
      "public static global::Google.Protobuf.Reflection.ServiceDescriptor "
      "Descriptor\n");
  out->Print("{\n");
  out->Print("  get { return $umbrella$.Descriptor.Services[$index$]; }\n",
             "umbrella",
             GRPC_CUSTOM_CSHARP_GETREFLECTIONCLASSNAME(service->file()),
             "index", index.str());
  out->Print("}\n");
  out->Print("\n");
}

void GenerateServerClass(Printer* out, const ServiceDescriptor* service) {
  out->Print(
      "/// <summary>Base class for server-side implementations of "
      "$servicename$</summary>\n",
      "servicename", GetServiceClassName(service));
  GenerateObsoleteAttribute(out, service->options().deprecated());
  out->Print(
      "[grpc::BindServiceMethod(typeof($classname$), "
      "\"BindService\")]\n",
      "classname", GetServiceClassName(service));
  out->Print("public abstract partial class $name$\n", "name",
             GetServerClassName(service));
  out->Print("{\n");
  out->Indent();
  for (int i = 0; i < service->method_count(); i++) {
    const MethodDescriptor* method = service->method(i);
    GenerateDocCommentServerMethod(out, method);
    GenerateObsoleteAttribute(out, method->options().deprecated());
    GenerateGeneratedCodeAttribute(out);
    out->Print(
        "public virtual $returntype$ "
        "$methodname$($request$$response_stream_maybe$, "
        "grpc::ServerCallContext context)\n",
        "methodname", method->name(), "returntype",
        GetMethodReturnTypeServer(method), "request",
        GetMethodRequestParamServer(method), "response_stream_maybe",
        GetMethodResponseStreamMaybe(method));
    out->Print("{\n");
    out->Indent();
    out->Print(
        "throw new grpc::RpcException("
        "new grpc::Status(grpc::StatusCode.Unimplemented, \"\"));\n");
    out->Outdent();
    out->Print("}\n\n");
  }
  out->Outdent();
  out->Print("}\n");
  out->Print("\n");
}

void GenerateClientStub(Printer* out, const ServiceDescriptor* service) {
  out->Print("/// <summary>Client for $servicename$</summary>\n", "servicename",
             GetServiceClassName(service));
  GenerateObsoleteAttribute(out, service->options().deprecated());
  out->Print("public partial class $name$ : grpc::ClientBase<$name$>\n", "name",
             GetClientClassName(service));
  out->Print("{\n");
  out->Indent();

  // constructors
  out->Print(
      "/// <summary>Creates a new client for $servicename$</summary>\n"
      "/// <param name=\"channel\">The channel to use to make remote "
      "calls.</param>\n",
      "servicename", GetServiceClassName(service));
  GenerateGeneratedCodeAttribute(out);
  out->Print("public $name$(grpc::ChannelBase channel) : base(channel)\n",
             "name", GetClientClassName(service));
  out->Print("{\n");
  out->Print("}\n");
  out->Print(
      "/// <summary>Creates a new client for $servicename$ that uses a custom "
      "<c>CallInvoker</c>.</summary>\n"
      "/// <param name=\"callInvoker\">The callInvoker to use to make remote "
      "calls.</param>\n",
      "servicename", GetServiceClassName(service));
  GenerateGeneratedCodeAttribute(out);
  out->Print(
      "public $name$(grpc::CallInvoker callInvoker) : base(callInvoker)\n",
      "name", GetClientClassName(service));
  out->Print("{\n");
  out->Print("}\n");
  out->Print(
      "/// <summary>Protected parameterless constructor to allow creation"
      " of test doubles.</summary>\n");
  GenerateGeneratedCodeAttribute(out);
  out->Print("protected $name$() : base()\n", "name",
             GetClientClassName(service));
  out->Print("{\n");
  out->Print("}\n");
  out->Print(
      "/// <summary>Protected constructor to allow creation of configured "
      "clients.</summary>\n"
      "/// <param name=\"configuration\">The client configuration.</param>\n");
  GenerateGeneratedCodeAttribute(out);
  out->Print(
      "protected $name$(ClientBaseConfiguration configuration)"
      " : base(configuration)\n",
      "name", GetClientClassName(service));
  out->Print("{\n");
  out->Print("}\n\n");

  for (int i = 0; i < service->method_count(); i++) {
    const MethodDescriptor* method = service->method(i);
    const bool is_deprecated = method->options().deprecated();
    if (!method->client_streaming() && !method->server_streaming()) {
      // unary calls have an extra synchronous stub method
      GenerateDocCommentClientMethod(out, method, true, false);
      GenerateObsoleteAttribute(out, is_deprecated);
      GenerateGeneratedCodeAttribute(out);
      out->Print(
          "public virtual $response$ $methodname$($request$ request, "
          "grpc::Metadata "
          "headers = null, global::System.DateTime? deadline = null, "
          "global::System.Threading.CancellationToken "
          "cancellationToken = "
          "default(global::System.Threading.CancellationToken))\n",
          "methodname", method->name(), "request",
          GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->input_type()), "response",
          GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->output_type()));
      out->Print("{\n");
      out->Indent();
      out->Print(
          "return $methodname$(request, new grpc::CallOptions(headers, "
          "deadline, "
          "cancellationToken));\n",
          "methodname", method->name());
      out->Outdent();
      out->Print("}\n");

      // overload taking CallOptions as a param
      GenerateDocCommentClientMethod(out, method, true, true);
      GenerateObsoleteAttribute(out, is_deprecated);
      GenerateGeneratedCodeAttribute(out);
      out->Print(
          "public virtual $response$ $methodname$($request$ request, "
          "grpc::CallOptions options)\n",
          "methodname", method->name(), "request",
          GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->input_type()), "response",
          GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->output_type()));
      out->Print("{\n");
      out->Indent();
      out->Print(
          "return CallInvoker.BlockingUnaryCall($methodfield$, null, options, "
          "request);\n",
          "methodfield", GetMethodFieldName(method));
      out->Outdent();
      out->Print("}\n");
    }

    std::string method_name = method->name();
    if (!method->client_streaming() && !method->server_streaming()) {
      method_name += "Async";  // prevent name clash with synchronous method.
    }
    GenerateDocCommentClientMethod(out, method, false, false);
    GenerateObsoleteAttribute(out, is_deprecated);
    GenerateGeneratedCodeAttribute(out);
    out->Print(
        "public virtual $returntype$ "
        "$methodname$($request_maybe$grpc::Metadata "
        "headers = null, global::System.DateTime? deadline = null, "
        "global::System.Threading.CancellationToken "
        "cancellationToken = "
        "default(global::System.Threading.CancellationToken))\n",
        "methodname", method_name, "request_maybe",
        GetMethodRequestParamMaybe(method), "returntype",
        GetMethodReturnTypeClient(method));
    out->Print("{\n");
    out->Indent();

    out->Print(
        "return $methodname$($request_maybe$new grpc::CallOptions(headers, "
        "deadline, "
        "cancellationToken));\n",
        "methodname", method_name, "request_maybe",
        GetMethodRequestParamMaybe(method, true));
    out->Outdent();
    out->Print("}\n");

    // overload taking CallOptions as a param
    GenerateDocCommentClientMethod(out, method, false, true);
    GenerateObsoleteAttribute(out, is_deprecated);
    GenerateGeneratedCodeAttribute(out);
    out->Print(
        "public virtual $returntype$ "
        "$methodname$($request_maybe$grpc::CallOptions "
        "options)\n",
        "methodname", method_name, "request_maybe",
        GetMethodRequestParamMaybe(method), "returntype",
        GetMethodReturnTypeClient(method));
    out->Print("{\n");
    out->Indent();
    if (!method->client_streaming() && !method->server_streaming()) {
      // Non-Streaming
      out->Print(
          "return CallInvoker.AsyncUnaryCall($methodfield$, null, options, "
          "request);\n",
          "methodfield", GetMethodFieldName(method));
    } else if (method->client_streaming() && !method->server_streaming()) {
      // Client Streaming Only
      out->Print(
          "return CallInvoker.AsyncClientStreamingCall($methodfield$, null, "
          "options);\n",
          "methodfield", GetMethodFieldName(method));
    } else if (!method->client_streaming() && method->server_streaming()) {
      // Server Streaming Only
      out->Print(
          "return CallInvoker.AsyncServerStreamingCall($methodfield$, null, "
          "options, request);\n",
          "methodfield", GetMethodFieldName(method));
    } else {
      // Bi-Directional Streaming
      out->Print(
          "return CallInvoker.AsyncDuplexStreamingCall($methodfield$, null, "
          "options);\n",
          "methodfield", GetMethodFieldName(method));
    }
    out->Outdent();
    out->Print("}\n");
  }

  // override NewInstance method
  out->Print(
      "/// <summary>Creates a new instance of client from given "
      "<c>ClientBaseConfiguration</c>.</summary>\n");
  GenerateGeneratedCodeAttribute(out);
  out->Print(
      "protected override $name$ NewInstance(ClientBaseConfiguration "
      "configuration)\n",
      "name", GetClientClassName(service));
  out->Print("{\n");
  out->Indent();
  out->Print("return new $name$(configuration);\n", "name",
             GetClientClassName(service));
  out->Outdent();
  out->Print("}\n");

  out->Outdent();
  out->Print("}\n");
  out->Print("\n");
}

void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor* service) {
  out->Print(
      "/// <summary>Creates service definition that can be registered with a "
      "server</summary>\n");
  out->Print(
      "/// <param name=\"serviceImpl\">An object implementing the server-side"
      " handling logic.</param>\n");
  GenerateGeneratedCodeAttribute(out);
  out->Print(
      "public static grpc::ServerServiceDefinition BindService($implclass$ "
      "serviceImpl)\n",
      "implclass", GetServerClassName(service));
  out->Print("{\n");
  out->Indent();

  out->Print("return grpc::ServerServiceDefinition.CreateBuilder()");
  out->Indent();
  out->Indent();
  for (int i = 0; i < service->method_count(); i++) {
    const MethodDescriptor* method = service->method(i);
    out->Print("\n.AddMethod($methodfield$, serviceImpl.$methodname$)",
               "methodfield", GetMethodFieldName(method), "methodname",
               method->name());
  }
  out->Print(".Build();\n");
  out->Outdent();
  out->Outdent();

  out->Outdent();
  out->Print("}\n");
  out->Print("\n");
}

void GenerateBindServiceWithBinderMethod(Printer* out,
                                         const ServiceDescriptor* service) {
  out->Print(
      "/// <summary>Register service method with a service "
      "binder with or without implementation. Useful when customizing the "
      "service binding logic.\n"
      "/// Note: this method is part of an experimental API that can change or "
      "be "
      "removed without any prior notice.</summary>\n");
  out->Print(
      "/// <param name=\"serviceBinder\">Service methods will be bound by "
      "calling <c>AddMethod</c> on this object."
      "</param>\n");
  out->Print(
      "/// <param name=\"serviceImpl\">An object implementing the server-side"
      " handling logic.</param>\n");
  GenerateGeneratedCodeAttribute(out);
  out->Print(
      "public static void BindService(grpc::ServiceBinderBase serviceBinder, "
      "$implclass$ "
      "serviceImpl)\n",
      "implclass", GetServerClassName(service));
  out->Print("{\n");
  out->Indent();

  for (int i = 0; i < service->method_count(); i++) {
    const MethodDescriptor* method = service->method(i);
    out->Print(
        "serviceBinder.AddMethod($methodfield$, serviceImpl == null ? null : "
        "new $servermethodtype$<$inputtype$, $outputtype$>("
        "serviceImpl.$methodname$));\n",
        "methodfield", GetMethodFieldName(method), "servermethodtype",
        GetCSharpServerMethodType(method), "inputtype",
        GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->input_type()), "outputtype",
        GRPC_CUSTOM_CSHARP_GETCLASSNAME(method->output_type()), "methodname",
        method->name());
  }

  out->Outdent();
  out->Print("}\n");
  out->Print("\n");
}

void GenerateService(Printer* out, const ServiceDescriptor* service,
                     bool generate_client, bool generate_server,
                     bool internal_access) {
  GenerateDocCommentBody(out, service);

  GenerateObsoleteAttribute(out, service->options().deprecated());
  out->Print("$access_level$ static partial class $classname$\n",
             "access_level", GetAccessLevel(internal_access), "classname",
             GetServiceClassName(service));
  out->Print("{\n");
  out->Indent();
  out->Print("static readonly string $servicenamefield$ = \"$servicename$\";\n",
             "servicenamefield", GetServiceNameFieldName(), "servicename",
             service->full_name());
  out->Print("\n");

  GenerateMarshallerFields(out, service);
  for (int i = 0; i < service->method_count(); i++) {
    GenerateStaticMethodField(out, service->method(i));
  }
  GenerateServiceDescriptorProperty(out, service);

  if (generate_server) {
    GenerateServerClass(out, service);
  }
  if (generate_client) {
    GenerateClientStub(out, service);
  }
  if (generate_server) {
    GenerateBindServiceMethod(out, service);
    GenerateBindServiceWithBinderMethod(out, service);
  }

  out->Outdent();
  out->Print("}\n");
}

}  // anonymous namespace

std::string GetServices(const FileDescriptor* file, bool generate_client,
                        bool generate_server, bool internal_access) {
  std::string output;
  {
    // Scope the output stream so it closes and finalizes output to the string.

    StringOutputStream output_stream(&output);
    Printer out(&output_stream, '$');

    // Don't write out any output if there no services, to avoid empty service
    // files being generated for proto files that don't declare any.
    if (file->service_count() == 0) {
      return output;
    }

    // Write out a file header.
    out.Print("// <auto-generated>\n");
    out.Print(
        "//     Generated by the protocol buffer compiler.  DO NOT EDIT!\n");
    out.Print("//     source: $filename$\n", "filename", file->name());
    out.Print("// </auto-generated>\n");

    // use C++ style as there are no file-level XML comments in .NET
    std::string leading_comments = GetCsharpComments(file, true);
    if (!leading_comments.empty()) {
      out.Print("// Original file comments:\n");
      out.PrintRaw(leading_comments.c_str());
    }

    out.Print("#pragma warning disable 0414, 1591, 8981, 0612\n");

    out.Print("#region Designer generated code\n");
    out.Print("\n");
    out.Print("using grpc = global::Grpc.Core;\n");
    out.Print("\n");

    std::string file_namespace = GRPC_CUSTOM_CSHARP_GETFILENAMESPACE(file);
    if (file_namespace != "") {
      out.Print("namespace $namespace$ {\n", "namespace", file_namespace);
      out.Indent();
    }
    for (int i = 0; i < file->service_count(); i++) {
      GenerateService(&out, file->service(i), generate_client, generate_server,
                      internal_access);
    }
    if (file_namespace != "") {
      out.Outdent();
      out.Print("}\n");
    }
    out.Print("#endregion\n");
  }
  return output;
}

}  // namespace grpc_csharp_generator
