Home | History | Annotate | Download | only in aidl
      1 /*
      2  * Copyright (C) 2015, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "generate_cpp.h"
     18 
     19 #include <cctype>
     20 #include <cstring>
     21 #include <memory>
     22 #include <random>
     23 #include <set>
     24 #include <string>
     25 
     26 #include <android-base/stringprintf.h>
     27 
     28 #include "aidl_language.h"
     29 #include "ast_cpp.h"
     30 #include "code_writer.h"
     31 #include "logging.h"
     32 #include "os.h"
     33 
     34 using android::base::StringPrintf;
     35 using std::string;
     36 using std::unique_ptr;
     37 using std::vector;
     38 using std::set;
     39 
     40 namespace android {
     41 namespace aidl {
     42 namespace cpp {
     43 namespace internals {
     44 namespace {
     45 
     46 const char kAndroidStatusVarName[] = "_aidl_ret_status";
     47 const char kCodeVarName[] = "_aidl_code";
     48 const char kFlagsVarName[] = "_aidl_flags";
     49 const char kDataVarName[] = "_aidl_data";
     50 const char kErrorLabel[] = "_aidl_error";
     51 const char kImplVarName[] = "_aidl_impl";
     52 const char kReplyVarName[] = "_aidl_reply";
     53 const char kReturnVarName[] = "_aidl_return";
     54 const char kStatusVarName[] = "_aidl_status";
     55 const char kAndroidParcelLiteral[] = "::android::Parcel";
     56 const char kAndroidStatusLiteral[] = "::android::status_t";
     57 const char kAndroidStatusOk[] = "::android::OK";
     58 const char kBinderStatusLiteral[] = "::android::binder::Status";
     59 const char kIBinderHeader[] = "binder/IBinder.h";
     60 const char kIInterfaceHeader[] = "binder/IInterface.h";
     61 const char kParcelHeader[] = "binder/Parcel.h";
     62 const char kStatusHeader[] = "binder/Status.h";
     63 const char kStrongPointerHeader[] = "utils/StrongPointer.h";
     64 
     65 unique_ptr<AstNode> BreakOnStatusNotOk() {
     66   IfStatement* ret = new IfStatement(new Comparison(
     67       new LiteralExpression(kAndroidStatusVarName), "!=",
     68       new LiteralExpression(kAndroidStatusOk)));
     69   ret->OnTrue()->AddLiteral("break");
     70   return unique_ptr<AstNode>(ret);
     71 }
     72 
     73 unique_ptr<AstNode> GotoErrorOnBadStatus() {
     74   IfStatement* ret = new IfStatement(new Comparison(
     75       new LiteralExpression(kAndroidStatusVarName), "!=",
     76       new LiteralExpression(kAndroidStatusOk)));
     77   ret->OnTrue()->AddLiteral(StringPrintf("goto %s", kErrorLabel));
     78   return unique_ptr<AstNode>(ret);
     79 }
     80 
     81 
     82 unique_ptr<AstNode> ReturnOnStatusNotOk() {
     83   IfStatement* ret = new IfStatement(new Comparison(
     84       new LiteralExpression(kAndroidStatusVarName), "!=",
     85       new LiteralExpression(kAndroidStatusOk)));
     86   ret->OnTrue()->AddLiteral(StringPrintf("return %s", kAndroidStatusVarName));
     87   return unique_ptr<AstNode>(ret);
     88 }
     89 
     90 string UpperCase(const std::string& s) {
     91   string result = s;
     92   for (char& c : result)
     93     c = toupper(c);
     94   return result;
     95 }
     96 
     97 string BuildVarName(const AidlArgument& a) {
     98   string prefix = "out_";
     99   if (a.GetDirection() & AidlArgument::IN_DIR) {
    100     prefix = "in_";
    101   }
    102   return prefix + a.GetName();
    103 }
    104 
    105 ArgList BuildArgList(const TypeNamespace& types,
    106                      const AidlMethod& method,
    107                      bool for_declaration) {
    108   // Build up the argument list for the server method call.
    109   vector<string> method_arguments;
    110   for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
    111     string literal;
    112     if (for_declaration) {
    113       // Method declarations need types, pointers to out params, and variable
    114       // names that match the .aidl specification.
    115       const Type* type = a->GetType().GetLanguageType<Type>();
    116 
    117       literal = type->CppType();
    118 
    119       if (a->IsOut()) {
    120         literal = literal + "*";
    121       } else {
    122         // We pass in parameters that are not primitives by const reference.
    123         // Arrays of primitives are not primitives.
    124         if (!type->IsCppPrimitive() || a->GetType().IsArray()) {
    125           literal = "const " + literal + "&";
    126         }
    127       }
    128 
    129       literal += " " + a->GetName();
    130     } else {
    131       if (a->IsOut()) { literal = "&"; }
    132       literal += BuildVarName(*a);
    133     }
    134     method_arguments.push_back(literal);
    135   }
    136 
    137   const Type* return_type = method.GetType().GetLanguageType<Type>();
    138 
    139   if (return_type != types.VoidType()) {
    140     string literal;
    141     if (for_declaration) {
    142       literal = StringPrintf(
    143           "%s* %s", return_type->CppType().c_str(),
    144           kReturnVarName);
    145     } else {
    146       literal = string{"&"} + kReturnVarName;
    147     }
    148     method_arguments.push_back(literal);
    149   }
    150 
    151   return ArgList(method_arguments);
    152 }
    153 
    154 unique_ptr<Declaration> BuildMethodDecl(const AidlMethod& method,
    155                                         const TypeNamespace& types,
    156                                         bool for_interface) {
    157   uint32_t modifiers = 0;
    158   if (for_interface) {
    159     modifiers |= MethodDecl::IS_VIRTUAL;
    160     modifiers |= MethodDecl::IS_PURE_VIRTUAL;
    161   } else {
    162     modifiers |= MethodDecl::IS_OVERRIDE;
    163   }
    164 
    165   return unique_ptr<Declaration>{
    166       new MethodDecl{kBinderStatusLiteral,
    167                      method.GetName(),
    168                      BuildArgList(types, method, true /* for method decl */),
    169                      modifiers}};
    170 }
    171 
    172 unique_ptr<CppNamespace> NestInNamespaces(
    173     vector<unique_ptr<Declaration>> decls,
    174     const vector<string>& package) {
    175   if (package.empty()) {
    176     // We should also be checking this before we get this far, but do it again
    177     // for the sake of unit tests and meaningful errors.
    178     LOG(FATAL) << "C++ generation requires a package declaration "
    179                   "for namespacing";
    180   }
    181   auto it = package.crbegin();  // Iterate over the namespaces inner to outer
    182   unique_ptr<CppNamespace> inner{new CppNamespace{*it, std::move(decls)}};
    183   ++it;
    184   for (; it != package.crend(); ++it) {
    185     inner.reset(new CppNamespace{*it, std::move(inner)});
    186   }
    187   return inner;
    188 }
    189 
    190 unique_ptr<CppNamespace> NestInNamespaces(unique_ptr<Declaration> decl,
    191                                           const vector<string>& package) {
    192   vector<unique_ptr<Declaration>> decls;
    193   decls.push_back(std::move(decl));
    194   return NestInNamespaces(std::move(decls), package);
    195 }
    196 
    197 bool DeclareLocalVariable(const TypeNamespace& types, const AidlArgument& a,
    198                           StatementBlock* b) {
    199   const Type* cpp_type = a.GetType().GetLanguageType<Type>();
    200   if (!cpp_type) { return false; }
    201 
    202   string type = cpp_type->CppType();
    203 
    204   b->AddLiteral(type + " " + BuildVarName(a));
    205   return true;
    206 }
    207 
    208 string ClassName(const AidlInterface& interface, ClassNames type) {
    209   string c_name = interface.GetName();
    210 
    211   if (c_name.length() >= 2 && c_name[0] == 'I' && isupper(c_name[1]))
    212     c_name = c_name.substr(1);
    213 
    214   switch (type) {
    215     case ClassNames::CLIENT:
    216       c_name = "Bp" + c_name;
    217       break;
    218     case ClassNames::SERVER:
    219       c_name = "Bn" + c_name;
    220       break;
    221     case ClassNames::INTERFACE:
    222       c_name = "I" + c_name;
    223       break;
    224     case ClassNames::BASE:
    225       break;
    226   }
    227   return c_name;
    228 }
    229 
    230 string BuildHeaderGuard(const AidlInterface& interface,
    231                         ClassNames header_type) {
    232   string class_name = ClassName(interface, header_type);
    233   for (size_t i = 1; i < class_name.size(); ++i) {
    234     if (isupper(class_name[i])) {
    235       class_name.insert(i, "_");
    236       ++i;
    237     }
    238   }
    239   string ret = StringPrintf("AIDL_GENERATED_%s_%s_H_",
    240                             interface.GetPackage().c_str(),
    241                             class_name.c_str());
    242   for (char& c : ret) {
    243     if (c == '.') {
    244       c = '_';
    245     }
    246     c = toupper(c);
    247   }
    248   return ret;
    249 }
    250 
    251 unique_ptr<Declaration> DefineClientTransaction(const TypeNamespace& types,
    252                                                 const AidlInterface& interface,
    253                                                 const AidlMethod& method) {
    254   const string i_name = ClassName(interface, ClassNames::INTERFACE);
    255   const string bp_name = ClassName(interface, ClassNames::CLIENT);
    256   unique_ptr<MethodImpl> ret{new MethodImpl{
    257       kBinderStatusLiteral, bp_name, method.GetName(),
    258       ArgList{BuildArgList(types, method, true /* for method decl */)}}};
    259   StatementBlock* b = ret->GetStatementBlock();
    260 
    261   // Declare parcels to hold our query and the response.
    262   b->AddLiteral(StringPrintf("%s %s", kAndroidParcelLiteral, kDataVarName));
    263   // Even if we're oneway, the transact method still takes a parcel.
    264   b->AddLiteral(StringPrintf("%s %s", kAndroidParcelLiteral, kReplyVarName));
    265 
    266   // Declare the status_t variable we need for error handling.
    267   b->AddLiteral(StringPrintf("%s %s = %s", kAndroidStatusLiteral,
    268                              kAndroidStatusVarName,
    269                              kAndroidStatusOk));
    270   // We unconditionally return a Status object.
    271   b->AddLiteral(StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName));
    272 
    273   // Add the name of the interface we're hoping to call.
    274   b->AddStatement(new Assignment(
    275       kAndroidStatusVarName,
    276       new MethodCall(StringPrintf("%s.writeInterfaceToken",
    277                                   kDataVarName),
    278                      "getInterfaceDescriptor()")));
    279   b->AddStatement(GotoErrorOnBadStatus());
    280 
    281   // Serialization looks roughly like:
    282   //     _aidl_ret_status = _aidl_data.WriteInt32(in_param_name);
    283   //     if (_aidl_ret_status != ::android::OK) { goto error; }
    284   for (const AidlArgument* a : method.GetInArguments()) {
    285     const Type* type = a->GetType().GetLanguageType<Type>();
    286     string method = type->WriteToParcelMethod();
    287 
    288     string var_name = ((a->IsOut()) ? "*" : "") + a->GetName();
    289     var_name = type->WriteCast(var_name);
    290     b->AddStatement(new Assignment(
    291         kAndroidStatusVarName,
    292         new MethodCall(StringPrintf("%s.%s", kDataVarName, method.c_str()),
    293                        ArgList(var_name))));
    294     b->AddStatement(GotoErrorOnBadStatus());
    295   }
    296 
    297   // Invoke the transaction on the remote binder and confirm status.
    298   string transaction_code = StringPrintf(
    299       "%s::%s", i_name.c_str(), UpperCase(method.GetName()).c_str());
    300 
    301   vector<string> args = {transaction_code, kDataVarName,
    302                          StringPrintf("&%s", kReplyVarName)};
    303 
    304   if (interface.IsOneway() || method.IsOneway()) {
    305     args.push_back("::android::IBinder::FLAG_ONEWAY");
    306   }
    307 
    308   b->AddStatement(new Assignment(
    309       kAndroidStatusVarName,
    310       new MethodCall("remote()->transact",
    311                      ArgList(args))));
    312   b->AddStatement(GotoErrorOnBadStatus());
    313 
    314   if (!interface.IsOneway() && !method.IsOneway()) {
    315     // Strip off the exception header and fail if we see a remote exception.
    316     // _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
    317     // if (_aidl_ret_status != ::android::OK) { goto error; }
    318     // if (!_aidl_status.isOk()) { return _aidl_ret_status; }
    319     b->AddStatement(new Assignment(
    320         kAndroidStatusVarName,
    321         StringPrintf("%s.readFromParcel(%s)", kStatusVarName, kReplyVarName)));
    322     b->AddStatement(GotoErrorOnBadStatus());
    323     IfStatement* exception_check = new IfStatement(
    324         new LiteralExpression(StringPrintf("!%s.isOk()", kStatusVarName)));
    325     b->AddStatement(exception_check);
    326     exception_check->OnTrue()->AddLiteral(
    327         StringPrintf("return %s", kStatusVarName));
    328   }
    329 
    330   // Type checking should guarantee that nothing below emits code until "return
    331   // status" if we are a oneway method, so no more fear of accessing reply.
    332 
    333   // If the method is expected to return something, read it first by convention.
    334   const Type* return_type = method.GetType().GetLanguageType<Type>();
    335   if (return_type != types.VoidType()) {
    336     string method_call = return_type->ReadFromParcelMethod();
    337     b->AddStatement(new Assignment(
    338         kAndroidStatusVarName,
    339         new MethodCall(StringPrintf("%s.%s", kReplyVarName,
    340                                     method_call.c_str()),
    341                        ArgList(kReturnVarName))));
    342     b->AddStatement(GotoErrorOnBadStatus());
    343   }
    344 
    345   for (const AidlArgument* a : method.GetOutArguments()) {
    346     // Deserialization looks roughly like:
    347     //     _aidl_ret_status = _aidl_reply.ReadInt32(out_param_name);
    348     //     if (_aidl_status != ::android::OK) { goto _aidl_error; }
    349     string method =
    350       a->GetType().GetLanguageType<Type>()->ReadFromParcelMethod();
    351 
    352     b->AddStatement(new Assignment(
    353         kAndroidStatusVarName,
    354         new MethodCall(StringPrintf("%s.%s", kReplyVarName,
    355                                     method.c_str()),
    356                        ArgList(a->GetName()))));
    357     b->AddStatement(GotoErrorOnBadStatus());
    358   }
    359 
    360   // If we've gotten to here, one of two things is true:
    361   //   1) We've read some bad status_t
    362   //   2) We've only read status_t == OK and there was no exception in the
    363   //      response.
    364   // In both cases, we're free to set Status from the status_t and return.
    365   b->AddLiteral(StringPrintf("%s:\n", kErrorLabel), false /* no semicolon */);
    366   b->AddLiteral(
    367       StringPrintf("%s.setFromStatusT(%s)", kStatusVarName,
    368                    kAndroidStatusVarName));
    369   b->AddLiteral(StringPrintf("return %s", kStatusVarName));
    370 
    371   return unique_ptr<Declaration>(ret.release());
    372 }
    373 
    374 }  // namespace
    375 
    376 unique_ptr<Document> BuildClientSource(const TypeNamespace& types,
    377                                        const AidlInterface& interface) {
    378   vector<string> include_list = {
    379       HeaderFile(interface, ClassNames::CLIENT, false),
    380       kParcelHeader
    381   };
    382   vector<unique_ptr<Declaration>> file_decls;
    383 
    384   // The constructor just passes the IBinder instance up to the super
    385   // class.
    386   const string i_name = ClassName(interface, ClassNames::INTERFACE);
    387   file_decls.push_back(unique_ptr<Declaration>{new ConstructorImpl{
    388       ClassName(interface, ClassNames::CLIENT),
    389       ArgList{StringPrintf("const ::android::sp<::android::IBinder>& %s",
    390                            kImplVarName)},
    391       { "BpInterface<" + i_name + ">(" + kImplVarName + ")" }}});
    392 
    393   // Clients define a method per transaction.
    394   for (const auto& method : interface.GetMethods()) {
    395     unique_ptr<Declaration> m = DefineClientTransaction(
    396         types, interface, *method);
    397     if (!m) { return nullptr; }
    398     file_decls.push_back(std::move(m));
    399   }
    400   return unique_ptr<Document>{new CppSource{
    401       include_list,
    402       NestInNamespaces(std::move(file_decls), interface.GetSplitPackage())}};
    403 }
    404 
    405 namespace {
    406 
    407 bool HandleServerTransaction(const TypeNamespace& types,
    408                              const AidlMethod& method,
    409                              StatementBlock* b) {
    410   // Declare all the parameters now.  In the common case, we expect no errors
    411   // in serialization.
    412   for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
    413     if (!DeclareLocalVariable(types, *a, b)) { return false; }
    414   }
    415 
    416   // Declare a variable to hold the return value.
    417   const Type* return_type = method.GetType().GetLanguageType<Type>();
    418   if (return_type != types.VoidType()) {
    419     b->AddLiteral(StringPrintf(
    420         "%s %s", return_type->CppType().c_str(),
    421         kReturnVarName));
    422   }
    423 
    424   // Check that the client is calling the correct interface.
    425   IfStatement* interface_check = new IfStatement(
    426       new MethodCall(StringPrintf("%s.checkInterface",
    427                                   kDataVarName), "this"),
    428       true /* invert the check */);
    429   b->AddStatement(interface_check);
    430   interface_check->OnTrue()->AddStatement(
    431       new Assignment(kAndroidStatusVarName, "::android::BAD_TYPE"));
    432   interface_check->OnTrue()->AddLiteral("break");
    433 
    434   // Deserialize each "in" parameter to the transaction.
    435   for (const AidlArgument* a : method.GetInArguments()) {
    436     // Deserialization looks roughly like:
    437     //     _aidl_ret_status = _aidl_data.ReadInt32(&in_param_name);
    438     //     if (_aidl_ret_status != ::android::OK) { break; }
    439     const Type* type = a->GetType().GetLanguageType<Type>();
    440     string readMethod = type->ReadFromParcelMethod();
    441 
    442     b->AddStatement(new Assignment{
    443         kAndroidStatusVarName,
    444         new MethodCall{string(kDataVarName) + "." + readMethod,
    445                        "&" + BuildVarName(*a)}});
    446     b->AddStatement(BreakOnStatusNotOk());
    447   }
    448 
    449   // Call the actual method.  This is implemented by the subclass.
    450   vector<unique_ptr<AstNode>> status_args;
    451   status_args.emplace_back(new MethodCall(
    452           method.GetName(),
    453           BuildArgList(types, method, false /* not for method decl */)));
    454   b->AddStatement(new Statement(new MethodCall(
    455       StringPrintf("%s %s", kBinderStatusLiteral, kStatusVarName),
    456       ArgList(std::move(status_args)))));
    457 
    458   // Write exceptions during transaction handling to parcel.
    459   if (!method.IsOneway()) {
    460     b->AddStatement(new Assignment(
    461         kAndroidStatusVarName,
    462         StringPrintf("%s.writeToParcel(%s)", kStatusVarName, kReplyVarName)));
    463     b->AddStatement(BreakOnStatusNotOk());
    464     IfStatement* exception_check = new IfStatement(
    465         new LiteralExpression(StringPrintf("!%s.isOk()", kStatusVarName)));
    466     b->AddStatement(exception_check);
    467     exception_check->OnTrue()->AddLiteral("break");
    468   }
    469 
    470   // If we have a return value, write it first.
    471   if (return_type != types.VoidType()) {
    472     string writeMethod =
    473         string(kReplyVarName) + "->" +
    474         return_type->WriteToParcelMethod();
    475     b->AddStatement(new Assignment{
    476         kAndroidStatusVarName, new MethodCall{writeMethod,
    477         ArgList{return_type->WriteCast(kReturnVarName)}}});
    478     b->AddStatement(BreakOnStatusNotOk());
    479   }
    480 
    481   // Write each out parameter to the reply parcel.
    482   for (const AidlArgument* a : method.GetOutArguments()) {
    483     // Serialization looks roughly like:
    484     //     _aidl_ret_status = data.WriteInt32(out_param_name);
    485     //     if (_aidl_ret_status != ::android::OK) { break; }
    486     const Type* type = a->GetType().GetLanguageType<Type>();
    487     string writeMethod = type->WriteToParcelMethod();
    488 
    489     b->AddStatement(new Assignment{
    490         kAndroidStatusVarName,
    491         new MethodCall{string(kReplyVarName) + "->" + writeMethod,
    492                        type->WriteCast(BuildVarName(*a))}});
    493     b->AddStatement(BreakOnStatusNotOk());
    494   }
    495 
    496   return true;
    497 }
    498 
    499 }  // namespace
    500 
    501 unique_ptr<Document> BuildServerSource(const TypeNamespace& types,
    502                                        const AidlInterface& interface) {
    503   const string bn_name = ClassName(interface, ClassNames::SERVER);
    504   vector<string> include_list{
    505       HeaderFile(interface, ClassNames::SERVER, false),
    506       kParcelHeader
    507   };
    508   unique_ptr<MethodImpl> on_transact{new MethodImpl{
    509       kAndroidStatusLiteral, bn_name, "onTransact",
    510       ArgList{{StringPrintf("uint32_t %s", kCodeVarName),
    511                StringPrintf("const %s& %s", kAndroidParcelLiteral,
    512                             kDataVarName),
    513                StringPrintf("%s* %s", kAndroidParcelLiteral, kReplyVarName),
    514                StringPrintf("uint32_t %s", kFlagsVarName)}}
    515       }};
    516 
    517   // Declare the status_t variable
    518   on_transact->GetStatementBlock()->AddLiteral(
    519       StringPrintf("%s %s = %s", kAndroidStatusLiteral, kAndroidStatusVarName,
    520                    kAndroidStatusOk));
    521 
    522   // Add the all important switch statement, but retain a pointer to it.
    523   SwitchStatement* s = new SwitchStatement{kCodeVarName};
    524   on_transact->GetStatementBlock()->AddStatement(s);
    525 
    526   // The switch statement has a case statement for each transaction code.
    527   for (const auto& method : interface.GetMethods()) {
    528     StatementBlock* b = s->AddCase("Call::" + UpperCase(method->GetName()));
    529     if (!b) { return nullptr; }
    530 
    531     if (!HandleServerTransaction(types, *method, b)) { return nullptr; }
    532   }
    533 
    534   // The switch statement has a default case which defers to the super class.
    535   // The superclass handles a few pre-defined transactions.
    536   StatementBlock* b = s->AddCase("");
    537   b->AddLiteral(StringPrintf(
    538                 "%s = ::android::BBinder::onTransact(%s, %s, "
    539                 "%s, %s)", kAndroidStatusVarName, kCodeVarName,
    540                 kDataVarName, kReplyVarName, kFlagsVarName));
    541 
    542   // If we saw a null reference, we can map that to an appropriate exception.
    543   IfStatement* null_check = new IfStatement(
    544       new LiteralExpression(string(kAndroidStatusVarName) +
    545                             " == ::android::UNEXPECTED_NULL"));
    546   on_transact->GetStatementBlock()->AddStatement(null_check);
    547   null_check->OnTrue()->AddStatement(new Assignment(
    548       kAndroidStatusVarName,
    549       StringPrintf("%s::fromExceptionCode(%s::EX_NULL_POINTER)"
    550                    ".writeToParcel(%s)",
    551                    kBinderStatusLiteral, kBinderStatusLiteral,
    552                    kReplyVarName)));
    553 
    554   // Finally, the server's onTransact method just returns a status code.
    555   on_transact->GetStatementBlock()->AddLiteral(
    556       StringPrintf("return %s", kAndroidStatusVarName));
    557 
    558   return unique_ptr<Document>{new CppSource{
    559       include_list,
    560       NestInNamespaces(std::move(on_transact), interface.GetSplitPackage())}};
    561 }
    562 
    563 unique_ptr<Document> BuildInterfaceSource(const TypeNamespace& /* types */,
    564                                           const AidlInterface& interface) {
    565   vector<string> include_list{
    566       HeaderFile(interface, ClassNames::INTERFACE, false),
    567       HeaderFile(interface, ClassNames::CLIENT, false),
    568   };
    569 
    570   string fq_name = ClassName(interface, ClassNames::INTERFACE);
    571   if (!interface.GetPackage().empty()) {
    572     fq_name = interface.GetPackage() + "." + fq_name;
    573   }
    574 
    575   unique_ptr<ConstructorDecl> meta_if{new ConstructorDecl{
    576       "IMPLEMENT_META_INTERFACE",
    577       ArgList{vector<string>{ClassName(interface, ClassNames::BASE),
    578                              '"' + fq_name + '"'}}}};
    579 
    580   return unique_ptr<Document>{new CppSource{
    581       include_list,
    582       NestInNamespaces(std::move(meta_if), interface.GetSplitPackage())}};
    583 }
    584 
    585 unique_ptr<Document> BuildClientHeader(const TypeNamespace& types,
    586                                        const AidlInterface& interface) {
    587   const string i_name = ClassName(interface, ClassNames::INTERFACE);
    588   const string bp_name = ClassName(interface, ClassNames::CLIENT);
    589 
    590   unique_ptr<ConstructorDecl> constructor{new ConstructorDecl{
    591       bp_name,
    592       ArgList{StringPrintf("const ::android::sp<::android::IBinder>& %s",
    593                            kImplVarName)},
    594       ConstructorDecl::IS_EXPLICIT
    595   }};
    596   unique_ptr<ConstructorDecl> destructor{new ConstructorDecl{
    597       "~" + bp_name,
    598       ArgList{},
    599       ConstructorDecl::IS_VIRTUAL | ConstructorDecl::IS_DEFAULT}};
    600 
    601   vector<unique_ptr<Declaration>> publics;
    602   publics.push_back(std::move(constructor));
    603   publics.push_back(std::move(destructor));
    604 
    605   for (const auto& method: interface.GetMethods()) {
    606     publics.push_back(BuildMethodDecl(*method, types, false));
    607   }
    608 
    609   unique_ptr<ClassDecl> bp_class{
    610       new ClassDecl{bp_name,
    611                     "::android::BpInterface<" + i_name + ">",
    612                     std::move(publics),
    613                     {}
    614       }};
    615 
    616   return unique_ptr<Document>{new CppHeader{
    617       BuildHeaderGuard(interface, ClassNames::CLIENT),
    618       {kIBinderHeader,
    619        kIInterfaceHeader,
    620        "utils/Errors.h",
    621        HeaderFile(interface, ClassNames::INTERFACE, false)},
    622       NestInNamespaces(std::move(bp_class), interface.GetSplitPackage())}};
    623 }
    624 
    625 unique_ptr<Document> BuildServerHeader(const TypeNamespace& /* types */,
    626                                        const AidlInterface& interface) {
    627   const string i_name = ClassName(interface, ClassNames::INTERFACE);
    628   const string bn_name = ClassName(interface, ClassNames::SERVER);
    629 
    630   unique_ptr<Declaration> on_transact{new MethodDecl{
    631       kAndroidStatusLiteral, "onTransact",
    632       ArgList{{StringPrintf("uint32_t %s", kCodeVarName),
    633                StringPrintf("const %s& %s", kAndroidParcelLiteral,
    634                             kDataVarName),
    635                StringPrintf("%s* %s", kAndroidParcelLiteral, kReplyVarName),
    636                StringPrintf("uint32_t %s = 0", kFlagsVarName)}},
    637       MethodDecl::IS_OVERRIDE
    638   }};
    639 
    640   std::vector<unique_ptr<Declaration>> publics;
    641   publics.push_back(std::move(on_transact));
    642 
    643   unique_ptr<ClassDecl> bn_class{
    644       new ClassDecl{bn_name,
    645                     "::android::BnInterface<" + i_name + ">",
    646                     std::move(publics),
    647                     {}
    648       }};
    649 
    650   return unique_ptr<Document>{new CppHeader{
    651       BuildHeaderGuard(interface, ClassNames::SERVER),
    652       {"binder/IInterface.h",
    653        HeaderFile(interface, ClassNames::INTERFACE, false)},
    654       NestInNamespaces(std::move(bn_class), interface.GetSplitPackage())}};
    655 }
    656 
    657 unique_ptr<Document> BuildInterfaceHeader(const TypeNamespace& types,
    658                                           const AidlInterface& interface) {
    659   set<string> includes = { kIBinderHeader, kIInterfaceHeader,
    660                            kStatusHeader, kStrongPointerHeader };
    661 
    662   for (const auto& method : interface.GetMethods()) {
    663     for (const auto& argument : method->GetArguments()) {
    664       const Type* type = argument->GetType().GetLanguageType<Type>();
    665       type->GetHeaders(&includes);
    666     }
    667 
    668     const Type* return_type = method->GetType().GetLanguageType<Type>();
    669     return_type->GetHeaders(&includes);
    670   }
    671 
    672   unique_ptr<ClassDecl> if_class{
    673       new ClassDecl{ClassName(interface, ClassNames::INTERFACE),
    674                     "::android::IInterface"}};
    675   if_class->AddPublic(unique_ptr<Declaration>{new ConstructorDecl{
    676       "DECLARE_META_INTERFACE",
    677       ArgList{vector<string>{ClassName(interface, ClassNames::BASE)}}}});
    678 
    679   unique_ptr<Enum> constant_enum{new Enum{"", "int32_t"}};
    680   for (const auto& constant : interface.GetConstants()) {
    681     constant_enum->AddValue(
    682         constant->GetName(), std::to_string(constant->GetValue()));
    683   }
    684   if (constant_enum->HasValues()) {
    685     if_class->AddPublic(std::move(constant_enum));
    686   }
    687 
    688   unique_ptr<Enum> call_enum{new Enum{"Call"}};
    689   for (const auto& method : interface.GetMethods()) {
    690     // Each method gets an enum entry and pure virtual declaration.
    691     if_class->AddPublic(BuildMethodDecl(*method, types, true));
    692     call_enum->AddValue(
    693         UpperCase(method->GetName()),
    694         StringPrintf("::android::IBinder::FIRST_CALL_TRANSACTION + %d",
    695                      method->GetId()));
    696   }
    697   if_class->AddPublic(std::move(call_enum));
    698 
    699   return unique_ptr<Document>{new CppHeader{
    700       BuildHeaderGuard(interface, ClassNames::INTERFACE),
    701       vector<string>(includes.begin(), includes.end()),
    702       NestInNamespaces(std::move(if_class), interface.GetSplitPackage())}};
    703 }
    704 
    705 bool WriteHeader(const CppOptions& options,
    706                  const TypeNamespace& types,
    707                  const AidlInterface& interface,
    708                  const IoDelegate& io_delegate,
    709                  ClassNames header_type) {
    710   unique_ptr<Document> header;
    711   switch (header_type) {
    712     case ClassNames::INTERFACE:
    713       header = BuildInterfaceHeader(types, interface);
    714       break;
    715     case ClassNames::CLIENT:
    716       header = BuildClientHeader(types, interface);
    717       break;
    718     case ClassNames::SERVER:
    719       header = BuildServerHeader(types, interface);
    720       break;
    721     default:
    722       LOG(FATAL) << "aidl internal error";
    723   }
    724   if (!header) {
    725     LOG(ERROR) << "aidl internal error: Failed to generate header.";
    726     return false;
    727   }
    728 
    729   const string header_path = options.OutputHeaderDir() + OS_PATH_SEPARATOR +
    730                              HeaderFile(interface, header_type);
    731   unique_ptr<CodeWriter> code_writer(io_delegate.GetCodeWriter(header_path));
    732   header->Write(code_writer.get());
    733 
    734   const bool success = code_writer->Close();
    735   if (!success) {
    736     io_delegate.RemovePath(header_path);
    737   }
    738 
    739   return success;
    740 }
    741 
    742 }  // namespace internals
    743 
    744 using namespace internals;
    745 
    746 string HeaderFile(const AidlInterface& interface,
    747                   ClassNames class_type,
    748                   bool use_os_sep) {
    749   string file_path = interface.GetPackage();
    750   for (char& c: file_path) {
    751     if (c == '.') {
    752       c = (use_os_sep) ? OS_PATH_SEPARATOR : '/';
    753     }
    754   }
    755   if (!file_path.empty()) {
    756     file_path += (use_os_sep) ? OS_PATH_SEPARATOR : '/';
    757   }
    758   file_path += ClassName(interface, class_type);
    759   file_path += ".h";
    760 
    761   return file_path;
    762 }
    763 
    764 bool GenerateCpp(const CppOptions& options,
    765                  const TypeNamespace& types,
    766                  const AidlInterface& interface,
    767                  const IoDelegate& io_delegate) {
    768   auto interface_src = BuildInterfaceSource(types, interface);
    769   auto client_src = BuildClientSource(types, interface);
    770   auto server_src = BuildServerSource(types, interface);
    771 
    772   if (!interface_src || !client_src || !server_src) {
    773     return false;
    774   }
    775 
    776   if (!io_delegate.CreatedNestedDirs(options.OutputHeaderDir(),
    777                                      interface.GetSplitPackage())) {
    778     LOG(ERROR) << "Failed to create directory structure for headers.";
    779     return false;
    780   }
    781 
    782   if (!WriteHeader(options, types, interface, io_delegate,
    783                    ClassNames::INTERFACE) ||
    784       !WriteHeader(options, types, interface, io_delegate,
    785                    ClassNames::CLIENT) ||
    786       !WriteHeader(options, types, interface, io_delegate,
    787                    ClassNames::SERVER)) {
    788     return false;
    789   }
    790 
    791   unique_ptr<CodeWriter> writer = io_delegate.GetCodeWriter(
    792       options.OutputCppFilePath());
    793   interface_src->Write(writer.get());
    794   client_src->Write(writer.get());
    795   server_src->Write(writer.get());
    796 
    797   const bool success = writer->Close();
    798   if (!success) {
    799     io_delegate.RemovePath(options.OutputCppFilePath());
    800   }
    801 
    802   return success;
    803 }
    804 
    805 }  // namespace cpp
    806 }  // namespace aidl
    807 }  // namespace android
    808