// 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.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.

#include <google/protobuf/compiler/java/java_service.h>

#include <google/protobuf/compiler/java/java_context.h>
#include <google/protobuf/compiler/java/java_doc_comment.h>
#include <google/protobuf/compiler/java/java_helpers.h>
#include <google/protobuf/compiler/java/java_name_resolver.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/stubs/strutil.h>


namespace google {
namespace protobuf {
namespace compiler {
namespace java {

ServiceGenerator::ServiceGenerator(const ServiceDescriptor* descriptor)
    : descriptor_(descriptor) {}

ServiceGenerator::~ServiceGenerator() {}

// ===================================================================
ImmutableServiceGenerator::ImmutableServiceGenerator(
    const ServiceDescriptor* descriptor, Context* context)
    : ServiceGenerator(descriptor),
      context_(context),
      name_resolver_(context->GetNameResolver()) {}

ImmutableServiceGenerator::~ImmutableServiceGenerator() {}

void ImmutableServiceGenerator::Generate(io::Printer* printer) {
  bool is_own_file = IsOwnFile(descriptor_, /* immutable = */ true);
  WriteServiceDocComment(printer, descriptor_);
  MaybePrintGeneratedAnnotation(context_, printer, descriptor_,
                                /* immutable = */ true);
  printer->Print(
      "public $static$ abstract class $classname$\n"
      "    implements com.google.protobuf.Service {\n",
      "static", is_own_file ? "" : "static", "classname", descriptor_->name());
  printer->Indent();

  printer->Print("protected $classname$() {}\n\n", "classname",
                 descriptor_->name());

  GenerateInterface(printer);

  GenerateNewReflectiveServiceMethod(printer);
  GenerateNewReflectiveBlockingServiceMethod(printer);

  GenerateAbstractMethods(printer);

  // Generate getDescriptor() and getDescriptorForType().
  printer->Print(
      "public static final\n"
      "    com.google.protobuf.Descriptors.ServiceDescriptor\n"
      "    getDescriptor() {\n"
      "  return $file$.getDescriptor().getServices().get($index$);\n"
      "}\n",
      "file", name_resolver_->GetImmutableClassName(descriptor_->file()),
      "index", StrCat(descriptor_->index()));
  GenerateGetDescriptorForType(printer);

  // Generate more stuff.
  GenerateCallMethod(printer);
  GenerateGetPrototype(REQUEST, printer);
  GenerateGetPrototype(RESPONSE, printer);
  GenerateStub(printer);
  GenerateBlockingStub(printer);

  // Add an insertion point.
  printer->Print(
      "\n"
      "// @@protoc_insertion_point(class_scope:$full_name$)\n",
      "full_name", descriptor_->full_name());

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

void ImmutableServiceGenerator::GenerateGetDescriptorForType(
    io::Printer* printer) {
  printer->Print(
      "public final com.google.protobuf.Descriptors.ServiceDescriptor\n"
      "    getDescriptorForType() {\n"
      "  return getDescriptor();\n"
      "}\n");
}

void ImmutableServiceGenerator::GenerateInterface(io::Printer* printer) {
  printer->Print("public interface Interface {\n");
  printer->Indent();
  GenerateAbstractMethods(printer);
  printer->Outdent();
  printer->Print("}\n\n");
}

void ImmutableServiceGenerator::GenerateNewReflectiveServiceMethod(
    io::Printer* printer) {
  printer->Print(
      "public static com.google.protobuf.Service newReflectiveService(\n"
      "    final Interface impl) {\n"
      "  return new $classname$() {\n",
      "classname", descriptor_->name());
  printer->Indent();
  printer->Indent();

  for (int i = 0; i < descriptor_->method_count(); i++) {
    const MethodDescriptor* method = descriptor_->method(i);
    printer->Print("@java.lang.Override\n");
    GenerateMethodSignature(printer, method, IS_CONCRETE);
    printer->Print(
        " {\n"
        "  impl.$method$(controller, request, done);\n"
        "}\n\n",
        "method", UnderscoresToCamelCase(method));
  }

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

void ImmutableServiceGenerator::GenerateNewReflectiveBlockingServiceMethod(
    io::Printer* printer) {
  printer->Print(
      "public static com.google.protobuf.BlockingService\n"
      "    newReflectiveBlockingService(final BlockingInterface impl) {\n"
      "  return new com.google.protobuf.BlockingService() {\n");
  printer->Indent();
  printer->Indent();

  GenerateGetDescriptorForType(printer);

  GenerateCallBlockingMethod(printer);
  GenerateGetPrototype(REQUEST, printer);
  GenerateGetPrototype(RESPONSE, printer);

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

void ImmutableServiceGenerator::GenerateAbstractMethods(io::Printer* printer) {
  for (int i = 0; i < descriptor_->method_count(); i++) {
    const MethodDescriptor* method = descriptor_->method(i);
    WriteMethodDocComment(printer, method);
    GenerateMethodSignature(printer, method, IS_ABSTRACT);
    printer->Print(";\n\n");
  }
}

std::string ImmutableServiceGenerator::GetOutput(
    const MethodDescriptor* method) {
  return name_resolver_->GetImmutableClassName(method->output_type());
}

void ImmutableServiceGenerator::GenerateCallMethod(io::Printer* printer) {
  printer->Print(
      "\n"
      "public final void callMethod(\n"
      "    com.google.protobuf.Descriptors.MethodDescriptor method,\n"
      "    com.google.protobuf.RpcController controller,\n"
      "    com.google.protobuf.Message request,\n"
      "    com.google.protobuf.RpcCallback<\n"
      "      com.google.protobuf.Message> done) {\n"
      "  if (method.getService() != getDescriptor()) {\n"
      "    throw new java.lang.IllegalArgumentException(\n"
      "      \"Service.callMethod() given method descriptor for wrong \" +\n"
      "      \"service type.\");\n"
      "  }\n"
      "  switch(method.getIndex()) {\n");
  printer->Indent();
  printer->Indent();

  for (int i = 0; i < descriptor_->method_count(); i++) {
    const MethodDescriptor* method = descriptor_->method(i);
    std::map<std::string, std::string> vars;
    vars["index"] = StrCat(i);
    vars["method"] = UnderscoresToCamelCase(method);
    vars["input"] = name_resolver_->GetImmutableClassName(method->input_type());
    vars["output"] = GetOutput(method);
    printer->Print(
        vars,
        "case $index$:\n"
        "  this.$method$(controller, ($input$)request,\n"
        "    com.google.protobuf.RpcUtil.<$output$>specializeCallback(\n"
        "      done));\n"
        "  return;\n");
  }

  printer->Print(
      "default:\n"
      "  throw new java.lang.AssertionError(\"Can't get here.\");\n");

  printer->Outdent();
  printer->Outdent();

  printer->Print(
      "  }\n"
      "}\n"
      "\n");
}

void ImmutableServiceGenerator::GenerateCallBlockingMethod(
    io::Printer* printer) {
  printer->Print(
      "\n"
      "public final com.google.protobuf.Message callBlockingMethod(\n"
      "    com.google.protobuf.Descriptors.MethodDescriptor method,\n"
      "    com.google.protobuf.RpcController controller,\n"
      "    com.google.protobuf.Message request)\n"
      "    throws com.google.protobuf.ServiceException {\n"
      "  if (method.getService() != getDescriptor()) {\n"
      "    throw new java.lang.IllegalArgumentException(\n"
      "      \"Service.callBlockingMethod() given method descriptor for \" +\n"
      "      \"wrong service type.\");\n"
      "  }\n"
      "  switch(method.getIndex()) {\n");
  printer->Indent();
  printer->Indent();

  for (int i = 0; i < descriptor_->method_count(); i++) {
    const MethodDescriptor* method = descriptor_->method(i);
    std::map<std::string, std::string> vars;
    vars["index"] = StrCat(i);
    vars["method"] = UnderscoresToCamelCase(method);
    vars["input"] = name_resolver_->GetImmutableClassName(method->input_type());
    vars["output"] = GetOutput(method);
    printer->Print(vars,
                   "case $index$:\n"
                   "  return impl.$method$(controller, ($input$)request);\n");
  }

  printer->Print(
      "default:\n"
      "  throw new java.lang.AssertionError(\"Can't get here.\");\n");

  printer->Outdent();
  printer->Outdent();

  printer->Print(
      "  }\n"
      "}\n"
      "\n");
}

void ImmutableServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
                                                     io::Printer* printer) {
  /*
   * TODO(cpovirk): The exception message says "Service.foo" when it may be
   * "BlockingService.foo."  Consider fixing.
   */
  printer->Print(
      "public final com.google.protobuf.Message\n"
      "    get$request_or_response$Prototype(\n"
      "    com.google.protobuf.Descriptors.MethodDescriptor method) {\n"
      "  if (method.getService() != getDescriptor()) {\n"
      "    throw new java.lang.IllegalArgumentException(\n"
      "      \"Service.get$request_or_response$Prototype() given method \" +\n"
      "      \"descriptor for wrong service type.\");\n"
      "  }\n"
      "  switch(method.getIndex()) {\n",
      "request_or_response", (which == REQUEST) ? "Request" : "Response");
  printer->Indent();
  printer->Indent();

  for (int i = 0; i < descriptor_->method_count(); i++) {
    const MethodDescriptor* method = descriptor_->method(i);
    std::map<std::string, std::string> vars;
    vars["index"] = StrCat(i);
    vars["type"] =
        (which == REQUEST)
            ? name_resolver_->GetImmutableClassName(method->input_type())
            : GetOutput(method);
    printer->Print(vars,
                   "case $index$:\n"
                   "  return $type$.getDefaultInstance();\n");
  }

  printer->Print(
      "default:\n"
      "  throw new java.lang.AssertionError(\"Can't get here.\");\n");

  printer->Outdent();
  printer->Outdent();

  printer->Print(
      "  }\n"
      "}\n"
      "\n");
}

void ImmutableServiceGenerator::GenerateStub(io::Printer* printer) {
  printer->Print(
      "public static Stub newStub(\n"
      "    com.google.protobuf.RpcChannel channel) {\n"
      "  return new Stub(channel);\n"
      "}\n"
      "\n"
      "public static final class Stub extends $classname$ implements Interface "
      "{"
      "\n",
      "classname", name_resolver_->GetImmutableClassName(descriptor_));
  printer->Indent();

  printer->Print(
      "private Stub(com.google.protobuf.RpcChannel channel) {\n"
      "  this.channel = channel;\n"
      "}\n"
      "\n"
      "private final com.google.protobuf.RpcChannel channel;\n"
      "\n"
      "public com.google.protobuf.RpcChannel getChannel() {\n"
      "  return channel;\n"
      "}\n");

  for (int i = 0; i < descriptor_->method_count(); i++) {
    const MethodDescriptor* method = descriptor_->method(i);
    printer->Print("\n");
    GenerateMethodSignature(printer, method, IS_CONCRETE);
    printer->Print(" {\n");
    printer->Indent();

    std::map<std::string, std::string> vars;
    vars["index"] = StrCat(i);
    vars["output"] = GetOutput(method);
    printer->Print(vars,
                   "channel.callMethod(\n"
                   "  getDescriptor().getMethods().get($index$),\n"
                   "  controller,\n"
                   "  request,\n"
                   "  $output$.getDefaultInstance(),\n"
                   "  com.google.protobuf.RpcUtil.generalizeCallback(\n"
                   "    done,\n"
                   "    $output$.class,\n"
                   "    $output$.getDefaultInstance()));\n");

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

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

void ImmutableServiceGenerator::GenerateBlockingStub(io::Printer* printer) {
  printer->Print(
      "public static BlockingInterface newBlockingStub(\n"
      "    com.google.protobuf.BlockingRpcChannel channel) {\n"
      "  return new BlockingStub(channel);\n"
      "}\n"
      "\n");

  printer->Print("public interface BlockingInterface {");
  printer->Indent();

  for (int i = 0; i < descriptor_->method_count(); i++) {
    const MethodDescriptor* method = descriptor_->method(i);
    GenerateBlockingMethodSignature(printer, method);
    printer->Print(";\n");
  }

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

  printer->Print(
      "private static final class BlockingStub implements BlockingInterface "
      "{\n");
  printer->Indent();

  printer->Print(
      "private BlockingStub(com.google.protobuf.BlockingRpcChannel channel) {\n"
      "  this.channel = channel;\n"
      "}\n"
      "\n"
      "private final com.google.protobuf.BlockingRpcChannel channel;\n");

  for (int i = 0; i < descriptor_->method_count(); i++) {
    const MethodDescriptor* method = descriptor_->method(i);
    GenerateBlockingMethodSignature(printer, method);
    printer->Print(" {\n");
    printer->Indent();

    std::map<std::string, std::string> vars;
    vars["index"] = StrCat(i);
    vars["output"] = GetOutput(method);
    printer->Print(vars,
                   "return ($output$) channel.callBlockingMethod(\n"
                   "  getDescriptor().getMethods().get($index$),\n"
                   "  controller,\n"
                   "  request,\n"
                   "  $output$.getDefaultInstance());\n");

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

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

void ImmutableServiceGenerator::GenerateMethodSignature(
    io::Printer* printer, const MethodDescriptor* method,
    IsAbstract is_abstract) {
  std::map<std::string, std::string> vars;
  vars["name"] = UnderscoresToCamelCase(method);
  vars["input"] = name_resolver_->GetImmutableClassName(method->input_type());
  vars["output"] = GetOutput(method);
  vars["abstract"] = (is_abstract == IS_ABSTRACT) ? "abstract" : "";
  printer->Print(vars,
                 "public $abstract$ void $name$(\n"
                 "    com.google.protobuf.RpcController controller,\n"
                 "    $input$ request,\n"
                 "    com.google.protobuf.RpcCallback<$output$> done)");
}

void ImmutableServiceGenerator::GenerateBlockingMethodSignature(
    io::Printer* printer, const MethodDescriptor* method) {
  std::map<std::string, std::string> vars;
  vars["method"] = UnderscoresToCamelCase(method);
  vars["input"] = name_resolver_->GetImmutableClassName(method->input_type());
  vars["output"] = GetOutput(method);
  printer->Print(vars,
                 "\n"
                 "public $output$ $method$(\n"
                 "    com.google.protobuf.RpcController controller,\n"
                 "    $input$ request)\n"
                 "    throws com.google.protobuf.ServiceException");
}

}  // namespace java
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
