Prepare CPP backend for nested interface

This refactoring allows nested interfaces to emit all interface-derived
classes (Bp/Bn/Default/etc) in a parent type.

To support nested interface types, new IMPLEMENT_META_INTERFACE variant
macro is added.

Since we don't support nested interface types at validate phase, this
doesn't change the observable behavior.

Bug: 182508839
Test: aidl_integration_test
Change-Id: I2db3f48db26d2b3d5c96de9830d8d2a1b1915f63
diff --git a/aidl_to_cpp.cpp b/aidl_to_cpp.cpp
index 24d27e3..06abf6c 100644
--- a/aidl_to_cpp.cpp
+++ b/aidl_to_cpp.cpp
@@ -222,8 +222,8 @@
   return raw_value;
 };
 
-std::string GetTransactionIdFor(const AidlInterface& iface, const AidlMethod& method) {
-  return ClassName(iface, ClassNames::SERVER) + "::TRANSACTION_" + method.GetName();
+std::string GetTransactionIdFor(const std::string& clazz, const AidlMethod& method) {
+  return clazz + "::TRANSACTION_" + method.GetName();
 }
 
 std::string CppNameOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames) {
diff --git a/aidl_to_cpp.h b/aidl_to_cpp.h
index 620897f..eab471e 100644
--- a/aidl_to_cpp.h
+++ b/aidl_to_cpp.h
@@ -34,7 +34,7 @@
   const bool isPointer;           // whether the variable 'name' is a pointer or not
 };
 
-std::string GetTransactionIdFor(const AidlInterface& iface, const AidlMethod& method);
+std::string GetTransactionIdFor(const std::string& clazz, const AidlMethod& method);
 
 std::string CppNameOf(const AidlTypeSpecifier& type, const AidlTypenames& typenames);
 
diff --git a/generate_cpp.cpp b/generate_cpp.cpp
index 8beb8eb..446581e 100644
--- a/generate_cpp.cpp
+++ b/generate_cpp.cpp
@@ -163,7 +163,8 @@
                                const AidlInterface& interface, const AidlMethod& method,
                                const Options& options) {
   const string i_name = ClassName(interface, ClassNames::INTERFACE);
-  const string bp_name = ClassName(interface, ClassNames::CLIENT);
+  const string bp_name = GetQualifiedName(interface, ClassNames::CLIENT);
+  const string bn_name = GetQualifiedName(interface, ClassNames::SERVER);
 
   GenerateMethodDecl(out, typenames, method, bp_name);
   out << " {\n";
@@ -225,7 +226,7 @@
   if (interface.IsSensitiveData()) flags.push_back("::android::IBinder::FLAG_CLEAR_BUF");
 
   out.Write("%s = remote()->transact(%s, %s, &%s, %s);\n", kAndroidStatusVarName,
-            GetTransactionIdFor(interface, method).c_str(), kDataVarName, kReplyVarName,
+            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
@@ -303,20 +304,20 @@
 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) {
-    const string iface = ClassName(interface, ClassNames::INTERFACE);
-    const string proxy = ClassName(interface, ClassNames::CLIENT);
     // 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 " << proxy << "::" << kGetInterfaceVersion << "() {\n"
+    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(interface, method) << ", data, &reply);\n"
+        << GetTransactionIdFor(bn_name, method) << ", data, &reply);\n"
         << "    if (err == ::android::OK) {\n"
         << "      ::android::binder::Status _aidl_status;\n"
         << "      err = _aidl_status.readFromParcel(reply);\n"
@@ -330,16 +331,14 @@
     out << "\n";
   }
   if (method.GetName() == kGetInterfaceHash && !options.Hash().empty()) {
-    const string iface = ClassName(interface, ClassNames::INTERFACE);
-    const string proxy = ClassName(interface, ClassNames::CLIENT);
-    out << "std::string " << proxy << "::" << kGetInterfaceHash << "() {\n"
+    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(interface, method) << ", data, &reply);\n"
+        << GetTransactionIdFor(bn_name, method) << ", data, &reply);\n"
         << "    if (err == ::android::OK) {\n"
         << "      ::android::binder::Status _aidl_status;\n"
         << "      err = _aidl_status.readFromParcel(reply);\n"
@@ -370,20 +369,22 @@
   }
   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.
-  const string i_name = ClassName(interface, ClassNames::INTERFACE);
-  const string bp_name = ClassName(interface, ClassNames::CLIENT);
-  out << bp_name << "::" << bp_name << "(const ::android::sp<::android::IBinder>& _aidl_impl)\n";
+  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 " + bp_name + "::TransactionLog&)> " << bp_name
+    out << "std::function<void(const " + q_name + "::TransactionLog&)> " << q_name
         << "::logFunc;\n";
     out << "\n";
   }
@@ -440,7 +441,7 @@
 void GenerateServerTransaction(CodeWriter& out, const AidlInterface& interface,
                                const AidlMethod& method, const AidlTypenames& typenames,
                                const Options& options) {
-  const string bn_name = ClassName(interface, ClassNames::SERVER);
+  const string bn_name = GetQualifiedName(interface, ClassNames::SERVER);
 
   // Declare all the parameters now.  In the common case, we expect no errors
   // in serialization.
@@ -546,9 +547,10 @@
 
 }  // namespace
 
-void GenerateOnTransact(CodeWriter& out, const AidlInterface& interface,
-                        const AidlTypenames& typenames, const Options& options) {
+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(),
@@ -560,7 +562,7 @@
   }
 
   out.Write("%s %s::onTransact(uint32_t %s, const %s& %s, %s* %s, uint32_t %s) {\n",
-            kAndroidStatusLiteral, bn_name.c_str(), kCodeVarName, kAndroidParcelLiteral,
+            kAndroidStatusLiteral, q_name.c_str(), kCodeVarName, kAndroidParcelLiteral,
             kDataVarName, kAndroidParcelLiteral, kReplyVarName, kFlagsVarName);
   out.Indent();
   // Declare the status_t variable
@@ -571,7 +573,7 @@
 
   // The switch statement has a case statement for each transaction code.
   for (const auto& method : interface.GetMethods()) {
-    out.Write("case %s:\n", GetTransactionIdFor(interface, *method).c_str());
+    out.Write("case %s:\n", GetTransactionIdFor(bn_name, *method).c_str());
     out << "{\n";
     out.Indent();
     if (method->IsUserDefined()) {
@@ -629,13 +631,15 @@
   }
   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", bn_name.c_str(), bn_name.c_str());
+  out.Write("%s::%s()\n", q_name.c_str(), bn_name.c_str());
   out << "{\n";
   out.Indent();
   if (interface.IsVintfStability()) {
@@ -647,20 +651,20 @@
   out << "}\n";
   out << "\n";
 
-  GenerateOnTransact(out, interface, typenames, options);
+  GenerateServerOnTransact(out, interface, typenames, options);
 
   if (options.Version() > 0) {
-    out << "int32_t " << bn_name << "::" << kGetInterfaceVersion << "() {\n"
-        << "  return " << ClassName(interface, ClassNames::INTERFACE) << "::VERSION;\n"
+    out << "int32_t " << q_name << "::" << kGetInterfaceVersion << "() {\n"
+        << "  return " << i_name << "::VERSION;\n"
         << "}\n";
   }
   if (!options.Hash().empty()) {
-    out << "std::string " << bn_name << "::" << kGetInterfaceHash << "() {\n"
-        << "  return " << ClassName(interface, ClassNames::INTERFACE) << "::HASH;\n"
+    out << "std::string " << q_name << "::" << kGetInterfaceHash << "() {\n"
+        << "  return " << i_name << "::HASH;\n"
         << "}\n";
   }
   if (options.GenLog()) {
-    out << "std::function<void(const " + bn_name + "::TransactionLog&)> " << bn_name
+    out << "std::function<void(const " + q_name + "::TransactionLog&)> " << q_name
         << "::logFunc;\n";
   }
 
@@ -674,8 +678,14 @@
 
   EnterNamespace(out, interface);
 
-  out << fmt::format("DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE({}, \"{}\")\n",
-                     ClassName(interface, ClassNames::BASE), interface.GetDescriptor());
+  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));
@@ -683,22 +693,11 @@
   LeaveNamespace(out, interface);
 }
 
-void GenerateClientHeader(CodeWriter& out, const AidlInterface& interface,
-                          const AidlTypenames& typenames, const Options& options) {
+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 << "#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);
   out << "class";
   GenerateDeprecated(out, interface);
   out << " " << bp_name << " : public ::android::BpInterface<" << iface << "> {\n";
@@ -741,16 +740,14 @@
   }
 
   out << "};  // class " << bp_name << "\n";
-  LeaveNamespace(out, interface);
 }
 
-void GenerateServerHeader(CodeWriter& out, const AidlInterface& interface,
+void GenerateClientHeader(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 << "#pragma once\n\n";
-  out << "#include <binder/IInterface.h>\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
@@ -758,6 +755,15 @@
   }
   out << "\n";
   EnterNamespace(out, interface);
+  GenerateClientClassDecl(out, interface, typenames, options);
+  LeaveNamespace(out, interface);
+}
+
+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 "
@@ -839,7 +845,20 @@
   out << "::android::sp<" << iface << "> " << kDelegateImplVarName << ";\n";
   out.Dedent();
   out << "};  // class " << d_name << "\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";
+  }
+  out << "\n";
+  EnterNamespace(out, interface);
+  GenerateServerClassDecl(out, interface, typenames, options);
   LeaveNamespace(out, interface);
 }
 
@@ -925,6 +944,14 @@
   }
   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);
+  }
 }
 
 string GetInitializer(const AidlTypenames& typenames, const AidlVariableDeclaration& variable) {
@@ -1178,7 +1205,7 @@
     }
 
     // Collect implementation-specific includes for each type definition
-    void Visit(const AidlInterface&) override {
+    void Visit(const AidlInterface& iface) override {
       includes.insert(kIBinderHeader);        // IBinder
       includes.insert(kIInterfaceHeader);     // IInterface
       includes.insert(kStatusHeader);         // Status
@@ -1187,6 +1214,15 @@
       if (options.GenTraces()) {
         includes.insert(kTraceHeader);
       }
+
+      // For a nested interface, client/server classes are declared the same header as well.
+      if (iface.GetParentType()) {
+        // 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 {