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 "type_cpp.h"
18 
19 #include <algorithm>
20 #include <iostream>
21 #include <vector>
22 
23 #include <android-base/stringprintf.h>
24 #include <android-base/strings.h>
25 
26 #include "logging.h"
27 
28 using std::cerr;
29 using std::endl;
30 using std::set;
31 using std::string;
32 using std::unique_ptr;
33 using std::vector;
34 
35 using android::base::Split;
36 using android::base::Join;
37 using android::base::StringPrintf;
38 
39 namespace android {
40 namespace aidl {
41 namespace cpp {
42 namespace {
43 
44 const char kNoPackage[] = "";
45 const char kNoHeader[] = "";
46 const char kNoValidMethod[] = "";
47 Type* const kNoArrayType = nullptr;
48 Type* const kNoNullableType = nullptr;
49 
is_cpp_keyword(const std::string & str)50 bool is_cpp_keyword(const std::string& str) {
51   static const std::vector<std::string> kCppKeywords{
52     "alignas", "alignof", "and", "and_eq", "asm", "auto", "bitand", "bitor",
53     "bool", "break", "case", "catch", "char", "char16_t", "char32_t", "class",
54     "compl", "concept", "const", "constexpr", "const_cast", "continue",
55     "decltype", "default", "delete", "do", "double", "dynamic_cast", "else",
56     "enum", "explicit", "export", "extern", "false", "float", "for", "friend",
57     "goto", "if", "inline", "int", "long", "mutable", "namespace", "new",
58     "noexcept", "not", "not_eq", "nullptr", "operator", "or", "or_eq",
59     "private", "protected", "public", "register", "reinterpret_cast",
60     "requires", "return", "short", "signed", "sizeof", "static",
61     "static_assert", "static_cast", "struct", "switch", "template", "this",
62     "thread_local", "throw", "true", "try", "typedef", "typeid", "typename",
63     "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t",
64     "while", "xor", "xor_eq",
65   };
66   return std::find(kCppKeywords.begin(), kCppKeywords.end(), str) !=
67       kCppKeywords.end();
68 }
69 
70 class VoidType : public Type {
71  public:
VoidType()72   VoidType() : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, "void",
73                     {}, "void", kNoValidMethod, kNoValidMethod) {}
74   virtual ~VoidType() = default;
CanBeOutParameter() const75   bool CanBeOutParameter() const override { return false; }
CanWriteToParcel() const76   bool CanWriteToParcel() const override { return false; }
77 };  // class VoidType
78 
79 class CppArrayType : public Type {
80  public:
CppArrayType(int kind,const std::string & package,const string & underlying_aidl_type,const string & cpp_header,const string & underlying_cpp_type,const string & read_method,const string & write_method,bool is_nullable,const string & src_file_name="")81   CppArrayType(int kind,  // from ValidatableType
82             const std::string& package,
83             const string& underlying_aidl_type,
84             const string& cpp_header,
85             const string& underlying_cpp_type,
86             const string& read_method,
87             const string& write_method,
88             bool is_nullable,
89             const string& src_file_name = "")
90       : Type(kind, package,
91              underlying_aidl_type + "[]",
92              GetHeaders(is_nullable, cpp_header),
93              GetCppType(is_nullable, underlying_cpp_type),
94              read_method, write_method, kNoArrayType,
95              (is_nullable)
96                  ? kNoNullableType
97                  // All arrays are nullable.
98                  : new CppArrayType(kind, package, underlying_aidl_type,
99                                     cpp_header, underlying_cpp_type,
100                                     read_method, write_method, true),
101              src_file_name) {}
102 
CanBeOutParameter() const103   bool CanBeOutParameter() const override { return true; }
104 
105  private:
GetHeaders(bool is_nullable,const string & cpp_header)106   static vector<string> GetHeaders(bool is_nullable, const string& cpp_header) {
107     vector<string> result = {"vector"};
108     if (is_nullable) {
109       result.push_back("memory");
110     }
111     if (!cpp_header.empty()) {
112       result.push_back(cpp_header);
113     }
114     return result;
115   }
116 
GetCppType(bool is_nullable,const string & underlying_cpp_type)117   static string GetCppType(bool is_nullable,
118                            const string& underlying_cpp_type) {
119     if (is_nullable)
120       return StringPrintf("::std::unique_ptr<::std::vector<%s>>",
121                           underlying_cpp_type.c_str());
122     return StringPrintf("::std::vector<%s>",
123                         underlying_cpp_type.c_str());
124   }
125 
126   DISALLOW_COPY_AND_ASSIGN(CppArrayType);
127 };  // class CppArrayType
128 
129 class PrimitiveType : public Type {
130  public:
PrimitiveType(const std::string & aidl_type,const std::string & header,const std::string & cpp_type,const std::string & read_method,const std::string & write_method,const std::string & read_array_method,const std::string & write_array_method)131   PrimitiveType(const std::string& aidl_type,
132                 const std::string& header,
133                 const std::string& cpp_type,
134                 const std::string& read_method,
135                 const std::string& write_method,
136                 const std::string& read_array_method,
137                 const std::string& write_array_method)
138       : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, aidl_type, {header},
139              cpp_type, read_method, write_method,
140              new CppArrayType(ValidatableType::KIND_BUILT_IN, kNoPackage,
141                               aidl_type, header, cpp_type,
142                               read_array_method, write_array_method,
143                               false)) {}
144 
145   virtual ~PrimitiveType() = default;
IsCppPrimitive() const146   bool IsCppPrimitive() const override { return true; }
147 
148  private:
149   DISALLOW_COPY_AND_ASSIGN(PrimitiveType);
150 };  // class PrimitiveType
151 
152 // Unfortunately, bytes in Java are signed.  However, most C authors would
153 // say that a byte is not in fact signed.  Compromise: customize this otherwise
154 // normal primitive to use signed single bytes, but unsigned byte arrays.
155 class ByteType : public Type {
156  public:
ByteType()157   ByteType()
158       : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, "byte",
159              {"cstdint"}, "int8_t", "readByte", "writeByte",
160              new CppArrayType(ValidatableType::KIND_BUILT_IN, kNoPackage,
161                               "byte", "cstdint", "uint8_t",
162                               "readByteVector", "writeByteVector",
163                               false)) {}
164 
165   virtual ~ByteType() = default;
IsCppPrimitive() const166   bool IsCppPrimitive() const override { return true; }
167 
168  private:
169   DISALLOW_COPY_AND_ASSIGN(ByteType);
170 };  // class PrimitiveType
171 
172 class BinderType : public Type {
173  public:
BinderType(const AidlInterface & interface,const std::string & src_file_name)174   BinderType(const AidlInterface& interface, const std::string& src_file_name)
175       : BinderType(interface, src_file_name,
176                    new BinderType(interface, src_file_name, kNoNullableType,
177                                   "readNullableStrongBinder"),
178                    "readStrongBinder") {}
179   virtual ~BinderType() = default;
180 
WriteCast(const string & val) const181   string WriteCast(const string& val) const override {
182     return write_cast_ + "(" + val + ")";
183   }
184 
185  private:
BinderType(const AidlInterface & interface,const std::string & src_file_name,Type * nullable_type,const std::string & read)186   BinderType(const AidlInterface& interface,
187              const std::string& src_file_name,
188              Type* nullable_type, const std::string& read)
189       : Type(ValidatableType::KIND_GENERATED,
190              interface.GetPackage(), interface.GetName(),
191              {GetCppHeader(interface)}, GetCppName(interface),
192              read, "writeStrongBinder", kNoArrayType, nullable_type,
193              src_file_name, interface.GetLine()),
194         write_cast_(GetRawCppName(interface) + "::asBinder") {}
195 
GetCppName(const AidlInterface & interface)196   static string GetCppName(const AidlInterface& interface) {
197     return "::android::sp<" + GetRawCppName(interface) + ">";
198   }
199 
GetRawCppName(const AidlInterface & interface)200   static string GetRawCppName(const AidlInterface& interface) {
201     vector<string> name = interface.GetSplitPackage();
202     string ret;
203 
204     name.push_back(interface.GetName());
205 
206     for (const auto& term : name) {
207       ret += "::" + term;
208     }
209 
210     return ret;
211   }
212 
GetCppHeader(const AidlInterface & interface)213   static string GetCppHeader(const AidlInterface& interface) {
214     vector<string> name = interface.GetSplitPackage();
215     name.push_back(interface.GetName());
216     return Join(name, '/') + ".h";
217   }
218 
219   std::string write_cast_;
220 };
221 
222 class NullableParcelableType : public Type {
223  public:
NullableParcelableType(const AidlParcelable & parcelable,const std::string & src_file_name)224   NullableParcelableType(const AidlParcelable& parcelable,
225                          const std::string& src_file_name)
226       : Type(ValidatableType::KIND_PARCELABLE,
227              parcelable.GetPackage(), parcelable.GetName(),
228              {parcelable.GetCppHeader()}, GetCppName(parcelable),
229              "readParcelable", "writeNullableParcelable",
230              kNoArrayType, kNoNullableType,
231              src_file_name, parcelable.GetLine()) {}
232   virtual ~NullableParcelableType() = default;
CanBeOutParameter() const233   bool CanBeOutParameter() const override { return true; }
234 
235  private:
GetCppName(const AidlParcelable & parcelable)236   static string GetCppName(const AidlParcelable& parcelable) {
237     return "::std::unique_ptr<::" + Join(parcelable.GetSplitPackage(), "::") +
238         "::" + parcelable.GetCppName() + ">";
239   }
240 };
241 
242 class ParcelableType : public Type {
243  public:
ParcelableType(const AidlParcelable & parcelable,const std::string & src_file_name)244   ParcelableType(const AidlParcelable& parcelable,
245                  const std::string& src_file_name)
246       : Type(ValidatableType::KIND_PARCELABLE,
247              parcelable.GetPackage(), parcelable.GetName(),
248              {parcelable.GetCppHeader()}, GetCppName(parcelable),
249              "readParcelable", "writeParcelable",
250              new CppArrayType(
251                  ValidatableType::KIND_PARCELABLE, parcelable.GetPackage(),
252                  parcelable.GetName(), parcelable.GetCppHeader(),
253                  GetCppName(parcelable),
254                  "readParcelableVector", "writeParcelableVector", false,
255                  src_file_name),
256              new NullableParcelableType(parcelable, src_file_name),
257              src_file_name, parcelable.GetLine()) {}
258   virtual ~ParcelableType() = default;
CanBeOutParameter() const259   bool CanBeOutParameter() const override { return true; }
260 
261  private:
GetCppName(const AidlParcelable & parcelable)262   static string GetCppName(const AidlParcelable& parcelable) {
263     return "::" + Join(parcelable.GetSplitPackage(), "::") +
264         "::" + parcelable.GetCppName();
265   }
266 };
267 
268 class NullableMap : public Type {
269  public:
NullableMap()270   NullableMap()
271       : Type(ValidatableType::KIND_BUILT_IN,
272              "java.util", "Map",
273              {"binder/Map.h", "binder/Value.h"},
274              "::std::unique_ptr<::android::binder::Map>",
275              "readNullableMap", "writeNullableMap") {}
276   virtual ~NullableMap() = default;
CanBeOutParameter() const277   bool CanBeOutParameter() const override { return true; }
278 };
279 
280 
281 class MapType : public Type {
282  public:
MapType()283   MapType()
284       : Type(ValidatableType::KIND_BUILT_IN,
285              "java.util", "Map",
286              {"binder/Map.h","binder/Value.h"},
287              "::android::binder::Map",
288              "readMap", "writeMap",
289              kNoArrayType,
290              new NullableMap() ) {}
291   virtual ~MapType() = default;
CanBeOutParameter() const292   bool CanBeOutParameter() const override { return true; }
293 
294  private:
295   DISALLOW_COPY_AND_ASSIGN(MapType);
296 };  // class MapType
297 
298 class NullableStringListType : public Type {
299  public:
NullableStringListType()300   NullableStringListType()
301       : Type(ValidatableType::KIND_BUILT_IN,
302              "java.util", "List<" + string(kStringCanonicalName) + ">",
303              {"utils/String16.h", "memory", "vector"},
304              "::std::unique_ptr<::std::vector<std::unique_ptr<::android::String16>>>",
305              "readString16Vector", "writeString16Vector") {}
306   virtual ~NullableStringListType() = default;
CanBeOutParameter() const307   bool CanBeOutParameter() const override { return true; }
308 
309  private:
310   DISALLOW_COPY_AND_ASSIGN(NullableStringListType);
311 };  // class NullableStringListType
312 
313 class StringListType : public Type {
314  public:
StringListType()315   StringListType()
316       : Type(ValidatableType::KIND_BUILT_IN,
317              "java.util", "List<" + string(kStringCanonicalName) + ">",
318              {"utils/String16.h", "vector"},
319              "::std::vector<::android::String16>",
320              "readString16Vector", "writeString16Vector",
321              kNoArrayType, new NullableStringListType()) {}
322   virtual ~StringListType() = default;
CanBeOutParameter() const323   bool CanBeOutParameter() const override { return true; }
324 
325  private:
326   DISALLOW_COPY_AND_ASSIGN(StringListType);
327 };  // class StringListType
328 
329 class NullableUtf8InCppStringListType : public Type {
330  public:
NullableUtf8InCppStringListType()331   NullableUtf8InCppStringListType()
332       : Type(ValidatableType::KIND_BUILT_IN,
333              "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
334              {"memory", "string", "vector"},
335              "::std::unique_ptr<::std::vector<std::unique_ptr<::std::string>>>",
336              "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector") {}
337   virtual ~NullableUtf8InCppStringListType() = default;
CanBeOutParameter() const338   bool CanBeOutParameter() const override { return true; }
339 
340  private:
341   DISALLOW_COPY_AND_ASSIGN(NullableUtf8InCppStringListType);
342 };  // class NullableUtf8InCppStringListType
343 
344 class Utf8InCppStringListType : public Type {
345  public:
Utf8InCppStringListType()346   Utf8InCppStringListType()
347       : Type(ValidatableType::KIND_BUILT_IN,
348              "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
349              {"string", "vector"},
350              "::std::vector<::std::string>",
351              "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
352              kNoArrayType, new NullableUtf8InCppStringListType()) {}
353   virtual ~Utf8InCppStringListType() = default;
CanBeOutParameter() const354   bool CanBeOutParameter() const override { return true; }
355 
356  private:
357   DISALLOW_COPY_AND_ASSIGN(Utf8InCppStringListType);
358 };  // class Utf8InCppStringListType
359 
360 class NullableBinderListType : public Type {
361  public:
NullableBinderListType()362   NullableBinderListType()
363       : Type(ValidatableType::KIND_BUILT_IN, "java.util",
364              "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
365              "::std::unique_ptr<::std::vector<::android::sp<::android::IBinder>>>",
366              "readStrongBinderVector", "writeStrongBinderVector") {}
367   virtual ~NullableBinderListType() = default;
CanBeOutParameter() const368   bool CanBeOutParameter() const override { return true; }
369 
370  private:
371   DISALLOW_COPY_AND_ASSIGN(NullableBinderListType);
372 };  // class NullableBinderListType
373 
374 class BinderListType : public Type {
375  public:
BinderListType()376   BinderListType()
377       : Type(ValidatableType::KIND_BUILT_IN, "java.util",
378              "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
379              "::std::vector<::android::sp<::android::IBinder>>",
380              "readStrongBinderVector", "writeStrongBinderVector",
381              kNoArrayType, new NullableBinderListType()) {}
382   virtual ~BinderListType() = default;
CanBeOutParameter() const383   bool CanBeOutParameter() const override { return true; }
384 
385  private:
386   DISALLOW_COPY_AND_ASSIGN(BinderListType);
387 };  // class BinderListType
388 
389 }  // namespace
390 
Type(int kind,const std::string & package,const std::string & aidl_type,const vector<string> & headers,const string & cpp_type,const string & read_method,const string & write_method,Type * array_type,Type * nullable_type,const string & src_file_name,int line)391 Type::Type(int kind,
392            const std::string& package,
393            const std::string& aidl_type,
394            const vector<string>& headers,
395            const string& cpp_type,
396            const string& read_method,
397            const string& write_method,
398            Type* array_type,
399            Type* nullable_type,
400            const string& src_file_name,
401            int line)
402     : ValidatableType(kind, package, aidl_type, src_file_name, line),
403       headers_(headers),
404       aidl_type_(aidl_type),
405       cpp_type_(cpp_type),
406       parcel_read_method_(read_method),
407       parcel_write_method_(write_method),
408       array_type_(array_type),
409       nullable_type_(nullable_type) {}
410 
CanWriteToParcel() const411 bool Type::CanWriteToParcel() const { return true; }
412 
Init()413 void TypeNamespace::Init() {
414   Add(new ByteType());
415   Add(new PrimitiveType(
416       "int",
417       "cstdint", "int32_t", "readInt32", "writeInt32",
418       "readInt32Vector", "writeInt32Vector"));
419   Add(new PrimitiveType(
420       "long",
421       "cstdint", "int64_t", "readInt64", "writeInt64",
422       "readInt64Vector", "writeInt64Vector"));
423   Add(new PrimitiveType(
424       "float",
425       kNoHeader, "float", "readFloat", "writeFloat",
426       "readFloatVector", "writeFloatVector"));
427   Add(new PrimitiveType(
428       "double",
429       kNoHeader, "double", "readDouble", "writeDouble",
430       "readDoubleVector", "writeDoubleVector"));
431   Add(new PrimitiveType(
432       "boolean",
433       kNoHeader, "bool", "readBool", "writeBool",
434       "readBoolVector", "writeBoolVector"));
435   // C++11 defines the char16_t type as a built in for Unicode characters.
436   Add(new PrimitiveType(
437       "char",
438       kNoHeader, "char16_t", "readChar", "writeChar",
439       "readCharVector", "writeCharVector"));
440 
441   Type* string_array_type = new CppArrayType(
442       ValidatableType::KIND_BUILT_IN, "java.lang", "String",
443       "utils/String16.h", "::android::String16",
444       "readString16Vector", "writeString16Vector", false);
445 
446   Type* nullable_string_type =
447       new Type(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
448                {"memory", "utils/String16.h"}, "::std::unique_ptr<::android::String16>",
449                "readString16", "writeString16");
450 
451   string_type_ = new Type(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
452                           {"utils/String16.h"}, "::android::String16",
453                           "readString16", "writeString16",
454                           string_array_type, nullable_string_type);
455   Add(string_type_);
456 
457   using ::android::aidl::kAidlReservedTypePackage;
458   using ::android::aidl::kUtf8InCppStringClass;
459 
460   // This type is a Utf16 string in the parcel, but deserializes to
461   // a std::string in Utf8 format when we use it in C++.
462   Type* cpp_utf8_string_array = new CppArrayType(
463       ValidatableType::KIND_BUILT_IN,
464       kAidlReservedTypePackage, kUtf8InCppStringClass,
465       "string", "::std::string",
466       "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
467       false);
468   Type* nullable_cpp_utf8_string_type = new Type(
469       ValidatableType::KIND_BUILT_IN,
470       kAidlReservedTypePackage, kUtf8InCppStringClass,
471       {"string", "memory"}, "::std::unique_ptr<::std::string>",
472       "readUtf8FromUtf16", "writeUtf8AsUtf16");
473   Add(new Type(
474       ValidatableType::KIND_BUILT_IN,
475       kAidlReservedTypePackage, kUtf8InCppStringClass,
476       {"string"}, "::std::string", "readUtf8FromUtf16", "writeUtf8AsUtf16",
477       cpp_utf8_string_array, nullable_cpp_utf8_string_type));
478 
479   Type* nullable_ibinder = new Type(
480       ValidatableType::KIND_BUILT_IN, "android.os", "IBinder",
481       {"binder/IBinder.h"}, "::android::sp<::android::IBinder>",
482       "readNullableStrongBinder", "writeStrongBinder");
483   ibinder_type_ = new Type(
484       ValidatableType::KIND_BUILT_IN, "android.os", "IBinder",
485       {"binder/IBinder.h"}, "::android::sp<::android::IBinder>",
486       "readStrongBinder", "writeStrongBinder",
487       kNoArrayType, nullable_ibinder);
488   Add(ibinder_type_);
489 
490   Add(new MapType());
491 
492   Add(new BinderListType());
493   Add(new StringListType());
494   Add(new Utf8InCppStringListType());
495 
496   Type* fd_vector_type = new CppArrayType(
497       ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
498       "android-base/unique_fd.h",
499       "::android::base::unique_fd",
500       "readUniqueFileDescriptorVector", "writeUniqueFileDescriptorVector",
501       false);
502 
503   Add(new Type(
504       ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
505       {"android-base/unique_fd.h"}, "::android::base::unique_fd",
506       "readUniqueFileDescriptor", "writeUniqueFileDescriptor",
507       fd_vector_type));
508 
509   void_type_ = new class VoidType();
510   Add(void_type_);
511 }
512 
AddParcelableType(const AidlParcelable & p,const string & filename)513 bool TypeNamespace::AddParcelableType(const AidlParcelable& p,
514                                       const string& filename) {
515   if (p.GetCppHeader().empty()) {
516     LOG(ERROR) << "Parcelable " << p.GetCanonicalName()
517                << " has no C++ header defined.";
518     return false;
519   }
520   Add(new ParcelableType(p, filename));
521   return true;
522 }
523 
AddBinderType(const AidlInterface & b,const string & file_name)524 bool TypeNamespace::AddBinderType(const AidlInterface& b,
525                                   const string& file_name) {
526   Add(new BinderType(b, file_name));
527   return true;
528 }
529 
AddListType(const std::string & type_name)530 bool TypeNamespace::AddListType(const std::string& type_name) {
531   const Type* contained_type = FindTypeByCanonicalName(type_name);
532   if (!contained_type) {
533     LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
534                   "type cannot be found or is invalid.";
535     return false;
536   }
537   if (contained_type->IsCppPrimitive()) {
538     LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
539                   "type is a primitive in Java and Java List cannot hold "
540                   "primitives.";
541     return false;
542   }
543 
544   if (contained_type->CanonicalName() == kStringCanonicalName ||
545       contained_type->CanonicalName() == kUtf8InCppStringCanonicalName ||
546       contained_type == IBinderType()) {
547     return true;
548   }
549 
550   // TODO Support lists of parcelables b/23600712
551 
552   LOG(ERROR) << "aidl-cpp does not yet support List<" << type_name << ">";
553   return false;
554 }
555 
AddMapType(const std::string &,const std::string &)556 bool TypeNamespace::AddMapType(const std::string& /* key_type_name */,
557                                const std::string& /* value_type_name */) {
558   // TODO Support list types b/25242025
559   LOG(ERROR) << "aidl does not implement support for typed maps!";
560   return false;
561 }
562 
IsValidPackage(const string & package) const563 bool TypeNamespace::IsValidPackage(const string& package) const {
564   if (package.empty()) {
565     return false;
566   }
567 
568   auto pieces = Split(package, ".");
569   for (const string& piece : pieces) {
570     if (is_cpp_keyword(piece)) {
571       return false;
572     }
573   }
574 
575   return true;
576 }
577 
GetArgType(const AidlArgument & a,int arg_index,const std::string & filename,const AidlInterface & interface) const578 const ValidatableType* TypeNamespace::GetArgType(const AidlArgument& a,
579     int arg_index,
580     const std::string& filename,
581     const AidlInterface& interface) const {
582   const string error_prefix = StringPrintf(
583       "In file %s line %d parameter %s (%d):\n    ",
584       filename.c_str(), a.GetLine(), a.GetName().c_str(), arg_index);
585 
586   // check that the name doesn't match a keyword
587   if (is_cpp_keyword(a.GetName().c_str())) {
588     cerr << error_prefix << "Argument name is a C++ keyword"
589          << endl;
590     return nullptr;
591   }
592 
593   return ::android::aidl::TypeNamespace::GetArgType(a, arg_index, filename,
594                                                     interface);
595 }
596 
597 }  // namespace cpp
598 }  // namespace aidl
599 }  // namespace android
600