• 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 <format>
24 #include <memory>
25 #include <set>
26 #include <string>
27 
28 #include <android-base/stringprintf.h>
29 #include <android-base/strings.h>
30 
31 #include "aidl_language.h"
32 #include "aidl_to_common.h"
33 #include "aidl_to_cpp.h"
34 
35 #include "aidl_typenames.h"
36 #include "logging.h"
37 
38 using android::base::Join;
39 using android::base::StringPrintf;
40 using std::set;
41 using std::string;
42 using std::unique_ptr;
43 using std::vector;
44 
45 namespace android {
46 namespace aidl {
47 namespace cpp {
48 namespace internals {
49 namespace {
50 
51 const char kAndroidStatusVarName[] = "_aidl_ret_status";
52 const char kCodeVarName[] = "_aidl_code";
53 const char kFlagsVarName[] = "_aidl_flags";
54 const char kDataVarName[] = "_aidl_data";
55 const char kErrorLabel[] = "_aidl_error";
56 const char kImplVarName[] = "_aidl_impl";
57 const char kDelegateImplVarName[] = "_aidl_delegate";
58 const char kParcelVarName[] = "_aidl_parcel";
59 const char kReplyVarName[] = "_aidl_reply";
60 const char kReturnVarName[] = "_aidl_return";
61 const char kStatusVarName[] = "_aidl_status";
62 const char kTraceVarName[] = "_aidl_trace";
63 const char kAndroidParcelLiteral[] = "::android::Parcel";
64 const char kAndroidStatusLiteral[] = "::android::status_t";
65 const char kAndroidStatusOk[] = "::android::OK";
66 const char kAndroidStatusBadValue[] = "::android::BAD_VALUE";
67 const char kBinderStatusLiteral[] = "::android::binder::Status";
68 const char kIBinderHeader[] = "binder/IBinder.h";
69 const char kIInterfaceHeader[] = "binder/IInterface.h";
70 const char kBinderDelegateHeader[] = "binder/Delegate.h";
71 const char kParcelHeader[] = "binder/Parcel.h";
72 const char kStabilityHeader[] = "binder/Stability.h";
73 const char kStatusHeader[] = "binder/Status.h";
74 const char kString16Header[] = "utils/String16.h";
75 const char kTraceHeader[] = "binder/Trace.h";
76 const char kStrongPointerHeader[] = "utils/StrongPointer.h";
77 
GenerateBreakOnStatusNotOk(CodeWriter & out)78 void GenerateBreakOnStatusNotOk(CodeWriter& out) {
79   out.Write("if (((%s) != (%s))) {\n", kAndroidStatusVarName, kAndroidStatusOk);
80   out.Write("  break;\n");
81   out.Write("}\n");
82 }
83 
GenerateGotoErrorOnBadStatus(CodeWriter & out)84 void GenerateGotoErrorOnBadStatus(CodeWriter& out) {
85   out.Write("if (((%s) != (%s))) {\n", kAndroidStatusVarName, kAndroidStatusOk);
86   out.Write("  goto %s;\n", kErrorLabel);
87   out.Write("}\n");
88 }
89 
90 // Format three types of arg list for method.
91 //  for_declaration & !type_name_only: int a      // for method decl with type and arg
92 //  for_declaration &  type_name_only: int /*a*/  // for method decl with type
93 // !for_declaration                  :     a      // for method call with arg (with direction)
GenerateArgList(const AidlTypenames & typenames,const AidlMethod & method,bool for_declaration,bool type_name_only)94 string GenerateArgList(const AidlTypenames& typenames, const AidlMethod& method,
95                        bool for_declaration, bool type_name_only) {
96   vector<string> method_arguments;
97   for (const unique_ptr<AidlArgument>& a : method.GetArguments()) {
98     string literal;
99     // b/144943748: CppNameOf FileDescriptor is unique_fd. Don't pass it by
100     // const reference but by value to make it easier for the user to keep
101     // it beyond the scope of the call. unique_fd is a thin wrapper for an
102     // int (fd) so passing by value is not expensive.
103     const bool non_copyable = IsNonCopyableType(a->GetType(), typenames);
104     if (for_declaration) {
105       // Method declarations need typenames, pointers to out params, and variable
106       // names that match the .aidl specification.
107       literal = CppNameOf(a->GetType(), typenames);
108 
109       if (a->IsOut()) {
110         literal = literal + "*";
111       } else {
112         const auto defined_type = typenames.TryGetDefinedType(a->GetType().GetName());
113 
114         const bool is_enum = defined_type && defined_type->AsEnumDeclaration() != nullptr;
115         const bool is_primitive = AidlTypenames::IsPrimitiveTypename(a->GetType().GetName());
116 
117         // We pass in parameters that are not primitives by const reference.
118         // Arrays of primitives are not primitives.
119         if (!(is_primitive || is_enum || non_copyable) || a->GetType().IsArray()) {
120           literal = "const " + literal + "&";
121         }
122       }
123       if (type_name_only) {
124         literal += " /*" + a->GetName() + "*/";
125       } else {
126         literal += " " + a->GetName();
127       }
128     } else {
129       std::string var_name = BuildVarName(*a);
130       if (a->IsOut()) {
131         literal = "&" + var_name;
132       } else if (non_copyable) {
133         literal = "std::move(" + var_name + ")";
134       } else {
135         literal = var_name;
136       }
137     }
138     method_arguments.push_back(literal);
139   }
140 
141   if (method.GetType().GetName() != "void") {
142     string literal;
143     if (for_declaration) {
144       literal = CppNameOf(method.GetType(), typenames) + "*";
145       if (type_name_only) {
146         literal += " /*" + string(kReturnVarName) + "*/";
147       } else {
148         literal += " " + string(kReturnVarName);
149       }
150     } else {
151       literal = string{"&"} + kReturnVarName;
152     }
153     method_arguments.push_back(literal);
154   }
155 
156   return Join(method_arguments, ", ");
157 }
158 
GenerateMethodDecl(CodeWriter & out,const AidlTypenames & types,const AidlMethod & method,const string & clazz)159 void GenerateMethodDecl(CodeWriter& out, const AidlTypenames& types, const AidlMethod& method,
160                         const string& clazz) {
161   string clazz_prefix = clazz.empty() ? "" : clazz + "::";
162   out << "::android::binder::Status " << clazz_prefix << method.GetName() << "("
163       << GenerateArgList(types, method, /*for_declartion=*/true, /*type_name_only=*/false) << ")";
164 }
165 
GenerateClientTransaction(CodeWriter & out,const AidlTypenames & typenames,const AidlInterface & interface,const AidlMethod & method,const Options & options)166 void GenerateClientTransaction(CodeWriter& out, const AidlTypenames& typenames,
167                                const AidlInterface& interface, const AidlMethod& method,
168                                const Options& options) {
169   const string i_name = ClassName(interface, ClassNames::INTERFACE);
170   const string bp_name = GetQualifiedName(interface, ClassNames::CLIENT);
171   const string bn_name = GetQualifiedName(interface, ClassNames::SERVER);
172 
173   GenerateMethodDecl(out, typenames, method, bp_name);
174   out << " {\n";
175   out.Indent();
176 
177   // Declare parcels to hold our query and the response.
178   out.Write("%s %s;\n", kAndroidParcelLiteral, kDataVarName);
179   if (interface.IsSensitiveData()) {
180     out.Write("%s.markSensitive();\n", kDataVarName);
181   }
182   out.Write("%s.markForBinder(remoteStrong());\n", kDataVarName);
183 
184   if (!method.IsOneway()) {
185     out.Write("%s %s;\n", kAndroidParcelLiteral, kReplyVarName);
186   }
187 
188   // Declare the status_t variable we need for error handling.
189   out.Write("%s %s = %s;\n", kAndroidStatusLiteral, kAndroidStatusVarName, kAndroidStatusOk);
190   // We unconditionally return a Status object.
191   out.Write("%s %s;\n", kBinderStatusLiteral, kStatusVarName);
192 
193   if (options.GenTraces()) {
194     out.Write(
195         "::android::binder::ScopedTrace %s(ATRACE_TAG_AIDL, \"AIDL::cpp::%s::%s::cppClient\");\n",
196         kTraceVarName, interface.GetName().c_str(), method.GetName().c_str());
197   }
198 
199   if (options.GenLog()) {
200     out << GenLogBeforeExecute(bp_name, method, false /* isServer */, false /* isNdk */);
201   }
202 
203   if (method.IsNew() && ShouldForceDowngradeFor(CommunicationSide::WRITE)) {
204     out << "if (true) {\n";
205     out.Write("  %s = ::android::UNKNOWN_TRANSACTION;\n", kAndroidStatusVarName);
206     out << "} else {\n";
207     out.Indent();
208   }
209 
210   // Add the name of the interface we're hoping to call.
211   out.Write("%s = %s.writeInterfaceToken(getInterfaceDescriptor());\n", kAndroidStatusVarName,
212             kDataVarName);
213   GenerateGotoErrorOnBadStatus(out);
214 
215   for (const auto& a : method.GetArguments()) {
216     const string var_name = ((a->IsOut()) ? "*" : "") + a->GetName();
217 
218     if (a->IsIn()) {
219       // Serialization looks roughly like:
220       //     _aidl_ret_status = _aidl_data.WriteInt32(in_param_name);
221       //     if (_aidl_ret_status != ::android::OK) { goto error; }
222       out.Write("%s = %s.%s(%s);\n", kAndroidStatusVarName, kDataVarName,
223                 ParcelWriteMethodOf(a->GetType(), typenames).c_str(),
224                 ParcelWriteCastOf(a->GetType(), typenames, var_name).c_str());
225       GenerateGotoErrorOnBadStatus(out);
226     } else if (a->IsOut() && a->GetType().IsDynamicArray()) {
227       // Special case, the length of the out array is written into the parcel.
228       //     _aidl_ret_status = _aidl_data.writeVectorSize(&out_param_name);
229       //     if (_aidl_ret_status != ::android::OK) { goto error; }
230       out.Write("%s = %s.writeVectorSize(%s);\n", kAndroidStatusVarName, kDataVarName,
231                 var_name.c_str());
232       GenerateGotoErrorOnBadStatus(out);
233     }
234   }
235 
236   // Invoke the transaction on the remote binder and confirm status.
237   std::vector<std::string> flags;
238   if (method.IsOneway()) flags.push_back("::android::IBinder::FLAG_ONEWAY");
239   if (interface.IsSensitiveData()) flags.push_back("::android::IBinder::FLAG_CLEAR_BUF");
240 
241   out.Write("%s = remote()->transact(%s, %s, %s%s, %s);\n", kAndroidStatusVarName,
242             GetTransactionIdFor(bn_name, method).c_str(), kDataVarName,
243             method.IsOneway() ? "" : "&", method.IsOneway() ? "nullptr" : 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 << std::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 << std::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 << std::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 << kDowngradeComment;
1039       out << "static inline const int32_t VERSION = true ? "
1040           << std::to_string(options.PreviousVersion()) << " : " << std::to_string(options.Version())
1041           << ";\n";
1042     } else {
1043       out << "static inline const int32_t VERSION = " << std::to_string(options.Version()) << ";\n";
1044     }
1045   }
1046   if (!options.Hash().empty()) {
1047     if (options.IsLatestUnfrozenVersion()) {
1048       out << "static inline const std::string HASH = true ? \"" << options.PreviousHash()
1049           << "\" : \"" << options.Hash() << "\";\n";
1050     } else {
1051       out << "static inline const std::string HASH = \"" << options.Hash() << "\";\n";
1052     }
1053   }
1054   GenerateNestedTypeDecls(out, interface, typenames, options);
1055   GenerateConstantDeclarations(out, interface, typenames);
1056   for (const auto& method : interface.GetMethods()) {
1057     if (method->IsUserDefined()) {
1058       out << "virtual ";
1059       GenerateMethodDecl(out, typenames, *method, /*clazz=*/"");
1060       GenerateDeprecated(out, *method);
1061       out << " = 0;\n";
1062     } else if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
1063       out << "virtual int32_t " << method->GetName() << "() = 0;\n";
1064     } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
1065       out << "virtual std::string " << method->GetName() << "() = 0;\n";
1066     }
1067   }
1068   out.Dedent();
1069   out << "};  // class " << i_name << "\n";
1070   out << "\n";
1071 
1072   // Implement the default impl class.
1073   const string default_impl = ClassName(interface, ClassNames::DEFAULT_IMPL);
1074   out << "class LIBBINDER_EXPORTED";
1075   GenerateDeprecated(out, interface);
1076   out << " " << default_impl << " : public " << i_name << " {\n";
1077   out << "public:\n";
1078   out.Indent();
1079   // onAsBinder returns nullptr as this interface is not associated with a
1080   // real binder.
1081   out << "::android::IBinder* onAsBinder() override {\n"
1082       << "  return nullptr;\n"
1083       << "}\n";
1084 
1085   // Each interface method by default returns UNKNOWN_TRANSACTION with is
1086   // the same status that is returned by transact() when the method is
1087   // not implemented in the server side. In other words, these default
1088   // methods do nothing; they only exist to aid making a real default
1089   // impl class without having to override all methods in an interface.
1090   for (const auto& method : interface.GetMethods()) {
1091     if (method->IsUserDefined()) {
1092       out << "::android::binder::Status " << method->GetName() << "("
1093           << GenerateArgList(typenames, *method, /*for_declaration=*/true, /*type_name_only=*/true)
1094           << ") override";
1095       GenerateDeprecated(out, *method);
1096       out << " {\n"
1097           << "  return ::android::binder::Status::fromStatusT(::android::UNKNOWN_TRANSACTION);\n"
1098           << "}\n";
1099     } else if (method->GetName() == kGetInterfaceVersion && options.Version() > 0) {
1100       out << "int32_t " << kGetInterfaceVersion << "() override {\n"
1101           << "  return 0;\n"
1102           << "}\n";
1103     } else if (method->GetName() == kGetInterfaceHash && !options.Hash().empty()) {
1104       out << "std::string " << kGetInterfaceHash << "() override {\n"
1105           << "  return \"\";\n"
1106           << "}\n";
1107     }
1108   }
1109   out.Dedent();
1110   out << "};  // class " << default_impl << "\n";
1111 
1112   // When an interface is nested, every class should be defined together here
1113   // because we don't have separate headers for them.
1114   // (e.g. IFoo, IFooDefault, BpFoo, BnFoo, IFooDelegator)
1115   if (interface.GetParentType()) {
1116     GenerateClientClassDecl(out, interface, typenames, options);
1117     GenerateServerClassDecl(out, interface, typenames, options);
1118   }
1119 }
1120 
GenerateReadFromParcel(CodeWriter & out,const AidlStructuredParcelable & parcel,const AidlTypenames & typenames)1121 void GenerateReadFromParcel(CodeWriter& out, const AidlStructuredParcelable& parcel,
1122                             const AidlTypenames& typenames) {
1123   out << "::android::status_t _aidl_ret_status = ::android::OK;\n";
1124   out << "size_t _aidl_start_pos = _aidl_parcel->dataPosition();\n";
1125   out << "int32_t _aidl_parcelable_raw_size = 0;\n";
1126   out << "_aidl_ret_status = _aidl_parcel->readInt32(&_aidl_parcelable_raw_size);\n";
1127   out << "if (((_aidl_ret_status) != (::android::OK))) {\n";
1128   out << "  return _aidl_ret_status;\n";
1129   out << "}\n";
1130   out << "if (_aidl_parcelable_raw_size < 4) return ::android::BAD_VALUE;\n";
1131   out << "size_t _aidl_parcelable_size = static_cast<size_t>(_aidl_parcelable_raw_size);\n";
1132   out << "if (_aidl_start_pos > INT32_MAX - _aidl_parcelable_size) return ::android::BAD_VALUE;\n";
1133   for (const auto& variable : parcel.GetFields()) {
1134     string method = ParcelReadMethodOf(variable->GetType(), typenames);
1135     string arg = ParcelReadCastOf(variable->GetType(), typenames, "&" + variable->GetName());
1136     out << "if (_aidl_parcel->dataPosition() - _aidl_start_pos >= _aidl_parcelable_size) {\n";
1137     out << "  _aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size);\n";
1138     out << "  return _aidl_ret_status;\n";
1139     out << "}\n";
1140     if (variable->IsNew() && ShouldForceDowngradeFor(CommunicationSide::READ)) {
1141       out << "if (false) {\n";
1142       out.Indent();
1143     }
1144     out << "_aidl_ret_status = _aidl_parcel->" << method << "(" << arg << ");\n";
1145     out << "if (((_aidl_ret_status) != (::android::OK))) {\n";
1146     out << "  return _aidl_ret_status;\n";
1147     out << "}\n";
1148     if (variable->IsNew() && ShouldForceDowngradeFor(CommunicationSide::READ)) {
1149       out.Dedent();
1150       out << "}\n";
1151     }
1152   }
1153   out << "_aidl_parcel->setDataPosition(_aidl_start_pos + _aidl_parcelable_size);\n";
1154   out << "return _aidl_ret_status;\n";
1155 }
1156 
GenerateWriteToParcel(CodeWriter & out,const AidlStructuredParcelable & parcel,const AidlTypenames & typenames)1157 void GenerateWriteToParcel(CodeWriter& out, const AidlStructuredParcelable& parcel,
1158                            const AidlTypenames& typenames) {
1159   out << "::android::status_t _aidl_ret_status = ::android::OK;\n";
1160   out << "size_t _aidl_start_pos = " << kParcelVarName << "->dataPosition();\n";
1161   out << kParcelVarName << "->writeInt32(0);\n";
1162   for (const auto& variable : parcel.GetFields()) {
1163     string method = ParcelWriteMethodOf(variable->GetType(), typenames);
1164     string arg = ParcelWriteCastOf(variable->GetType(), typenames, variable->GetName());
1165     if (variable->IsNew() && ShouldForceDowngradeFor(CommunicationSide::WRITE)) {
1166       out << "if (false) {\n";
1167       out.Indent();
1168     }
1169     out << "_aidl_ret_status = " << kParcelVarName << "->" << method << "(" << arg << ");\n";
1170     out << "if (((_aidl_ret_status) != (::android::OK))) {\n";
1171     out << "  return _aidl_ret_status;\n";
1172     out << "}\n";
1173     if (variable->IsNew() && ShouldForceDowngradeFor(CommunicationSide::WRITE)) {
1174       out.Dedent();
1175       out << "}\n";
1176     }
1177   }
1178   out << "size_t _aidl_end_pos = " << kParcelVarName << "->dataPosition();\n";
1179   out << kParcelVarName << "->setDataPosition(_aidl_start_pos);\n";
1180   out << kParcelVarName << "->writeInt32(static_cast<int32_t>(_aidl_end_pos - _aidl_start_pos));\n";
1181   out << kParcelVarName << "->setDataPosition(_aidl_end_pos);\n";
1182   out << "return _aidl_ret_status;\n";
1183 }
1184 
GetParcelWriterContext(const AidlTypenames & typenames)1185 ParcelWriterContext GetParcelWriterContext(const AidlTypenames& typenames) {
1186   return ParcelWriterContext{
1187       .status_type = kAndroidStatusLiteral,
1188       .status_ok = kAndroidStatusOk,
1189       .status_bad = kAndroidStatusBadValue,
1190       .read_func =
1191           [&](CodeWriter& out, const string& var, const AidlTypeSpecifier& type) {
1192             out << std::format("{}->{}({})", kParcelVarName, ParcelReadMethodOf(type, typenames),
1193                                ParcelReadCastOf(type, typenames, "&" + var));
1194           },
1195       .write_func =
1196           [&](CodeWriter& out, const string& value, const AidlTypeSpecifier& type) {
1197             out << std::format("{}->{}({})", kParcelVarName, ParcelWriteMethodOf(type, typenames),
1198                                ParcelWriteCastOf(type, typenames, value));
1199           },
1200   };
1201 }
1202 
GenerateReadFromParcel(CodeWriter & out,const AidlUnionDecl & decl,const AidlTypenames & typenames)1203 void GenerateReadFromParcel(CodeWriter& out, const AidlUnionDecl& decl,
1204                             const AidlTypenames& typenames) {
1205   UnionWriter uw{decl, typenames, &CppNameOf, &ConstantValueDecorator};
1206   uw.ReadFromParcel(out, GetParcelWriterContext(typenames));
1207 }
1208 
GenerateWriteToParcel(CodeWriter & out,const AidlUnionDecl & decl,const AidlTypenames & typenames)1209 void GenerateWriteToParcel(CodeWriter& out, const AidlUnionDecl& decl,
1210                            const AidlTypenames& typenames) {
1211   UnionWriter uw{decl, typenames, &CppNameOf, &ConstantValueDecorator};
1212   uw.WriteToParcel(out, GetParcelWriterContext(typenames));
1213 }
1214 
GenerateParcelFields(CodeWriter & out,const AidlStructuredParcelable & decl,const AidlTypenames & typenames)1215 void GenerateParcelFields(CodeWriter& out, const AidlStructuredParcelable& decl,
1216                           const AidlTypenames& typenames) {
1217   for (const auto& variable : decl.GetFields()) {
1218     const auto& type = variable->GetType();
1219     std::string cpp_type = CppNameOf(type, typenames);
1220     out << cpp_type;
1221     GenerateDeprecated(out, *variable);
1222     out << " " << variable->GetName();
1223     if (variable->GetDefaultValue()) {
1224       out << " = " << variable->ValueString(ConstantValueDecorator);
1225     } else {
1226       // Some types needs to be explicitly initialized even when no default value is set.
1227       // - ParcelableHolder should be initialized with stability
1228       // - enum should be zero initialized, otherwise the value will be indeterminate
1229       // - fixed-size arrays should be initialized, otherwise the value will be indeterminate
1230       if (type.GetName() == "ParcelableHolder") {
1231         if (decl.IsVintfStability()) {
1232           out << " { ::android::Parcelable::Stability::STABILITY_VINTF }";
1233         } else {
1234           out << " { ::android::Parcelable::Stability::STABILITY_LOCAL }";
1235         }
1236       } else if (typenames.GetEnumDeclaration(type) && !type.IsArray()) {
1237         out << " = " << cpp_type << "(0)";
1238       } else if (type.IsFixedSizeArray() && !type.IsNullable()) {
1239         out << " = {{}}";
1240       }
1241     }
1242     out << ";\n";
1243   }
1244 }
1245 
GenerateParcelFields(CodeWriter & out,const AidlUnionDecl & decl,const AidlTypenames & typenames)1246 void GenerateParcelFields(CodeWriter& out, const AidlUnionDecl& decl,
1247                           const AidlTypenames& typenames) {
1248   UnionWriter uw{decl, typenames, &CppNameOf, &ConstantValueDecorator};
1249   uw.PublicFields(out);
1250 }
1251 
1252 template <typename ParcelableType>
GenerateParcelClassDecl(CodeWriter & out,const ParcelableType & parcel,const AidlTypenames & typenames,const Options & options)1253 void GenerateParcelClassDecl(CodeWriter& out, const ParcelableType& parcel,
1254                              const AidlTypenames& typenames, const Options& options) {
1255   const string clazz = parcel.GetName();
1256 
1257   ClangDiagnosticIgnoreDeprecated guard(out, HasDeprecatedField(parcel));
1258   out << TemplateDecl(parcel);
1259   out << "class LIBBINDER_EXPORTED";
1260   GenerateDeprecated(out, parcel);
1261   out << " " << clazz << " : public ::android::Parcelable {\n";
1262   out << "public:\n";
1263   out.Indent();
1264 
1265   GenerateNestedTypeDecls(out, parcel, typenames, options);
1266   GenerateParcelFields(out, parcel, typenames);
1267   GenerateParcelableComparisonOperators(out, parcel);
1268   GenerateConstantDeclarations(out, parcel, typenames);
1269 
1270   if (parcel.IsVintfStability()) {
1271     out << "::android::Parcelable::Stability getStability() const override { return "
1272            "::android::Parcelable::Stability::STABILITY_VINTF; }\n";
1273   }
1274 
1275   out << kAndroidStatusLiteral << " readFromParcel(const ::android::Parcel* _aidl_parcel) final;\n";
1276   out << kAndroidStatusLiteral << " writeToParcel(::android::Parcel* _aidl_parcel) const final;\n";
1277 
1278   const string canonical_name = parcel.GetCanonicalName();
1279   out << "static const ::android::String16& getParcelableDescriptor() {\n"
1280       << "  static const ::android::StaticString16 DESCRIPTOR (u\"" << canonical_name << "\");\n"
1281       << "  return DESCRIPTOR;\n"
1282       << "}\n";
1283 
1284   GenerateToString(out, parcel);
1285 
1286   out.Dedent();
1287 
1288   if (auto decl = AidlCast<AidlUnionDecl>(parcel); decl) {
1289     out << "private:\n";
1290     out.Indent();
1291     UnionWriter uw{*decl, typenames, &CppNameOf, &ConstantValueDecorator};
1292     uw.PrivateFields(out);
1293     out.Dedent();
1294   }
1295 
1296   out << "};  // class " << clazz << "\n";
1297 }
1298 
1299 template <typename T>
GenerateParcelSource(CodeWriter & out,const T & parcel,const AidlTypenames & typenames,const Options &)1300 void GenerateParcelSource(CodeWriter& out, const T& parcel, const AidlTypenames& typenames,
1301                           const Options&) {
1302   string q_name = GetQualifiedName(parcel);
1303   if (parcel.IsGeneric()) {
1304     q_name += "<" + Join(parcel.GetTypeParameters(), ",") + ">";
1305   }
1306 
1307   out << "#include <" << CppHeaderForType(parcel) << ">\n\n";
1308 
1309   EnterNamespace(out, parcel);
1310   GenerateConstantDefinitions(out, parcel, typenames, TemplateDecl(parcel), q_name);
1311 
1312   {
1313     ClangDiagnosticIgnoreDeprecated guard(out, HasDeprecatedField(parcel));
1314     out << TemplateDecl(parcel);
1315     out << "::android::status_t " << q_name << "::readFromParcel(const ::android::Parcel* "
1316         << kParcelVarName << ") {\n";
1317     out.Indent();
1318     GenerateReadFromParcel(out, parcel, typenames);
1319     out.Dedent();
1320     out << "}\n";
1321 
1322     out << TemplateDecl(parcel);
1323     out << "::android::status_t " << q_name << "::writeToParcel(::android::Parcel* "
1324         << kParcelVarName << ") const {\n";
1325     out.Indent();
1326     GenerateWriteToParcel(out, parcel, typenames);
1327     out.Dedent();
1328     out << "}\n";
1329   }
1330   LeaveNamespace(out, parcel);
1331 }
1332 
GenerateEnumClassDecl(CodeWriter & out,const AidlEnumDeclaration & enum_decl,const AidlTypenames & typenames)1333 void GenerateEnumClassDecl(CodeWriter& out, const AidlEnumDeclaration& enum_decl,
1334                            const AidlTypenames& typenames) {
1335   cpp::GenerateEnumClassDecl(out, enum_decl, CppNameOf(enum_decl.GetBackingType(), typenames),
1336                              ConstantValueDecorator);
1337 }
1338 
GenerateClassDecl(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1339 void GenerateClassDecl(CodeWriter& out, const AidlDefinedType& defined_type,
1340                        const AidlTypenames& typenames, const Options& options) {
1341   if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
1342     GenerateInterfaceClassDecl(out, *iface, typenames, options);
1343   } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
1344     GenerateParcelClassDecl(out, *parcelable, typenames, options);
1345   } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
1346     GenerateParcelClassDecl(out, *union_decl, typenames, options);
1347   } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
1348     GenerateEnumClassDecl(out, *enum_decl, typenames);
1349   } else {
1350     AIDL_FATAL(defined_type) << "Unrecognized type sent for CPP generation.";
1351   }
1352 }
1353 
1354 }  // namespace internals
1355 
1356 using namespace internals;
1357 
1358 // 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)1359 void GenerateHeaderIncludes(CodeWriter& out, const AidlDefinedType& defined_type,
1360                             const AidlTypenames& typenames, const Options& options) {
1361   struct Visitor : AidlVisitor {
1362     const AidlTypenames& typenames;
1363     const Options& options;
1364     std::set<std::string> includes;
1365     Visitor(const AidlTypenames& typenames, const Options& options)
1366         : typenames(typenames), options(options) {}
1367 
1368     // Collect includes for each type reference including built-in type
1369     void Visit(const AidlTypeSpecifier& type) override {
1370       cpp::AddHeaders(type, typenames, &includes);
1371     }
1372 
1373     // Collect implementation-specific includes for each type definition
1374     void Visit(const AidlInterface& iface) override {
1375       includes.insert(kIBinderHeader);        // IBinder
1376       includes.insert(kIInterfaceHeader);     // IInterface
1377       includes.insert(kStatusHeader);         // Status
1378       includes.insert(kStrongPointerHeader);  // sp<>
1379 
1380       if (options.GenTraces()) {
1381         includes.insert(kTraceHeader);
1382       }
1383 
1384       // For a nested interface, client/server classes are declared the same header as well.
1385       if (iface.GetParentType()) {
1386         includes.insert(kBinderDelegateHeader);  // Delegate.h
1387         // client/server class provides logFunc when gen_log is on
1388         if (options.GenLog()) {
1389           includes.insert("functional");                  // std::function for logFunc
1390           includes.insert("android/binder_to_string.h");  // Generic ToString helper
1391         }
1392       }
1393     }
1394 
1395     void Visit(const AidlStructuredParcelable&) override {
1396       AddParcelableCommonHeaders();
1397       includes.insert("tuple");  // std::tie in comparison operators
1398     }
1399 
1400     void Visit(const AidlUnionDecl& union_decl) override {
1401       AddParcelableCommonHeaders();
1402       auto union_headers = cpp::UnionWriter::GetHeaders(union_decl);
1403       includes.insert(std::begin(union_headers), std::end(union_headers));
1404     }
1405 
1406     void Visit(const AidlEnumDeclaration&) override {
1407       includes.insert("array");           // used in enum_values
1408       includes.insert("binder/Enums.h");  // provides enum_range
1409       includes.insert("string");          // toString() returns std::string
1410     }
1411 
1412     void AddParcelableCommonHeaders() {
1413       includes.insert(kParcelHeader);                 // Parcel in readFromParcel/writeToParcel
1414       includes.insert(kStatusHeader);                 // Status
1415       includes.insert(kString16Header);               // String16 in getParcelableDescriptor
1416       includes.insert("android/binder_to_string.h");  // toString()
1417     }
1418   } v(typenames, options);
1419   VisitTopDown(v, defined_type);
1420 
1421   for (const auto& path : v.includes) {
1422     out << "#include <" << path << ">\n";
1423   }
1424   out << "\n";
1425   if (v.includes.count("cassert")) {
1426     // TODO(b/31559095) bionic on host should define __assert2
1427     out << "#ifndef __BIONIC__\n#define __assert2(a,b,c,d) ((void)0)\n#endif\n\n";
1428   }
1429 }
1430 
1431 // Generic parcelables and enum utilities should be defined in header.
GenerateHeaderDefinitions(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1432 void GenerateHeaderDefinitions(CodeWriter& out, const AidlDefinedType& defined_type,
1433                                const AidlTypenames& typenames, const Options& options) {
1434   struct Visitor : AidlVisitor {
1435     CodeWriter& out;
1436     const AidlTypenames& typenames;
1437     const Options& options;
1438     Visitor(CodeWriter& out, const AidlTypenames& typenames, const Options& options)
1439         : out(out), typenames(typenames), options(options) {}
1440 
1441     void Visit(const AidlEnumDeclaration& enum_decl) override {
1442       const auto backing_type = CppNameOf(enum_decl.GetBackingType(), typenames);
1443       EnterNamespace(out, enum_decl);
1444       out << GenerateEnumToString(enum_decl, backing_type);
1445       LeaveNamespace(out, enum_decl);
1446 
1447       out << "namespace android {\n";
1448       out << "namespace internal {\n";
1449       out << GenerateEnumValues(enum_decl, {""});
1450       out << "}  // namespace internal\n";
1451       out << "}  // namespace android\n";
1452     }
1453 
1454     void Visit(const AidlStructuredParcelable& parcelable) override {
1455       if (parcelable.IsGeneric()) {
1456         GenerateParcelSource(out, parcelable, typenames, options);
1457       }
1458     }
1459 
1460     void Visit(const AidlUnionDecl& union_decl) override {
1461       if (union_decl.IsGeneric()) {
1462         GenerateParcelSource(out, union_decl, typenames, options);
1463       }
1464     }
1465 
1466   } v(out, typenames, options);
1467   VisitTopDown(v, defined_type);
1468 }
1469 
GenerateHeader(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1470 void GenerateHeader(CodeWriter& out, const AidlDefinedType& defined_type,
1471                     const AidlTypenames& typenames, const Options& options) {
1472   if (auto parcelable = AidlCast<AidlParcelable>(defined_type); parcelable) {
1473     out << "#error TODO(b/111362593) parcelables do not have headers";
1474     return;
1475   }
1476   out << "#pragma once\n\n";
1477   GenerateHeaderIncludes(out, defined_type, typenames, options);
1478   GenerateForwardDecls(out, defined_type, false);
1479   EnterNamespace(out, defined_type);
1480   // Each class decl contains its own nested types' class decls
1481   GenerateClassDecl(out, defined_type, typenames, options);
1482   LeaveNamespace(out, defined_type);
1483   GenerateHeaderDefinitions(out, defined_type, typenames, options);
1484 }
1485 
GenerateClientHeader(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1486 void GenerateClientHeader(CodeWriter& out, const AidlDefinedType& defined_type,
1487                           const AidlTypenames& typenames, const Options& options) {
1488   if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
1489     GenerateClientHeader(out, *iface, typenames, options);
1490   } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
1491     out << "#error TODO(b/111362593) parcelables do not have bp classes";
1492   } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
1493     out << "#error TODO(b/111362593) parcelables do not have bp classes";
1494   } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
1495     out << "#error TODO(b/111362593) enums do not have bp classes";
1496   } else if (auto parcelable = AidlCast<AidlParcelable>(defined_type); parcelable) {
1497     out << "#error TODO(b/111362593) parcelables do not have bp classes";
1498   } else {
1499     AIDL_FATAL(defined_type) << "Unrecognized type sent for CPP generation.";
1500   }
1501 }
1502 
GenerateServerHeader(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1503 void GenerateServerHeader(CodeWriter& out, const AidlDefinedType& defined_type,
1504                           const AidlTypenames& typenames, const Options& options) {
1505   if (auto iface = AidlCast<AidlInterface>(defined_type); iface) {
1506     GenerateServerHeader(out, *iface, typenames, options);
1507   } else if (auto parcelable = AidlCast<AidlStructuredParcelable>(defined_type); parcelable) {
1508     out << "#error TODO(b/111362593) parcelables do not have bn classes";
1509   } else if (auto union_decl = AidlCast<AidlUnionDecl>(defined_type); union_decl) {
1510     out << "#error TODO(b/111362593) parcelables do not have bn classes";
1511   } else if (auto enum_decl = AidlCast<AidlEnumDeclaration>(defined_type); enum_decl) {
1512     out << "#error TODO(b/111362593) enums do not have bn classes";
1513   } else if (auto parcelable = AidlCast<AidlParcelable>(defined_type); parcelable) {
1514     out << "#error TODO(b/111362593) parcelables do not have bn classes";
1515   } else {
1516     AIDL_FATAL(defined_type) << "Unrecognized type sent for CPP generation.";
1517   }
1518 }
1519 
GenerateSource(CodeWriter & out,const AidlDefinedType & defined_type,const AidlTypenames & typenames,const Options & options)1520 void GenerateSource(CodeWriter& out, const AidlDefinedType& defined_type,
1521                     const AidlTypenames& typenames, const Options& options) {
1522   struct Visitor : AidlVisitor {
1523     CodeWriter& out;
1524     const AidlTypenames& typenames;
1525     const Options& options;
1526     Visitor(CodeWriter& out, const AidlTypenames& typenames, const Options& options)
1527         : out(out), typenames(typenames), options(options) {}
1528 
1529     void Visit(const AidlInterface& interface) override {
1530       GenerateInterfaceSource(out, interface, typenames, options);
1531       GenerateClientSource(out, interface, typenames, options);
1532       GenerateServerSource(out, interface, typenames, options);
1533     }
1534 
1535     void Visit(const AidlStructuredParcelable& parcelable) override {
1536       if (!parcelable.IsGeneric()) {
1537         GenerateParcelSource(out, parcelable, typenames, options);
1538       } else {
1539         out << "\n";
1540       }
1541     }
1542 
1543     void Visit(const AidlUnionDecl& union_decl) override {
1544       if (!union_decl.IsGeneric()) {
1545         GenerateParcelSource(out, union_decl, typenames, options);
1546       } else {
1547         out << "\n";
1548       }
1549     }
1550 
1551     void Visit(const AidlEnumDeclaration& enum_decl) override {
1552       if (!enum_decl.GetParentType()) {
1553         out << "// This file is intentionally left blank as placeholder for enum declaration.\n";
1554       }
1555     }
1556 
1557     void Visit(const AidlParcelable& parcelable) override {
1558       AIDL_FATAL_IF(parcelable.GetParentType(), parcelable)
1559           << "Unstructured parcelable can't be nested.";
1560       out << "// This file is intentionally left blank as placeholder for parcel declaration.\n";
1561     }
1562   } v(out, typenames, options);
1563   VisitTopDown(v, defined_type);
1564 }
1565 
GenerateCpp(const string & output_file,const Options & options,const AidlTypenames & typenames,const AidlDefinedType & defined_type,const IoDelegate & io_delegate)1566 bool GenerateCpp(const string& output_file, const Options& options, const AidlTypenames& typenames,
1567                  const AidlDefinedType& defined_type, const IoDelegate& io_delegate) {
1568   if (!ValidateOutputFilePath(output_file, options, defined_type)) {
1569     return false;
1570   }
1571 
1572   using GenFn = void (*)(CodeWriter& out, const AidlDefinedType& defined_type,
1573                          const AidlTypenames& typenames, const Options& options);
1574   // Wrap Generate* function to handle CodeWriter for a file.
1575   auto gen = [&](auto file, GenFn fn) {
1576     unique_ptr<CodeWriter> writer(io_delegate.GetCodeWriter(file));
1577 
1578     GenerateAutoGenHeader(*writer, options);
1579 
1580     fn(*writer, defined_type, typenames, options);
1581     AIDL_FATAL_IF(!writer->Close(), defined_type) << "I/O Error!";
1582     return true;
1583   };
1584 
1585   return gen(options.OutputHeaderDir() + HeaderFile(defined_type, ClassNames::RAW),
1586              &GenerateHeader) &&
1587          gen(options.OutputHeaderDir() + HeaderFile(defined_type, ClassNames::CLIENT),
1588              &GenerateClientHeader) &&
1589          gen(options.OutputHeaderDir() + HeaderFile(defined_type, ClassNames::SERVER),
1590              &GenerateServerHeader) &&
1591          gen(output_file, &GenerateSource);
1592 }
1593 
1594 }  // namespace cpp
1595 }  // namespace aidl
1596 }  // namespace android
1597