/**
 * Copyright (C) 2015, 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 "generate_cpp.h"
#include "aidl.h"

#include <algorithm>
#include <cctype>
#include <cstring>
#include <memory>
#include <random>
#include <set>
#include <string>

#include <android-base/format.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>

#include "aidl_language.h"
#include "aidl_to_cpp.h"

#include "logging.h"
#include "os.h"

using android::base::Join;
using android::base::StringPrintf;
using std::set;
using std::string;
using std::unique_ptr;
using std::vector;

namespace android {
namespace aidl {
namespace cpp {
namespace internals {
namespace {

const char kAndroidStatusVarName[] = "_aidl_ret_status";
const char kCodeVarName[] = "_aidl_code";
const char kFlagsVarName[] = "_aidl_flags";
const char kDataVarName[] = "_aidl_data";
const char kErrorLabel[] = "_aidl_error";
const char kImplVarName[] = "_aidl_impl";
const char kDelegateImplVarName[] = "_aidl_delegate";
const char kParcelVarName[] = "_aidl_parcel";
const char kReplyVarName[] = "_aidl_reply";
const char kReturnVarName[] = "_aidl_return";
const char kStatusVarName[] = "_aidl_status";
const char kTraceVarName[] = "_aidl_trace";
const char kAndroidParcelLiteral[] = "::android::Parcel";
const char kAndroidStatusLiteral[] = "::android::status_t";
const char kAndroidStatusOk[] = "::android::OK";
const char kAndroidStatusBadValue[] = "::android::BAD_VALUE";
const char kBinderStatusLiteral[] = "::android::binder::Status";
const char kIBinderHeader[] = "binder/IBinder.h";
const char kIInterfaceHeader[] = "binder/IInterface.h";
const char kBinderDelegateHeader[] = "binder/Delegate.h";
const char kParcelHeader[] = "binder/Parcel.h";
const char kStabilityHeader[] = "binder/Stability.h";
const char kStatusHeader[] = "binder/Status.h";
const char kString16Header[] = "utils/String16.h";
const char kTraceHeader[] = "binder/Trace.h";
const char kStrongPointerHeader[] = "utils/StrongPointer.h";
const char kAndroidBaseMacrosHeader[] = "android-base/macros.h";

void GenerateBreakOnStatusNotOk(CodeWriter& out) {
  out.Write("if (((%s) != (%s))) {\n", kAndroidStatusVarName, kAndroidStatusOk);
  out.Write("  break;\n");
  out.Write("}\n");
}

void GenerateGotoErrorOnBadStatus(CodeWriter& out) {
  out.Write("if (((%s) != (%s))) {\n", kAndroidStatusVarName, kAndroidStatusOk);
  out.Write("  goto %s;\n", kErrorLabel);
  out.Write("}\n");
}

// Format three types of arg list for method.
//  for_declaration & !type_name_only: int a      // for method decl with type and arg
//  for_declaration &  type_name_only: int /*a*/  // for method decl with type
// !for_declaration                  :     a      // for method call with arg (with direction)
string GenerateArgList(const AidlTypenames& typenames, const AidlMethod& method,
                       bool for_declaration, bool type_name_only) {
  vector<string> method_arguments;
  for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
    string literal;
    // b/144943748: CppNameOf FileDescriptor is unique_fd. Don't pass it by
    // const reference but by value to make it easier for the user to keep
    // it beyond the scope of the call. unique_fd is a thin wrapper for an
    // int (fd) so passing by value is not expensive.
    const bool non_copyable = IsNonCopyableType(a->GetType(), typenames);
    if (for_declaration) {
      // Method declarations need typenames, pointers to out params, and variable
      // names that match the .aidl specification.
      literal = CppNameOf(a->GetType(), typenames);

      if (a->IsOut()) {
        literal = literal + "*";
      } else {
        const auto defined_type = typenames.TryGetDefinedType(a->GetType().GetName());

        const bool is_enum = defined_type && defined_type->AsEnumDeclaration() != nullptr;
        const bool is_primitive = AidlTypenames::IsPrimitiveTypename(a->GetType().GetName());

        // We pass in parameters that are not primitives by const reference.
        // Arrays of primitives are not primitives.
        if (!(is_primitive || is_enum || non_copyable) || a->GetType().IsArray()) {
          literal = "const " + literal + "&";
        }
      }
      if (type_name_only) {
        literal += " /*" + a->GetName() + "*/";
      } else {
        literal += " " + a->GetName();
      }
    } else {
      std::string var_name = BuildVarName(*a);
      if (a->IsOut()) {
        literal = "&" + var_name;
      } else if (non_copyable) {
        literal = "std::move(" + var_name + ")";
      } else {
        literal = var_name;
      }
    }
    method_arguments.push_back(literal);
  }

  if (method.GetType().GetName() != "void") {
    string literal;
    if (for_declaration) {
      literal = CppNameOf(method.GetType(), typenames) + "*";
      if (type_name_only) {
        literal += " /*" + string(kReturnVarName) + "*/";
      } else {
        literal += " " + string(kReturnVarName);
      }
    } else {
      literal = string{"&"} + kReturnVarName;
    }
    method_arguments.push_back(literal);
  }

  return Join(method_arguments, ", ");
}

void GenerateMethodDecl(CodeWriter& out, const AidlTypenames& types, const AidlMethod& method,
                        const string& clazz) {
  string clazz_prefix = clazz.empty() ? "" : clazz + "::";
  out << "::android::binder::Status " << clazz_prefix << method.GetName() << "("
      << GenerateArgList(types, method, /*for_declartion=*/true, /*type_name_only=*/false) << ")";
}

void GenerateClientTransaction(CodeWriter& out, const AidlTypenames& typenames,
                               const AidlInterface& interface, const AidlMethod& method,
                               const Options& options) {
  const string i_name = ClassName(interface, ClassNames::INTERFACE);
  const string bp_name = GetQualifiedName(interface, ClassNames::CLIENT);
  const string bn_name = GetQualifiedName(interface, ClassNames::SERVER);

  GenerateMethodDecl(out, typenames, method, bp_name);
  out << " {\n";
  out.Indent();

  // Declare parcels to hold our query and the response.
  out.Write("%s %s;\n", kAndroidParcelLiteral, kDataVarName);
  if (interface.IsSensitiveData()) {
    out.Write("%s.markSensitive();\n", kDataVarName);
  }
  out.Write("%s.markForBinder(remoteStrong());\n", kDataVarName);

  // Even if we're oneway, the transact method still takes a parcel.
  out.Write("%s %s;\n", kAndroidParcelLiteral, kReplyVarName);

  // Declare the status_t variable we need for error handling.
  out.Write("%s %s = %s;\n", kAndroidStatusLiteral, kAndroidStatusVarName, kAndroidStatusOk);
  // We unconditionally return a Status object.
  out.Write("%s %s;\n", kBinderStatusLiteral, kStatusVarName);

  if (options.GenTraces()) {
    out.Write(
        "::android::binder::ScopedTrace %s(ATRACE_TAG_AIDL, \"AIDL::cpp::%s::%s::cppClient\");\n",
        kTraceVarName, interface.GetName().c_str(), method.GetName().c_str());
  }

  if (options.GenLog()) {
    out << GenLogBeforeExecute(bp_name, method, false /* isServer */, false /* isNdk */);
  }

  // Add the name of the interface we're hoping to call.
  out.Write("%s = %s.writeInterfaceToken(getInterfaceDescriptor());\n", kAndroidStatusVarName,
            kDataVarName);
  GenerateGotoErrorOnBadStatus(out);

  for (const auto& a : method.GetArguments()) {
    const string var_name = ((a->IsOut()) ? "*" : "") + a->GetName();

    if (a->IsIn()) {
      // Serialization looks roughly like:
      //     _aidl_ret_status = _aidl_data.WriteInt32(in_param_name);
      //     if (_aidl_ret_status != ::android::OK) { goto error; }
      out.Write("%s = %s.%s(%s);\n", kAndroidStatusVarName, kDataVarName,
                ParcelWriteMethodOf(a->GetType(), typenames).c_str(),
                ParcelWriteCastOf(a->GetType(), typenames, var_name).c_str());
      GenerateGotoErrorOnBadStatus(out);
    } else if (a->IsOut() && a->GetType().IsDynamicArray()) {
      // Special case, the length of the out array is written into the parcel.
      //     _aidl_ret_status = _aidl_data.writeVectorSize(&out_param_name);
      //     if (_aidl_ret_status != ::android::OK) { goto error; }
      out.Write("%s = %s.writeVectorSize(%s);\n", kAndroidStatusVarName, kDataVarName,
                var_name.c_str());
      GenerateGotoErrorOnBadStatus(out);
    }
  }

  // Invoke the transaction on the remote binder and confirm status.
  std::vector<std::string> flags;
  if (method.IsOneway()) flags.push_back("::android::IBinder::FLAG_ONEWAY");
  if (interface.IsSensitiveData()) flags.push_back("::android::IBinder::FLAG_CLEAR_BUF");

  out.Write("%s = remote()->transact(%s, %s, &%s, %s);\n", kAndroidStatusVarName,
            GetTransactionIdFor(bn_name, method).c_str(), kDataVarName, kReplyVarName,
            flags.empty() ? "0" : Join(flags, " | ").c_str());

  // If the method is not implemented in the remote side, try to call the
  // default implementation, if provided.
  vector<string> arg_names;
  for (const auto& a : method.GetArguments()) {
    if (IsNonCopyableType(a->GetType(), typenames)) {
      arg_names.emplace_back(StringPrintf("std::move(%s)", a->GetName().c_str()));
    } else {
      arg_names.emplace_back(a->GetName());
    }
  }
  if (method.GetType().GetName() != "void") {
    arg_names.emplace_back(kReturnVarName);
  }
  out.Write("if (UNLIKELY(%s == ::android::UNKNOWN_TRANSACTION && %s::getDefaultImpl())) {\n",
            kAndroidStatusVarName, i_name.c_str());
  out.Write("   return %s::getDefaultImpl()->%s(%s);\n", i_name.c_str(), method.GetName().c_str(),
            Join(arg_names, ", ").c_str());
  out.Write("}\n");
  GenerateGotoErrorOnBadStatus(out);

  if (!method.IsOneway()) {
    // Strip off the exception header and fail if we see a remote exception.
    // _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
    // if (_aidl_ret_status != ::android::OK) { goto error; }
    // if (!_aidl_status.isOk()) { return _aidl_ret_status; }
    out.Write("%s = %s.readFromParcel(%s);\n", kAndroidStatusVarName, kStatusVarName,
              kReplyVarName);
    GenerateGotoErrorOnBadStatus(out);
    out.Write("if (!%s.isOk()) {\n", kStatusVarName);
    out.Write("  return %s;\n", kStatusVarName);
    out.Write("}\n");
  }

  // Type checking should guarantee that nothing below emits code until "return
  // status" if we are a oneway method, so no more fear of accessing reply.

  // If the method is expected to return something, read it first by convention.
  if (method.GetType().GetName() != "void") {
    out.Write("%s = %s.%s(%s);\n", kAndroidStatusVarName, kReplyVarName,
              ParcelReadMethodOf(method.GetType(), typenames).c_str(),
              ParcelReadCastOf(method.GetType(), typenames, kReturnVarName).c_str());
    GenerateGotoErrorOnBadStatus(out);
  }

  for (const AidlArgument* a : method.GetOutArguments()) {
    // Deserialization looks roughly like:
    //     _aidl_ret_status = _aidl_reply.ReadInt32(out_param_name);
    //     if (_aidl_status != ::android::OK) { goto _aidl_error; }
    out.Write("%s = %s.%s(%s);\n", kAndroidStatusVarName, kReplyVarName,
              ParcelReadMethodOf(a->GetType(), typenames).c_str(),
              ParcelReadCastOf(a->GetType(), typenames, a->GetName()).c_str());
    GenerateGotoErrorOnBadStatus(out);
  }

  // If we've gotten to here, one of two things is true:
  //   1) We've read some bad status_t
  //   2) We've only read status_t == OK and there was no exception in the
  //      response.
  // In both cases, we're free to set Status from the status_t and return.
  out.Write("%s:\n", kErrorLabel);
  out.Write("%s.setFromStatusT(%s);\n", kStatusVarName, kAndroidStatusVarName);

  if (options.GenLog()) {
    out << GenLogAfterExecute(bp_name, interface, method, kStatusVarName, kReturnVarName,
                              false /* isServer */, false /* isNdk */);
  }

  out.Write("return %s;\n", kStatusVarName);
  out.Dedent();
  out << "}\n";
}

void GenerateClientMetaTransaction(CodeWriter& out, const AidlInterface& interface,
                                   const AidlMethod& method, const Options& options) {
  AIDL_FATAL_IF(method.IsUserDefined(), method);
  const string bp_name = GetQualifiedName(interface, ClassNames::CLIENT);
  const string bn_name = GetQualifiedName(interface, ClassNames::SERVER);
  if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
    // Note: race condition can happen here, but no locking is required
    // because 1) writing an interger is atomic and 2) this transaction
    // will always return the same value, i.e., competing threads will
    // give write the same value to cached_version_.
    out << "int32_t " << bp_name << "::" << kGetInterfaceVersion << "() {\n"
        << "  if (cached_version_ == -1) {\n"
        << "    ::android::Parcel data;\n"
        << "    ::android::Parcel reply;\n"
        << "    data.writeInterfaceToken(getInterfaceDescriptor());\n"
        << "    ::android::status_t err = remote()->transact("
        << GetTransactionIdFor(bn_name, method) << ", data, &reply);\n"
        << "    if (err == ::android::OK) {\n"
        << "      ::android::binder::Status _aidl_status;\n"
        << "      err = _aidl_status.readFromParcel(reply);\n"
        << "      if (err == ::android::OK && _aidl_status.isOk()) {\n"
        << "        cached_version_ = reply.readInt32();\n"
        << "      }\n"
        << "    }\n"
        << "  }\n"
        << "  return cached_version_;\n"
        << "}\n";
    out << "\n";
  }
  if (method.GetName() == kGetInterfaceHash && !options.Hash().empty()) {
    out << "std::string " << bp_name << "::" << kGetInterfaceHash << "() {\n"
        << "  std::lock_guard<std::mutex> lockGuard(cached_hash_mutex_);\n"
        << "  if (cached_hash_ == \"-1\") {\n"
        << "    ::android::Parcel data;\n"
        << "    ::android::Parcel reply;\n"
        << "    data.writeInterfaceToken(getInterfaceDescriptor());\n"
        << "    ::android::status_t err = remote()->transact("
        << GetTransactionIdFor(bn_name, method) << ", data, &reply);\n"
        << "    if (err == ::android::OK) {\n"
        << "      ::android::binder::Status _aidl_status;\n"
        << "      err = _aidl_status.readFromParcel(reply);\n"
        << "      if (err == ::android::OK && _aidl_status.isOk()) {\n"
        << "        reply.readUtf8FromUtf16(&cached_hash_);\n"
        << "      }\n"
        << "    }\n"
        << "  }\n"
        << "  return cached_hash_;\n"
        << "}\n";
  }
}

}  // namespace

void GenerateClientSource(CodeWriter& out, const AidlInterface& interface,
                          const AidlTypenames& typenames, const Options& options) {
  vector<string> include_list = {
      HeaderFile(interface, ClassNames::CLIENT, false),
      HeaderFile(interface, ClassNames::SERVER, false),  // for TRANSACTION_* consts
      kParcelHeader, kAndroidBaseMacrosHeader};
  if (options.GenLog()) {
    include_list.emplace_back("chrono");
    include_list.emplace_back("functional");
  }
  for (const auto& path : include_list) {
    out << "#include <" << path << ">\n";
  }
  out << "\n";

  const string i_name = ClassName(interface, ClassNames::INTERFACE);
  const string bp_name = ClassName(interface, ClassNames::CLIENT);
  const string q_name = GetQualifiedName(interface, ClassNames::CLIENT);

  EnterNamespace(out, interface);
  out << "\n";

  // The constructor just passes the IBinder instance up to the super
  // class.
  out << q_name << "::" << bp_name << "(const ::android::sp<::android::IBinder>& _aidl_impl)\n";
  out << "    : BpInterface<" + i_name + ">(_aidl_impl){\n";
  out << "}\n";
  out << "\n";

  if (options.GenLog()) {
    out << "std::function<void(const " + q_name + "::TransactionLog&)> " << q_name
        << "::logFunc;\n";
    out << "\n";
  }

  // Clients define a method per transaction.
  for (const auto& method : interface.GetMethods()) {
    if (method->IsUserDefined()) {
      GenerateClientTransaction(out, typenames, interface, *method, options);
    } else {
      GenerateClientMetaTransaction(out, interface, *method, options);
    }
    out << "\n";
  }

  LeaveNamespace(out, interface);
}

namespace {

void GenerateConstantDefinitions(CodeWriter& out, const AidlDefinedType& type,
                                 const AidlTypenames& typenames, const string& template_decl,
                                 const string& q_name) {
  for (const auto& constant : type.GetConstantDeclarations()) {
    const AidlConstantValue& value = constant->GetValue();
    if (value.GetType() != AidlConstantValue::Type::STRING) continue;

    std::string cpp_type = CppNameOf(constant->GetType(), typenames);
    out << template_decl;
    out << "const " << cpp_type << "& " << q_name << "::" << constant->GetName() << "() {\n";
    out << "  static const " << cpp_type << " value("
        << constant->ValueString(ConstantValueDecorator) << ");\n";
    out << "  return value;\n";
    out << "}\n";
  }
}

void GenerateConstantDeclarations(CodeWriter& out, const AidlDefinedType& type,
                                  const AidlTypenames& typenames) {
  for (const auto& constant : type.GetConstantDeclarations()) {
    const AidlTypeSpecifier& type = constant->GetType();
    const auto cpp_type = CppNameOf(type, typenames);
    if (type.Signature() == "String") {
      out << "static const " << cpp_type << "& " << constant->GetName() << "()";
      GenerateDeprecated(out, *constant);
      out << ";\n";
    } else {
      out << "enum : " << cpp_type << " { " << constant->GetName();
      GenerateDeprecated(out, *constant);
      out << " = " << constant->ValueString(ConstantValueDecorator) << " };\n";
    }
  }
}

void GenerateServerTransaction(CodeWriter& out, const AidlInterface& interface,
                               const AidlMethod& method, const AidlTypenames& typenames,
                               const Options& options) {
  const string bn_name = GetQualifiedName(interface, ClassNames::SERVER);

  // Declare all the parameters now.  In the common case, we expect no errors
  // in serialization.
  for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
    out.Write("%s %s;\n", CppNameOf(a->GetType(), typenames).c_str(), BuildVarName(*a).c_str());
  }

  // Declare a variable to hold the return value.
  if (method.GetType().GetName() != "void") {
    out.Write("%s %s;\n", CppNameOf(method.GetType(), typenames).c_str(), kReturnVarName);
  }

  // Check that the client is calling the correct interface.
  out.Write("if (!(%s.checkInterface(this))) {\n", kDataVarName);
  out.Write("  %s = ::android::BAD_TYPE;\n", kAndroidStatusVarName);
  out.Write("  break;\n");
  out.Write("}\n");

  if (options.GenTraces()) {
    out.Write(
        "::android::binder::ScopedTrace %s(ATRACE_TAG_AIDL, \"AIDL::cpp::%s::%s::cppServer\");\n",
        kTraceVarName, interface.GetName().c_str(), method.GetName().c_str());
  }

  if (interface.EnforceExpression() || method.GetType().EnforceExpression()) {
    out.Write("#error Permission checks not implemented for the cpp backend\n");
  }

  // Deserialize each "in" parameter to the transaction.
  for (const auto& a: method.GetArguments()) {
    // Deserialization looks roughly like:
    //     _aidl_ret_status = _aidl_data.ReadInt32(&in_param_name);
    //     if (_aidl_ret_status != ::android::OK) { break; }
    const string& var_name = "&" + BuildVarName(*a);
    if (a->IsIn()) {
      out.Write("%s = %s.%s(%s);\n", kAndroidStatusVarName, kDataVarName,
                ParcelReadMethodOf(a->GetType(), typenames).c_str(),
                ParcelReadCastOf(a->GetType(), typenames, var_name).c_str());
      GenerateBreakOnStatusNotOk(out);
    } else if (a->IsOut() && a->GetType().IsDynamicArray()) {
      // Special case, the length of the out array is written into the parcel.
      //     _aidl_ret_status = _aidl_data.resizeOutVector(&out_param_name);
      //     if (_aidl_ret_status != ::android::OK) { break; }
      out.Write("%s = %s.resizeOutVector(%s);\n", kAndroidStatusVarName, kDataVarName,
                var_name.c_str());
      GenerateBreakOnStatusNotOk(out);
    }
  }

  if (options.GenLog()) {
    out << GenLogBeforeExecute(bn_name, method, true /* isServer */, false /* isNdk */);
  }

  if (!method.GetArguments().empty() && options.GetMinSdkVersion() >= SDK_VERSION_Tiramisu) {
    out << "if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {\n";
    out << "  _aidl_ret_status = st.writeToParcel(_aidl_reply);\n";
    out << "  break;\n";
    out << "}\n";
  }

  // Call the actual method.  This is implemented by the subclass.
  out.Write("%s %s(%s(%s));\n", kBinderStatusLiteral, kStatusVarName, method.GetName().c_str(),
            GenerateArgList(typenames, method, /*for_declaration=*/false, /*type_name_only=*/false)
                .c_str());

  if (options.GenLog()) {
    out << GenLogAfterExecute(bn_name, interface, method, kStatusVarName, kReturnVarName,
                              true /* isServer */, false /* isNdk */);
  }

  // Write exceptions during transaction handling to parcel.
  if (!method.IsOneway()) {
    out.Write("%s = %s.writeToParcel(%s);\n", kAndroidStatusVarName, kStatusVarName, kReplyVarName);
    GenerateBreakOnStatusNotOk(out);
    out.Write("if (!%s.isOk()) {\n", kStatusVarName);
    out.Write("  break;\n");
    out.Write("}\n");
  }

  // If we have a return value, write it first.
  if (method.GetType().GetName() != "void") {
    out.Write("%s = %s->%s(%s);\n", kAndroidStatusVarName, kReplyVarName,
              ParcelWriteMethodOf(method.GetType(), typenames).c_str(),
              ParcelWriteCastOf(method.GetType(), typenames, kReturnVarName).c_str());
    GenerateBreakOnStatusNotOk(out);
  }
  // Write each out parameter to the reply parcel.
  for (const AidlArgument* a : method.GetOutArguments()) {
    // Serialization looks roughly like:
    //     _aidl_ret_status = data.WriteInt32(out_param_name);
    //     if (_aidl_ret_status != ::android::OK) { break; }
    out.Write("%s = %s->%s(%s);\n", kAndroidStatusVarName, kReplyVarName,
              ParcelWriteMethodOf(a->GetType(), typenames).c_str(),
              ParcelWriteCastOf(a->GetType(), typenames, BuildVarName(*a)).c_str());
    GenerateBreakOnStatusNotOk(out);
  }
}

void GenerateServerMetaTransaction(CodeWriter& out, const AidlInterface& interface,
                                   const AidlMethod& method, const Options& options) {
  AIDL_FATAL_IF(method.IsUserDefined(), method);

  string iface = ClassName(interface, ClassNames::INTERFACE);
  if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
    out << "_aidl_data.checkInterface(this);\n"
        << "_aidl_reply->writeNoException();\n"
        << "_aidl_reply->writeInt32(" << iface << "::VERSION);\n";
  }
  if (method.GetName() == kGetInterfaceHash && !options.Hash().empty()) {
    out << "_aidl_data.checkInterface(this);\n"
        << "_aidl_reply->writeNoException();\n"
        << "_aidl_reply->writeUtf8AsUtf16(" << iface << "::HASH);\n";
  }
}

}  // namespace

void GenerateServerOnTransact(CodeWriter& out, const AidlInterface& interface,
                              const AidlTypenames& typenames, const Options& options) {
  const string bn_name = ClassName(interface, ClassNames::SERVER);
  const string q_name = GetQualifiedName(interface, ClassNames::SERVER);

  bool deprecated = interface.IsDeprecated() ||
                    std::any_of(interface.GetMethods().begin(), interface.GetMethods().end(),
                                [](const auto& m) { return m->IsDeprecated(); });
  if (deprecated) {
    out << "#pragma clang diagnostic push\n";
    out << "#pragma clang diagnostic ignored \"-Wdeprecated\"\n";
    out << "\n";
  }

  out.Write("%s %s::onTransact(uint32_t %s, const %s& %s, %s* %s, uint32_t %s) {\n",
            kAndroidStatusLiteral, q_name.c_str(), kCodeVarName, kAndroidParcelLiteral,
            kDataVarName, kAndroidParcelLiteral, kReplyVarName, kFlagsVarName);
  out.Indent();
  // Declare the status_t variable
  out.Write("%s %s = %s;\n", kAndroidStatusLiteral, kAndroidStatusVarName, kAndroidStatusOk);

  // Add the all important switch statement
  out.Write("switch (%s) {\n", kCodeVarName);

  // The switch statement has a case statement for each transaction code.
  for (const auto& method : interface.GetMethods()) {
    out.Write("case %s:\n", GetTransactionIdFor(bn_name, *method).c_str());
    out << "{\n";
    out.Indent();
    if (method->IsUserDefined()) {
      GenerateServerTransaction(out, interface, *method, typenames, options);
    } else {
      GenerateServerMetaTransaction(out, interface, *method, options);
    }
    out.Dedent();
    out << "}\n";
    out << "break;\n";
  }

  // The switch statement has a default case which defers to the super class.
  // The superclass handles a few pre-defined transactions.
  out << "default:\n";
  out << "{\n";
  out.Write("  %s = ::android::BBinder::onTransact(%s, %s, %s, %s);\n", kAndroidStatusVarName,
            kCodeVarName, kDataVarName, kReplyVarName, kFlagsVarName);
  out << "}\n";
  out << "break;\n";
  out << "}\n";  // switch

  // If we saw a null reference, we can map that to an appropriate exception.
  out.Write("if (%s == ::android::UNEXPECTED_NULL) {\n", kAndroidStatusVarName);
  out.Write("  %s = %s::fromExceptionCode(%s::EX_NULL_POINTER).writeOverParcel(%s);\n",
            kAndroidStatusVarName, kBinderStatusLiteral, kBinderStatusLiteral, kReplyVarName);
  out.Write("}\n");

  // Finally, the server's onTransact method just returns a status code.
  out.Write("return %s;\n", kAndroidStatusVarName);

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

  if (deprecated) {
    out << "#pragma clang diagnostic pop\n";
    out << "\n";
  }
}

void GenerateServerSource(CodeWriter& out, const AidlInterface& interface,
                          const AidlTypenames& typenames, const Options& options) {
  vector<string> include_list{
      HeaderFile(interface, ClassNames::SERVER, false),
      kParcelHeader,
      kStabilityHeader,
  };
  if (options.GenLog()) {
    include_list.emplace_back("chrono");
    include_list.emplace_back("functional");
  }
  for (const auto& include : include_list) {
    out << "#include <" << include << ">\n";
  }
  out << "\n";

  const string i_name = ClassName(interface, ClassNames::INTERFACE);
  const string bn_name = ClassName(interface, ClassNames::SERVER);
  const string q_name = GetQualifiedName(interface, ClassNames::SERVER);

  EnterNamespace(out, interface);
  out << "\n";

  // constructor
  out.Write("%s::%s()\n", q_name.c_str(), bn_name.c_str());
  out << "{\n";
  out.Indent();
  if (interface.IsVintfStability()) {
    out << "::android::internal::Stability::markVintf(this);\n";
  } else {
    out << "::android::internal::Stability::markCompilationUnit(this);\n";
  }
  out.Dedent();
  out << "}\n";
  out << "\n";

  GenerateServerOnTransact(out, interface, typenames, options);

  if (options.Version() > 0) {
    out << "int32_t " << q_name << "::" << kGetInterfaceVersion << "() {\n"
        << "  return " << i_name << "::VERSION;\n"
        << "}\n";
  }
  if (!options.Hash().empty()) {
    out << "std::string " << q_name << "::" << kGetInterfaceHash << "() {\n"
        << "  return " << i_name << "::HASH;\n"
        << "}\n";
  }
  if (options.GenLog()) {
    out << "std::function<void(const " + q_name + "::TransactionLog&)> " << q_name
        << "::logFunc;\n";
  }

  LeaveNamespace(out, interface);
}

void GenerateInterfaceSource(CodeWriter& out, const AidlInterface& interface,
                             const AidlTypenames& typenames, const Options&) {
  out << "#include <" << HeaderFile(interface, ClassNames::RAW, false) << ">\n";
  out << "#include <" << HeaderFile(interface, ClassNames::CLIENT, false) << ">\n";

  EnterNamespace(out, interface);

  if (auto parent = interface.GetParentType(); parent) {
    out << fmt::format("DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_NESTED_INTERFACE({}, {}, \"{}\")\n",
                       GetQualifiedName(*parent), ClassName(interface, ClassNames::BASE),
                       interface.GetDescriptor());
  } else {
    out << fmt::format("DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE({}, \"{}\")\n",
                       ClassName(interface, ClassNames::BASE), interface.GetDescriptor());
  }

  GenerateConstantDefinitions(out, interface, typenames, /*template_decl=*/"",
                              ClassName(interface, ClassNames::INTERFACE));

  LeaveNamespace(out, interface);
}

void GenerateClientClassDecl(CodeWriter& out, const AidlInterface& interface,
                             const AidlTypenames& typenames, const Options& options) {
  const string bp_name = ClassName(interface, ClassNames::CLIENT);
  const string iface = ClassName(interface, ClassNames::INTERFACE);

  out << "class";
  GenerateDeprecated(out, interface);
  out << " " << bp_name << " : public ::android::BpInterface<" << iface << "> {\n";
  out << "public:\n";
  out.Indent();
  out << "explicit " << bp_name << "(const ::android::sp<::android::IBinder>& " << kImplVarName
      << ");\n";
  out << "virtual ~" << bp_name << "() = default;\n";

  for (const auto& method : interface.GetMethods()) {
    if (method->IsUserDefined()) {
      GenerateMethodDecl(out, typenames, *method, /*clazz=*/"");
      out << " override";
      GenerateDeprecated(out, *method);
      out << ";\n";
    } else if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
      out << "int32_t " << method->GetName() << "() override;\n";
    } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
      out << "std::string " << method->GetName() << "() override;\n";
    }
  }

  if (options.GenLog()) {
    out << kTransactionLogStruct;
    out << "static std::function<void(const TransactionLog&)> logFunc;\n";
  }
  out.Dedent();

  if (options.Version() > 0 || !options.Hash().empty()) {
    out << "private:\n";
    out.Indent();
    if (options.Version() > 0) {
      out << "int32_t cached_version_ = -1;\n";
    }
    if (!options.Hash().empty()) {
      out << "std::string cached_hash_ = \"-1\";\n";
      out << "std::mutex cached_hash_mutex_;\n";
    }
    out.Dedent();
  }

  out << "};  // class " << bp_name << "\n";
}

void GenerateClientHeader(CodeWriter& out, const AidlInterface& interface,
                          const AidlTypenames& typenames, const Options& options) {
  out << "#pragma once\n\n";
  out << "#include <" << kIBinderHeader << ">\n";
  out << "#include <" << kIInterfaceHeader << ">\n";
  out << "#include <utils/Errors.h>\n";
  out << "#include <" << HeaderFile(interface, ClassNames::RAW, false) << ">\n";
  if (options.GenLog()) {
    out << "#include <functional>\n";  // for std::function
    out << "#include <android/binder_to_string.h>\n";
  }
  out << "\n";
  EnterNamespace(out, interface);
  GenerateClientClassDecl(out, interface, typenames, options);
  LeaveNamespace(out, interface);
}

// Some interfaces are declared in .aidl files, but defined elsewhere.
// These interfaces can not have Delegators and need to be avoided.
// TODO(b/242920522) These should all be defined in .aidl files.
bool isKnownUndefinedInterface(const std::string& canonicalName) {
  static const auto* kKnownUndefinedInterfaces = new std::set<std::string>{
      "android.hardware.ICamera", "android.hardware.ICameraClient",
      "android.IOMXNode",         "android.IMediaExtractor",
      "android.IDataSource",
  };
  return kKnownUndefinedInterfaces->find(canonicalName) != kKnownUndefinedInterfaces->end();
};

bool isDelegateable(const AidlTypeSpecifier& type) {
  return type.GetDefinedType() && type.GetDefinedType()->AsInterface() &&
         !isKnownUndefinedInterface(type.GetDefinedType()->GetCanonicalName()) && !type.IsArray();
}

void wrapDelegate(CodeWriter& out, const std::string& argName, const AidlTypeSpecifier& type,
                  bool in) {
  const std::string argRef = in ? argName : "*" + argName;
  const std::string targetArgName = in ? "_" + argName : argName;
  const std::string targetArgRef = in ? targetArgName : "*" + targetArgName;
  // input binders need local variables for each arg to pass to the delegate
  // because the parameters are const
  if (in) {
    out << "::android::sp<::" << Join(type.GetSplitName(), "::") << "Delegator> " << targetArgName
        << ";\n";
  }
  out << "if (" << argRef << ") {\n";
  out.Indent();
  out << targetArgRef << " = ::android::sp<::" << Join(type.GetSplitName(), "::")
      << "Delegator>::cast(delegate(" << argRef << "));\n";
  out.Dedent();
  out << "}\n";
}

void GenerateServerClassDecl(CodeWriter& out, const AidlInterface& interface,
                             const AidlTypenames& typenames, const Options& options) {
  const string bn_name = ClassName(interface, ClassNames::SERVER);
  const string iface = ClassName(interface, ClassNames::INTERFACE);

  out << "class";
  GenerateDeprecated(out, interface);
  out << " " << bn_name << " : public "
      << "::android::BnInterface<" << iface << "> {\n";
  out << "public:\n";
  out.Indent();
  for (const auto& method : interface.GetMethods()) {
    out << "static constexpr uint32_t TRANSACTION_" << method->GetName() << " = "
        << "::android::IBinder::FIRST_CALL_TRANSACTION + " << std::to_string(method->GetId())
        << ";\n";
  }
  out << "explicit " << bn_name << "();\n";
  out << fmt::format("{} onTransact(uint32_t {}, const {}& {}, {}* {}, uint32_t {}) override;\n",
                     kAndroidStatusLiteral, kCodeVarName, kAndroidParcelLiteral, kDataVarName,
                     kAndroidParcelLiteral, kReplyVarName, kFlagsVarName);
  if (options.Version() > 0) {
    out << "int32_t " << kGetInterfaceVersion << "();\n";
  }
  if (!options.Hash().empty()) {
    out << "std::string " << kGetInterfaceHash << "();\n";
  }
  if (options.GenLog()) {
    out << kTransactionLogStruct;
    out << "static std::function<void(const TransactionLog&)> logFunc;\n";
  }
  out.Dedent();
  out << "};  // class " << bn_name << "\n\n";

  std::string d_name = ClassName(interface, ClassNames::DELEGATOR_IMPL);
  out << "class";
  GenerateDeprecated(out, interface);
  out << " " << d_name << " : public " << bn_name << " {\n";
  out << "public:\n";
  out.Indent();
  out << "explicit " << d_name << "("
      << StringPrintf("const ::android::sp<%s> &impl", iface.c_str()) << ") "
      << StringPrintf(": %s(impl)", kDelegateImplVarName) << " {}\n\n";
  out << "::android::sp<" << iface << "> getImpl() { return " << kDelegateImplVarName << "; }\n";
  for (const auto& method : interface.GetMethods()) {
    if (method->IsUserDefined()) {
      GenerateMethodDecl(out, typenames, *method, /*clazz=*/"");
      out << " override";
      GenerateDeprecated(out, *method);

      std::vector<std::string> args;

      // arg name, type
      std::vector<pair<const std::string, const AidlTypeSpecifier&>> outBinders;
      std::vector<pair<const std::string, const AidlTypeSpecifier&>> inBinders;
      for (const auto& arg : method->GetArguments()) {
        if (isDelegateable(arg->GetType())) {
          if (arg->IsOut()) {
            outBinders.push_back({arg->GetName(), arg->GetType()});
          } else if (arg->IsIn()) {
            inBinders.push_back({arg->GetName(), arg->GetType()});
          } else {
            AIDL_FATAL(*arg) << "inout interface?";
          }
          AIDL_FATAL_IF(!arg->IsIn() && !arg->IsOut(), *arg) << "Not in or out?";
          args.push_back("_" + arg->GetName());
        } else {
          if (IsNonCopyableType(arg->GetType(), typenames)) {
            args.push_back(StringPrintf("std::move(%s)", arg->GetName().c_str()));
          } else {
            args.push_back(arg->GetName());
          }
        }
      }
      if (method->GetType().GetName() != "void") {
        if (isDelegateable(method->GetType())) {
          outBinders.push_back({kReturnVarName, method->GetType()});
        }
        args.push_back(kReturnVarName);
      }
      out << " {\n";
      out.Indent();
      for (const auto binder : inBinders) {
        wrapDelegate(out, binder.first, binder.second, true);
      }
      if (outBinders.empty()) {
        out << "return " << kDelegateImplVarName << "->" << method->GetName() << "("
            << base::Join(args, ", ") << ");\n";
      } else {
        out << "auto _status = " << kDelegateImplVarName << "->" << method->GetName() << "("
            << base::Join(args, ", ") << ");\n";
        for (const auto& binder : outBinders) {
          wrapDelegate(out, binder.first, binder.second, false);
        }
        out << "return _status;\n";
      }
      out.Dedent();
      out << "}\n";
    } else if (method->GetName() == kGetInterfaceVersion && options.Version()) {
      out << "int32_t " << kGetInterfaceVersion << "()"
          << " override {\n";
      out.Indent();
      out << "int32_t _delegator_ver = " << bn_name << "::" << kGetInterfaceVersion << "();\n";
      out << "int32_t _impl_ver = " << kDelegateImplVarName << "->" << kGetInterfaceVersion
          << "();\n";
      out << "return _delegator_ver < _impl_ver ? _delegator_ver : _impl_ver;\n";
      out.Dedent();
      out << "}\n";
    } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
      out << "std::string " << kGetInterfaceHash << "()"
          << " override {\n";
      out << "  return " << kDelegateImplVarName << "->" << kGetInterfaceHash << "();\n";
      out << "}\n";
    }
  }
  out.Dedent();
  out << "private:\n";
  out.Indent();
  out << "::android::sp<" << iface << "> " << kDelegateImplVarName << ";\n";
  out.Dedent();
  out << "};  // class " << d_name << "\n";
}

// Collect all includes for the type's server header. Nested types are visited as well via
// VisitTopDown.
void GenerateServerHeaderIncludes(CodeWriter& out, const AidlDefinedType& defined_type,
                                  const AidlTypenames& typenames, const Options& options) {
  struct Visitor : AidlVisitor {
    const AidlTypenames& typenames;
    const Options& options;
    std::set<std::string> includes;
    Visitor(const AidlTypenames& typenames, const Options& options)
        : typenames(typenames), options(options) {}

    // Collect includes for each type reference
    void Visit(const AidlTypeSpecifier& type) override {
      // Add Bn* header files for types used in this header. The *Delegator
      // definitions require them.
      const auto defined_type = type.GetDefinedType();
      if (defined_type && defined_type->AsInterface()) {
        if (!isKnownUndefinedInterface(defined_type->GetCanonicalName())) {
          includes.insert(HeaderFile(*defined_type, ClassNames::SERVER, /*use_os_sep=*/false));
        }
      }
    }

    // Collect implementation-specific includes for each type definition
    void Visit(const AidlInterface& iface) override {
      includes.insert(HeaderFile(iface, ClassNames::SERVER, false));
    }
  } v(typenames, options);
  VisitTopDown(v, defined_type);

  v.includes.insert(kBinderDelegateHeader);
  for (const auto& path : v.includes) {
    out << "#include <" << path << ">\n";
  }
  out << "\n";
}

void GenerateServerHeader(CodeWriter& out, const AidlInterface& interface,
                          const AidlTypenames& typenames, const Options& options) {
  out << "#pragma once\n\n";
  out << "#include <binder/IInterface.h>\n";
  out << "#include <" << HeaderFile(interface, ClassNames::RAW, false) << ">\n";
  if (options.GenLog()) {
    out << "#include <functional>\n";  // for std::function
    out << "#include <android/binder_to_string.h>\n";
  }
  GenerateServerHeaderIncludes(out, interface, typenames, options);
  out << "\n";
  EnterNamespace(out, interface);
  GenerateServerClassDecl(out, interface, typenames, options);
  LeaveNamespace(out, interface);
}

void GenerateClassDecl(CodeWriter& out, const AidlDefinedType& defined_type,
                       const AidlTypenames& typenames, const Options& options);

void GenerateNestedTypeDecls(CodeWriter& out, const AidlDefinedType& type,
                             const AidlTypenames& typenames, const Options& options) {
  auto visit = [&](const auto& nested) { GenerateClassDecl(out, nested, typenames, options); };
  AIDL_FATAL_IF(!TopologicalVisit(type.GetNestedTypes(), visit), type) << "Cycle detected.";
}

void GenerateInterfaceClassDecl(CodeWriter& out, const AidlInterface& interface,
                                const AidlTypenames& typenames, const Options& options) {
  const string i_name = ClassName(interface, ClassNames::INTERFACE);
  out << "class " << ClassName(interface, ClassNames::DELEGATOR_IMPL) << ";\n\n";
  out << "class";
  GenerateDeprecated(out, interface);
  out << " " << i_name << " : public ::android::IInterface {\n";
  out << "public:\n";
  out.Indent();
  out << "typedef " << ClassName(interface, ClassNames::DELEGATOR_IMPL) << " DefaultDelegator;\n";
  out << "DECLARE_META_INTERFACE(" << ClassName(interface, ClassNames::BASE) << ")\n";
  if (options.Version() > 0) {
    out << "const int32_t VERSION = " << std::to_string(options.Version()) << ";\n";
  }
  if (!options.Hash().empty()) {
    out << "const std::string HASH = \"" << options.Hash() << "\";\n";
  }
  GenerateNestedTypeDecls(out, interface, typenames, options);
  GenerateConstantDeclarations(out, interface, typenames);
  for (const auto& method : interface.GetMethods()) {
    if (method->IsUserDefined()) {
      out << "virtual ";
      GenerateMethodDecl(out, typenames, *method, /*clazz=*/"");
      GenerateDeprecated(out, *method);
      out << " = 0;\n";
    } else if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
      out << "virtual int32_t " << method->GetName() << "() = 0;\n";
    } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
      out << "virtual std::string " << method->GetName() << "() = 0;\n";
    }
  }
  out.Dedent();
  out << "};  // class " << i_name << "\n";
  out << "\n";

  // Implement the default impl class.
  const string default_impl = ClassName(interface, ClassNames::DEFAULT_IMPL);
  out << "class";
  GenerateDeprecated(out, interface);
  out << " " << default_impl << " : public " << i_name << " {\n";
  out << "public:\n";
  out.Indent();
  // onAsBinder returns nullptr as this interface is not associated with a
  // real binder.
  out << "::android::IBinder* onAsBinder() override {\n"
      << "  return nullptr;\n"
      << "}\n";

  // Each interface method by default returns UNKNOWN_TRANSACTION with is
  // the same status that is returned by transact() when the method is
  // not implemented in the server side. In other words, these default
  // methods do nothing; they only exist to aid making a real default
  // impl class without having to override all methods in an interface.
  for (const auto& method : interface.GetMethods()) {
    if (method->IsUserDefined()) {
      out << "::android::binder::Status " << method->GetName() << "("
          << GenerateArgList(typenames, *method, /*for_declaration=*/true, /*type_name_only=*/true)
          << ") override";
      GenerateDeprecated(out, *method);
      out << " {\n"
          << "  return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);\n"
          << "}\n";
    } else if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
      out << "int32_t " << kGetInterfaceVersion << "() override {\n"
          << "  return 0;\n"
          << "}\n";
    } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
      out << "std::string " << kGetInterfaceHash << "() override {\n"
          << "  return \"\";\n"
          << "}\n";
    }
  }
  out.Dedent();
  out << "};  // class " << default_impl << "\n";

  // When an interface is nested, every class should be defined together here
  // because we don't have separate headers for them.
  // (e.g. IFoo, IFooDefault, BpFoo, BnFoo, IFooDelegator)
  if (interface.GetParentType()) {
    GenerateClientClassDecl(out, interface, typenames, options);
    GenerateServerClassDecl(out, interface, typenames, options);
  }
}

void GenerateReadFromParcel(CodeWriter& out, const AidlStructuredParcelable& parcel,
                            const AidlTypenames& typenames) {
  out << "::android::status_t _aidl_ret_status = ::android::OK;\n";
  out << "size_t _aidl_start_pos = _aidl_parcel->dataPosition();\n";
  out << "int32_t _aidl_parcelable_raw_size = 0;\n";
  out << "_aidl_ret_status = _aidl_parcel->readInt32(&_aidl_parcelable_raw_size);\n";
  out << "if (((_aidl_ret_status) != (::android::OK))) {\n";
  out << "  return _aidl_ret_status;\n";
  out << "}\n";
  out << "if (_aidl_parcelable_raw_size < 4) return ::android::BAD_VALUE;\n";
  out << "size_t _aidl_parcelable_size = static_cast<size_t>(_aidl_parcelable_raw_size);\n";
  out << "if (_aidl_start_pos > INT32_MAX - _aidl_parcelable_size) return ::android::BAD_VALUE;\n";
  for (const auto& variable : parcel.GetFields()) {
    string method = ParcelReadMethodOf(variable->GetType(), typenames);
    string arg = ParcelReadCastOf(variable->GetType(), typenames, "&" + variable->GetName());
    out << "if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) {\n";
    out << "  _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size);\n";
    out << "  return _aidl_ret_status;\n";
    out << "}\n";
    out << "_aidl_ret_status = _aidl_parcel->" << method << "(" << arg << ");\n";
    out << "if (((_aidl_ret_status) != (::android::OK))) {\n";
    out << "  return _aidl_ret_status;\n";
    out << "}\n";
  }
  out << "_aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size);\n";
  out << "return _aidl_ret_status;\n";
}

void GenerateWriteToParcel(CodeWriter& out, const AidlStructuredParcelable& parcel,
                           const AidlTypenames& typenames) {
  out << "::android::status_t _aidl_ret_status = ::android::OK;\n";
  out << "auto _aidl_start_pos = " << kParcelVarName << "->dataPosition();\n";
  out << kParcelVarName << "->writeInt32(0);\n";
  for (const auto& variable : parcel.GetFields()) {
    string method = ParcelWriteMethodOf(variable->GetType(), typenames);
    string arg = ParcelWriteCastOf(variable->GetType(), typenames, variable->GetName());
    out << "_aidl_ret_status = " << kParcelVarName << "->" << method << "(" << arg << ");\n";
    out << "if (((_aidl_ret_status) != (::android::OK))) {\n";
    out << "  return _aidl_ret_status;\n";
    out << "}\n";
  }
  out << "auto _aidl_end_pos = " << kParcelVarName << "->dataPosition();\n";
  out << kParcelVarName << "->setDataPosition(_aidl_start_pos);\n";
  out << kParcelVarName << "->writeInt32(_aidl_end_pos - _aidl_start_pos);\n";
  out << kParcelVarName << "->setDataPosition(_aidl_end_pos);\n";
  out << "return _aidl_ret_status;\n";
}

ParcelWriterContext GetParcelWriterContext(const AidlTypenames& typenames) {
  return ParcelWriterContext{
      .status_type = kAndroidStatusLiteral,
      .status_ok = kAndroidStatusOk,
      .status_bad = kAndroidStatusBadValue,
      .read_func =
          [&](CodeWriter& out, const string& var, const AidlTypeSpecifier& type) {
            out << fmt::format("{}->{}({})", kParcelVarName, ParcelReadMethodOf(type, typenames),
                               ParcelReadCastOf(type, typenames, "&" + var));
          },
      .write_func =
          [&](CodeWriter& out, const string& value, const AidlTypeSpecifier& type) {
            out << fmt::format("{}->{}({})", kParcelVarName, ParcelWriteMethodOf(type, typenames),
                               ParcelWriteCastOf(type, typenames, value));
          },
  };
}

void GenerateReadFromParcel(CodeWriter& out, const AidlUnionDecl& decl,
                            const AidlTypenames& typenames) {
  UnionWriter uw{decl, typenames, &CppNameOf, &ConstantValueDecorator};
  uw.ReadFromParcel(out, GetParcelWriterContext(typenames));
}

void GenerateWriteToParcel(CodeWriter& out, const AidlUnionDecl& decl,
                           const AidlTypenames& typenames) {
  UnionWriter uw{decl, typenames, &CppNameOf, &ConstantValueDecorator};
  uw.WriteToParcel(out, GetParcelWriterContext(typenames));
}

void GenerateParcelFields(CodeWriter& out, const AidlStructuredParcelable& decl,
                          const AidlTypenames& typenames) {
  for (const auto& variable : decl.GetFields()) {
    const auto& type = variable->GetType();
    std::string cpp_type = CppNameOf(type, typenames);
    out << cpp_type;
    GenerateDeprecated(out, *variable);
    out << " " << variable->GetName();
    if (variable->GetDefaultValue()) {
      out << " = " << variable->ValueString(ConstantValueDecorator);
    } else {
      // Some types needs to be explicitly initialized even when no default value is set.
      // - ParcelableHolder should be initialized with stability
      // - enum should be zero initialized, otherwise the value will be indeterminate
      // - fixed-size arrays should be initialized, otherwise the value will be indeterminate
      if (type.GetName() == "ParcelableHolder") {
        if (decl.IsVintfStability()) {
          out << " { ::android::Parcelable::Stability::STABILITY_VINTF }";
        } else {
          out << " { ::android::Parcelable::Stability::STABILITY_LOCAL }";
        }
      } else if (typenames.GetEnumDeclaration(type) && !type.IsArray()) {
        out << " = " << cpp_type << "(0)";
      } else if (type.IsFixedSizeArray() && !type.IsNullable()) {
        out << " = {{}}";
      }
    }
    out << ";\n";
  }
}

void GenerateParcelFields(CodeWriter& out, const AidlUnionDecl& decl,
                          const AidlTypenames& typenames) {
  UnionWriter uw{decl, typenames, &CppNameOf, &ConstantValueDecorator};
  uw.PublicFields(out);
}

template <typename ParcelableType>
void GenerateParcelClassDecl(CodeWriter& out, const ParcelableType& parcel,
                             const AidlTypenames& typenames, const Options& options) {
  const string clazz = parcel.GetName();

  ClangDiagnosticIgnoreDeprecated guard(out, HasDeprecatedField(parcel));
  out << TemplateDecl(parcel);
  out << "class";
  GenerateDeprecated(out, parcel);
  out << " " << clazz << " : public ::android::Parcelable {\n";
  out << "public:\n";
  out.Indent();

  GenerateNestedTypeDecls(out, parcel, typenames, options);
  GenerateParcelFields(out, parcel, typenames);
  GenerateParcelableComparisonOperators(out, parcel);
  GenerateConstantDeclarations(out, parcel, typenames);

  if (parcel.IsVintfStability()) {
    out << "::android::Parcelable::Stability getStability() const override { return "
           "::android::Parcelable::Stability::STABILITY_VINTF; }\n";
  }

  out << kAndroidStatusLiteral << " readFromParcel(const ::android::Parcel* _aidl_parcel) final;\n";
  out << kAndroidStatusLiteral << " writeToParcel(::android::Parcel* _aidl_parcel) const final;\n";

  const string canonical_name = parcel.GetCanonicalName();
  out << "static const ::android::String16& getParcelableDescriptor() {\n"
      << "  static const ::android::StaticString16 DESCRIPTOR (u\"" << canonical_name << "\");\n"
      << "  return DESCRIPTOR;\n"
      << "}\n";

  GenerateToString(out, parcel);

  out.Dedent();

  if (auto decl = AidlCast<AidlUnionDecl>(parcel); decl) {
    out << "private:\n";
    out.Indent();
    UnionWriter uw{*decl, typenames, &CppNameOf, &ConstantValueDecorator};
    uw.PrivateFields(out);
    out.Dedent();
  }

  out << "};  // class " << clazz << "\n";
}

template <typename T>
void GenerateParcelSource(CodeWriter& out, const T& parcel, const AidlTypenames& typenames,
                          const Options&) {
  string q_name = GetQualifiedName(parcel);
  if (parcel.IsGeneric()) {
    q_name += "<" + Join(parcel.GetTypeParameters(), ",") + ">";
  }

  out << "#include <" << CppHeaderForType(parcel) << ">\n\n";

  EnterNamespace(out, parcel);
  GenerateConstantDefinitions(out, parcel, typenames, TemplateDecl(parcel), q_name);

  {
    ClangDiagnosticIgnoreDeprecated guard(out, HasDeprecatedField(parcel));
    out << TemplateDecl(parcel);
    out << "::android::status_t " << q_name << "::readFromParcel(const ::android::Parcel* "
        << kParcelVarName << ") {\n";
    out.Indent();
    GenerateReadFromParcel(out, parcel, typenames);
    out.Dedent();
    out << "}\n";

    out << TemplateDecl(parcel);
    out << "::android::status_t " << q_name << "::writeToParcel(::android::Parcel* "
        << kParcelVarName << ") const {\n";
    out.Indent();
    GenerateWriteToParcel(out, parcel, typenames);
    out.Dedent();
    out << "}\n";
  }
  LeaveNamespace(out, parcel);
}

void GenerateEnumClassDecl(CodeWriter& out, const AidlEnumDeclaration& enum_decl,
                           const AidlTypenames& typenames) {
  cpp::GenerateEnumClassDecl(out, enum_decl, CppNameOf(enum_decl.GetBackingType(), typenames),
                             ConstantValueDecorator);
}

void GenerateClassDecl(CodeWriter& out, const AidlDefinedType& defined_type,
                       const AidlTypenames& typenames, const Options& options) {
  if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
    GenerateInterfaceClassDecl(out, *iface, typenames, options);
  } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
    GenerateParcelClassDecl(out, *parcelable, typenames, options);
  } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
    GenerateParcelClassDecl(out, *union_decl, typenames, options);
  } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
    GenerateEnumClassDecl(out, *enum_decl, typenames);
  } else {
    AIDL_FATAL(defined_type) << "Unrecognized type sent for CPP generation.";
  }
}

}  // namespace internals

using namespace internals;

// Collect all includes for the type's header. Nested types are visited as well via VisitTopDown.
void GenerateHeaderIncludes(CodeWriter& out, const AidlDefinedType& defined_type,
                            const AidlTypenames& typenames, const Options& options) {
  struct Visitor : AidlVisitor {
    const AidlTypenames& typenames;
    const Options& options;
    std::set<std::string> includes;
    Visitor(const AidlTypenames& typenames, const Options& options)
        : typenames(typenames), options(options) {}

    // Collect includes for each type reference including built-in type
    void Visit(const AidlTypeSpecifier& type) override {
      cpp::AddHeaders(type, typenames, &includes);
    }

    // Collect implementation-specific includes for each type definition
    void Visit(const AidlInterface& iface) override {
      includes.insert(kIBinderHeader);        // IBinder
      includes.insert(kIInterfaceHeader);     // IInterface
      includes.insert(kStatusHeader);         // Status
      includes.insert(kStrongPointerHeader);  // sp<>

      if (options.GenTraces()) {
        includes.insert(kTraceHeader);
      }

      // For a nested interface, client/server classes are declared the same header as well.
      if (iface.GetParentType()) {
        includes.insert(kBinderDelegateHeader);  // Delegate.h
        // client/server class provides logFunc when gen_log is on
        if (options.GenLog()) {
          includes.insert("functional");                  // std::function for logFunc
          includes.insert("android/binder_to_string.h");  // Generic ToString helper
        }
      }
    }

    void Visit(const AidlStructuredParcelable&) override {
      AddParcelableCommonHeaders();
      includes.insert("tuple");  // std::tie in comparison operators
    }

    void Visit(const AidlUnionDecl& union_decl) override {
      AddParcelableCommonHeaders();
      auto union_headers = cpp::UnionWriter::GetHeaders(union_decl);
      includes.insert(std::begin(union_headers), std::end(union_headers));
    }

    void Visit(const AidlEnumDeclaration&) override {
      includes.insert("array");           // used in enum_values
      includes.insert("binder/Enums.h");  // provides enum_range
      includes.insert("string");          // toString() returns std::string
    }

    void AddParcelableCommonHeaders() {
      includes.insert(kParcelHeader);                 // Parcel in readFromParcel/writeToParcel
      includes.insert(kStatusHeader);                 // Status
      includes.insert(kString16Header);               // String16 in getParcelableDescriptor
      includes.insert("android/binder_to_string.h");  // toString()
    }
  } v(typenames, options);
  VisitTopDown(v, defined_type);

  for (const auto& path : v.includes) {
    out << "#include <" << path << ">\n";
  }
  out << "\n";
  if (v.includes.count("cassert")) {
    // TODO(b/31559095) bionic on host should define __assert2
    out << "#ifndef __BIONIC__\n#define __assert2(a,b,c,d) ((void)0)\n#endif\n\n";
  }
}

// Generic parcelables and enum utilities should be defined in header.
void GenerateHeaderDefinitions(CodeWriter& out, const AidlDefinedType& defined_type,
                               const AidlTypenames& typenames, const Options& options) {
  struct Visitor : AidlVisitor {
    CodeWriter& out;
    const AidlTypenames& typenames;
    const Options& options;
    Visitor(CodeWriter& out, const AidlTypenames& typenames, const Options& options)
        : out(out), typenames(typenames), options(options) {}

    void Visit(const AidlEnumDeclaration& enum_decl) override {
      const auto backing_type = CppNameOf(enum_decl.GetBackingType(), typenames);
      EnterNamespace(out, enum_decl);
      out << GenerateEnumToString(enum_decl, backing_type);
      LeaveNamespace(out, enum_decl);

      out << "namespace android {\n";
      out << "namespace internal {\n";
      out << GenerateEnumValues(enum_decl, {""});
      out << "}  // namespace internal\n";
      out << "}  // namespace android\n";
    }

    void Visit(const AidlStructuredParcelable& parcelable) override {
      if (parcelable.IsGeneric()) {
        GenerateParcelSource(out, parcelable, typenames, options);
      }
    }

    void Visit(const AidlUnionDecl& union_decl) override {
      if (union_decl.IsGeneric()) {
        GenerateParcelSource(out, union_decl, typenames, options);
      }
    }

  } v(out, typenames, options);
  VisitTopDown(v, defined_type);
}

void GenerateHeader(CodeWriter& out, const AidlDefinedType& defined_type,
                    const AidlTypenames& typenames, const Options& options) {
  if (auto parcelable = AidlCast<AidlParcelable>(defined_type); parcelable) {
    out << "#error TODO(b/111362593) parcelables do not have headers";
    return;
  }
  out << "#pragma once\n\n";
  GenerateHeaderIncludes(out, defined_type, typenames, options);
  GenerateForwardDecls(out, defined_type, false);
  EnterNamespace(out, defined_type);
  // Each class decl contains its own nested types' class decls
  GenerateClassDecl(out, defined_type, typenames, options);
  LeaveNamespace(out, defined_type);
  GenerateHeaderDefinitions(out, defined_type, typenames, options);
}

void GenerateClientHeader(CodeWriter& out, const AidlDefinedType& defined_type,
                          const AidlTypenames& typenames, const Options& options) {
  if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
    GenerateClientHeader(out, *iface, typenames, options);
  } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
    out << "#error TODO(b/111362593) parcelables do not have bp classes";
  } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
    out << "#error TODO(b/111362593) parcelables do not have bp classes";
  } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
    out << "#error TODO(b/111362593) enums do not have bp classes";
  } else if (auto parcelable = AidlCast<AidlParcelable>(defined_type); parcelable) {
    out << "#error TODO(b/111362593) parcelables do not have bp classes";
  } else {
    AIDL_FATAL(defined_type) << "Unrecognized type sent for CPP generation.";
  }
}

void GenerateServerHeader(CodeWriter& out, const AidlDefinedType& defined_type,
                          const AidlTypenames& typenames, const Options& options) {
  if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
    GenerateServerHeader(out, *iface, typenames, options);
  } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
    out << "#error TODO(b/111362593) parcelables do not have bn classes";
  } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
    out << "#error TODO(b/111362593) parcelables do not have bn classes";
  } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
    out << "#error TODO(b/111362593) enums do not have bn classes";
  } else if (auto parcelable = AidlCast<AidlParcelable>(defined_type); parcelable) {
    out << "#error TODO(b/111362593) parcelables do not have bn classes";
  } else {
    AIDL_FATAL(defined_type) << "Unrecognized type sent for CPP generation.";
  }
}

void GenerateSource(CodeWriter& out, const AidlDefinedType& defined_type,
                    const AidlTypenames& typenames, const Options& options) {
  struct Visitor : AidlVisitor {
    CodeWriter& out;
    const AidlTypenames& typenames;
    const Options& options;
    Visitor(CodeWriter& out, const AidlTypenames& typenames, const Options& options)
        : out(out), typenames(typenames), options(options) {}

    void Visit(const AidlInterface& interface) override {
      GenerateInterfaceSource(out, interface, typenames, options);
      GenerateClientSource(out, interface, typenames, options);
      GenerateServerSource(out, interface, typenames, options);
    }

    void Visit(const AidlStructuredParcelable& parcelable) override {
      if (!parcelable.IsGeneric()) {
        GenerateParcelSource(out, parcelable, typenames, options);
      } else {
        out << "\n";
      }
    }

    void Visit(const AidlUnionDecl& union_decl) override {
      if (!union_decl.IsGeneric()) {
        GenerateParcelSource(out, union_decl, typenames, options);
      } else {
        out << "\n";
      }
    }

    void Visit(const AidlEnumDeclaration& enum_decl) override {
      if (!enum_decl.GetParentType()) {
        out << "// This file is intentionally left blank as placeholder for enum declaration.\n";
      }
    }

    void Visit(const AidlParcelable& parcelable) override {
      AIDL_FATAL_IF(parcelable.GetParentType(), parcelable)
          << "Unstructured parcelable can't be nested.";
      out << "// This file is intentionally left blank as placeholder for parcel declaration.\n";
    }
  } v(out, typenames, options);
  VisitTopDown(v, defined_type);
}

bool GenerateCpp(const string& output_file, const Options& options, const AidlTypenames& typenames,
                 const AidlDefinedType& defined_type, const IoDelegate& io_delegate) {
  if (!ValidateOutputFilePath(output_file, options, defined_type)) {
    return false;
  }

  using GenFn = void (*)(CodeWriter & out, const AidlDefinedType& defined_type,
                         const AidlTypenames& typenames, const Options& options);
  // Wrap Generate* function to handle CodeWriter for a file.
  auto gen = [&](auto file, GenFn fn) {
    unique_ptr<CodeWriter> writer(io_delegate.GetCodeWriter(file));
    fn(*writer, defined_type, typenames, options);
    AIDL_FATAL_IF(!writer->Close(), defined_type) << "I/O Error!";
    return true;
  };

  return gen(options.OutputHeaderDir() + HeaderFile(defined_type, ClassNames::RAW),
             &GenerateHeader) &&
         gen(options.OutputHeaderDir() + HeaderFile(defined_type, ClassNames::CLIENT),
             &GenerateClientHeader) &&
         gen(options.OutputHeaderDir() + HeaderFile(defined_type, ClassNames::SERVER),
             &GenerateServerHeader) &&
         gen(output_file, &GenerateSource);
}

}  // namespace cpp
}  // namespace aidl
}  // namespace android
