// 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", SimpleItoa(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");
  }
}

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<string, string> vars;
    vars["index"] = SimpleItoa(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<string, string> vars;
    vars["index"] = SimpleItoa(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<string, string> vars;
    vars["index"] = SimpleItoa(i);
    vars["type"] = name_resolver_->GetImmutableClassName(
      (which == REQUEST) ? method->input_type() : method->output_type());
    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<string, string> vars;
    vars["index"] = SimpleItoa(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<string, string> vars;
    vars["index"] = SimpleItoa(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<string, 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<string, 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
