• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "aidl.h"
19 
20 #include <algorithm>
21 #include <cctype>
22 #include <cstring>
23 #include <memory>
24 #include <random>
25 #include <set>
26 #include <string>
27 
28 #include <android-base/format.h>
29 #include <android-base/stringprintf.h>
30 #include <android-base/strings.h>
31 
32 #include "aidl_language.h"
33 #include "aidl_to_common.h"
34 #include "aidl_to_cpp.h"
35 
36 #include "aidl_typenames.h"
37 #include "logging.h"
38 #include "os.h"
39 
40 using android::base::Join;
41 using android::base::StringPrintf;
42 using std::set;
43 using std::string;
44 using std::unique_ptr;
45 using std::vector;
46 
47 namespace android {
48 namespace aidl {
49 namespace cpp {
50 namespace internals {
51 namespace {
52 
53 const char kAndroidStatusVarName[] = "_aidl_ret_status";
54 const char kCodeVarName[] = "_aidl_code";
55 const char kFlagsVarName[] = "_aidl_flags";
56 const char kDataVarName[] = "_aidl_data";
57 const char kErrorLabel[] = "_aidl_error";
58 const char kImplVarName[] = "_aidl_impl";
59 const char kDelegateImplVarName[] = "_aidl_delegate";
60 const char kParcelVarName[] = "_aidl_parcel";
61 const char kReplyVarName[] = "_aidl_reply";
62 const char kReturnVarName[] = "_aidl_return";
63 const char kStatusVarName[] = "_aidl_status";
64 const char kTraceVarName[] = "_aidl_trace";
65 const char kAndroidParcelLiteral[] = "::android::Parcel";
66 const char kAndroidStatusLiteral[] = "::android::status_t";
67 const char kAndroidStatusOk[] = "::android::OK";
68 const char kAndroidStatusBadValue[] = "::android::BAD_VALUE";
69 const char kBinderStatusLiteral[] = "::android::binder::Status";
70 const char kIBinderHeader[] = "binder/IBinder.h";
71 const char kIInterfaceHeader[] = "binder/IInterface.h";
72 const char kBinderDelegateHeader[] = "binder/Delegate.h";
73 const char kParcelHeader[] = "binder/Parcel.h";
74 const char kStabilityHeader[] = "binder/Stability.h";
75 const char kStatusHeader[] = "binder/Status.h";
76 const char kString16Header[] = "utils/String16.h";
77 const char kTraceHeader[] = "binder/Trace.h";
78 const char kStrongPointerHeader[] = "utils/StrongPointer.h";
79 
GenerateBreakOnStatusNotOk(CodeWriter & out)80 void GenerateBreakOnStatusNotOk(CodeWriter& out) {
81   out.Write("if (((%s) != (%s))) {\n", kAndroidStatusVarName, kAndroidStatusOk);
82   out.Write("  break;\n");
83   out.Write("}\n");
84 }
85 
GenerateGotoErrorOnBadStatus(CodeWriter & out)86 void GenerateGotoErrorOnBadStatus(CodeWriter& out) {
87   out.Write("if (((%s) != (%s))) {\n", kAndroidStatusVarName, kAndroidStatusOk);
88   out.Write("  goto %s;\n", kErrorLabel);
89   out.Write("}\n");
90 }
91 
92 // Format three types of arg list for method.
93 //  for_declaration & !type_name_only: int a      // for method decl with type and arg
94 //  for_declaration &  type_name_only: int /*a*/  // for method decl with type
95 // !for_declaration                  :     a      // for method call with arg (with direction)
GenerateArgList(const AidlTypenames & typenames,const AidlMethod & method,bool for_declaration,bool type_name_only)96 string GenerateArgList(const AidlTypenames& typenames, const AidlMethod& method,
97                        bool for_declaration, bool type_name_only) {
98   vector<string> method_arguments;
99   for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
100     string literal;
101     // b/144943748: CppNameOf FileDescriptor is unique_fd. Don't pass it by
102     // const reference but by value to make it easier for the user to keep
103     // it beyond the scope of the call. unique_fd is a thin wrapper for an
104     // int (fd) so passing by value is not expensive.
105     const bool non_copyable = IsNonCopyableType(a->GetType(), typenames);
106     if (for_declaration) {
107       // Method declarations need typenames, pointers to out params, and variable
108       // names that match the .aidl specification.
109       literal = CppNameOf(a->GetType(), typenames);
110 
111       if (a->IsOut()) {
112         literal = literal + "*";
113       } else {
114         const auto defined_type = typenames.TryGetDefinedType(a->GetType().GetName());
115 
116         const bool is_enum = defined_type && defined_type->AsEnumDeclaration() != nullptr;
117         const bool is_primitive = AidlTypenames::IsPrimitiveTypename(a->GetType().GetName());
118 
119         // We pass in parameters that are not primitives by const reference.
120         // Arrays of primitives are not primitives.
121         if (!(is_primitive || is_enum || non_copyable) || a->GetType().IsArray()) {
122           literal = "const " + literal + "&";
123         }
124       }
125       if (type_name_only) {
126         literal += " /*" + a->GetName() + "*/";
127       } else {
128         literal += " " + a->GetName();
129       }
130     } else {
131       std::string var_name = BuildVarName(*a);
132       if (a->IsOut()) {
133         literal = "&" + var_name;
134       } else if (non_copyable) {
135         literal = "std::move(" + var_name + ")";
136       } else {
137         literal = var_name;
138       }
139     }
140     method_arguments.push_back(literal);
141   }
142 
143   if (method.GetType().GetName() != "void") {
144     string literal;
145     if (for_declaration) {
146       literal = CppNameOf(method.GetType(), typenames) + "*";
147       if (type_name_only) {
148         literal += " /*" + string(kReturnVarName) + "*/";
149       } else {
150         literal += " " + string(kReturnVarName);
151       }
152     } else {
153       literal = string{"&"} + kReturnVarName;
154     }
155     method_arguments.push_back(literal);
156   }
157 
158   return Join(method_arguments, ", ");
159 }
160 
GenerateMethodDecl(CodeWriter & out,const AidlTypenames & types,const AidlMethod & method,const string & clazz)161 void GenerateMethodDecl(CodeWriter& out, const AidlTypenames& types, const AidlMethod& method,
162                         const string& clazz) {
163   string clazz_prefix = clazz.empty() ? "" : clazz + "::";
164   out << "::android::binder::Status " << clazz_prefix << method.GetName() << "("
165       << GenerateArgList(types, method, /*for_declartion=*/true, /*type_name_only=*/false) << ")";
166 }
167 
GenerateClientTransaction(CodeWriter & out,const AidlTypenames & typenames,const AidlInterface & interface,const AidlMethod & method,const Options & options)168 void GenerateClientTransaction(CodeWriter& out, const AidlTypenames& typenames,
169                                const AidlInterface& interface, const AidlMethod& method,
170                                const Options& options) {
171   const string i_name = ClassName(interface, ClassNames::INTERFACE);
172   const string bp_name = GetQualifiedName(interface, ClassNames::CLIENT);
173   const string bn_name = GetQualifiedName(interface, ClassNames::SERVER);
174 
175   GenerateMethodDecl(out, typenames, method, bp_name);
176   out << " {\n";
177   out.Indent();
178 
179   // Declare parcels to hold our query and the response.
180   out.Write("%s %s;\n", kAndroidParcelLiteral, kDataVarName);
181   if (interface.IsSensitiveData()) {
182     out.Write("%s.markSensitive();\n", kDataVarName);
183   }
184   out.Write("%s.markForBinder(remoteStrong());\n", kDataVarName);
185 
186   // Even if we're oneway, the transact method still takes a parcel.
187   out.Write("%s %s;\n", kAndroidParcelLiteral, kReplyVarName);
188 
189   // Declare the status_t variable we need for error handling.
190   out.Write("%s %s = %s;\n", kAndroidStatusLiteral, kAndroidStatusVarName, kAndroidStatusOk);
191   // We unconditionally return a Status object.
192   out.Write("%s %s;\n", kBinderStatusLiteral, kStatusVarName);
193 
194   if (options.GenTraces()) {
195     out.Write(
196         "::android::binder::ScopedTrace %s(ATRACE_TAG_AIDL, \"AIDL::cpp::%s::%s::cppClient\");\n",
197         kTraceVarName, interface.GetName().c_str(), method.GetName().c_str());
198   }
199 
200   if (options.GenLog()) {
201     out << GenLogBeforeExecute(bp_name, method, false /* isServer */, false /* isNdk */);
202   }
203 
204   if (method.IsNew() && ShouldForceDowngradeFor(CommunicationSide::WRITE)) {
205     out << "if (true) {\n";
206     out.Write("  %s = ::android::UNKNOWN_TRANSACTION;\n", kAndroidStatusVarName);
207     out << "} else {\n";
208     out.Indent();
209   }
210 
211   // Add the name of the interface we're hoping to call.
212   out.Write("%s = %s.writeInterfaceToken(getInterfaceDescriptor());\n", kAndroidStatusVarName,
213             kDataVarName);
214   GenerateGotoErrorOnBadStatus(out);
215 
216   for (const auto& a : method.GetArguments()) {
217     const string var_name = ((a->IsOut()) ? "*" : "") + a->GetName();
218 
219     if (a->IsIn()) {
220       // Serialization looks roughly like:
221       //     _aidl_ret_status = _aidl_data.WriteInt32(in_param_name);
222       //     if (_aidl_ret_status != ::android::OK) { goto error; }
223       out.Write("%s = %s.%s(%s);\n", kAndroidStatusVarName, kDataVarName,
224                 ParcelWriteMethodOf(a->GetType(), typenames).c_str(),
225                 ParcelWriteCastOf(a->GetType(), typenames, var_name).c_str());
226       GenerateGotoErrorOnBadStatus(out);
227     } else if (a->IsOut() && a->GetType().IsDynamicArray()) {
228       // Special case, the length of the out array is written into the parcel.
229       //     _aidl_ret_status = _aidl_data.writeVectorSize(&out_param_name);
230       //     if (_aidl_ret_status != ::android::OK) { goto error; }
231       out.Write("%s = %s.writeVectorSize(%s);\n", kAndroidStatusVarName, kDataVarName,
232                 var_name.c_str());
233       GenerateGotoErrorOnBadStatus(out);
234     }
235   }
236 
237   // Invoke the transaction on the remote binder and confirm status.
238   std::vector<std::string> flags;
239   if (method.IsOneway()) flags.push_back("::android::IBinder::FLAG_ONEWAY");
240   if (interface.IsSensitiveData()) flags.push_back("::android::IBinder::FLAG_CLEAR_BUF");
241 
242   out.Write("%s = remote()->transact(%s, %s, &%s, %s);\n", kAndroidStatusVarName,
243             GetTransactionIdFor(bn_name, method).c_str(), kDataVarName, kReplyVarName,
244             flags.empty() ? "0" : Join(flags, " | ").c_str());
245 
246   // If the method is not implemented in the remote side, try to call the
247   // default implementation, if provided.
248   vector<string> arg_names;
249   for (const auto& a : method.GetArguments()) {
250     if (IsNonCopyableType(a->GetType(), typenames)) {
251       arg_names.emplace_back(StringPrintf("std::move(%s)", a->GetName().c_str()));
252     } else {
253       arg_names.emplace_back(a->GetName());
254     }
255   }
256   if (method.GetType().GetName() != "void") {
257     arg_names.emplace_back(kReturnVarName);
258   }
259   if (method.IsNew() && ShouldForceDowngradeFor(CommunicationSide::WRITE)) {
260     out.Dedent();
261     out << "}\n";
262   }
263   out.Write("if (%s == ::android::UNKNOWN_TRANSACTION && %s::getDefaultImpl()) [[unlikely]] {\n",
264             kAndroidStatusVarName, i_name.c_str());
265   out.Write("   return %s::getDefaultImpl()->%s(%s);\n", i_name.c_str(), method.GetName().c_str(),
266             Join(arg_names, ", ").c_str());
267   out.Write("}\n");
268   GenerateGotoErrorOnBadStatus(out);
269 
270   if (!method.IsOneway()) {
271     // Strip off the exception header and fail if we see a remote exception.
272     // _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
273     // if (_aidl_ret_status != ::android::OK) { goto error; }
274     // if (!_aidl_status.isOk()) { return _aidl_ret_status; }
275     out.Write("%s = %s.readFromParcel(%s);\n", kAndroidStatusVarName, kStatusVarName,
276               kReplyVarName);
277     GenerateGotoErrorOnBadStatus(out);
278     out.Write("if (!%s.isOk()) {\n", kStatusVarName);
279     out.Write("  return %s;\n", kStatusVarName);
280     out.Write("}\n");
281   }
282 
283   // Type checking should guarantee that nothing below emits code until "return
284   // status" if we are a oneway method, so no more fear of accessing reply.
285 
286   // If the method is expected to return something, read it first by convention.
287   if (method.GetType().GetName() != "void") {
288     out.Write("%s = %s.%s(%s);\n", kAndroidStatusVarName, kReplyVarName,
289               ParcelReadMethodOf(method.GetType(), typenames).c_str(),
290               ParcelReadCastOf(method.GetType(), typenames, kReturnVarName).c_str());
291     GenerateGotoErrorOnBadStatus(out);
292   }
293 
294   for (const AidlArgument* a : method.GetOutArguments()) {
295     // Deserialization looks roughly like:
296     //     _aidl_ret_status = _aidl_reply.ReadInt32(out_param_name);
297     //     if (_aidl_status != ::android::OK) { goto _aidl_error; }
298     out.Write("%s = %s.%s(%s);\n", kAndroidStatusVarName, kReplyVarName,
299               ParcelReadMethodOf(a->GetType(), typenames).c_str(),
300               ParcelReadCastOf(a->GetType(), typenames, a->GetName()).c_str());
301     GenerateGotoErrorOnBadStatus(out);
302   }
303 
304   // If we've gotten to here, one of two things is true:
305   //   1) We've read some bad status_t
306   //   2) We've only read status_t == OK and there was no exception in the
307   //      response.
308   // In both cases, we're free to set Status from the status_t and return.
309   out.Write("%s:\n", kErrorLabel);
310   out.Write("%s.setFromStatusT(%s);\n", kStatusVarName, kAndroidStatusVarName);
311 
312   if (options.GenLog()) {
313     out << GenLogAfterExecute(bp_name, interface, method, kStatusVarName, kReturnVarName,
314                               false /* isServer */, false /* isNdk */);
315   }
316 
317   out.Write("return %s;\n", kStatusVarName);
318   out.Dedent();
319   out << "}\n";
320 }
321 
GenerateClientMetaTransaction(CodeWriter & out,const AidlInterface & interface,const AidlMethod & method,const Options & options)322 void GenerateClientMetaTransaction(CodeWriter& out, const AidlInterface& interface,
323                                    const AidlMethod& method, const Options& options) {
324   AIDL_FATAL_IF(method.IsUserDefined(), method);
325   const string bp_name = GetQualifiedName(interface, ClassNames::CLIENT);
326   const string bn_name = GetQualifiedName(interface, ClassNames::SERVER);
327   if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
328     // Note: race condition can happen here, but no locking is required
329     // because 1) writing an interger is atomic and 2) this transaction
330     // will always return the same value, i.e., competing threads will
331     // give write the same value to cached_version_.
332     out << "int32_t " << bp_name << "::" << kGetInterfaceVersion << "() {\n"
333         << "  if (cached_version_ == -1) {\n"
334         << "    ::android::Parcel data;\n"
335         << "    ::android::Parcel reply;\n"
336         << "    data.writeInterfaceToken(getInterfaceDescriptor());\n"
337         << "    ::android::status_t err = remote()->transact("
338         << GetTransactionIdFor(bn_name, method) << ", data, &reply);\n"
339         << "    if (err == ::android::OK) {\n"
340         << "      ::android::binder::Status _aidl_status;\n"
341         << "      err = _aidl_status.readFromParcel(reply);\n"
342         << "      if (err == ::android::OK && _aidl_status.isOk()) {\n"
343         << "        cached_version_ = reply.readInt32();\n"
344         << "      }\n"
345         << "    }\n"
346         << "  }\n"
347         << "  return cached_version_;\n"
348         << "}\n";
349     out << "\n";
350   }
351   if (method.GetName() == kGetInterfaceHash && !options.Hash().empty()) {
352     out << "std::string " << bp_name << "::" << kGetInterfaceHash << "() {\n"
353         << "  std::lock_guard<std::mutex> lockGuard(cached_hash_mutex_);\n"
354         << "  if (cached_hash_ == \"-1\") {\n"
355         << "    ::android::Parcel data;\n"
356         << "    ::android::Parcel reply;\n"
357         << "    data.writeInterfaceToken(getInterfaceDescriptor());\n"
358         << "    ::android::status_t err = remote()->transact("
359         << GetTransactionIdFor(bn_name, method) << ", data, &reply);\n"
360         << "    if (err == ::android::OK) {\n"
361         << "      ::android::binder::Status _aidl_status;\n"
362         << "      err = _aidl_status.readFromParcel(reply);\n"
363         << "      if (err == ::android::OK && _aidl_status.isOk()) {\n"
364         << "        reply.readUtf8FromUtf16(&cached_hash_);\n"
365         << "      }\n"
366         << "    }\n"
367         << "  }\n"
368         << "  return cached_hash_;\n"
369         << "}\n";
370   }
371 }
372 
373 }  // namespace
374 
GenerateClientSource(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)375 void GenerateClientSource(CodeWriter& out, const AidlInterface& interface,
376                           const AidlTypenames& typenames, const Options& options) {
377   vector<string> include_list = {
378       HeaderFile(interface, ClassNames::CLIENT, false),
379       HeaderFile(interface, ClassNames::SERVER, false),  // for TRANSACTION_* consts
380       kParcelHeader};
381   if (options.GenLog()) {
382     include_list.emplace_back("chrono");
383     include_list.emplace_back("functional");
384   }
385   for (const auto& path : include_list) {
386     out << "#include <" << path << ">\n";
387   }
388   out << "\n";
389 
390   const string i_name = ClassName(interface, ClassNames::INTERFACE);
391   const string bp_name = ClassName(interface, ClassNames::CLIENT);
392   const string q_name = GetQualifiedName(interface, ClassNames::CLIENT);
393 
394   EnterNamespace(out, interface);
395   out << "\n";
396 
397   // The constructor just passes the IBinder instance up to the super
398   // class.
399   out << q_name << "::" << bp_name << "(const ::android::sp<::android::IBinder>& _aidl_impl)\n";
400   out << "    : BpInterface<" + i_name + ">(_aidl_impl){\n";
401   out << "}\n";
402   out << "\n";
403 
404   if (options.GenLog()) {
405     out << "std::function<void(const " + q_name + "::TransactionLog&)> " << q_name
406         << "::logFunc;\n";
407     out << "\n";
408   }
409 
410   // Clients define a method per transaction.
411   for (const auto& method : interface.GetMethods()) {
412     if (method->IsUserDefined()) {
413       GenerateClientTransaction(out, typenames, interface, *method, options);
414     } else {
415       GenerateClientMetaTransaction(out, interface, *method, options);
416     }
417     out << "\n";
418   }
419 
420   LeaveNamespace(out, interface);
421 }
422 
423 namespace {
424 
GenerateConstantDefinitions(CodeWriter & out,const AidlDefinedType & type,const AidlTypenames & typenames,const string & template_decl,const string & q_name)425 void GenerateConstantDefinitions(CodeWriter& out, const AidlDefinedType& type,
426                                  const AidlTypenames& typenames, const string& template_decl,
427                                  const string& q_name) {
428   for (const auto& constant : type.GetConstantDeclarations()) {
429     const AidlConstantValue& value = constant->GetValue();
430     if (value.GetType() != AidlConstantValue::Type::STRING) continue;
431 
432     std::string cpp_type = CppNameOf(constant->GetType(), typenames);
433     out << template_decl;
434     out << "const " << cpp_type << "& " << q_name << "::" << constant->GetName() << "() {\n";
435     out << "  static const " << cpp_type << " value("
436         << constant->ValueString(ConstantValueDecorator) << ");\n";
437     out << "  return value;\n";
438     out << "}\n";
439   }
440 }
441 
GenerateConstantDeclarations(CodeWriter & out,const AidlDefinedType & type,const AidlTypenames & typenames)442 void GenerateConstantDeclarations(CodeWriter& out, const AidlDefinedType& type,
443                                   const AidlTypenames& typenames) {
444   for (const auto& constant : type.GetConstantDeclarations()) {
445     const AidlTypeSpecifier& type = constant->GetType();
446     const auto cpp_type = CppNameOf(type, typenames);
447     if (type.Signature() == "String") {
448       out << "static const " << cpp_type << "& " << constant->GetName() << "()";
449       GenerateDeprecated(out, *constant);
450       out << ";\n";
451     } else if (type.Signature() == "float" || type.Signature() == "double") {
452       out << "static constexpr " << cpp_type << " " << constant->GetName();
453       GenerateDeprecated(out, *constant);
454       out << " = " << constant->ValueString(ConstantValueDecorator) << ";\n";
455     } else {
456       out << "enum : " << cpp_type << " { " << constant->GetName();
457       GenerateDeprecated(out, *constant);
458       out << " = " << constant->ValueString(ConstantValueDecorator) << " };\n";
459     }
460   }
461 }
462 
GenerateServerTransaction(CodeWriter & out,const AidlInterface & interface,const AidlMethod & method,const AidlTypenames & typenames,const Options & options)463 void GenerateServerTransaction(CodeWriter& out, const AidlInterface& interface,
464                                const AidlMethod& method, const AidlTypenames& typenames,
465                                const Options& options) {
466   const string bn_name = GetQualifiedName(interface, ClassNames::SERVER);
467   if (method.IsNew() && ShouldForceDowngradeFor(CommunicationSide::READ)) {
468     out << "if (true) {\n";
469     out << "  _aidl_ret_status = ::android::UNKNOWN_TRANSACTION;\n";
470     out << "  break;\n";
471     out << "}\n";
472   }
473 
474   // Declare all the parameters now.  In the common case, we expect no errors
475   // in serialization.
476   for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
477     out.Write("%s %s;\n", CppNameOf(a->GetType(), typenames).c_str(), BuildVarName(*a).c_str());
478   }
479 
480   // Declare a variable to hold the return value.
481   if (method.GetType().GetName() != "void") {
482     out.Write("%s %s;\n", CppNameOf(method.GetType(), typenames).c_str(), kReturnVarName);
483   }
484 
485   // Check that the client is calling the correct interface.
486   out.Write("if (!(%s.checkInterface(this))) {\n", kDataVarName);
487   out.Write("  %s = ::android::BAD_TYPE;\n", kAndroidStatusVarName);
488   out.Write("  break;\n");
489   out.Write("}\n");
490 
491   if (options.GenTraces()) {
492     out.Write(
493         "::android::binder::ScopedTrace %s(ATRACE_TAG_AIDL, \"AIDL::cpp::%s::%s::cppServer\");\n",
494         kTraceVarName, interface.GetName().c_str(), method.GetName().c_str());
495   }
496 
497   if (interface.EnforceExpression() || method.GetType().EnforceExpression()) {
498     out.Write("#error Permission checks not implemented for the cpp backend\n");
499   }
500 
501   // Deserialize each "in" parameter to the transaction.
502   for (const auto& a: method.GetArguments()) {
503     // Deserialization looks roughly like:
504     //     _aidl_ret_status = _aidl_data.ReadInt32(&in_param_name);
505     //     if (_aidl_ret_status != ::android::OK) { break; }
506     const string& var_name = "&" + BuildVarName(*a);
507     if (a->IsIn()) {
508       out.Write("%s = %s.%s(%s);\n", kAndroidStatusVarName, kDataVarName,
509                 ParcelReadMethodOf(a->GetType(), typenames).c_str(),
510                 ParcelReadCastOf(a->GetType(), typenames, var_name).c_str());
511       GenerateBreakOnStatusNotOk(out);
512     } else if (a->IsOut() && a->GetType().IsDynamicArray()) {
513       // Special case, the length of the out array is written into the parcel.
514       //     _aidl_ret_status = _aidl_data.resizeOutVector(&out_param_name);
515       //     if (_aidl_ret_status != ::android::OK) { break; }
516       out.Write("%s = %s.resizeOutVector(%s);\n", kAndroidStatusVarName, kDataVarName,
517                 var_name.c_str());
518       GenerateBreakOnStatusNotOk(out);
519     }
520   }
521 
522   if (options.GenLog()) {
523     out << GenLogBeforeExecute(bn_name, method, true /* isServer */, false /* isNdk */);
524   }
525 
526   if (!method.GetArguments().empty() && options.GetMinSdkVersion() >= SDK_VERSION_Tiramisu) {
527     out << "if (auto st = _aidl_data.enforceNoDataAvail(); !st.isOk()) {\n";
528     out << "  _aidl_ret_status = st.writeToParcel(_aidl_reply);\n";
529     out << "  break;\n";
530     out << "}\n";
531   }
532 
533   // Call the actual method.  This is implemented by the subclass.
534   out.Write("%s %s(%s(%s));\n", kBinderStatusLiteral, kStatusVarName, method.GetName().c_str(),
535             GenerateArgList(typenames, method, /*for_declaration=*/false, /*type_name_only=*/false)
536                 .c_str());
537 
538   if (options.GenLog()) {
539     out << GenLogAfterExecute(bn_name, interface, method, kStatusVarName, kReturnVarName,
540                               true /* isServer */, false /* isNdk */);
541   }
542 
543   // Write exceptions during transaction handling to parcel.
544   if (!method.IsOneway()) {
545     out.Write("%s = %s.writeToParcel(%s);\n", kAndroidStatusVarName, kStatusVarName, kReplyVarName);
546     GenerateBreakOnStatusNotOk(out);
547     out.Write("if (!%s.isOk()) {\n", kStatusVarName);
548     out.Write("  break;\n");
549     out.Write("}\n");
550   }
551 
552   // If we have a return value, write it first.
553   if (method.GetType().GetName() != "void") {
554     out.Write("%s = %s->%s(%s);\n", kAndroidStatusVarName, kReplyVarName,
555               ParcelWriteMethodOf(method.GetType(), typenames).c_str(),
556               ParcelWriteCastOf(method.GetType(), typenames, kReturnVarName).c_str());
557     GenerateBreakOnStatusNotOk(out);
558   }
559   // Write each out parameter to the reply parcel.
560   for (const AidlArgument* a : method.GetOutArguments()) {
561     // Serialization looks roughly like:
562     //     _aidl_ret_status = data.WriteInt32(out_param_name);
563     //     if (_aidl_ret_status != ::android::OK) { break; }
564     out.Write("%s = %s->%s(%s);\n", kAndroidStatusVarName, kReplyVarName,
565               ParcelWriteMethodOf(a->GetType(), typenames).c_str(),
566               ParcelWriteCastOf(a->GetType(), typenames, BuildVarName(*a)).c_str());
567     GenerateBreakOnStatusNotOk(out);
568   }
569 }
570 
GenerateServerMetaTransaction(CodeWriter & out,const AidlInterface & interface,const AidlMethod & method,const Options & options)571 void GenerateServerMetaTransaction(CodeWriter& out, const AidlInterface& interface,
572                                    const AidlMethod& method, const Options& options) {
573   AIDL_FATAL_IF(method.IsUserDefined(), method);
574 
575   string iface = ClassName(interface, ClassNames::INTERFACE);
576   if (method.GetName() == kGetInterfaceVersion && options.Version() > 0) {
577     out << "_aidl_data.checkInterface(this);\n"
578         << "_aidl_reply->writeNoException();\n";
579     out << "_aidl_reply->writeInt32(" << iface << "::VERSION);\n";
580   }
581   if (method.GetName() == kGetInterfaceHash && !options.Hash().empty()) {
582     out << "_aidl_data.checkInterface(this);\n"
583         << "_aidl_reply->writeNoException();\n";
584     out << "_aidl_reply->writeUtf8AsUtf16(" << iface << "::HASH);\n";
585   }
586 }
587 
588 }  // namespace
589 
GenerateServerOnTransact(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)590 void GenerateServerOnTransact(CodeWriter& out, const AidlInterface& interface,
591                               const AidlTypenames& typenames, const Options& options) {
592   const string bn_name = ClassName(interface, ClassNames::SERVER);
593   const string q_name = GetQualifiedName(interface, ClassNames::SERVER);
594 
595   bool deprecated = interface.IsDeprecated() ||
596                     std::any_of(interface.GetMethods().begin(), interface.GetMethods().end(),
597                                 [](const auto& m) { return m->IsDeprecated(); });
598   if (deprecated) {
599     out << "#pragma clang diagnostic push\n";
600     out << "#pragma clang diagnostic ignored \"-Wdeprecated\"\n";
601     out << "\n";
602   }
603 
604   out.Write("%s %s::onTransact(uint32_t %s, const %s& %s, %s* %s, uint32_t %s) {\n",
605             kAndroidStatusLiteral, q_name.c_str(), kCodeVarName, kAndroidParcelLiteral,
606             kDataVarName, kAndroidParcelLiteral, kReplyVarName, kFlagsVarName);
607   out.Indent();
608   // Declare the status_t variable
609   out.Write("%s %s = %s;\n", kAndroidStatusLiteral, kAndroidStatusVarName, kAndroidStatusOk);
610 
611   // Add the all important switch statement
612   out.Write("switch (%s) {\n", kCodeVarName);
613 
614   // The switch statement has a case statement for each transaction code.
615   for (const auto& method : interface.GetMethods()) {
616     out.Write("case %s:\n", GetTransactionIdFor(bn_name, *method).c_str());
617     out << "{\n";
618     out.Indent();
619     if (method->IsUserDefined()) {
620       GenerateServerTransaction(out, interface, *method, typenames, options);
621     } else {
622       GenerateServerMetaTransaction(out, interface, *method, options);
623     }
624     out.Dedent();
625     out << "}\n";
626     out << "break;\n";
627   }
628 
629   // The switch statement has a default case which defers to the super class.
630   // The superclass handles a few pre-defined transactions.
631   out << "default:\n";
632   out << "{\n";
633   out.Write("  %s = ::android::BBinder::onTransact(%s, %s, %s, %s);\n", kAndroidStatusVarName,
634             kCodeVarName, kDataVarName, kReplyVarName, kFlagsVarName);
635   out << "}\n";
636   out << "break;\n";
637   out << "}\n";  // switch
638 
639   // If we saw a null reference, we can map that to an appropriate exception.
640   out.Write("if (%s == ::android::UNEXPECTED_NULL) {\n", kAndroidStatusVarName);
641   out.Write("  %s = %s::fromExceptionCode(%s::EX_NULL_POINTER).writeOverParcel(%s);\n",
642             kAndroidStatusVarName, kBinderStatusLiteral, kBinderStatusLiteral, kReplyVarName);
643   out.Write("}\n");
644 
645   // Finally, the server's onTransact method just returns a status code.
646   out.Write("return %s;\n", kAndroidStatusVarName);
647 
648   out.Dedent();
649   out << "}\n";
650   out << "\n";
651 
652   if (deprecated) {
653     out << "#pragma clang diagnostic pop\n";
654     out << "\n";
655   }
656 }
657 
GenerateServerSource(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)658 void GenerateServerSource(CodeWriter& out, const AidlInterface& interface,
659                           const AidlTypenames& typenames, const Options& options) {
660   vector<string> include_list{
661       HeaderFile(interface, ClassNames::SERVER, false),
662       kParcelHeader,
663       kStabilityHeader,
664   };
665   if (options.GenLog()) {
666     include_list.emplace_back("chrono");
667     include_list.emplace_back("functional");
668   }
669   for (const auto& include : include_list) {
670     out << "#include <" << include << ">\n";
671   }
672   out << "\n";
673 
674   const string i_name = ClassName(interface, ClassNames::INTERFACE);
675   const string bn_name = ClassName(interface, ClassNames::SERVER);
676   const string q_name = GetQualifiedName(interface, ClassNames::SERVER);
677 
678   EnterNamespace(out, interface);
679   out << "\n";
680 
681   // constructor
682   out.Write("%s::%s()\n", q_name.c_str(), bn_name.c_str());
683   out << "{\n";
684   out.Indent();
685   if (interface.IsVintfStability()) {
686     out << "::android::internal::Stability::markVintf(this);\n";
687   } else {
688     out << "::android::internal::Stability::markCompilationUnit(this);\n";
689   }
690   out.Dedent();
691   out << "}\n";
692   out << "\n";
693 
694   GenerateServerOnTransact(out, interface, typenames, options);
695 
696   if (options.Version() > 0) {
697     out << "int32_t " << q_name << "::" << kGetInterfaceVersion << "() {\n"
698         << "  return " << i_name << "::VERSION;\n"
699         << "}\n";
700   }
701   if (!options.Hash().empty()) {
702     out << "std::string " << q_name << "::" << kGetInterfaceHash << "() {\n"
703         << "  return " << i_name << "::HASH;\n"
704         << "}\n";
705   }
706   if (options.GenLog()) {
707     out << "std::function<void(const " + q_name + "::TransactionLog&)> " << q_name
708         << "::logFunc;\n";
709   }
710 
711   LeaveNamespace(out, interface);
712 }
713 
GenerateInterfaceSource(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options &)714 void GenerateInterfaceSource(CodeWriter& out, const AidlInterface& interface,
715                              const AidlTypenames& typenames, const Options&) {
716   out << "#include <" << HeaderFile(interface, ClassNames::RAW, false) << ">\n";
717   out << "#include <" << HeaderFile(interface, ClassNames::CLIENT, false) << ">\n";
718 
719   EnterNamespace(out, interface);
720 
721   if (auto parent = interface.GetParentType(); parent) {
722     out << fmt::format("DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_NESTED_INTERFACE({}, {}, \"{}\")\n",
723                        GetQualifiedName(*parent, ClassNames::MAYBE_INTERFACE),
724                        ClassName(interface, ClassNames::BASE), interface.GetDescriptor());
725   } else {
726     out << fmt::format("DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE({}, \"{}\")\n",
727                        ClassName(interface, ClassNames::BASE), interface.GetDescriptor());
728   }
729 
730   GenerateConstantDefinitions(out, interface, typenames, /*template_decl=*/"",
731                               ClassName(interface, ClassNames::INTERFACE));
732 
733   LeaveNamespace(out, interface);
734 }
735 
GenerateClientClassDecl(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)736 void GenerateClientClassDecl(CodeWriter& out, const AidlInterface& interface,
737                              const AidlTypenames& typenames, const Options& options) {
738   const string bp_name = ClassName(interface, ClassNames::CLIENT);
739   const string iface = ClassName(interface, ClassNames::INTERFACE);
740 
741   out << "class LIBBINDER_EXPORTED";
742   GenerateDeprecated(out, interface);
743   out << " " << bp_name << " : public ::android::BpInterface<" << iface << "> {\n";
744   out << "public:\n";
745   out.Indent();
746   out << "explicit " << bp_name << "(const ::android::sp<::android::IBinder>& " << kImplVarName
747       << ");\n";
748   out << "virtual ~" << bp_name << "() = default;\n";
749 
750   for (const auto& method : interface.GetMethods()) {
751     if (method->IsUserDefined()) {
752       GenerateMethodDecl(out, typenames, *method, /*clazz=*/"");
753       out << " override";
754       GenerateDeprecated(out, *method);
755       out << ";\n";
756     } else if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
757       out << "int32_t " << method->GetName() << "() override;\n";
758     } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
759       out << "std::string " << method->GetName() << "() override;\n";
760     }
761   }
762 
763   if (options.GenLog()) {
764     out << kTransactionLogStruct;
765     out << "static std::function<void(const TransactionLog&)> logFunc;\n";
766   }
767   out.Dedent();
768 
769   if (options.Version() > 0 || !options.Hash().empty()) {
770     out << "private:\n";
771     out.Indent();
772     if (options.Version() > 0) {
773       out << "int32_t cached_version_ = -1;\n";
774     }
775     if (!options.Hash().empty()) {
776       out << "std::string cached_hash_ = \"-1\";\n";
777       out << "std::mutex cached_hash_mutex_;\n";
778     }
779     out.Dedent();
780   }
781 
782   out << "};  // class " << bp_name << "\n";
783 }
784 
GenerateClientHeader(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)785 void GenerateClientHeader(CodeWriter& out, const AidlInterface& interface,
786                           const AidlTypenames& typenames, const Options& options) {
787   out << "#pragma once\n\n";
788   if (!options.Hash().empty()) {
789     out << "#include <mutex>\n";
790   }
791   out << "#include <" << kIBinderHeader << ">\n";
792   out << "#include <" << kIInterfaceHeader << ">\n";
793   out << "#include <utils/Errors.h>\n";
794   out << "#include <" << HeaderFile(interface, ClassNames::RAW, false) << ">\n";
795   if (options.GenLog()) {
796     out << "#include <functional>\n";  // for std::function
797     out << "#include <android/binder_to_string.h>\n";
798   }
799   out << "\n";
800   EnterNamespace(out, interface);
801   GenerateClientClassDecl(out, interface, typenames, options);
802   LeaveNamespace(out, interface);
803 }
804 
805 // Some interfaces are declared in .aidl files, but defined elsewhere.
806 // These interfaces can not have Delegators and need to be avoided.
807 // TODO(b/242920522) These should all be defined in .aidl files.
isKnownUndefinedInterface(const std::string & canonicalName)808 bool isKnownUndefinedInterface(const std::string& canonicalName) {
809   static const auto* kKnownUndefinedInterfaces = new std::set<std::string>{
810       "android.hardware.ICamera", "android.hardware.ICameraClient",
811       "android.IOMXNode",         "android.IMediaExtractor",
812       "android.IDataSource",
813   };
814   return kKnownUndefinedInterfaces->find(canonicalName) != kKnownUndefinedInterfaces->end();
815 };
816 
isDelegateable(const AidlTypeSpecifier & type)817 bool isDelegateable(const AidlTypeSpecifier& type) {
818   return type.GetDefinedType() && type.GetDefinedType()->AsInterface() &&
819          !isKnownUndefinedInterface(type.GetDefinedType()->GetCanonicalName()) && !type.IsArray();
820 }
821 
wrapDelegate(CodeWriter & out,const std::string & argName,const AidlTypeSpecifier & type,bool in)822 void wrapDelegate(CodeWriter& out, const std::string& argName, const AidlTypeSpecifier& type,
823                   bool in) {
824   const std::string argRef = in ? argName : "*" + argName;
825   const std::string targetArgName = in ? "_" + argName : argName;
826   const std::string targetArgRef = in ? targetArgName : "*" + targetArgName;
827   // input binders need local variables for each arg to pass to the delegate
828   // because the parameters are const
829   if (in) {
830     out << "::android::sp<::" << Join(type.GetSplitName(), "::") << "Delegator> " << targetArgName
831         << ";\n";
832   }
833   out << "if (" << argRef << ") {\n";
834   out.Indent();
835   out << targetArgRef << " = ::android::sp<::" << Join(type.GetSplitName(), "::")
836       << "Delegator>::cast(delegate(" << argRef << "));\n";
837   out.Dedent();
838   out << "}\n";
839 }
840 
GenerateServerClassDecl(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)841 void GenerateServerClassDecl(CodeWriter& out, const AidlInterface& interface,
842                              const AidlTypenames& typenames, const Options& options) {
843   const string bn_name = ClassName(interface, ClassNames::SERVER);
844   const string iface = ClassName(interface, ClassNames::INTERFACE);
845 
846   out << "class LIBBINDER_EXPORTED";
847   GenerateDeprecated(out, interface);
848   out << " " << bn_name << " : public "
849       << "::android::BnInterface<" << iface << "> {\n";
850   out << "public:\n";
851   out.Indent();
852   for (const auto& method : interface.GetMethods()) {
853     out << "static constexpr uint32_t TRANSACTION_" << method->GetName() << " = "
854         << "::android::IBinder::FIRST_CALL_TRANSACTION + " << std::to_string(method->GetId())
855         << ";\n";
856   }
857   out << "explicit " << bn_name << "();\n";
858   out << fmt::format("{} onTransact(uint32_t {}, const {}& {}, {}* {}, uint32_t {}) override;\n",
859                      kAndroidStatusLiteral, kCodeVarName, kAndroidParcelLiteral, kDataVarName,
860                      kAndroidParcelLiteral, kReplyVarName, kFlagsVarName);
861   if (options.Version() > 0) {
862     out << "int32_t " << kGetInterfaceVersion << "();\n";
863   }
864   if (!options.Hash().empty()) {
865     out << "std::string " << kGetInterfaceHash << "();\n";
866   }
867   if (options.GenLog()) {
868     out << kTransactionLogStruct;
869     out << "static std::function<void(const TransactionLog&)> logFunc;\n";
870   }
871   out.Dedent();
872   out << "};  // class " << bn_name << "\n\n";
873 
874   std::string d_name = ClassName(interface, ClassNames::DELEGATOR_IMPL);
875   out << "class LIBBINDER_EXPORTED";
876   GenerateDeprecated(out, interface);
877   out << " " << d_name << " : public " << bn_name << " {\n";
878   out << "public:\n";
879   out.Indent();
880   out << "explicit " << d_name << "("
881       << StringPrintf("const ::android::sp<%s> &impl", iface.c_str()) << ") "
882       << StringPrintf(": %s(impl)", kDelegateImplVarName) << " {}\n\n";
883   out << "::android::sp<" << iface << "> getImpl() { return " << kDelegateImplVarName << "; }\n";
884   for (const auto& method : interface.GetMethods()) {
885     if (method->IsUserDefined()) {
886       GenerateMethodDecl(out, typenames, *method, /*clazz=*/"");
887       out << " override";
888       GenerateDeprecated(out, *method);
889 
890       std::vector<std::string> args;
891 
892       // arg name, type
893       std::vector<pair<const std::string, const AidlTypeSpecifier&>> outBinders;
894       std::vector<pair<const std::string, const AidlTypeSpecifier&>> inBinders;
895       for (const auto& arg : method->GetArguments()) {
896         if (isDelegateable(arg->GetType())) {
897           if (arg->IsOut()) {
898             outBinders.push_back({arg->GetName(), arg->GetType()});
899           } else if (arg->IsIn()) {
900             inBinders.push_back({arg->GetName(), arg->GetType()});
901           } else {
902             AIDL_FATAL(*arg) << "inout interface?";
903           }
904           AIDL_FATAL_IF(!arg->IsIn() && !arg->IsOut(), *arg) << "Not in or out?";
905           args.push_back("_" + arg->GetName());
906         } else {
907           if (IsNonCopyableType(arg->GetType(), typenames)) {
908             args.push_back(StringPrintf("std::move(%s)", arg->GetName().c_str()));
909           } else {
910             args.push_back(arg->GetName());
911           }
912         }
913       }
914       if (method->GetType().GetName() != "void") {
915         if (isDelegateable(method->GetType())) {
916           outBinders.push_back({kReturnVarName, method->GetType()});
917         }
918         args.push_back(kReturnVarName);
919       }
920       out << " {\n";
921       out.Indent();
922       for (const auto binder : inBinders) {
923         wrapDelegate(out, binder.first, binder.second, true);
924       }
925       if (outBinders.empty()) {
926         out << "return " << kDelegateImplVarName << "->" << method->GetName() << "("
927             << base::Join(args, ", ") << ");\n";
928       } else {
929         out << "auto _status = " << kDelegateImplVarName << "->" << method->GetName() << "("
930             << base::Join(args, ", ") << ");\n";
931         for (const auto& binder : outBinders) {
932           wrapDelegate(out, binder.first, binder.second, false);
933         }
934         out << "return _status;\n";
935       }
936       out.Dedent();
937       out << "}\n";
938     } else if (method->GetName() == kGetInterfaceVersion && options.Version()) {
939       out << "int32_t " << kGetInterfaceVersion << "()"
940           << " override {\n";
941       out.Indent();
942       out << "int32_t _delegator_ver = " << bn_name << "::" << kGetInterfaceVersion << "();\n";
943       out << "int32_t _impl_ver = " << kDelegateImplVarName << "->" << kGetInterfaceVersion
944           << "();\n";
945       out << "return _delegator_ver < _impl_ver ? _delegator_ver : _impl_ver;\n";
946       out.Dedent();
947       out << "}\n";
948     } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
949       out << "std::string " << kGetInterfaceHash << "()"
950           << " override {\n";
951       out << "  return " << kDelegateImplVarName << "->" << kGetInterfaceHash << "();\n";
952       out << "}\n";
953     }
954   }
955   out.Dedent();
956   out << "private:\n";
957   out.Indent();
958   out << "::android::sp<" << iface << "> " << kDelegateImplVarName << ";\n";
959   out.Dedent();
960   out << "};  // class " << d_name << "\n";
961 }
962 
963 // Collect all includes for the type's server header. Nested types are visited as well via
964 // VisitTopDown.
GenerateServerHeaderIncludes(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)965 void GenerateServerHeaderIncludes(CodeWriter& out, const AidlDefinedType& defined_type,
966                                   const AidlTypenames& typenames, const Options& options) {
967   struct Visitor : AidlVisitor {
968     const AidlTypenames& typenames;
969     const Options& options;
970     std::set<std::string> includes;
971     Visitor(const AidlTypenames& typenames, const Options& options)
972         : typenames(typenames), options(options) {}
973 
974     // Collect includes for each type reference
975     void Visit(const AidlTypeSpecifier& type) override {
976       // Add Bn* header files for types used in this header. The *Delegator
977       // definitions require them.
978       const auto defined_type = type.GetDefinedType();
979       if (defined_type && defined_type->AsInterface()) {
980         if (!isKnownUndefinedInterface(defined_type->GetCanonicalName())) {
981           includes.insert(HeaderFile(*defined_type, ClassNames::SERVER, /*use_os_sep=*/false));
982         }
983       }
984     }
985 
986     // Collect implementation-specific includes for each type definition
987     void Visit(const AidlInterface& iface) override {
988       includes.insert(HeaderFile(iface, ClassNames::SERVER, false));
989     }
990   } v(typenames, options);
991   VisitTopDown(v, defined_type);
992 
993   v.includes.insert(kBinderDelegateHeader);
994   for (const auto& path : v.includes) {
995     out << "#include <" << path << ">\n";
996   }
997   out << "\n";
998 }
999 
GenerateServerHeader(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)1000 void GenerateServerHeader(CodeWriter& out, const AidlInterface& interface,
1001                           const AidlTypenames& typenames, const Options& options) {
1002   out << "#pragma once\n\n";
1003   out << "#include <binder/IInterface.h>\n";
1004   out << "#include <" << HeaderFile(interface, ClassNames::RAW, false) << ">\n";
1005   if (options.GenLog()) {
1006     out << "#include <functional>\n";  // for std::function
1007     out << "#include <android/binder_to_string.h>\n";
1008   }
1009   GenerateServerHeaderIncludes(out, interface, typenames, options);
1010   out << "\n";
1011   EnterNamespace(out, interface);
1012   GenerateServerClassDecl(out, interface, typenames, options);
1013   LeaveNamespace(out, interface);
1014 }
1015 
1016 void GenerateClassDecl(CodeWriter& out, const AidlDefinedType& defined_type,
1017                        const AidlTypenames& typenames, const Options& options);
1018 
GenerateNestedTypeDecls(CodeWriter & out,const AidlDefinedType & type,const AidlTypenames & typenames,const Options & options)1019 void GenerateNestedTypeDecls(CodeWriter& out, const AidlDefinedType& type,
1020                              const AidlTypenames& typenames, const Options& options) {
1021   auto visit = [&](const auto& nested) { GenerateClassDecl(out, nested, typenames, options); };
1022   AIDL_FATAL_IF(!TopologicalVisit(type.GetNestedTypes(), visit), type) << "Cycle detected.";
1023 }
1024 
GenerateInterfaceClassDecl(CodeWriter & out,const AidlInterface & interface,const AidlTypenames & typenames,const Options & options)1025 void GenerateInterfaceClassDecl(CodeWriter& out, const AidlInterface& interface,
1026                                 const AidlTypenames& typenames, const Options& options) {
1027   const string i_name = ClassName(interface, ClassNames::INTERFACE);
1028   out << "class LIBBINDER_EXPORTED " << ClassName(interface, ClassNames::DELEGATOR_IMPL) << ";\n\n";
1029   out << "class LIBBINDER_EXPORTED";
1030   GenerateDeprecated(out, interface);
1031   out << " " << i_name << " : public ::android::IInterface {\n";
1032   out << "public:\n";
1033   out.Indent();
1034   out << "typedef " << ClassName(interface, ClassNames::DELEGATOR_IMPL) << " DefaultDelegator;\n";
1035   out << "DECLARE_META_INTERFACE(" << ClassName(interface, ClassNames::BASE) << ")\n";
1036   if (options.Version() > 0) {
1037     if (options.IsLatestUnfrozenVersion()) {
1038       out << "static inline const int32_t VERSION = true ? "
1039           << std::to_string(options.PreviousVersion()) << " : " << std::to_string(options.Version())
1040           << ";\n";
1041     } else {
1042       out << "static inline const int32_t VERSION = " << std::to_string(options.Version()) << ";\n";
1043     }
1044   }
1045   if (!options.Hash().empty()) {
1046     if (options.IsLatestUnfrozenVersion()) {
1047       out << "static inline const std::string HASH = true ? \"" << options.PreviousHash()
1048           << "\" : \"" << options.Hash() << "\";\n";
1049     } else {
1050       out << "static inline const std::string HASH = \"" << options.Hash() << "\";\n";
1051     }
1052   }
1053   GenerateNestedTypeDecls(out, interface, typenames, options);
1054   GenerateConstantDeclarations(out, interface, typenames);
1055   for (const auto& method : interface.GetMethods()) {
1056     if (method->IsUserDefined()) {
1057       out << "virtual ";
1058       GenerateMethodDecl(out, typenames, *method, /*clazz=*/"");
1059       GenerateDeprecated(out, *method);
1060       out << " = 0;\n";
1061     } else if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
1062       out << "virtual int32_t " << method->GetName() << "() = 0;\n";
1063     } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
1064       out << "virtual std::string " << method->GetName() << "() = 0;\n";
1065     }
1066   }
1067   out.Dedent();
1068   out << "};  // class " << i_name << "\n";
1069   out << "\n";
1070 
1071   // Implement the default impl class.
1072   const string default_impl = ClassName(interface, ClassNames::DEFAULT_IMPL);
1073   out << "class LIBBINDER_EXPORTED";
1074   GenerateDeprecated(out, interface);
1075   out << " " << default_impl << " : public " << i_name << " {\n";
1076   out << "public:\n";
1077   out.Indent();
1078   // onAsBinder returns nullptr as this interface is not associated with a
1079   // real binder.
1080   out << "::android::IBinder* onAsBinder() override {\n"
1081       << "  return nullptr;\n"
1082       << "}\n";
1083 
1084   // Each interface method by default returns UNKNOWN_TRANSACTION with is
1085   // the same status that is returned by transact() when the method is
1086   // not implemented in the server side. In other words, these default
1087   // methods do nothing; they only exist to aid making a real default
1088   // impl class without having to override all methods in an interface.
1089   for (const auto& method : interface.GetMethods()) {
1090     if (method->IsUserDefined()) {
1091       out << "::android::binder::Status " << method->GetName() << "("
1092           << GenerateArgList(typenames, *method, /*for_declaration=*/true, /*type_name_only=*/true)
1093           << ") override";
1094       GenerateDeprecated(out, *method);
1095       out << " {\n"
1096           << "  return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);\n"
1097           << "}\n";
1098     } else if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
1099       out << "int32_t " << kGetInterfaceVersion << "() override {\n"
1100           << "  return 0;\n"
1101           << "}\n";
1102     } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
1103       out << "std::string " << kGetInterfaceHash << "() override {\n"
1104           << "  return \"\";\n"
1105           << "}\n";
1106     }
1107   }
1108   out.Dedent();
1109   out << "};  // class " << default_impl << "\n";
1110 
1111   // When an interface is nested, every class should be defined together here
1112   // because we don't have separate headers for them.
1113   // (e.g. IFoo, IFooDefault, BpFoo, BnFoo, IFooDelegator)
1114   if (interface.GetParentType()) {
1115     GenerateClientClassDecl(out, interface, typenames, options);
1116     GenerateServerClassDecl(out, interface, typenames, options);
1117   }
1118 }
1119 
GenerateReadFromParcel(CodeWriter & out,const AidlStructuredParcelable & parcel,const AidlTypenames & typenames)1120 void GenerateReadFromParcel(CodeWriter& out, const AidlStructuredParcelable& parcel,
1121                             const AidlTypenames& typenames) {
1122   out << "::android::status_t _aidl_ret_status = ::android::OK;\n";
1123   out << "size_t _aidl_start_pos = _aidl_parcel->dataPosition();\n";
1124   out << "int32_t _aidl_parcelable_raw_size = 0;\n";
1125   out << "_aidl_ret_status = _aidl_parcel->readInt32(&_aidl_parcelable_raw_size);\n";
1126   out << "if (((_aidl_ret_status) != (::android::OK))) {\n";
1127   out << "  return _aidl_ret_status;\n";
1128   out << "}\n";
1129   out << "if (_aidl_parcelable_raw_size < 4) return ::android::BAD_VALUE;\n";
1130   out << "size_t _aidl_parcelable_size = static_cast<size_t>(_aidl_parcelable_raw_size);\n";
1131   out << "if (_aidl_start_pos > INT32_MAX - _aidl_parcelable_size) return ::android::BAD_VALUE;\n";
1132   for (const auto& variable : parcel.GetFields()) {
1133     string method = ParcelReadMethodOf(variable->GetType(), typenames);
1134     string arg = ParcelReadCastOf(variable->GetType(), typenames, "&" + variable->GetName());
1135     out << "if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) {\n";
1136     out << "  _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size);\n";
1137     out << "  return _aidl_ret_status;\n";
1138     out << "}\n";
1139     if (variable->IsNew() && ShouldForceDowngradeFor(CommunicationSide::READ)) {
1140       out << "if (false) {\n";
1141       out.Indent();
1142     }
1143     out << "_aidl_ret_status = _aidl_parcel->" << method << "(" << arg << ");\n";
1144     out << "if (((_aidl_ret_status) != (::android::OK))) {\n";
1145     out << "  return _aidl_ret_status;\n";
1146     out << "}\n";
1147     if (variable->IsNew() && ShouldForceDowngradeFor(CommunicationSide::READ)) {
1148       out.Dedent();
1149       out << "}\n";
1150     }
1151   }
1152   out << "_aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size);\n";
1153   out << "return _aidl_ret_status;\n";
1154 }
1155 
GenerateWriteToParcel(CodeWriter & out,const AidlStructuredParcelable & parcel,const AidlTypenames & typenames)1156 void GenerateWriteToParcel(CodeWriter& out, const AidlStructuredParcelable& parcel,
1157                            const AidlTypenames& typenames) {
1158   out << "::android::status_t _aidl_ret_status = ::android::OK;\n";
1159   out << "size_t _aidl_start_pos = " << kParcelVarName << "->dataPosition();\n";
1160   out << kParcelVarName << "->writeInt32(0);\n";
1161   for (const auto& variable : parcel.GetFields()) {
1162     string method = ParcelWriteMethodOf(variable->GetType(), typenames);
1163     string arg = ParcelWriteCastOf(variable->GetType(), typenames, variable->GetName());
1164     if (variable->IsNew() && ShouldForceDowngradeFor(CommunicationSide::WRITE)) {
1165       out << "if (false) {\n";
1166       out.Indent();
1167     }
1168     out << "_aidl_ret_status = " << kParcelVarName << "->" << method << "(" << arg << ");\n";
1169     out << "if (((_aidl_ret_status) != (::android::OK))) {\n";
1170     out << "  return _aidl_ret_status;\n";
1171     out << "}\n";
1172     if (variable->IsNew() && ShouldForceDowngradeFor(CommunicationSide::WRITE)) {
1173       out.Dedent();
1174       out << "}\n";
1175     }
1176   }
1177   out << "size_t _aidl_end_pos = " << kParcelVarName << "->dataPosition();\n";
1178   out << kParcelVarName << "->setDataPosition(_aidl_start_pos);\n";
1179   out << kParcelVarName << "->writeInt32(static_cast<int32_t>(_aidl_end_pos - _aidl_start_pos));\n";
1180   out << kParcelVarName << "->setDataPosition(_aidl_end_pos);\n";
1181   out << "return _aidl_ret_status;\n";
1182 }
1183 
GetParcelWriterContext(const AidlTypenames & typenames)1184 ParcelWriterContext GetParcelWriterContext(const AidlTypenames& typenames) {
1185   return ParcelWriterContext{
1186       .status_type = kAndroidStatusLiteral,
1187       .status_ok = kAndroidStatusOk,
1188       .status_bad = kAndroidStatusBadValue,
1189       .read_func =
1190           [&](CodeWriter& out, const string& var, const AidlTypeSpecifier& type) {
1191             out << fmt::format("{}->{}({})", kParcelVarName, ParcelReadMethodOf(type, typenames),
1192                                ParcelReadCastOf(type, typenames, "&" + var));
1193           },
1194       .write_func =
1195           [&](CodeWriter& out, const string& value, const AidlTypeSpecifier& type) {
1196             out << fmt::format("{}->{}({})", kParcelVarName, ParcelWriteMethodOf(type, typenames),
1197                                ParcelWriteCastOf(type, typenames, value));
1198           },
1199   };
1200 }
1201 
GenerateReadFromParcel(CodeWriter & out,const AidlUnionDecl & decl,const AidlTypenames & typenames)1202 void GenerateReadFromParcel(CodeWriter& out, const AidlUnionDecl& decl,
1203                             const AidlTypenames& typenames) {
1204   UnionWriter uw{decl, typenames, &CppNameOf, &ConstantValueDecorator};
1205   uw.ReadFromParcel(out, GetParcelWriterContext(typenames));
1206 }
1207 
GenerateWriteToParcel(CodeWriter & out,const AidlUnionDecl & decl,const AidlTypenames & typenames)1208 void GenerateWriteToParcel(CodeWriter& out, const AidlUnionDecl& decl,
1209                            const AidlTypenames& typenames) {
1210   UnionWriter uw{decl, typenames, &CppNameOf, &ConstantValueDecorator};
1211   uw.WriteToParcel(out, GetParcelWriterContext(typenames));
1212 }
1213 
GenerateParcelFields(CodeWriter & out,const AidlStructuredParcelable & decl,const AidlTypenames & typenames)1214 void GenerateParcelFields(CodeWriter& out, const AidlStructuredParcelable& decl,
1215                           const AidlTypenames& typenames) {
1216   for (const auto& variable : decl.GetFields()) {
1217     const auto& type = variable->GetType();
1218     std::string cpp_type = CppNameOf(type, typenames);
1219     out << cpp_type;
1220     GenerateDeprecated(out, *variable);
1221     out << " " << variable->GetName();
1222     if (variable->GetDefaultValue()) {
1223       out << " = " << variable->ValueString(ConstantValueDecorator);
1224     } else {
1225       // Some types needs to be explicitly initialized even when no default value is set.
1226       // - ParcelableHolder should be initialized with stability
1227       // - enum should be zero initialized, otherwise the value will be indeterminate
1228       // - fixed-size arrays should be initialized, otherwise the value will be indeterminate
1229       if (type.GetName() == "ParcelableHolder") {
1230         if (decl.IsVintfStability()) {
1231           out << " { ::android::Parcelable::Stability::STABILITY_VINTF }";
1232         } else {
1233           out << " { ::android::Parcelable::Stability::STABILITY_LOCAL }";
1234         }
1235       } else if (typenames.GetEnumDeclaration(type) && !type.IsArray()) {
1236         out << " = " << cpp_type << "(0)";
1237       } else if (type.IsFixedSizeArray() && !type.IsNullable()) {
1238         out << " = {{}}";
1239       }
1240     }
1241     out << ";\n";
1242   }
1243 }
1244 
GenerateParcelFields(CodeWriter & out,const AidlUnionDecl & decl,const AidlTypenames & typenames)1245 void GenerateParcelFields(CodeWriter& out, const AidlUnionDecl& decl,
1246                           const AidlTypenames& typenames) {
1247   UnionWriter uw{decl, typenames, &CppNameOf, &ConstantValueDecorator};
1248   uw.PublicFields(out);
1249 }
1250 
1251 template <typename ParcelableType>
GenerateParcelClassDecl(CodeWriter & out,const ParcelableType & parcel,const AidlTypenames & typenames,const Options & options)1252 void GenerateParcelClassDecl(CodeWriter& out, const ParcelableType& parcel,
1253                              const AidlTypenames& typenames, const Options& options) {
1254   const string clazz = parcel.GetName();
1255 
1256   ClangDiagnosticIgnoreDeprecated guard(out, HasDeprecatedField(parcel));
1257   out << TemplateDecl(parcel);
1258   out << "class LIBBINDER_EXPORTED";
1259   GenerateDeprecated(out, parcel);
1260   out << " " << clazz << " : public ::android::Parcelable {\n";
1261   out << "public:\n";
1262   out.Indent();
1263 
1264   GenerateNestedTypeDecls(out, parcel, typenames, options);
1265   GenerateParcelFields(out, parcel, typenames);
1266   GenerateParcelableComparisonOperators(out, parcel);
1267   GenerateConstantDeclarations(out, parcel, typenames);
1268 
1269   if (parcel.IsVintfStability()) {
1270     out << "::android::Parcelable::Stability getStability() const override { return "
1271            "::android::Parcelable::Stability::STABILITY_VINTF; }\n";
1272   }
1273 
1274   out << kAndroidStatusLiteral << " readFromParcel(const ::android::Parcel* _aidl_parcel) final;\n";
1275   out << kAndroidStatusLiteral << " writeToParcel(::android::Parcel* _aidl_parcel) const final;\n";
1276 
1277   const string canonical_name = parcel.GetCanonicalName();
1278   out << "static const ::android::String16& getParcelableDescriptor() {\n"
1279       << "  static const ::android::StaticString16 DESCRIPTOR (u\"" << canonical_name << "\");\n"
1280       << "  return DESCRIPTOR;\n"
1281       << "}\n";
1282 
1283   GenerateToString(out, parcel);
1284 
1285   out.Dedent();
1286 
1287   if (auto decl = AidlCast<AidlUnionDecl>(parcel); decl) {
1288     out << "private:\n";
1289     out.Indent();
1290     UnionWriter uw{*decl, typenames, &CppNameOf, &ConstantValueDecorator};
1291     uw.PrivateFields(out);
1292     out.Dedent();
1293   }
1294 
1295   out << "};  // class " << clazz << "\n";
1296 }
1297 
1298 template <typename T>
GenerateParcelSource(CodeWriter & out,const T & parcel,const AidlTypenames & typenames,const Options &)1299 void GenerateParcelSource(CodeWriter& out, const T& parcel, const AidlTypenames& typenames,
1300                           const Options&) {
1301   string q_name = GetQualifiedName(parcel);
1302   if (parcel.IsGeneric()) {
1303     q_name += "<" + Join(parcel.GetTypeParameters(), ",") + ">";
1304   }
1305 
1306   out << "#include <" << CppHeaderForType(parcel) << ">\n\n";
1307 
1308   EnterNamespace(out, parcel);
1309   GenerateConstantDefinitions(out, parcel, typenames, TemplateDecl(parcel), q_name);
1310 
1311   {
1312     ClangDiagnosticIgnoreDeprecated guard(out, HasDeprecatedField(parcel));
1313     out << TemplateDecl(parcel);
1314     out << "::android::status_t " << q_name << "::readFromParcel(const ::android::Parcel* "
1315         << kParcelVarName << ") {\n";
1316     out.Indent();
1317     GenerateReadFromParcel(out, parcel, typenames);
1318     out.Dedent();
1319     out << "}\n";
1320 
1321     out << TemplateDecl(parcel);
1322     out << "::android::status_t " << q_name << "::writeToParcel(::android::Parcel* "
1323         << kParcelVarName << ") const {\n";
1324     out.Indent();
1325     GenerateWriteToParcel(out, parcel, typenames);
1326     out.Dedent();
1327     out << "}\n";
1328   }
1329   LeaveNamespace(out, parcel);
1330 }
1331 
GenerateEnumClassDecl(CodeWriter & out,const AidlEnumDeclaration & enum_decl,const AidlTypenames & typenames)1332 void GenerateEnumClassDecl(CodeWriter& out, const AidlEnumDeclaration& enum_decl,
1333                            const AidlTypenames& typenames) {
1334   cpp::GenerateEnumClassDecl(out, enum_decl, CppNameOf(enum_decl.GetBackingType(), typenames),
1335                              ConstantValueDecorator);
1336 }
1337 
GenerateClassDecl(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1338 void GenerateClassDecl(CodeWriter& out, const AidlDefinedType& defined_type,
1339                        const AidlTypenames& typenames, const Options& options) {
1340   if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
1341     GenerateInterfaceClassDecl(out, *iface, typenames, options);
1342   } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
1343     GenerateParcelClassDecl(out, *parcelable, typenames, options);
1344   } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
1345     GenerateParcelClassDecl(out, *union_decl, typenames, options);
1346   } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
1347     GenerateEnumClassDecl(out, *enum_decl, typenames);
1348   } else {
1349     AIDL_FATAL(defined_type) << "Unrecognized type sent for CPP generation.";
1350   }
1351 }
1352 
1353 }  // namespace internals
1354 
1355 using namespace internals;
1356 
1357 // Collect all includes for the type's header. Nested types are visited as well via VisitTopDown.
GenerateHeaderIncludes(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1358 void GenerateHeaderIncludes(CodeWriter& out, const AidlDefinedType& defined_type,
1359                             const AidlTypenames& typenames, const Options& options) {
1360   struct Visitor : AidlVisitor {
1361     const AidlTypenames& typenames;
1362     const Options& options;
1363     std::set<std::string> includes;
1364     Visitor(const AidlTypenames& typenames, const Options& options)
1365         : typenames(typenames), options(options) {}
1366 
1367     // Collect includes for each type reference including built-in type
1368     void Visit(const AidlTypeSpecifier& type) override {
1369       cpp::AddHeaders(type, typenames, &includes);
1370     }
1371 
1372     // Collect implementation-specific includes for each type definition
1373     void Visit(const AidlInterface& iface) override {
1374       includes.insert(kIBinderHeader);        // IBinder
1375       includes.insert(kIInterfaceHeader);     // IInterface
1376       includes.insert(kStatusHeader);         // Status
1377       includes.insert(kStrongPointerHeader);  // sp<>
1378 
1379       if (options.GenTraces()) {
1380         includes.insert(kTraceHeader);
1381       }
1382 
1383       // For a nested interface, client/server classes are declared the same header as well.
1384       if (iface.GetParentType()) {
1385         includes.insert(kBinderDelegateHeader);  // Delegate.h
1386         // client/server class provides logFunc when gen_log is on
1387         if (options.GenLog()) {
1388           includes.insert("functional");                  // std::function for logFunc
1389           includes.insert("android/binder_to_string.h");  // Generic ToString helper
1390         }
1391       }
1392     }
1393 
1394     void Visit(const AidlStructuredParcelable&) override {
1395       AddParcelableCommonHeaders();
1396       includes.insert("tuple");  // std::tie in comparison operators
1397     }
1398 
1399     void Visit(const AidlUnionDecl& union_decl) override {
1400       AddParcelableCommonHeaders();
1401       auto union_headers = cpp::UnionWriter::GetHeaders(union_decl);
1402       includes.insert(std::begin(union_headers), std::end(union_headers));
1403     }
1404 
1405     void Visit(const AidlEnumDeclaration&) override {
1406       includes.insert("array");           // used in enum_values
1407       includes.insert("binder/Enums.h");  // provides enum_range
1408       includes.insert("string");          // toString() returns std::string
1409     }
1410 
1411     void AddParcelableCommonHeaders() {
1412       includes.insert(kParcelHeader);                 // Parcel in readFromParcel/writeToParcel
1413       includes.insert(kStatusHeader);                 // Status
1414       includes.insert(kString16Header);               // String16 in getParcelableDescriptor
1415       includes.insert("android/binder_to_string.h");  // toString()
1416     }
1417   } v(typenames, options);
1418   VisitTopDown(v, defined_type);
1419 
1420   for (const auto& path : v.includes) {
1421     out << "#include <" << path << ">\n";
1422   }
1423   out << "\n";
1424   if (v.includes.count("cassert")) {
1425     // TODO(b/31559095) bionic on host should define __assert2
1426     out << "#ifndef __BIONIC__\n#define __assert2(a,b,c,d) ((void)0)\n#endif\n\n";
1427   }
1428 }
1429 
1430 // Generic parcelables and enum utilities should be defined in header.
GenerateHeaderDefinitions(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1431 void GenerateHeaderDefinitions(CodeWriter& out, const AidlDefinedType& defined_type,
1432                                const AidlTypenames& typenames, const Options& options) {
1433   struct Visitor : AidlVisitor {
1434     CodeWriter& out;
1435     const AidlTypenames& typenames;
1436     const Options& options;
1437     Visitor(CodeWriter& out, const AidlTypenames& typenames, const Options& options)
1438         : out(out), typenames(typenames), options(options) {}
1439 
1440     void Visit(const AidlEnumDeclaration& enum_decl) override {
1441       const auto backing_type = CppNameOf(enum_decl.GetBackingType(), typenames);
1442       EnterNamespace(out, enum_decl);
1443       out << GenerateEnumToString(enum_decl, backing_type);
1444       LeaveNamespace(out, enum_decl);
1445 
1446       out << "namespace android {\n";
1447       out << "namespace internal {\n";
1448       out << GenerateEnumValues(enum_decl, {""});
1449       out << "}  // namespace internal\n";
1450       out << "}  // namespace android\n";
1451     }
1452 
1453     void Visit(const AidlStructuredParcelable& parcelable) override {
1454       if (parcelable.IsGeneric()) {
1455         GenerateParcelSource(out, parcelable, typenames, options);
1456       }
1457     }
1458 
1459     void Visit(const AidlUnionDecl& union_decl) override {
1460       if (union_decl.IsGeneric()) {
1461         GenerateParcelSource(out, union_decl, typenames, options);
1462       }
1463     }
1464 
1465   } v(out, typenames, options);
1466   VisitTopDown(v, defined_type);
1467 }
1468 
GenerateHeader(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1469 void GenerateHeader(CodeWriter& out, const AidlDefinedType& defined_type,
1470                     const AidlTypenames& typenames, const Options& options) {
1471   if (auto parcelable = AidlCast<AidlParcelable>(defined_type); parcelable) {
1472     out << "#error TODO(b/111362593) parcelables do not have headers";
1473     return;
1474   }
1475   out << "#pragma once\n\n";
1476   GenerateHeaderIncludes(out, defined_type, typenames, options);
1477   GenerateForwardDecls(out, defined_type, false);
1478   EnterNamespace(out, defined_type);
1479   // Each class decl contains its own nested types' class decls
1480   GenerateClassDecl(out, defined_type, typenames, options);
1481   LeaveNamespace(out, defined_type);
1482   GenerateHeaderDefinitions(out, defined_type, typenames, options);
1483 }
1484 
GenerateClientHeader(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1485 void GenerateClientHeader(CodeWriter& out, const AidlDefinedType& defined_type,
1486                           const AidlTypenames& typenames, const Options& options) {
1487   if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
1488     GenerateClientHeader(out, *iface, typenames, options);
1489   } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
1490     out << "#error TODO(b/111362593) parcelables do not have bp classes";
1491   } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
1492     out << "#error TODO(b/111362593) parcelables do not have bp classes";
1493   } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
1494     out << "#error TODO(b/111362593) enums do not have bp classes";
1495   } else if (auto parcelable = AidlCast<AidlParcelable>(defined_type); parcelable) {
1496     out << "#error TODO(b/111362593) parcelables do not have bp classes";
1497   } else {
1498     AIDL_FATAL(defined_type) << "Unrecognized type sent for CPP generation.";
1499   }
1500 }
1501 
GenerateServerHeader(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1502 void GenerateServerHeader(CodeWriter& out, const AidlDefinedType& defined_type,
1503                           const AidlTypenames& typenames, const Options& options) {
1504   if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
1505     GenerateServerHeader(out, *iface, typenames, options);
1506   } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
1507     out << "#error TODO(b/111362593) parcelables do not have bn classes";
1508   } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
1509     out << "#error TODO(b/111362593) parcelables do not have bn classes";
1510   } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
1511     out << "#error TODO(b/111362593) enums do not have bn classes";
1512   } else if (auto parcelable = AidlCast<AidlParcelable>(defined_type); parcelable) {
1513     out << "#error TODO(b/111362593) parcelables do not have bn classes";
1514   } else {
1515     AIDL_FATAL(defined_type) << "Unrecognized type sent for CPP generation.";
1516   }
1517 }
1518 
GenerateSource(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1519 void GenerateSource(CodeWriter& out, const AidlDefinedType& defined_type,
1520                     const AidlTypenames& typenames, const Options& options) {
1521   struct Visitor : AidlVisitor {
1522     CodeWriter& out;
1523     const AidlTypenames& typenames;
1524     const Options& options;
1525     Visitor(CodeWriter& out, const AidlTypenames& typenames, const Options& options)
1526         : out(out), typenames(typenames), options(options) {}
1527 
1528     void Visit(const AidlInterface& interface) override {
1529       GenerateInterfaceSource(out, interface, typenames, options);
1530       GenerateClientSource(out, interface, typenames, options);
1531       GenerateServerSource(out, interface, typenames, options);
1532     }
1533 
1534     void Visit(const AidlStructuredParcelable& parcelable) override {
1535       if (!parcelable.IsGeneric()) {
1536         GenerateParcelSource(out, parcelable, typenames, options);
1537       } else {
1538         out << "\n";
1539       }
1540     }
1541 
1542     void Visit(const AidlUnionDecl& union_decl) override {
1543       if (!union_decl.IsGeneric()) {
1544         GenerateParcelSource(out, union_decl, typenames, options);
1545       } else {
1546         out << "\n";
1547       }
1548     }
1549 
1550     void Visit(const AidlEnumDeclaration& enum_decl) override {
1551       if (!enum_decl.GetParentType()) {
1552         out << "// This file is intentionally left blank as placeholder for enum declaration.\n";
1553       }
1554     }
1555 
1556     void Visit(const AidlParcelable& parcelable) override {
1557       AIDL_FATAL_IF(parcelable.GetParentType(), parcelable)
1558           << "Unstructured parcelable can't be nested.";
1559       out << "// This file is intentionally left blank as placeholder for parcel declaration.\n";
1560     }
1561   } v(out, typenames, options);
1562   VisitTopDown(v, defined_type);
1563 }
1564 
GenerateCpp(const string & output_file,const Options & options,const AidlTypenames & typenames,const AidlDefinedType & defined_type,const IoDelegate & io_delegate)1565 bool GenerateCpp(const string& output_file, const Options& options, const AidlTypenames& typenames,
1566                  const AidlDefinedType& defined_type, const IoDelegate& io_delegate) {
1567   if (!ValidateOutputFilePath(output_file, options, defined_type)) {
1568     return false;
1569   }
1570 
1571   using GenFn = void (*)(CodeWriter& out, const AidlDefinedType& defined_type,
1572                          const AidlTypenames& typenames, const Options& options);
1573   // Wrap Generate* function to handle CodeWriter for a file.
1574   auto gen = [&](auto file, GenFn fn) {
1575     unique_ptr<CodeWriter> writer(io_delegate.GetCodeWriter(file));
1576 
1577     GenerateAutoGenHeader(*writer, options);
1578 
1579     fn(*writer, defined_type, typenames, options);
1580     AIDL_FATAL_IF(!writer->Close(), defined_type) << "I/O Error!";
1581     return true;
1582   };
1583 
1584   return gen(options.OutputHeaderDir() + HeaderFile(defined_type, ClassNames::RAW),
1585              &GenerateHeader) &&
1586          gen(options.OutputHeaderDir() + HeaderFile(defined_type, ClassNames::CLIENT),
1587              &GenerateClientHeader) &&
1588          gen(options.OutputHeaderDir() + HeaderFile(defined_type, ClassNames::SERVER),
1589              &GenerateServerHeader) &&
1590          gen(output_file, &GenerateSource);
1591 }
1592 
1593 }  // namespace cpp
1594 }  // namespace aidl
1595 }  // namespace android
1596