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 PrimitiveType : public Type {
80  public:
PrimitiveType(int kind,const std::string & package,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)81   PrimitiveType(int kind,  // from ValidatableType
82                 const std::string& package,
83                 const std::string& aidl_type,
84                 const std::string& header,
85                 const std::string& cpp_type,
86                 const std::string& read_method,
87                 const std::string& write_method,
88                 const std::string& read_array_method,
89                 const std::string& write_array_method)
90       : Type(kind, package, aidl_type, {header}, cpp_type, read_method,
91              write_method, PrimitiveArrayType(kind, package, aidl_type,
92                                               header, cpp_type,
93                                               read_array_method,
94                                               write_array_method)) {}
95 
96   virtual ~PrimitiveType() = default;
IsCppPrimitive() const97   bool IsCppPrimitive() const override { return true; }
CanBeOutParameter() const98   bool CanBeOutParameter() const override { return is_array_; }
99 
100  protected:
PrimitiveArrayType(int kind,const std::string & package,const std::string & aidl_type,const std::string & header,const std::string & cpp_type,const std::string & read_method,const std::string & write_method)101   static PrimitiveType* PrimitiveArrayType(int kind,  // from ValidatableType
102                                            const std::string& package,
103                                            const std::string& aidl_type,
104                                            const std::string& header,
105                                            const std::string& cpp_type,
106                                            const std::string& read_method,
107                                            const std::string& write_method) {
108     PrimitiveType* nullable =
109         new PrimitiveType(kind, package, aidl_type + "[]", header,
110                           "::std::unique_ptr<::std::vector<" + cpp_type + ">>",
111                           read_method, write_method);
112 
113     return new PrimitiveType(kind, package, aidl_type + "[]", header,
114                              "::std::vector<" + cpp_type + ">",
115                              read_method, write_method, nullable);
116   }
117 
PrimitiveType(int kind,const std::string & package,const std::string & aidl_type,const std::string & header,const std::string & cpp_type,const std::string & read_method,const std::string & write_method,Type * nullable_type=nullptr)118   PrimitiveType(int kind,  // from ValidatableType
119                 const std::string& package,
120                 const std::string& aidl_type,
121                 const std::string& header,
122                 const std::string& cpp_type,
123                 const std::string& read_method,
124                 const std::string& write_method,
125                 Type* nullable_type = nullptr)
126       : Type(kind, package, aidl_type, {header, "vector"}, cpp_type, read_method,
127              write_method, kNoArrayType, nullable_type) {
128     is_array_ = true;
129   }
130 
131  private:
132   bool is_array_ = false;
133 
134   DISALLOW_COPY_AND_ASSIGN(PrimitiveType);
135 };  // class PrimitiveType
136 
137 class ByteType : public Type {
138  public:
ByteType()139   ByteType() : ByteType(false, "byte", "int8_t", "readByte", "writeByte",
140      new ByteType(true, "byte[]", "::std::vector<uint8_t>", "readByteVector",
141          "writeByteVector", kNoArrayType,
142          new ByteType(true, "byte[]",
143              "::std::unique_ptr<::std::vector<uint8_t>>",
144              "readByteVector", "writeByteVector", kNoArrayType,
145              kNoNullableType)), kNoNullableType) {}
146 
147   virtual ~ByteType() = default;
IsCppPrimitive() const148   bool IsCppPrimitive() const override { return true; }
CanBeOutParameter() const149   bool CanBeOutParameter() const override { return is_array_; }
150 
151  protected:
ByteType(bool is_array,const std::string & name,const std::string & cpp_type,const std::string & read_method,const std::string & write_method,Type * array_type,Type * nullable_type)152   ByteType(bool is_array,
153            const std::string& name,
154            const std::string& cpp_type,
155            const std::string& read_method,
156            const std::string& write_method,
157            Type* array_type,
158            Type* nullable_type)
159       : Type(ValidatableType::KIND_BUILT_IN, kNoPackage, name, {"cstdint"},
160              cpp_type, read_method, write_method, array_type, nullable_type),
161         is_array_(is_array) {}
162 
163  private:
164   bool is_array_ = false;
165 
166   DISALLOW_COPY_AND_ASSIGN(ByteType);
167 };  // class PrimitiveType
168 
169 class BinderType : public Type {
170  public:
BinderType(const AidlInterface & interface,const std::string & src_file_name)171   BinderType(const AidlInterface& interface, const std::string& src_file_name)
172       : Type(ValidatableType::KIND_GENERATED,
173              interface.GetPackage(), interface.GetName(),
174              {GetCppHeader(interface)}, GetCppName(interface),
175              "readStrongBinder", "writeStrongBinder",
176              kNoArrayType, kNoNullableType, src_file_name,
177              interface.GetLine()),
178         write_cast_(GetRawCppName(interface) + "::asBinder") {}
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:
GetCppName(const AidlInterface & interface)186   static string GetCppName(const AidlInterface& interface) {
187     return "::android::sp<" + GetRawCppName(interface) + ">";
188   }
189 
GetRawCppName(const AidlInterface & interface)190   static string GetRawCppName(const AidlInterface& interface) {
191     vector<string> name = interface.GetSplitPackage();
192     string ret;
193 
194     name.push_back(interface.GetName());
195 
196     for (const auto& term : name) {
197       ret += "::" + term;
198     }
199 
200     return ret;
201   }
202 
GetCppHeader(const AidlInterface & interface)203   static string GetCppHeader(const AidlInterface& interface) {
204     vector<string> name = interface.GetSplitPackage();
205     name.push_back(interface.GetName());
206     return Join(name, '/') + ".h";
207   }
208 
209   std::string write_cast_;
210 };
211 
212 class NullableParcelableArrayType : public ArrayType {
213  public:
NullableParcelableArrayType(const AidlParcelable & parcelable,const std::string & src_file_name)214   NullableParcelableArrayType(const AidlParcelable& parcelable,
215                               const std::string& src_file_name)
216       : ArrayType(ValidatableType::KIND_PARCELABLE,
217                   parcelable.GetPackage(), parcelable.GetName(),
218                   {parcelable.GetCppHeader(), "vector"},
219                   GetCppName(parcelable), "readParcelableVector",
220                   "writeParcelableVector", kNoArrayType, kNoNullableType,
221                   src_file_name, parcelable.GetLine()) {}
222   virtual ~NullableParcelableArrayType() = default;
223 
224  private:
GetCppName(const AidlParcelable & parcelable)225   static string GetCppName(const AidlParcelable& parcelable) {
226     return "::std::unique_ptr<::std::vector<std::unique_ptr<" +
227         Join(parcelable.GetSplitPackage(), "::") + "::" +
228         parcelable.GetName() + ">>>";
229   }
230 };
231 
232 class ParcelableArrayType : public ArrayType {
233  public:
ParcelableArrayType(const AidlParcelable & parcelable,const std::string & src_file_name)234   ParcelableArrayType(const AidlParcelable& parcelable,
235                       const std::string& src_file_name)
236       : ArrayType(ValidatableType::KIND_PARCELABLE,
237                   parcelable.GetPackage(), parcelable.GetName(),
238                   {parcelable.GetCppHeader(), "vector"},
239                   GetCppName(parcelable), "readParcelableVector",
240                   "writeParcelableVector", kNoArrayType,
241                   new NullableParcelableArrayType(parcelable, src_file_name),
242                   src_file_name, parcelable.GetLine()) {}
243   virtual ~ParcelableArrayType() = default;
244 
245  private:
GetCppName(const AidlParcelable & parcelable)246   static string GetCppName(const AidlParcelable& parcelable) {
247     return "::std::vector<" + Join(parcelable.GetSplitPackage(), "::") +
248         "::" + parcelable.GetName() + ">";
249   }
250 };
251 
252 class NullableParcelableType : public Type {
253  public:
NullableParcelableType(const AidlParcelable & parcelable,const std::string & src_file_name)254   NullableParcelableType(const AidlParcelable& parcelable,
255                          const std::string& src_file_name)
256       : Type(ValidatableType::KIND_PARCELABLE,
257              parcelable.GetPackage(), parcelable.GetName(),
258              {parcelable.GetCppHeader()}, GetCppName(parcelable),
259              "readParcelable", "writeNullableParcelable",
260              kNoArrayType, kNoNullableType,
261              src_file_name, parcelable.GetLine()) {}
262   virtual ~NullableParcelableType() = default;
CanBeOutParameter() const263   bool CanBeOutParameter() const override { return true; }
264 
265  private:
GetCppName(const AidlParcelable & parcelable)266   static string GetCppName(const AidlParcelable& parcelable) {
267     return "::std::unique_ptr<::" + Join(parcelable.GetSplitPackage(), "::") +
268         "::" + parcelable.GetName() + ">";
269   }
270 };
271 
272 class ParcelableType : public Type {
273  public:
ParcelableType(const AidlParcelable & parcelable,const std::string & src_file_name)274   ParcelableType(const AidlParcelable& parcelable,
275                  const std::string& src_file_name)
276       : Type(ValidatableType::KIND_PARCELABLE,
277              parcelable.GetPackage(), parcelable.GetName(),
278              {parcelable.GetCppHeader()}, GetCppName(parcelable),
279              "readParcelable", "writeParcelable",
280              new ParcelableArrayType(parcelable, src_file_name),
281              new NullableParcelableType(parcelable, src_file_name),
282              src_file_name, parcelable.GetLine()) {}
283   virtual ~ParcelableType() = default;
CanBeOutParameter() const284   bool CanBeOutParameter() const override { return true; }
285 
286  private:
GetCppName(const AidlParcelable & parcelable)287   static string GetCppName(const AidlParcelable& parcelable) {
288     return "::" + Join(parcelable.GetSplitPackage(), "::") +
289         "::" + parcelable.GetName();
290   }
291 };
292 
293 class NullableStringListType : public Type {
294  public:
NullableStringListType()295   NullableStringListType()
296       : Type(ValidatableType::KIND_BUILT_IN,
297              "java.util", "List<" + string(kStringCanonicalName) + ">",
298              {"utils/String16.h", "memory", "vector"},
299              "::std::unique_ptr<::std::vector<std::unique_ptr<::android::String16>>>",
300              "readString16Vector", "writeString16Vector") {}
301   virtual ~NullableStringListType() = default;
CanBeOutParameter() const302   bool CanBeOutParameter() const override { return true; }
303 
304  private:
305   DISALLOW_COPY_AND_ASSIGN(NullableStringListType);
306 };  // class NullableStringListType
307 
308 class StringListType : public Type {
309  public:
StringListType()310   StringListType()
311       : Type(ValidatableType::KIND_BUILT_IN,
312              "java.util", "List<" + string(kStringCanonicalName) + ">",
313              {"utils/String16.h", "vector"},
314              "::std::vector<::android::String16>",
315              "readString16Vector", "writeString16Vector",
316              kNoArrayType, new NullableStringListType()) {}
317   virtual ~StringListType() = default;
CanBeOutParameter() const318   bool CanBeOutParameter() const override { return true; }
319 
320  private:
321   DISALLOW_COPY_AND_ASSIGN(StringListType);
322 };  // class StringListType
323 
324 class NullableUtf8InCppStringListType : public Type {
325  public:
NullableUtf8InCppStringListType()326   NullableUtf8InCppStringListType()
327       : Type(ValidatableType::KIND_BUILT_IN,
328              "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
329              {"memory", "string", "vector"},
330              "::std::unique_ptr<::std::vector<std::unique_ptr<::std::string>>>",
331              "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector") {}
332   virtual ~NullableUtf8InCppStringListType() = default;
CanBeOutParameter() const333   bool CanBeOutParameter() const override { return true; }
334 
335  private:
336   DISALLOW_COPY_AND_ASSIGN(NullableUtf8InCppStringListType);
337 };  // class NullableUtf8InCppStringListType
338 
339 class Utf8InCppStringListType : public Type {
340  public:
Utf8InCppStringListType()341   Utf8InCppStringListType()
342       : Type(ValidatableType::KIND_BUILT_IN,
343              "java.util", "List<" + string(kUtf8InCppStringCanonicalName) + ">",
344              {"string", "vector"},
345              "::std::vector<::std::string>",
346              "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
347              kNoArrayType, new NullableUtf8InCppStringListType()) {}
348   virtual ~Utf8InCppStringListType() = default;
CanBeOutParameter() const349   bool CanBeOutParameter() const override { return true; }
350 
351  private:
352   DISALLOW_COPY_AND_ASSIGN(Utf8InCppStringListType);
353 };  // class Utf8InCppStringListType
354 
355 class NullableBinderListType : public Type {
356  public:
NullableBinderListType()357   NullableBinderListType()
358       : Type(ValidatableType::KIND_BUILT_IN, "java.util",
359              "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
360              "::std::unique_ptr<::std::vector<::android::sp<::android::IBinder>>>",
361              "readStrongBinderVector", "writeStrongBinderVector") {}
362   virtual ~NullableBinderListType() = default;
CanBeOutParameter() const363   bool CanBeOutParameter() const override { return true; }
364 
365  private:
366   DISALLOW_COPY_AND_ASSIGN(NullableBinderListType);
367 };  // class NullableBinderListType
368 
369 class BinderListType : public Type {
370  public:
BinderListType()371   BinderListType()
372       : Type(ValidatableType::KIND_BUILT_IN, "java.util",
373              "List<android.os.IBinder>", {"binder/IBinder.h", "vector"},
374              "::std::vector<::android::sp<::android::IBinder>>",
375              "readStrongBinderVector", "writeStrongBinderVector",
376              kNoArrayType, new NullableBinderListType()) {}
377   virtual ~BinderListType() = default;
CanBeOutParameter() const378   bool CanBeOutParameter() const override { return true; }
379 
380  private:
381   DISALLOW_COPY_AND_ASSIGN(BinderListType);
382 };  // class BinderListType
383 
384 }  // namespace
385 
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)386 Type::Type(int kind,
387            const std::string& package,
388            const std::string& aidl_type,
389            const vector<string>& headers,
390            const string& cpp_type,
391            const string& read_method,
392            const string& write_method,
393            Type* array_type,
394            Type* nullable_type,
395            const string& src_file_name,
396            int line)
397     : ValidatableType(kind, package, aidl_type, src_file_name, line),
398       headers_(headers),
399       aidl_type_(aidl_type),
400       cpp_type_(cpp_type),
401       parcel_read_method_(read_method),
402       parcel_write_method_(write_method),
403       array_type_(array_type),
404       nullable_type_(nullable_type) {}
405 
CanWriteToParcel() const406 bool Type::CanWriteToParcel() const { return true; }
407 
Init()408 void TypeNamespace::Init() {
409   Add(new ByteType());
410   Add(new PrimitiveType(
411       ValidatableType::KIND_BUILT_IN, kNoPackage, "int",
412       "cstdint", "int32_t", "readInt32", "writeInt32",
413       "readInt32Vector", "writeInt32Vector"));
414   Add(new PrimitiveType(
415       ValidatableType::KIND_BUILT_IN, kNoPackage, "long",
416       "cstdint", "int64_t", "readInt64", "writeInt64",
417       "readInt64Vector", "writeInt64Vector"));
418   Add(new PrimitiveType(
419       ValidatableType::KIND_BUILT_IN, kNoPackage, "float",
420       kNoHeader, "float", "readFloat", "writeFloat",
421       "readFloatVector", "writeFloatVector"));
422   Add(new PrimitiveType(
423       ValidatableType::KIND_BUILT_IN, kNoPackage, "double",
424       kNoHeader, "double", "readDouble", "writeDouble",
425       "readDoubleVector", "writeDoubleVector"));
426   Add(new PrimitiveType(
427       ValidatableType::KIND_BUILT_IN, kNoPackage, "boolean",
428       kNoHeader, "bool", "readBool", "writeBool",
429       "readBoolVector", "writeBoolVector"));
430   // C++11 defines the char16_t type as a built in for Unicode characters.
431   Add(new PrimitiveType(
432       ValidatableType::KIND_BUILT_IN, kNoPackage, "char",
433       kNoHeader, "char16_t", "readChar", "writeChar",
434       "readCharVector", "writeCharVector"));
435 
436   Type* nullable_string_array_type =
437       new ArrayType(ValidatableType::KIND_BUILT_IN, "java.lang", "String[]",
438                     {"utils/String16.h", "memory", "vector"},
439                     "::std::unique_ptr<::std::vector<::std::unique_ptr<::android::String16>>>",
440                     "readString16Vector", "writeString16Vector");
441 
442   Type* string_array_type = new ArrayType(ValidatableType::KIND_BUILT_IN,
443                                           "java.lang", "String[]",
444                                           {"utils/String16.h", "vector"},
445                                           "::std::vector<::android::String16>",
446                                           "readString16Vector",
447                                           "writeString16Vector", kNoArrayType,
448                                           nullable_string_array_type);
449 
450   Type* nullable_string_type =
451       new Type(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
452                {"memory", "utils/String16.h"}, "::std::unique_ptr<::android::String16>",
453                "readString16", "writeString16");
454 
455   string_type_ = new Type(ValidatableType::KIND_BUILT_IN, "java.lang", "String",
456                           {"utils/String16.h"}, "::android::String16",
457                           "readString16", "writeString16",
458                           string_array_type, nullable_string_type);
459   Add(string_type_);
460 
461   using ::android::aidl::kAidlReservedTypePackage;
462   using ::android::aidl::kUtf8InCppStringClass;
463 
464   // This type is a Utf16 string in the parcel, but deserializes to
465   // a std::string in Utf8 format when we use it in C++.
466   Type* nullable_cpp_utf8_string_array = new ArrayType(
467       ValidatableType::KIND_BUILT_IN,
468       kAidlReservedTypePackage, StringPrintf("%s[]", kUtf8InCppStringClass),
469       {"memory", "string", "vector"},
470       "::std::unique_ptr<::std::vector<::std::unique_ptr<::std::string>>>",
471       "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector");
472   Type* cpp_utf8_string_array = new ArrayType(
473       ValidatableType::KIND_BUILT_IN,
474       kAidlReservedTypePackage, StringPrintf("%s[]", kUtf8InCppStringClass),
475       {"string", "vector"},
476       "::std::vector<::std::string>",
477       "readUtf8VectorFromUtf16Vector", "writeUtf8VectorAsUtf16Vector",
478       kNoArrayType, nullable_cpp_utf8_string_array);
479   Type* nullable_cpp_utf8_string_type = new Type(
480       ValidatableType::KIND_BUILT_IN,
481       kAidlReservedTypePackage, kUtf8InCppStringClass,
482       {"string", "memory"}, "::std::unique_ptr<::std::string>",
483       "readUtf8FromUtf16", "writeUtf8AsUtf16");
484   Add(new Type(
485       ValidatableType::KIND_BUILT_IN,
486       kAidlReservedTypePackage, kUtf8InCppStringClass,
487       {"string"}, "::std::string", "readUtf8FromUtf16", "writeUtf8AsUtf16",
488       cpp_utf8_string_array, nullable_cpp_utf8_string_type));
489 
490   ibinder_type_ = new Type(ValidatableType::KIND_BUILT_IN, "android.os",
491                            "IBinder", {"binder/IBinder.h"},
492                            "::android::sp<::android::IBinder>", "readStrongBinder",
493                            "writeStrongBinder");
494   Add(ibinder_type_);
495 
496   Add(new BinderListType());
497   Add(new StringListType());
498   Add(new Utf8InCppStringListType());
499 
500   Type* fd_vector_type = new ArrayType(
501       ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor[]",
502       {"nativehelper/ScopedFd.h", "vector"}, "::std::vector<::ScopedFd>",
503       "readUniqueFileDescriptorVector", "writeUniqueFileDescriptorVector");
504 
505   Add(new Type(
506       ValidatableType::KIND_BUILT_IN, kNoPackage, "FileDescriptor",
507       {"nativehelper/ScopedFd.h"}, "::ScopedFd",
508       "readUniqueFileDescriptor", "writeUniqueFileDescriptor",
509       fd_vector_type));
510 
511   void_type_ = new class VoidType();
512   Add(void_type_);
513 }
514 
AddParcelableType(const AidlParcelable & p,const string & filename)515 bool TypeNamespace::AddParcelableType(const AidlParcelable& p,
516                                       const string& filename) {
517   if (p.GetCppHeader().empty()) {
518     LOG(ERROR) << "Parcelable " << p.GetCanonicalName()
519                << " has no C++ header defined.";
520     return false;
521   }
522   Add(new ParcelableType(p, filename));
523   return true;
524 }
525 
AddBinderType(const AidlInterface & b,const string & file_name)526 bool TypeNamespace::AddBinderType(const AidlInterface& b,
527                                   const string& file_name) {
528   Add(new BinderType(b, file_name));
529   return true;
530 }
531 
AddListType(const std::string & type_name)532 bool TypeNamespace::AddListType(const std::string& type_name) {
533   const Type* contained_type = FindTypeByCanonicalName(type_name);
534   if (!contained_type) {
535     LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
536                   "type cannot be found or is invalid.";
537     return false;
538   }
539   if (contained_type->IsCppPrimitive()) {
540     LOG(ERROR) << "Cannot create List<" << type_name << "> because contained "
541                   "type is a primitive in Java and Java List cannot hold "
542                   "primitives.";
543     return false;
544   }
545 
546   if (contained_type->CanonicalName() == kStringCanonicalName ||
547       contained_type->CanonicalName() == kUtf8InCppStringCanonicalName ||
548       contained_type == IBinderType()) {
549     return true;
550   }
551 
552   // TODO Support lists of parcelables b/23600712
553 
554   LOG(ERROR) << "aidl-cpp does not yet support List<" << type_name << ">";
555   return false;
556 }
557 
AddMapType(const std::string &,const std::string &)558 bool TypeNamespace::AddMapType(const std::string& /* key_type_name */,
559                                const std::string& /* value_type_name */) {
560   // TODO Support list types b/25242025
561   LOG(ERROR) << "aidl does not implement support for typed maps!";
562   return false;
563 }
564 
IsValidPackage(const string & package) const565 bool TypeNamespace::IsValidPackage(const string& package) const {
566   if (package.empty()) {
567     return false;
568   }
569 
570   auto pieces = Split(package, ".");
571   for (const string& piece : pieces) {
572     if (is_cpp_keyword(piece)) {
573       return false;
574     }
575   }
576 
577   return true;
578 }
579 
GetArgType(const AidlArgument & a,int arg_index,const std::string & filename) const580 const ValidatableType* TypeNamespace::GetArgType(const AidlArgument& a,
581     int arg_index,
582     const std::string& filename) const {
583   const string error_prefix = StringPrintf(
584       "In file %s line %d parameter %s (%d):\n    ",
585       filename.c_str(), a.GetLine(), a.GetName().c_str(), arg_index);
586 
587   // check that the name doesn't match a keyword
588   if (is_cpp_keyword(a.GetName().c_str())) {
589     cerr << error_prefix << "Argument name is a C++ keyword"
590          << endl;
591     return nullptr;
592   }
593 
594   return ::android::aidl::TypeNamespace::GetArgType(a, arg_index, filename);
595 }
596 
597 }  // namespace cpp
598 }  // namespace aidl
599 }  // namespace android
600