/*
 * Copyright (C) 2016, The Android Open Source Project
 *
 * 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 "aidl.h"
#include "aidl_language.h"
#include "aidl_to_java.h"
#include "aidl_typenames.h"
#include "ast_java.h"
#include "code_writer.h"
#include "generate_java.h"
#include "logging.h"
#include "options.h"
#include "parser.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <unordered_set>
#include <utility>
#include <vector>

#include <android-base/stringprintf.h>

using android::base::Join;
using android::base::StringPrintf;

using std::string;
using std::unique_ptr;
using std::vector;

namespace android {
namespace aidl {
namespace java {

// =================================================
class VariableFactory {
 public:
  using Variable = ::android::aidl::java::Variable;

  explicit VariableFactory(const std::string& base) : base_(base), index_(0) {}
  std::shared_ptr<Variable> Get(const AidlTypeSpecifier& type) {
    auto v = std::make_shared<Variable>(JavaSignatureOf(type),
                                        StringPrintf("%s%d", base_.c_str(), index_));
    vars_.push_back(v);
    index_++;
    return v;
  }

  std::shared_ptr<Variable> Get(int index) { return vars_[index]; }

 private:
  std::vector<std::shared_ptr<Variable>> vars_;
  std::string base_;
  int index_;
};

// =================================================
class StubClass : public Class {
 public:
  StubClass(const AidlInterface* interfaceType, const Options& options);
  ~StubClass() override = default;

  // non-copyable, non-movable
  StubClass(const StubClass&) = delete;
  StubClass(StubClass&&) = delete;
  StubClass& operator=(const StubClass&) = delete;
  StubClass& operator=(StubClass&&) = delete;

  std::shared_ptr<Variable> transact_code;
  std::shared_ptr<Variable> transact_data;
  std::shared_ptr<Variable> transact_reply;
  std::shared_ptr<Variable> transact_flags;
  std::shared_ptr<SwitchStatement> transact_switch_meta;
  std::shared_ptr<SwitchStatement> transact_switch_user;
  std::shared_ptr<StatementBlock> transact_statements;
  std::shared_ptr<SwitchStatement> code_to_method_name_switch;

  // Where onTransact cases should be generated as separate methods.
  bool transact_outline;
  // Specific methods that should be outlined when transact_outline is true.
  std::unordered_set<const AidlMethod*> outline_methods;
  // Number of all methods.
  size_t all_method_count;

  // Finish generation. This will add a default case to the switch.
  void Finish();

  std::shared_ptr<Expression> GetTransactDescriptor(const AidlMethod* method);

 private:
  void MakeConstructors(const AidlInterface* interfaceType);
  void MakeAsInterface(const AidlInterface* interfaceType);

  std::shared_ptr<Variable> transact_descriptor;
  const Options& options_;
};

StubClass::StubClass(const AidlInterface* interfaceType, const Options& options)
    : Class(), options_(options) {
  transact_descriptor = nullptr;
  transact_outline = false;
  all_method_count = 0;  // Will be set when outlining may be enabled.

  this->comment = "/** Local-side IPC implementation stub class. */";
  this->modifiers = PUBLIC | ABSTRACT | STATIC;
  this->what = Class::CLASS;
  this->type = interfaceType->GetCanonicalName() + ".Stub";
  this->extends = "android.os.Binder";
  this->interfaces.push_back(interfaceType->GetCanonicalName());

  MakeConstructors(interfaceType);
  MakeAsInterface(interfaceType);

  // asBinder
  auto asBinder = std::make_shared<Method>();
  asBinder->modifiers = PUBLIC | OVERRIDE;
  asBinder->returnType = "android.os.IBinder";
  asBinder->name = "asBinder";
  asBinder->statements = std::make_shared<StatementBlock>();
  asBinder->statements->Add(std::make_shared<ReturnStatement>(THIS_VALUE));
  this->elements.push_back(asBinder);

  if (options_.GenTransactionNames() || options_.GenTraces()) {
    // getDefaultTransactionName
    auto getDefaultTransactionName = std::make_shared<Method>();
    getDefaultTransactionName->comment = "/** @hide */";
    getDefaultTransactionName->modifiers = PUBLIC | STATIC;
    getDefaultTransactionName->returnType = "java.lang.String";
    getDefaultTransactionName->name = "getDefaultTransactionName";
    auto code = std::make_shared<Variable>("int", "transactionCode");
    getDefaultTransactionName->parameters.push_back(code);
    getDefaultTransactionName->statements = std::make_shared<StatementBlock>();
    this->code_to_method_name_switch = std::make_shared<SwitchStatement>(code);
    getDefaultTransactionName->statements->Add(this->code_to_method_name_switch);
    this->elements.push_back(getDefaultTransactionName);

    // getTransactionName
    auto getTransactionName = std::make_shared<Method>();
    getTransactionName->comment = "/** @hide */";
    getTransactionName->modifiers = PUBLIC;
    getTransactionName->returnType = "java.lang.String";
    getTransactionName->name = "getTransactionName";
    auto code2 = std::make_shared<Variable>("int", "transactionCode");
    getTransactionName->parameters.push_back(code2);
    getTransactionName->statements = std::make_shared<StatementBlock>();
    getTransactionName->statements->Add(std::make_shared<ReturnStatement>(
        std::make_shared<MethodCall>(THIS_VALUE, "getDefaultTransactionName",
                                     std::vector<std::shared_ptr<Expression>>{code2})));
    this->elements.push_back(getTransactionName);
  }

  // onTransact
  this->transact_code = std::make_shared<Variable>("int", "code");
  this->transact_data = std::make_shared<Variable>("android.os.Parcel", "data");
  this->transact_reply = std::make_shared<Variable>("android.os.Parcel", "reply");
  this->transact_flags = std::make_shared<Variable>("int", "flags");
  auto onTransact = std::make_shared<Method>();
  onTransact->modifiers = PUBLIC | OVERRIDE;
  onTransact->returnType = "boolean";
  onTransact->name = "onTransact";
  onTransact->parameters.push_back(this->transact_code);
  onTransact->parameters.push_back(this->transact_data);
  onTransact->parameters.push_back(this->transact_reply);
  onTransact->parameters.push_back(this->transact_flags);
  onTransact->statements = std::make_shared<StatementBlock>();
  transact_statements = onTransact->statements;
  onTransact->exceptions.push_back("android.os.RemoteException");
  this->elements.push_back(onTransact);
  this->transact_switch_meta = std::make_shared<SwitchStatement>(this->transact_code);
  this->transact_switch_user = std::make_shared<SwitchStatement>(this->transact_code);
}

void StubClass::Finish() {
  auto default_case = std::make_shared<Case>();

  auto superCall = std::make_shared<MethodCall>(
      SUPER_VALUE, "onTransact",
      std::vector<std::shared_ptr<Expression>>{this->transact_code, this->transact_data,
                                               this->transact_reply, this->transact_flags});
  default_case->statements->Add(std::make_shared<ReturnStatement>(superCall));

  auto case_count = transact_switch_user->cases.size();
  transact_switch_user->cases.push_back(default_case);

  // Interface token validation is done for user-defined transactions.
  if (case_count > 0) {
    auto ifStatement = std::make_shared<IfStatement>();
    ifStatement->expression = std::make_shared<LiteralExpression>(
        "code >= android.os.IBinder.FIRST_CALL_TRANSACTION && "
        "code <= android.os.IBinder.LAST_CALL_TRANSACTION");
    ifStatement->statements = std::make_shared<StatementBlock>();
    ifStatement->statements->Add(std::make_shared<MethodCall>(
        this->transact_data, "enforceInterface",
        std::vector<std::shared_ptr<Expression>>{this->GetTransactDescriptor(nullptr)}));
    transact_statements->Add(ifStatement);
  }

  // Meta transactions are looked up prior to user-defined transactions.
  transact_statements->Add(this->transact_switch_meta);
  transact_statements->Add(this->transact_switch_user);

  // getTransactionName
  if (options_.GenTransactionNames() || options_.GenTraces()) {
    // Some transaction codes are common, e.g. INTERFACE_TRANSACTION or DUMP_TRANSACTION.
    // Common transaction codes will not be resolved to a string by getTransactionName. The method
    // will return NULL in this case.
    auto code_switch_default_case = std::make_shared<Case>();
    code_switch_default_case->statements->Add(std::make_shared<ReturnStatement>(NULL_VALUE));
    this->code_to_method_name_switch->cases.push_back(code_switch_default_case);
  }

  // There will be at least one statement for the default, but if we emit a
  // return true after that default, it will be unreachable.
  if (case_count > 0) {
    transact_statements->Add(std::make_shared<ReturnStatement>(TRUE_VALUE));
  }
}

// The the expression for the interface's descriptor to be used when
// generating code for the given method. Null is acceptable for method
// and stands for synthetic cases.
std::shared_ptr<Expression> StubClass::GetTransactDescriptor(const AidlMethod* method) {
  if (transact_outline) {
    if (method != nullptr) {
      // When outlining, each outlined method needs its own literal.
      if (outline_methods.count(method) != 0) {
        return std::make_shared<LiteralExpression>("DESCRIPTOR");
      }
    } else {
      // Synthetic case. A small number is assumed. Use its own descriptor
      // if there are only synthetic cases.
      if (outline_methods.size() == all_method_count) {
        return std::make_shared<LiteralExpression>("DESCRIPTOR");
      }
    }
  }

  // When not outlining, store the descriptor literal into a local variable, in
  // an effort to save const-string instructions in each switch case.
  if (transact_descriptor == nullptr) {
    transact_descriptor = std::make_shared<Variable>("java.lang.String", "descriptor");
    transact_statements->Add(std::make_shared<VariableDeclaration>(
        transact_descriptor, std::make_shared<LiteralExpression>("DESCRIPTOR")));
  }
  return transact_descriptor;
}

void StubClass::MakeConstructors(const AidlInterface* interfaceType) {
  string ctors_code;
  CodeWriterPtr writer = CodeWriter::ForString(&ctors_code);
  CodeWriter& code = *writer;

  if (interfaceType->UsesPermissions()) {
    code << "private final android.os.PermissionEnforcer mEnforcer;\n";
    code << "/** Construct the stub using the Enforcer provided. */\n";
    code << "public Stub(android.os.PermissionEnforcer enforcer)\n";
  } else {
    code << "/** Construct the stub at attach it to the interface. */\n";
    code << "public Stub()\n";
  }
  code << "{\n";
  code.Indent();
  if (interfaceType->IsVintfStability()) {
    code << "this.markVintfStability();\n";
  }
  code << "this.attachInterface(this, DESCRIPTOR);\n";
  if (interfaceType->UsesPermissions()) {
    code << "if (enforcer == null) {\n";
    code.Indent();
    code << "throw new IllegalArgumentException(\"enforcer cannot be null\");\n";
    code.Dedent();
    code << "}\n";
    code << "mEnforcer = enforcer;\n";
  }
  code.Dedent();
  code << "}\n";

  // Setup a default constructor for permissions interfaces.
  if (interfaceType->UsesPermissions()) {
    code << "@Deprecated\n";
    code << "/** Default constructor. */\n";
    code << "public Stub() {\n";
    code.Indent();
    code << "this(android.os.PermissionEnforcer.fromContext(\n";
    code << "   android.app.ActivityThread.currentActivityThread().getSystemContext()));\n";
    code.Dedent();
    code << "}\n";
  }

  code.Close();
  this->elements.push_back(std::make_shared<LiteralClassElement>(ctors_code));
}

void StubClass::MakeAsInterface(const AidlInterface* interfaceType) {
  auto obj = std::make_shared<Variable>("android.os.IBinder", "obj");

  auto m = std::make_shared<Method>();
  m->comment = "/**\n * Cast an IBinder object into an ";
  m->comment += interfaceType->GetCanonicalName();
  m->comment += " interface,\n";
  m->comment += " * generating a proxy if needed.\n */";
  m->modifiers = PUBLIC | STATIC;
  m->returnType = interfaceType->GetCanonicalName();
  m->name = "asInterface";
  m->parameters.push_back(obj);
  m->statements = std::make_shared<StatementBlock>();

  auto ifstatement = std::make_shared<IfStatement>();
  ifstatement->expression = std::make_shared<Comparison>(obj, "==", NULL_VALUE);
  ifstatement->statements = std::make_shared<StatementBlock>();
  ifstatement->statements->Add(std::make_shared<ReturnStatement>(NULL_VALUE));
  m->statements->Add(ifstatement);

  // IInterface iin = obj.queryLocalInterface(DESCRIPTOR)
  auto queryLocalInterface = std::make_shared<MethodCall>(obj, "queryLocalInterface");
  queryLocalInterface->arguments.push_back(std::make_shared<LiteralExpression>("DESCRIPTOR"));
  auto iin = std::make_shared<Variable>("android.os.IInterface", "iin");
  auto iinVd = std::make_shared<VariableDeclaration>(iin, queryLocalInterface);
  m->statements->Add(iinVd);

  // Ensure the instance type of the local object is as expected.
  // One scenario where this is needed is if another package (with a
  // different class loader) runs in the same process as the service.

  // if (iin != null && iin instanceof <interfaceType>) return (<interfaceType>)
  // iin;
  auto iinNotNull = std::make_shared<Comparison>(iin, "!=", NULL_VALUE);
  auto instOfCheck = std::make_shared<Comparison>(
      iin, " instanceof ", std::make_shared<LiteralExpression>(interfaceType->GetCanonicalName()));
  auto instOfStatement = std::make_shared<IfStatement>();
  instOfStatement->expression = std::make_shared<Comparison>(iinNotNull, "&&", instOfCheck);
  instOfStatement->statements = std::make_shared<StatementBlock>();
  instOfStatement->statements->Add(std::make_shared<ReturnStatement>(
      std::make_shared<Cast>(interfaceType->GetCanonicalName(), iin)));
  m->statements->Add(instOfStatement);

  auto ne = std::make_shared<NewExpression>(interfaceType->GetCanonicalName() + ".Stub.Proxy");
  ne->arguments.push_back(obj);
  m->statements->Add(std::make_shared<ReturnStatement>(ne));

  this->elements.push_back(m);
}

// =================================================
class ProxyClass : public Class {
 public:
  ProxyClass(const AidlInterface* interfaceType, const Options& options);
  ~ProxyClass() override;

  std::shared_ptr<Variable> mRemote;
};

ProxyClass::ProxyClass(const AidlInterface* interfaceType, const Options& options) : Class() {
  this->modifiers = PRIVATE | STATIC;
  this->what = Class::CLASS;
  this->type = interfaceType->GetCanonicalName() + ".Stub.Proxy";
  this->interfaces.push_back(interfaceType->GetCanonicalName());

  // IBinder mRemote
  mRemote = std::make_shared<Variable>("android.os.IBinder", "mRemote");
  this->elements.push_back(std::make_shared<Field>(PRIVATE, mRemote));

  // Proxy()
  auto remote = std::make_shared<Variable>("android.os.IBinder", "remote");
  auto ctor = std::make_shared<Method>();
  ctor->name = "Proxy";
  ctor->statements = std::make_shared<StatementBlock>();
  ctor->parameters.push_back(remote);
  ctor->statements->Add(std::make_shared<Assignment>(mRemote, remote));
  this->elements.push_back(ctor);

  if (options.Version() > 0) {
    std::ostringstream code;
    code << "private int mCachedVersion = -1;\n";
    this->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
  }
  if (!options.Hash().empty()) {
    std::ostringstream code;
    code << "private String mCachedHash = \"-1\";\n";
    this->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
  }

  // IBinder asBinder()
  auto asBinder = std::make_shared<Method>();
  asBinder->modifiers = PUBLIC | OVERRIDE;
  asBinder->returnType = "android.os.IBinder";
  asBinder->name = "asBinder";
  asBinder->statements = std::make_shared<StatementBlock>();
  asBinder->statements->Add(std::make_shared<ReturnStatement>(mRemote));
  this->elements.push_back(asBinder);
}

ProxyClass::~ProxyClass() {}

// =================================================

static void GenerateWriteToParcel(CodeWriter& out, const AidlTypenames& typenames,
                                  const AidlTypeSpecifier& type, const std::string& parcel,
                                  const std::string& var, uint32_t min_sdk_version,
                                  bool is_return_value) {
  WriteToParcelFor(CodeGeneratorContext{
      .writer = out,
      .typenames = typenames,
      .type = type,
      .parcel = parcel,
      .var = var,
      .min_sdk_version = min_sdk_version,
      .write_to_parcel_flag =
          is_return_value ? "android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE" : "0",
  });
}

static void GenerateWriteToParcel(std::shared_ptr<StatementBlock> addTo,
                                  const AidlTypenames& typenames, const AidlTypeSpecifier& type,
                                  const std::string& parcel, const std::string& var,
                                  uint32_t min_sdk_version, bool is_return_value) {
  string code;
  GenerateWriteToParcel(*CodeWriter::ForString(&code), typenames, type, parcel, var,
                        min_sdk_version, is_return_value);
  addTo->Add(std::make_shared<LiteralStatement>(code));
}

void GenerateConstantDeclarations(CodeWriter& out, const AidlDefinedType& type) {
  for (const auto& constant : type.GetConstantDeclarations()) {
    const AidlTypeSpecifier& type = constant->GetType();
    out << GenerateComments(*constant);
    out << GenerateAnnotations(*constant);
    out << "public static final " << type.Signature() << " " << constant->GetName() << " = "
        << constant->ValueString(ConstantValueDecorator) << ";\n";
  }
}

static std::shared_ptr<Method> GenerateInterfaceMethod(const AidlInterface& iface,
                                                       const AidlMethod& method) {
  auto decl = std::make_shared<Method>();
  decl->comment = GenerateComments(method);
  decl->modifiers = PUBLIC;
  decl->returnType = JavaSignatureOf(method.GetType());
  decl->name = method.GetName();
  decl->annotations = JavaAnnotationsFor(method);
  // If the interface has some permission annotation, add it to the method.
  if (auto iface_annotation = JavaPermissionAnnotation(iface); iface_annotation) {
    decl->annotations.push_back(*iface_annotation);
  }

  for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
    auto var = std::make_shared<Variable>(JavaSignatureOf(arg->GetType()), arg->GetName());
    var->annotations = JavaAnnotationsFor(arg->GetType());
    decl->parameters.push_back(var);
  }

  decl->exceptions.push_back("android.os.RemoteException");

  return decl;
}

// Visitor for the permission declared in the @EnforcePermission annotation.
class PermissionVisitor {
 public:
  PermissionVisitor(CodeWriter* code, const AidlMethod& method) : code_(code), method_(method) {}

  ~PermissionVisitor() {
    code_->Dedent();
    *code_ << "}\n";
  }

  string Credentials() const { return "getCallingPid(), getCallingUid()"; }

  void Prologue() {
    *code_ << "/** Helper method to enforce permissions for " << method_.GetName() << " */\n";
    *code_ << "protected void " << method_.GetName() << "_enforcePermission() "
           << "throws SecurityException {\n";
    code_->Indent();
  }

  void AddStaticArrayPermissions(const std::vector<std::string>& permissions) {
    *code_ << "static final String[] PERMISSIONS_" << method_.GetName() << " = {"
           << Join(permissions, ", ") << "};\n";
  }

  void operator()(const perm::AllOf& quantifier) {
    std::vector<std::string> permissions;
    permissions.reserve(quantifier.operands.size());
    for (auto const& permission : quantifier.operands) {
      permissions.push_back(android::aidl::perm::JavaFullName(permission));
    }
    AddStaticArrayPermissions(permissions);
    Prologue();
    *code_ << "mEnforcer.enforcePermissionAllOf(PERMISSIONS_" << method_.GetName() << ", "
           << Credentials() << ");\n";
  }

  void operator()(const perm::AnyOf& quantifier) {
    std::vector<std::string> permissions;
    permissions.reserve(quantifier.operands.size());
    for (auto const& permission : quantifier.operands) {
      permissions.push_back(android::aidl::perm::JavaFullName(permission));
    }
    AddStaticArrayPermissions(permissions);
    Prologue();
    *code_ << "mEnforcer.enforcePermissionAnyOf(PERMISSIONS_" << method_.GetName() << ", "
           << Credentials() << ");\n";
  }

  void operator()(const std::string& permission) {
    auto permissionName = android::aidl::perm::JavaFullName(permission);
    Prologue();
    *code_ << "mEnforcer.enforcePermission(" << permissionName << ", " << Credentials() << ");\n";
  }

 private:
  CodeWriter* code_;
  const AidlMethod& method_;
};

static void GeneratePermissionMethod(const AidlInterface& iface, const AidlMethod& method,
                                     const std::shared_ptr<Class>& addTo) {
  string code;
  CodeWriterPtr writer = CodeWriter::ForString(&code);

  if (auto ifacePermExpr = iface.EnforceExpression(); ifacePermExpr) {
    std::visit(PermissionVisitor(writer.get(), method), *ifacePermExpr.get());
  } else if (auto methodPermExpr = method.GetType().EnforceExpression(); methodPermExpr) {
    std::visit(PermissionVisitor(writer.get(), method), *methodPermExpr.get());
  }
  writer->Close();
  addTo->elements.push_back(std::make_shared<LiteralClassElement>(code));
}

static void GenerateStubCode(const AidlMethod& method, bool oneway,
                             std::shared_ptr<Variable> transact_data,
                             std::shared_ptr<Variable> transact_reply,
                             const AidlTypenames& typenames,
                             std::shared_ptr<StatementBlock> statement_block,
                             const Options& options) {
  // try and finally
  auto& statements = statement_block;

  auto realCall = std::make_shared<MethodCall>(THIS_VALUE, method.GetName());

  // args
  VariableFactory stubArgs("_arg");
  {
    // keep this across different args in order to create the classloader
    // at most once.
    bool is_classloader_created = false;
    for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
      std::shared_ptr<Variable> v = stubArgs.Get(arg->GetType());

      statements->Add(std::make_shared<VariableDeclaration>(v));

      string code;
      CodeWriterPtr writer = CodeWriter::ForString(&code);
      if (arg->GetDirection() & AidlArgument::IN_DIR) {
        // "in/inout" parameter should be created from parcel.
        CodeGeneratorContext context{.writer = *(writer.get()),
                                     .typenames = typenames,
                                     .type = arg->GetType(),
                                     .parcel = transact_data->name,
                                     .var = v->name,
                                     .min_sdk_version = options.GetMinSdkVersion(),
                                     .is_classloader_created = &is_classloader_created};
        CreateFromParcelFor(context);
      } else {
        // "out" parameter should be instantiated before calling the real impl.
        string java_type = InstantiableJavaSignatureOf(arg->GetType());

        if (arg->GetType().IsDynamicArray()) {
          // dynamic array should be created with a passed length.
          string var_length = v->name + "_length";
          (*writer) << "int " << var_length << " = data.readInt();\n";
          (*writer) << "if (" << var_length << " < 0) {\n";
          (*writer) << "  " << v->name << " = null;\n";
          (*writer) << "} else {\n";
          (*writer) << "  " << v->name << " = new " << java_type << "[" << var_length << "];\n";
          (*writer) << "}\n";
        } else if (arg->GetType().IsFixedSizeArray()) {
          // fixed-size array can be created with a known size
          string dimensions;
          for (auto dim : arg->GetType().GetFixedSizeArrayDimensions()) {
            dimensions += "[" + std::to_string(dim) + "]";
          }
          (*writer) << v->name << " = new " << java_type << dimensions << ";\n";
        } else {
          // otherwise, create a new instance with a default constructor
          (*writer) << v->name << " = new " << java_type << "();\n";
        }
      }
      writer->Close();
      statements->Add(std::make_shared<LiteralStatement>(code));

      realCall->arguments.push_back(v);
    }
  }

  // EOF check
  if (!method.GetArguments().empty() && options.GetMinSdkVersion() > 32u) {
    statements->Add(std::make_shared<MethodCall>(transact_data, "enforceNoDataAvail"));
  }

  // the real call
  if (method.GetType().GetName() == "void") {
    statements->Add(realCall);

    if (!oneway) {
      // report that there were no exceptions
      auto ex = std::make_shared<MethodCall>(transact_reply, "writeNoException");
      statements->Add(ex);
    }
  } else {
    auto _result = std::make_shared<Variable>(JavaSignatureOf(method.GetType()), "_result");
    statements->Add(std::make_shared<VariableDeclaration>(_result, realCall));

    if (!oneway) {
      // report that there were no exceptions
      auto ex = std::make_shared<MethodCall>(transact_reply, "writeNoException");
      statements->Add(ex);
    }

    // marshall the return value
    GenerateWriteToParcel(statements, typenames, method.GetType(), transact_reply->name,
                          _result->name, options.GetMinSdkVersion(), /*is_return_value=*/true);
  }

  // out parameters
  int i = 0;
  for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
    std::shared_ptr<Variable> v = stubArgs.Get(i++);
    if (arg->GetDirection() & AidlArgument::OUT_DIR) {
      GenerateWriteToParcel(statements, typenames, arg->GetType(), transact_reply->name, v->name,
                            options.GetMinSdkVersion(), /*is_return_value=*/true);
    }
  }
}

static void GenerateStubCase(const AidlMethod& method, const std::string& transactCodeName,
                             bool oneway, const std::shared_ptr<StubClass>& stubClass,
                             const AidlTypenames& typenames, const Options& options) {
  auto c = std::make_shared<Case>(transactCodeName);

  GenerateStubCode(method, oneway, stubClass->transact_data, stubClass->transact_reply, typenames,
                   c->statements, options);
  c->statements->Add(std::make_shared<BreakStatement>());

  stubClass->transact_switch_user->cases.push_back(c);
}

static void GenerateStubCaseOutline(const AidlMethod& method, const std::string& transactCodeName,
                                    bool oneway, const std::shared_ptr<StubClass>& stubClass,
                                    const AidlTypenames& typenames, const Options& options) {
  std::string outline_name = "onTransact$" + method.GetName() + "$";
  // Generate an "outlined" method with the actual code.
  {
    auto transact_data = std::make_shared<Variable>("android.os.Parcel", "data");
    auto transact_reply = std::make_shared<Variable>("android.os.Parcel", "reply");
    auto onTransact_case = std::make_shared<Method>();
    onTransact_case->modifiers = PRIVATE;
    onTransact_case->returnType = "boolean";
    onTransact_case->name = outline_name;
    onTransact_case->parameters.push_back(transact_data);
    onTransact_case->parameters.push_back(transact_reply);
    onTransact_case->statements = std::make_shared<StatementBlock>();
    onTransact_case->exceptions.push_back("android.os.RemoteException");
    stubClass->elements.push_back(onTransact_case);

    GenerateStubCode(method, oneway, transact_data, transact_reply, typenames,
                     onTransact_case->statements, options);
    onTransact_case->statements->Add(std::make_shared<ReturnStatement>(TRUE_VALUE));
  }

  // Generate the case dispatch.
  {
    auto c = std::make_shared<Case>(transactCodeName);

    auto helper_call =
        std::make_shared<MethodCall>(THIS_VALUE, outline_name,
                                     std::vector<std::shared_ptr<Expression>>{
                                         stubClass->transact_data, stubClass->transact_reply});
    c->statements->Add(std::make_shared<ReturnStatement>(helper_call));

    stubClass->transact_switch_user->cases.push_back(c);
  }
}

template <typename Formatter>
static std::string ArgList(const AidlMethod& method, Formatter formatter) {
  vector<string> args;
  for (const auto& arg : method.GetArguments()) {
    args.push_back(std::invoke(formatter, *arg));
  }
  return Join(args, ", ");
}

static std::string FormatArgForDecl(const AidlArgument& arg) {
  return JavaSignatureOf(arg.GetType()) + " " + arg.GetName();
}

static void GenerateProxyMethod(CodeWriter& out, const AidlInterface& iface,
                                const AidlMethod& method, const std::string& transactCodeName,
                                bool oneway, const AidlTypenames& typenames,
                                const Options& options) {
  bool is_void = method.GetType().GetName() == "void";

  out << GenerateComments(method);
  out << "@Override public " << JavaSignatureOf(method.GetType()) << " " << method.GetName() << "("
      << ArgList(method, FormatArgForDecl) << ") throws android.os.RemoteException\n{\n";
  out.Indent();

  // the parcels
  if (options.GenRpc()) {
    out << "android.os.Parcel _data = android.os.Parcel.obtain(asBinder());\n";
  } else {
    out << "android.os.Parcel _data = android.os.Parcel.obtain();\n";
  }

  if (iface.IsSensitiveData()) {
    out << "_data.markSensitive();\n";
  }

  if (!oneway) {
    out << "android.os.Parcel _reply = android.os.Parcel.obtain();\n";
  }

  // the return value
  if (!is_void) {
    out << JavaSignatureOf(method.GetType()) << " _result;\n";
  }

  out << "try {\n";
  out.Indent();

  // the interface identifier token: the DESCRIPTOR constant, marshalled as a
  // string
  out << "_data.writeInterfaceToken(DESCRIPTOR);\n";

  // the parameters
  for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
    AidlArgument::Direction dir = arg->GetDirection();
    if (dir == AidlArgument::OUT_DIR && arg->GetType().IsDynamicArray()) {
      // In Java we pass a pre-allocated array for an 'out' argument. For transaction,
      // we pass the size of the array so that the remote can allocate the array with the same size.
      out << "_data.writeInt(" << arg->GetName() << ".length);\n";
    } else if (dir & AidlArgument::IN_DIR) {
      GenerateWriteToParcel(out, typenames, arg->GetType(), "_data", arg->GetName(),
                            options.GetMinSdkVersion(), /*is_return_value=*/false);
    }
  }

  std::vector<std::string> flags;
  if (oneway) flags.push_back("android.os.IBinder.FLAG_ONEWAY");
  if (iface.IsSensitiveData()) flags.push_back("android.os.IBinder.FLAG_CLEAR_BUF");

  // the transact call
  out << "boolean _status = mRemote.transact(Stub." << transactCodeName << ", _data, "
      << (oneway ? "null" : "_reply") << ", " << (flags.empty() ? "0" : Join(flags, " | "))
      << ");\n";

  // TODO(b/151102494): annotation is applied on the return type
  if (method.GetType().IsPropagateAllowBlocking() && !oneway) {
    if (options.GetMinSdkVersion() < JAVA_PROPAGATE_VERSION) {
      out << "if (android.os.Build.VERSION.SDK_INT >= " + std::to_string(JAVA_PROPAGATE_VERSION) +
                 ") { _reply.setPropagateAllowBlocking(); }\n";
    } else {
      out << "_reply.setPropagateAllowBlocking();\n";
    }
  }

  // If the transaction returns false, which means UNKNOWN_TRANSACTION, fall back to the local
  // method in the default impl, if set before. Otherwise, throw a RuntimeException if the interface
  // is versioned. We can't throw the exception for unversioned interface because that would be an
  // app breaking change.
  if (iface.IsJavaDefault() || options.Version() > 0) {
    out << "if (!_status) {\n";
    out.Indent();

    if (iface.IsJavaDefault()) {
      out << "if (getDefaultImpl() != null) {\n";
      out.Indent();
      if (is_void) {
        out << "getDefaultImpl()." << method.GetName() << "("
            << ArgList(method, &AidlArgument::GetName) << ");\n";
        out << "return;\n";
      } else {
        out << "return getDefaultImpl()." << method.GetName() << "("
            << ArgList(method, &AidlArgument::GetName) << ");\n";
      }
      out.Dedent();
      out << "}\n";
    }

    // TODO(b/274144762): we shouldn't have different behavior for versioned interfaces
    // also this set to false for all exceptions, not just unimplemented methods.
    if (options.Version() > 0) {
      out << "throw new android.os.RemoteException(\"Method " << method.GetName()
          << " is unimplemented.\");\n";
    }

    out.Dedent();
    out << "}\n";
  }

  if (!oneway) {
    // keep this across return value and arguments in order to create the
    // classloader at most once.
    bool is_classloader_created = false;

    // throw back exceptions.
    out << "_reply.readException();\n";

    if (!is_void) {
      CreateFromParcelFor(CodeGeneratorContext{.writer = out,
                                               .typenames = typenames,
                                               .type = method.GetType(),
                                               .parcel = "_reply",
                                               .var = "_result",
                                               .min_sdk_version = options.GetMinSdkVersion(),
                                               .is_classloader_created = &is_classloader_created});
    }

    // the out/inout parameters
    for (const std::unique_ptr<AidlArgument>& arg : method.GetArguments()) {
      if (arg->GetDirection() & AidlArgument::OUT_DIR) {
        ReadFromParcelFor(CodeGeneratorContext{.writer = out,
                                               .typenames = typenames,
                                               .type = arg->GetType(),
                                               .parcel = "_reply",
                                               .var = arg->GetName(),
                                               .min_sdk_version = options.GetMinSdkVersion(),
                                               .is_classloader_created = &is_classloader_created});
      }
    }
  }

  out.Dedent();
  out << "}\nfinally {\n";
  out.Indent();

  // returning and cleanup
  if (!oneway) {
    out << "_reply.recycle();\n";
  }
  out << "_data.recycle();\n";

  out.Dedent();
  out << "}\n";  // finally

  if (!is_void) {
    out << "return _result;\n";
  }

  out.Dedent();
  out << "}\n";  // method body
}

static void GenerateMethods(const AidlInterface& iface, const AidlMethod& method, Class* interface,
                            std::shared_ptr<StubClass> stubClass,
                            std::shared_ptr<ProxyClass> proxyClass, int index,
                            const AidlTypenames& typenames, const Options& options) {
  const bool oneway = method.IsOneway();

  // == the TRANSACT_ constant =============================================
  string transactCodeName = "TRANSACTION_";
  transactCodeName += method.GetName();

  auto transactCode =
      std::make_shared<Field>(STATIC | FINAL, std::make_shared<Variable>("int", transactCodeName));
  transactCode->value =
      StringPrintf("(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index);
  stubClass->elements.push_back(transactCode);

  // getTransactionName
  if (options.GenTransactionNames() || options.GenTraces()) {
    auto c = std::make_shared<Case>(transactCodeName);
    c->statements->Add(std::make_shared<ReturnStatement>(
        std::make_shared<StringLiteralExpression>(method.GetName())));
    stubClass->code_to_method_name_switch->cases.push_back(c);
  }

  // == the declaration in the interface ===================================
  std::shared_ptr<ClassElement> decl;
  if (method.IsUserDefined()) {
    decl = GenerateInterfaceMethod(iface, method);
  } else {
    if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
      std::ostringstream code;
      code << "public int " << kGetInterfaceVersion << "() "
           << "throws android.os.RemoteException;\n";
      decl = std::make_shared<LiteralClassElement>(code.str());
    }
    if (method.GetName() == kGetInterfaceHash && !options.Hash().empty()) {
      std::ostringstream code;
      code << "public String " << kGetInterfaceHash << "() "
           << "throws android.os.RemoteException;\n";
      decl = std::make_shared<LiteralClassElement>(code.str());
    }
  }
  interface->elements.push_back(decl);

  // == the stub method ====================================================
  if (method.IsUserDefined()) {
    bool outline_stub =
        stubClass->transact_outline && stubClass->outline_methods.count(&method) != 0;
    if (outline_stub) {
      GenerateStubCaseOutline(method, transactCodeName, oneway, stubClass, typenames, options);
    } else {
      GenerateStubCase(method, transactCodeName, oneway, stubClass, typenames, options);
    }
    if (iface.EnforceExpression() || method.GetType().EnforceExpression()) {
      GeneratePermissionMethod(iface, method, stubClass);
    }
  } else {
    if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
      auto c = std::make_shared<Case>(transactCodeName);
      std::ostringstream code;
      code << "reply.writeNoException();\n"
           << "reply.writeInt(" << kGetInterfaceVersion << "());\n"
           << "return true;\n";
      c->statements->Add(std::make_shared<LiteralStatement>(code.str()));
      stubClass->transact_switch_meta->cases.push_back(c);
    }
    if (method.GetName() == kGetInterfaceHash && !options.Hash().empty()) {
      auto c = std::make_shared<Case>(transactCodeName);
      std::ostringstream code;
      code << "reply.writeNoException();\n"
           << "reply.writeString(" << kGetInterfaceHash << "());\n"
           << "return true;\n";
      c->statements->Add(std::make_shared<LiteralStatement>(code.str()));
      stubClass->transact_switch_meta->cases.push_back(c);
    }
  }

  // == the proxy method ===================================================
  string proxy_code;
  CodeWriterPtr writer = CodeWriter::ForString(&proxy_code);
  CodeWriter& code = *writer;
  if (method.IsUserDefined()) {
    GenerateProxyMethod(code, iface, method, transactCodeName, oneway, typenames, options);
  } else {
    if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
      code << "@Override\n"
           << "public int " << kGetInterfaceVersion << "()"
           << " throws "
           << "android.os.RemoteException {\n"
           << "  if (mCachedVersion == -1) {\n";
      if (options.GenRpc()) {
        code << "    android.os.Parcel data = android.os.Parcel.obtain(asBinder());\n";
      } else {
        code << "    android.os.Parcel data = android.os.Parcel.obtain();\n";
      }
      code << "    android.os.Parcel reply = android.os.Parcel.obtain();\n"
           << "    try {\n"
           << "      data.writeInterfaceToken(DESCRIPTOR);\n"
           << "      boolean _status = mRemote.transact(Stub." << transactCodeName << ", "
           << "data, reply, 0);\n";
      if (iface.IsJavaDefault()) {
        code << "      if (!_status) {\n"
             << "        if (getDefaultImpl() != null) {\n"
             << "          return getDefaultImpl().getInterfaceVersion();\n"
             << "        }\n"
             << "      }\n";
      }
      code << "      reply.readException();\n"
           << "      mCachedVersion = reply.readInt();\n"
           << "    } finally {\n"
           << "      reply.recycle();\n"
           << "      data.recycle();\n"
           << "    }\n"
           << "  }\n"
           << "  return mCachedVersion;\n"
           << "}\n";
    }
    if (method.GetName() == kGetInterfaceHash && !options.Hash().empty()) {
      code << "@Override\n"
           << "public synchronized String " << kGetInterfaceHash << "()"
           << " throws "
           << "android.os.RemoteException {\n"
           << "  if (\"-1\".equals(mCachedHash)) {\n";
      if (options.GenRpc()) {
        code << "    android.os.Parcel data = android.os.Parcel.obtain(asBinder());\n";
      } else {
        code << "    android.os.Parcel data = android.os.Parcel.obtain();\n";
      }
      code << "    android.os.Parcel reply = android.os.Parcel.obtain();\n"
           << "    try {\n"
           << "      data.writeInterfaceToken(DESCRIPTOR);\n"
           << "      boolean _status = mRemote.transact(Stub." << transactCodeName << ", "
           << "data, reply, 0);\n";
      if (iface.IsJavaDefault()) {
        code << "      if (!_status) {\n"
             << "        if (getDefaultImpl() != null) {\n"
             << "          return getDefaultImpl().getInterfaceHash();\n"
             << "        }\n"
             << "      }\n";
      }
      code << "      reply.readException();\n"
           << "      mCachedHash = reply.readString();\n"
           << "    } finally {\n"
           << "      reply.recycle();\n"
           << "      data.recycle();\n"
           << "    }\n"
           << "  }\n"
           << "  return mCachedHash;\n"
           << "}\n";
    }
  }
  code.Close();
  if (!proxy_code.empty()) {
    proxyClass->elements.push_back(std::make_shared<LiteralClassElement>(proxy_code));
  }
}

static void GenerateInterfaceDescriptors(const Options& options, const AidlInterface* iface,
                                         Class* interface, std::shared_ptr<StubClass> stub,
                                         std::shared_ptr<ProxyClass> proxy) {
  // the interface descriptor transaction handler
  auto c = std::make_shared<Case>("INTERFACE_TRANSACTION");
  c->statements->Add(std::make_shared<MethodCall>(
      stub->transact_reply, "writeString",
      std::vector<std::shared_ptr<Expression>>{stub->GetTransactDescriptor(nullptr)}));
  c->statements->Add(std::make_shared<ReturnStatement>(TRUE_VALUE));
  stub->transact_switch_meta->cases.push_back(c);

  // and the proxy-side method returning the descriptor directly
  auto getDesc = std::make_shared<Method>();
  getDesc->modifiers = PUBLIC;
  getDesc->returnType = "java.lang.String";
  getDesc->name = "getInterfaceDescriptor";
  getDesc->statements = std::make_shared<StatementBlock>();
  getDesc->statements->Add(
      std::make_shared<ReturnStatement>(std::make_shared<LiteralExpression>("DESCRIPTOR")));
  proxy->elements.push_back(getDesc);

  // add the DESCRIPTOR field to the interface class
  Class* classToAddDescriptor = interface;
  static std::set<std::string> greylist = {
#include "hiddenapi-greylist"
  };
  if (greylist.find(iface->GetCanonicalName()) != greylist.end()) {
    // For app compatibility, we keep DESCRIPTOR to the stub class for
    // the interfaces that are in the greylist.
    classToAddDescriptor = stub.get();
  }
  auto descriptor = std::make_shared<Field>(
      STATIC | FINAL | PUBLIC, std::make_shared<Variable>("java.lang.String", "DESCRIPTOR"));
  std::string name = iface->GetDescriptor();

  // TODO(b/242862858): avoid differentiating behahavior. This is currently blocked
  // to fix because of a metalava lint which disallows running code to generate
  // static fields.
  if (options.IsStructured()) {
    // mangle the interface name at build time and demangle it at runtime, to avoid
    // being renamed by jarjar. See b/153843174
    std::replace(name.begin(), name.end(), '.', '$');
    descriptor->value = "\"" + name + "\".replace('$', '.')";
  } else {
    descriptor->value = "\"" + name + "\"";
  }
  classToAddDescriptor->elements.push_back(descriptor);
}

// Check whether (some) methods in this interface should be "outlined," that
// is, have specific onTransact methods for certain cases. Set up StubClass
// metadata accordingly.
//
// Outlining will be enabled if the interface has more than outline_threshold
// methods. In that case, the methods are sorted by number of arguments
// (so that more "complex" methods come later), and the first non_outline_count
// number of methods not outlined (are kept in the onTransact() method).
//
// Requirements: non_outline_count <= outline_threshold.
static void ComputeOutlineMethods(const AidlInterface* iface, const std::shared_ptr<StubClass> stub,
                                  size_t outline_threshold, size_t non_outline_count) {
  AIDL_FATAL_IF(non_outline_count > outline_threshold, iface);
  // We'll outline (create sub methods) if there are more than min_methods
  // cases.
  stub->transact_outline = iface->GetMethods().size() > outline_threshold;
  if (stub->transact_outline) {
    stub->all_method_count = iface->GetMethods().size();
    std::vector<const AidlMethod*> methods;
    methods.reserve(iface->GetMethods().size());
    for (const auto& ptr : iface->GetMethods()) {
      methods.push_back(ptr.get());
    }

    std::stable_sort(
        methods.begin(),
        methods.end(),
        [](const AidlMethod* m1, const AidlMethod* m2) {
          return m1->GetArguments().size() < m2->GetArguments().size();
        });

    stub->outline_methods.insert(methods.begin() + non_outline_count,
                                 methods.end());
  }
}

static shared_ptr<ClassElement> GenerateDefaultImplMethod(const AidlMethod& method) {
  auto default_method = std::make_shared<Method>();
  default_method->comment = GenerateComments(method);
  default_method->modifiers = PUBLIC | OVERRIDE;
  default_method->returnType = JavaSignatureOf(method.GetType());
  default_method->name = method.GetName();
  default_method->statements = std::make_shared<StatementBlock>();
  for (const auto& arg : method.GetArguments()) {
    default_method->parameters.push_back(
        std::make_shared<Variable>(JavaSignatureOf(arg->GetType()), arg->GetName()));
  }
  default_method->exceptions.push_back("android.os.RemoteException");

  if (method.GetType().GetName() != "void") {
    const string& defaultValue = DefaultJavaValueOf(method.GetType());
    default_method->statements->Add(
        std::make_shared<LiteralStatement>(StringPrintf("return %s;\n", defaultValue.c_str())));
  }
  return default_method;
}

static shared_ptr<Class> GenerateDefaultImplClass(const AidlInterface& iface,
                                                  const Options& options) {
  auto default_class = std::make_shared<Class>();
  default_class->comment = "/** Default implementation for " + iface.GetName() + ". */";
  default_class->modifiers = PUBLIC | STATIC;
  default_class->what = Class::CLASS;
  default_class->type = iface.GetCanonicalName() + ".Default";
  default_class->interfaces.emplace_back(iface.GetCanonicalName());

  for (const auto& m : iface.GetMethods()) {
    if (m->IsUserDefined()) {
      default_class->elements.emplace_back(GenerateDefaultImplMethod(*m));
    } else {
      // These are called only when the remote side does not implement these
      // methods, which is normally impossible, because these methods are
      // automatically declared in the interface class and not implementing
      // them on the remote side causes a compilation error. But if the remote
      // side somehow managed to not implement it, that's an error and we
      // report the case by returning an invalid value here.
      if (m->GetName() == kGetInterfaceVersion && options.Version() > 0) {
        std::ostringstream code;
        code << "@Override\n"
             << "public int " << kGetInterfaceVersion << "() {\n"
             << "  return 0;\n"
             << "}\n";
        default_class->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
      }
      if (m->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
        std::ostringstream code;
        code << "@Override\n"
             << "public String " << kGetInterfaceHash << "() {\n"
             << "  return \"\";\n"
             << "}\n";
        default_class->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
      }
    }
  }

  default_class->elements.emplace_back(
      std::make_shared<LiteralClassElement>("@Override\n"
                                            "public android.os.IBinder asBinder() {\n"
                                            "  return null;\n"
                                            "}\n"));

  return default_class;
}

static shared_ptr<ClassElement> GenerateDelegatorMethod(const AidlMethod& method) {
  auto delegator_method = std::make_shared<Method>();
  delegator_method->comment = GenerateComments(method);
  delegator_method->modifiers = PUBLIC | OVERRIDE;
  delegator_method->returnType = JavaSignatureOf(method.GetType());
  delegator_method->name = method.GetName();
  delegator_method->statements = std::make_shared<StatementBlock>();
  std::vector<std::string> argNames;
  for (const auto& arg : method.GetArguments()) {
    delegator_method->parameters.push_back(
        std::make_shared<Variable>(JavaSignatureOf(arg->GetType()), arg->GetName()));
    argNames.push_back(arg->GetName());
  }
  delegator_method->exceptions.push_back("android.os.RemoteException");

  std::string return_str;
  if (method.GetType().GetName() != "void") {
    return_str = "return ";
  }
  delegator_method->statements->Add(
      std::make_shared<LiteralStatement>(return_str + "mImpl." + method.GetName() + "(" +
                                         android::base::Join(argNames, ",") + ");\n"));
  return delegator_method;
}

static shared_ptr<Class> GenerateDelegatorClass(const AidlInterface& iface,
                                                const Options& options) {
  auto delegator_class = std::make_shared<Class>();
  delegator_class->comment = "/** Delegator implementation for " + iface.GetName() + ". */";
  delegator_class->modifiers = PUBLIC | STATIC;
  delegator_class->what = Class::CLASS;
  delegator_class->type = iface.GetCanonicalName() + ".Delegator";
  delegator_class->extends = iface.GetCanonicalName() + ".Stub";

  // constructor
  delegator_class->elements.emplace_back(
      std::make_shared<LiteralClassElement>("public Delegator(" + iface.GetCanonicalName() +
                                            " impl) {\n"
                                            "  this.mImpl = impl;\n"
                                            "}\n"));
  // meta methods
  if (!options.Hash().empty()) {
    delegator_class->elements.emplace_back(
        std::make_shared<LiteralClassElement>("@Override\n"
                                              "public String " +
                                              kGetInterfaceHash +
                                              "() throws android.os.RemoteException {\n"
                                              "  return mImpl." +
                                              kGetInterfaceHash +
                                              "();\n"
                                              "}\n"));
  }
  if (options.Version() > 0) {
    delegator_class->elements.emplace_back(
        std::make_shared<LiteralClassElement>("@Override\n"
                                              "public int " +
                                              kGetInterfaceVersion +
                                              "() throws android.os.RemoteException {\n"
                                              "  int implVer = mImpl." +
                                              kGetInterfaceVersion +
                                              "();\n"
                                              "  return VERSION < implVer ? VERSION : implVer;\n"
                                              "}\n"));
  }

  // user defined methods
  for (const auto& m : iface.GetMethods()) {
    if (m->IsUserDefined()) {
      delegator_class->elements.emplace_back(GenerateDelegatorMethod(*m));
    }
  }

  delegator_class->elements.emplace_back(
      std::make_shared<LiteralClassElement>(iface.GetCanonicalName() + " mImpl;\n"));

  return delegator_class;
}

static shared_ptr<ClassElement> GenerateMaxTransactionId(int max_transaction_id) {
  auto getMaxTransactionId = std::make_shared<Method>();
  getMaxTransactionId->comment = "/** @hide */";
  getMaxTransactionId->modifiers = PUBLIC;
  getMaxTransactionId->returnType = "int";
  getMaxTransactionId->name = "getMaxTransactionId";
  getMaxTransactionId->statements = std::make_shared<StatementBlock>();
  getMaxTransactionId->statements->Add(std::make_shared<ReturnStatement>(
      std::make_shared<LiteralExpression>(std::to_string(max_transaction_id))));
  return getMaxTransactionId;
}

std::unique_ptr<Class> GenerateInterfaceClass(const AidlInterface* iface,
                                              const AidlTypenames& typenames,
                                              const Options& options) {
  // the interface class
  auto interface = std::make_unique<Class>();
  interface->comment = GenerateComments(*iface);
  interface->modifiers = PUBLIC;
  interface->what = Class::INTERFACE;
  interface->type = iface->GetCanonicalName();
  interface->interfaces.push_back("android.os.IInterface");
  interface->annotations = JavaAnnotationsFor(*iface);

  if (options.Version()) {
    std::ostringstream code;
    code << "/**\n"
         << " * The version of this interface that the caller is built against.\n"
         << " * This might be different from what {@link #getInterfaceVersion()\n"
         << " * getInterfaceVersion} returns as that is the version of the interface\n"
         << " * that the remote object is implementing.\n"
         << " */\n"
         << "public static final int VERSION = " << options.Version() << ";\n";
    interface->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
  }
  if (!options.Hash().empty()) {
    std::ostringstream code;
    code << "public static final String HASH = \"" << options.Hash() << "\";\n";
    interface->elements.emplace_back(std::make_shared<LiteralClassElement>(code.str()));
  }

  // the default impl class
  auto default_impl = GenerateDefaultImplClass(*iface, options);
  interface->elements.emplace_back(default_impl);

  // the delegator class
  if (iface->IsJavaDelegator()) {
    auto delegator = GenerateDelegatorClass(*iface, options);
    interface->elements.emplace_back(delegator);
  }

  // the stub inner class
  auto stub = std::make_shared<StubClass>(iface, options);
  interface->elements.push_back(stub);

  ComputeOutlineMethods(iface, stub, options.onTransact_outline_threshold_,
                        options.onTransact_non_outline_count_);

  // the proxy inner class
  auto proxy = std::make_shared<ProxyClass>(iface, options);
  stub->elements.push_back(proxy);

  // stub and proxy support for getInterfaceDescriptor()
  GenerateInterfaceDescriptors(options, iface, interface.get(), stub, proxy);

  // all the declared constants of the interface
  string constants;
  GenerateConstantDeclarations(*CodeWriter::ForString(&constants), *iface);
  interface->elements.push_back(std::make_shared<LiteralClassElement>(constants));

  // all the declared methods of the interface
  int max_transaction_id = 0;
  for (const auto& item : iface->GetMethods()) {
    GenerateMethods(*iface, *item, interface.get(), stub, proxy, item->GetId(), typenames, options);
    max_transaction_id = std::max(max_transaction_id, item->GetId());
  }

  // getMaxTransactionId
  if (options.GenTransactionNames() || options.GenTraces()) {
    stub->elements.push_back(GenerateMaxTransactionId(max_transaction_id));
  }

  // all the nested types
  string code;
  auto writer = CodeWriter::ForString(&code);
  for (const auto& nested : iface->GetNestedTypes()) {
    GenerateClass(*writer, *nested, typenames, options);
  }
  GenerateParcelHelpers(*writer, *iface, typenames, options);
  writer->Close();
  interface->elements.push_back(std::make_shared<LiteralClassElement>(code));

  if (iface->IsJavaDefault()) {
    // additional static methods for the default impl set/get to the
    // stub class. Can't add them to the interface as the generated java files
    // may be compiled with Java < 1.7 where static interface method isn't
    // supported.
    // TODO(b/111417145) make this conditional depending on the Java language
    // version requested
    const string i_name = iface->GetCanonicalName();
    stub->elements.emplace_back(std::make_shared<LiteralClassElement>(
        StringPrintf("public static boolean setDefaultImpl(%s impl) {\n"
                     "  // Only one user of this interface can use this function\n"
                     "  // at a time. This is a heuristic to detect if two different\n"
                     "  // users in the same process use this function.\n"
                     "  if (Stub.Proxy.sDefaultImpl != null) {\n"
                     "    throw new IllegalStateException(\"setDefaultImpl() called twice\");\n"
                     "  }\n"
                     "  if (impl != null) {\n"
                     "    Stub.Proxy.sDefaultImpl = impl;\n"
                     "    return true;\n"
                     "  }\n"
                     "  return false;\n"
                     "}\n",
                     i_name.c_str())));
    stub->elements.emplace_back(
        std::make_shared<LiteralClassElement>(StringPrintf("public static %s getDefaultImpl() {\n"
                                                           "  return Stub.Proxy.sDefaultImpl;\n"
                                                           "}\n",
                                                           i_name.c_str())));

    // the static field is defined in the proxy class, not in the interface class
    // because all fields in an interface class are by default final.
    proxy->elements.emplace_back(std::make_shared<LiteralClassElement>(
        StringPrintf("public static %s sDefaultImpl;\n", i_name.c_str())));
  }

  stub->Finish();

  return interface;
}

}  // namespace java
}  // namespace aidl
}  // namespace android
