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 "aidl_language.h"
18 #include "aidl_typenames.h"
19 #include "parser.h"
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <algorithm>
25 #include <iostream>
26 #include <set>
27 #include <sstream>
28 #include <string>
29 #include <utility>
30 
31 #include <android-base/parsedouble.h>
32 #include <android-base/parseint.h>
33 #include <android-base/strings.h>
34 
35 #include "aidl_language_y-module.h"
36 #include "logging.h"
37 
38 #include "aidl.h"
39 
40 #ifdef _WIN32
isatty(int fd)41 int isatty(int  fd)
42 {
43     return (fd == 0);
44 }
45 #endif
46 
47 using android::aidl::IoDelegate;
48 using android::base::Join;
49 using android::base::Split;
50 using std::cerr;
51 using std::pair;
52 using std::set;
53 using std::string;
54 using std::unique_ptr;
55 using std::vector;
56 
57 namespace {
IsJavaKeyword(const char * str)58 bool IsJavaKeyword(const char* str) {
59   static const std::vector<std::string> kJavaKeywords{
60       "abstract", "assert", "boolean",    "break",     "byte",       "case",      "catch",
61       "char",     "class",  "const",      "continue",  "default",    "do",        "double",
62       "else",     "enum",   "extends",    "final",     "finally",    "float",     "for",
63       "goto",     "if",     "implements", "import",    "instanceof", "int",       "interface",
64       "long",     "native", "new",        "package",   "private",    "protected", "public",
65       "return",   "short",  "static",     "strictfp",  "super",      "switch",    "synchronized",
66       "this",     "throw",  "throws",     "transient", "try",        "void",      "volatile",
67       "while",    "true",   "false",      "null",
68   };
69   return std::find(kJavaKeywords.begin(), kJavaKeywords.end(), str) != kJavaKeywords.end();
70 }
71 
AddHideComment(CodeWriter * writer)72 void AddHideComment(CodeWriter* writer) {
73   writer->Write("/* @hide */\n");
74 }
75 
HasHideComment(const std::string & comment)76 inline bool HasHideComment(const std::string& comment) {
77   return std::regex_search(comment, std::regex("@hide\\b"));
78 }
79 }  // namespace
80 
AidlLocation(const std::string & file,Point begin,Point end,Source source)81 AidlLocation::AidlLocation(const std::string& file, Point begin, Point end, Source source)
82     : file_(file), begin_(begin), end_(end), source_(source) {}
83 
operator <<(std::ostream & os,const AidlLocation & l)84 std::ostream& operator<<(std::ostream& os, const AidlLocation& l) {
85   os << l.file_;
86   if (l.LocationKnown()) {
87     os << ":" << l.begin_.line << "." << l.begin_.column << "-";
88     if (l.begin_.line != l.end_.line) {
89       os << l.end_.line << ".";
90     }
91     os << l.end_.column;
92   }
93   return os;
94 }
95 
AidlNode(const AidlLocation & location)96 AidlNode::AidlNode(const AidlLocation& location) : location_(location) {}
97 
PrintLine() const98 std::string AidlNode::PrintLine() const {
99   std::stringstream ss;
100   ss << location_.file_ << ":" << location_.begin_.line;
101   return ss.str();
102 }
103 
PrintLocation() const104 std::string AidlNode::PrintLocation() const {
105   std::stringstream ss;
106   ss << location_.file_ << ":" << location_.begin_.line << ":" << location_.begin_.column << ":"
107      << location_.end_.line << ":" << location_.end_.column;
108   return ss.str();
109 }
110 
AllSchemas()111 const std::vector<AidlAnnotation::Schema>& AidlAnnotation::AllSchemas() {
112   static const std::vector<Schema> kSchemas{
113       {AidlAnnotation::Type::NULLABLE, "nullable", {}},
114       {AidlAnnotation::Type::UTF8_IN_CPP, "utf8InCpp", {}},
115       {AidlAnnotation::Type::VINTF_STABILITY, "VintfStability", {}},
116       {AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
117        "UnsupportedAppUsage",
118        {{"expectedSignature", "String"},
119         {"implicitMember", "String"},
120         {"maxTargetSdk", "int"},
121         {"publicAlternatives", "String"},
122         {"trackingBug", "long"}}},
123       {AidlAnnotation::Type::JAVA_STABLE_PARCELABLE, "JavaOnlyStableParcelable", {}},
124       {AidlAnnotation::Type::HIDE, "Hide", {}},
125       {AidlAnnotation::Type::BACKING, "Backing", {{"type", "String"}}},
126       {AidlAnnotation::Type::JAVA_PASSTHROUGH, "JavaPassthrough", {{"annotation", "String"}}},
127       {AidlAnnotation::Type::JAVA_DEBUG, "JavaDebug", {}},
128       {AidlAnnotation::Type::IMMUTABLE, "Immutable", {}},
129   };
130   return kSchemas;
131 }
132 
TypeToString(Type type)133 std::string AidlAnnotation::TypeToString(Type type) {
134   for (const Schema& schema : AllSchemas()) {
135     if (type == schema.type) return schema.name;
136   }
137   AIDL_FATAL(AIDL_LOCATION_HERE) << "Unrecognized type: " << static_cast<size_t>(type);
138   __builtin_unreachable();
139 }
140 
Parse(const AidlLocation & location,const string & name,std::map<std::string,std::shared_ptr<AidlConstantValue>> * parameter_list)141 AidlAnnotation* AidlAnnotation::Parse(
142     const AidlLocation& location, const string& name,
143     std::map<std::string, std::shared_ptr<AidlConstantValue>>* parameter_list) {
144   const Schema* schema = nullptr;
145   for (const Schema& a_schema : AllSchemas()) {
146     if (a_schema.name == name) {
147       schema = &a_schema;
148     }
149   }
150 
151   if (schema == nullptr) {
152     std::ostringstream stream;
153     stream << "'" << name << "' is not a recognized annotation. ";
154     stream << "It must be one of:";
155     for (const Schema& s : AllSchemas()) {
156       stream << " " << s.name;
157     }
158     stream << ".";
159     AIDL_ERROR(location) << stream.str();
160     return nullptr;
161   }
162   if (parameter_list == nullptr) {
163     return new AidlAnnotation(location, *schema, {});
164   }
165 
166   return new AidlAnnotation(location, *schema, std::move(*parameter_list));
167 }
168 
AidlAnnotation(const AidlLocation & location,const Schema & schema,std::map<std::string,std::shared_ptr<AidlConstantValue>> && parameters)169 AidlAnnotation::AidlAnnotation(
170     const AidlLocation& location, const Schema& schema,
171     std::map<std::string, std::shared_ptr<AidlConstantValue>>&& parameters)
172     : AidlNode(location), schema_(schema), parameters_(std::move(parameters)) {}
173 
CheckValid() const174 bool AidlAnnotation::CheckValid() const {
175   for (const auto& name_and_param : parameters_) {
176     const std::string& param_name = name_and_param.first;
177     const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
178     if (!param->CheckValid()) {
179       AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
180                        << GetName() << ".";
181       return false;
182     }
183     auto parameter_mapping_it = schema_.supported_parameters.find(param_name);
184     if (parameter_mapping_it == schema_.supported_parameters.end()) {
185       std::ostringstream stream;
186       stream << "Parameter " << param_name << " not supported ";
187       stream << "for annotation " << GetName() << ". ";
188       stream << "It must be one of:";
189       for (const auto& kv : schema_.supported_parameters) {
190         stream << " " << kv.first;
191       }
192       AIDL_ERROR(this) << stream.str();
193       return false;
194     }
195     AidlTypeSpecifier type{AIDL_LOCATION_HERE, parameter_mapping_it->second, false, nullptr, ""};
196     const std::string param_value = param->ValueString(type, AidlConstantValueDecorator);
197     // Assume error on empty string.
198     if (param_value == "") {
199       AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
200                        << GetName() << ".";
201       return false;
202     }
203   }
204   return true;
205 }
206 
AnnotationParams(const ConstantValueDecorator & decorator) const207 std::map<std::string, std::string> AidlAnnotation::AnnotationParams(
208     const ConstantValueDecorator& decorator) const {
209   std::map<std::string, std::string> raw_params;
210   for (const auto& name_and_param : parameters_) {
211     const std::string& param_name = name_and_param.first;
212     const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
213     if (schema_.supported_parameters.find(param_name) == schema_.supported_parameters.end()) {
214       std::ostringstream stream;
215       stream << "Parameter " << param_name << " not supported ";
216       stream << "for annotation " << GetName() << ". ";
217       stream << "It must be one of:";
218       for (const auto& kv : schema_.supported_parameters) {
219         stream << " " << kv.first;
220       }
221       AIDL_ERROR(this) << stream.str();
222       continue;
223     }
224     AidlTypeSpecifier type{AIDL_LOCATION_HERE, schema_.supported_parameters.at(param_name), false,
225                            nullptr, ""};
226     if (!param->CheckValid()) {
227       AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
228                        << GetName() << ".";
229       continue;
230     }
231 
232     raw_params.emplace(param_name, param->ValueString(type, decorator));
233   }
234   return raw_params;
235 }
236 
ToString(const ConstantValueDecorator & decorator) const237 std::string AidlAnnotation::ToString(const ConstantValueDecorator& decorator) const {
238   if (parameters_.empty()) {
239     return "@" + GetName();
240   } else {
241     vector<string> param_strings;
242     for (const auto& [name, value] : AnnotationParams(decorator)) {
243       param_strings.emplace_back(name + "=" + value);
244     }
245     return "@" + GetName() + "(" + Join(param_strings, ", ") + ")";
246   }
247 }
248 
GetAnnotation(const vector<AidlAnnotation> & annotations,AidlAnnotation::Type type)249 static const AidlAnnotation* GetAnnotation(const vector<AidlAnnotation>& annotations,
250                                            AidlAnnotation::Type type) {
251   for (const auto& a : annotations) {
252     if (a.GetType() == type) {
253       return &a;
254     }
255   }
256   return nullptr;
257 }
258 
AidlAnnotatable(const AidlLocation & location)259 AidlAnnotatable::AidlAnnotatable(const AidlLocation& location) : AidlNode(location) {}
260 
IsNullable() const261 bool AidlAnnotatable::IsNullable() const {
262   return GetAnnotation(annotations_, AidlAnnotation::Type::NULLABLE);
263 }
264 
IsUtf8InCpp() const265 bool AidlAnnotatable::IsUtf8InCpp() const {
266   return GetAnnotation(annotations_, AidlAnnotation::Type::UTF8_IN_CPP);
267 }
268 
IsVintfStability() const269 bool AidlAnnotatable::IsVintfStability() const {
270   return GetAnnotation(annotations_, AidlAnnotation::Type::VINTF_STABILITY);
271 }
272 
IsImmutable() const273 bool AidlAnnotatable::IsImmutable() const {
274   return GetAnnotation(annotations_, AidlAnnotation::Type::IMMUTABLE);
275 }
276 
UnsupportedAppUsage() const277 const AidlAnnotation* AidlAnnotatable::UnsupportedAppUsage() const {
278   return GetAnnotation(annotations_, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE);
279 }
280 
JavaPassthrough() const281 const AidlAnnotation* AidlAnnotatable::JavaPassthrough() const {
282   return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_PASSTHROUGH);
283 }
284 
BackingType(const AidlTypenames & typenames) const285 const AidlTypeSpecifier* AidlAnnotatable::BackingType(const AidlTypenames& typenames) const {
286   auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::BACKING);
287   if (annotation != nullptr) {
288     auto annotation_params = annotation->AnnotationParams(AidlConstantValueDecorator);
289     if (auto it = annotation_params.find("type"); it != annotation_params.end()) {
290       const string& type = it->second;
291 
292       AIDL_FATAL_IF(type.size() < 2, this) << type;
293       AIDL_FATAL_IF(type[0] != '"', this) << type;
294       AIDL_FATAL_IF(type[type.length() - 1] != '"', this) << type;
295       string unquoted_type = type.substr(1, type.length() - 2);
296 
297       AidlTypeSpecifier* type_specifier =
298           new AidlTypeSpecifier(AIDL_LOCATION_HERE, unquoted_type, false, nullptr, "");
299       type_specifier->Resolve(typenames);
300       return type_specifier;
301     }
302   }
303   return nullptr;
304 }
305 
IsStableApiParcelable(Options::Language lang) const306 bool AidlAnnotatable::IsStableApiParcelable(Options::Language lang) const {
307   return lang == Options::Language::JAVA &&
308          GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_STABLE_PARCELABLE);
309 }
310 
IsHide() const311 bool AidlAnnotatable::IsHide() const {
312   return GetAnnotation(annotations_, AidlAnnotation::Type::HIDE);
313 }
314 
IsJavaDebug() const315 bool AidlAnnotatable::IsJavaDebug() const {
316   return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_DEBUG);
317 }
318 
DumpAnnotations(CodeWriter * writer) const319 void AidlAnnotatable::DumpAnnotations(CodeWriter* writer) const {
320   if (annotations_.empty()) return;
321 
322   writer->Write("%s\n", AidlAnnotatable::ToString().c_str());
323 }
324 
CheckValid(const AidlTypenames &) const325 bool AidlAnnotatable::CheckValid(const AidlTypenames&) const {
326   std::set<AidlAnnotation::Type> supported_annotations = GetSupportedAnnotations();
327   for (const auto& annotation : GetAnnotations()) {
328     if (!annotation.CheckValid()) {
329       return false;
330     }
331 
332     std::vector<std::string> supported_annot_strings;
333     for (AidlAnnotation::Type type : supported_annotations) {
334       supported_annot_strings.push_back(AidlAnnotation::TypeToString(type));
335     }
336 
337     if (supported_annotations.find(annotation.GetType()) == supported_annotations.end()) {
338       AIDL_ERROR(this) << "'" << annotation.GetName()
339                        << "' is not a supported annotation for this node. "
340                        << "It must be one of: "
341                        << android::base::Join(supported_annot_strings, ", ");
342       return false;
343     }
344   }
345 
346   return true;
347 }
348 
ToString() const349 string AidlAnnotatable::ToString() const {
350   vector<string> ret;
351   for (const auto& a : annotations_) {
352     ret.emplace_back(a.ToString(AidlConstantValueDecorator));
353   }
354   std::sort(ret.begin(), ret.end());
355   return Join(ret, " ");
356 }
357 
AidlTypeSpecifier(const AidlLocation & location,const string & unresolved_name,bool is_array,vector<unique_ptr<AidlTypeSpecifier>> * type_params,const string & comments)358 AidlTypeSpecifier::AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name,
359                                      bool is_array,
360                                      vector<unique_ptr<AidlTypeSpecifier>>* type_params,
361                                      const string& comments)
362     : AidlAnnotatable(location),
363       AidlParameterizable<unique_ptr<AidlTypeSpecifier>>(type_params),
364       unresolved_name_(unresolved_name),
365       is_array_(is_array),
366       comments_(comments),
367       split_name_(Split(unresolved_name, ".")) {}
368 
ArrayBase() const369 AidlTypeSpecifier AidlTypeSpecifier::ArrayBase() const {
370   AIDL_FATAL_IF(!is_array_, this);
371   // Declaring array of generic type cannot happen, it is grammar error.
372   AIDL_FATAL_IF(IsGeneric(), this);
373 
374   AidlTypeSpecifier array_base = *this;
375   array_base.is_array_ = false;
376   return array_base;
377 }
378 
IsHidden() const379 bool AidlTypeSpecifier::IsHidden() const {
380   return HasHideComment(GetComments());
381 }
382 
ToString() const383 string AidlTypeSpecifier::ToString() const {
384   string ret = GetName();
385   if (IsGeneric()) {
386     vector<string> arg_names;
387     for (const auto& ta : GetTypeParameters()) {
388       arg_names.emplace_back(ta->ToString());
389     }
390     ret += "<" + Join(arg_names, ",") + ">";
391   }
392   if (IsArray()) {
393     ret += "[]";
394   }
395   return ret;
396 }
397 
Signature() const398 string AidlTypeSpecifier::Signature() const {
399   string ret = ToString();
400   string annotations = AidlAnnotatable::ToString();
401   if (annotations != "") {
402     ret = annotations + " " + ret;
403   }
404   return ret;
405 }
406 
Resolve(const AidlTypenames & typenames)407 bool AidlTypeSpecifier::Resolve(const AidlTypenames& typenames) {
408   CHECK(!IsResolved());
409   AidlTypenames::ResolvedTypename result = typenames.ResolveTypename(unresolved_name_);
410   if (result.is_resolved) {
411     fully_qualified_name_ = result.canonical_name;
412     split_name_ = Split(fully_qualified_name_, ".");
413   }
414   return result.is_resolved;
415 }
416 
GetSupportedAnnotations() const417 std::set<AidlAnnotation::Type> AidlTypeSpecifier::GetSupportedAnnotations() const {
418   // kHide and kUnsupportedAppUsage are both method return annotations
419   // which we don't distinguish from other type specifiers.
420   return {AidlAnnotation::Type::NULLABLE, AidlAnnotation::Type::UTF8_IN_CPP,
421           AidlAnnotation::Type::UNSUPPORTED_APP_USAGE, AidlAnnotation::Type::HIDE,
422           AidlAnnotation::Type::JAVA_PASSTHROUGH};
423 }
424 
CheckValid(const AidlTypenames & typenames) const425 bool AidlTypeSpecifier::CheckValid(const AidlTypenames& typenames) const {
426   if (!AidlAnnotatable::CheckValid(typenames)) {
427     return false;
428   }
429   if (IsGeneric()) {
430     const string& type_name = GetName();
431 
432     auto& types = GetTypeParameters();
433     // TODO(b/136048684) Disallow to use primitive types only if it is List or Map.
434     if (type_name == "List" || type_name == "Map") {
435       if (std::any_of(types.begin(), types.end(), [](auto& type_ptr) {
436             return AidlTypenames::IsPrimitiveTypename(type_ptr->GetName());
437           })) {
438         AIDL_ERROR(this) << "A generic type cannot have any primitive type parameters.";
439         return false;
440       }
441     }
442     const auto defined_type = typenames.TryGetDefinedType(type_name);
443     const auto parameterizable =
444         defined_type != nullptr ? defined_type->AsParameterizable() : nullptr;
445     const bool is_user_defined_generic_type =
446         parameterizable != nullptr && parameterizable->IsGeneric();
447     const size_t num_params = GetTypeParameters().size();
448     if (type_name == "List") {
449       if (num_params > 1) {
450         AIDL_ERROR(this) << " List cannot have type parameters more than one, but got "
451                          << "'" << ToString() << "'";
452         return false;
453       }
454     } else if (type_name == "Map") {
455       if (num_params != 0 && num_params != 2) {
456         AIDL_ERROR(this) << "Map must have 0 or 2 type parameters, but got "
457                          << "'" << ToString() << "'";
458         return false;
459       }
460       if (num_params == 2) {
461         const string& key_type = GetTypeParameters()[0]->GetName();
462         if (key_type != "String") {
463           AIDL_ERROR(this) << "The type of key in map must be String, but it is "
464                            << "'" << key_type << "'";
465           return false;
466         }
467       }
468     } else if (is_user_defined_generic_type) {
469       const size_t allowed = parameterizable->GetTypeParameters().size();
470       if (num_params != allowed) {
471         AIDL_ERROR(this) << type_name << " must have " << allowed << " type parameters, but got "
472                          << num_params;
473         return false;
474       }
475     } else {
476       AIDL_ERROR(this) << type_name << " is not a generic type.";
477       return false;
478     }
479   }
480 
481   const bool is_generic_string_list = GetName() == "List" && IsGeneric() &&
482                                       GetTypeParameters().size() == 1 &&
483                                       GetTypeParameters()[0]->GetName() == "String";
484   if (IsUtf8InCpp() && (GetName() != "String" && !is_generic_string_list)) {
485     AIDL_ERROR(this) << "@utf8InCpp can only be used on String, String[], and List<String>.";
486     return false;
487   }
488 
489   if (GetName() == "void") {
490     if (IsArray() || IsNullable() || IsUtf8InCpp()) {
491       AIDL_ERROR(this) << "void type cannot be an array or nullable or utf8 string";
492       return false;
493     }
494   }
495 
496   if (IsArray()) {
497     const auto defined_type = typenames.TryGetDefinedType(GetName());
498     if (defined_type != nullptr && defined_type->AsInterface() != nullptr) {
499       AIDL_ERROR(this) << "Binder type cannot be an array";
500       return false;
501     }
502   }
503 
504   if (IsNullable()) {
505     if (AidlTypenames::IsPrimitiveTypename(GetName()) && !IsArray()) {
506       AIDL_ERROR(this) << "Primitive type cannot get nullable annotation";
507       return false;
508     }
509     const auto defined_type = typenames.TryGetDefinedType(GetName());
510     if (defined_type != nullptr && defined_type->AsEnumDeclaration() != nullptr && !IsArray()) {
511       AIDL_ERROR(this) << "Enum type cannot get nullable annotation";
512       return false;
513     }
514   }
515   return true;
516 }
517 
AidlConstantValueDecorator(const AidlTypeSpecifier &,const std::string & raw_value)518 std::string AidlConstantValueDecorator(const AidlTypeSpecifier& /*type*/,
519                                        const std::string& raw_value) {
520   return raw_value;
521 }
522 
AidlVariableDeclaration(const AidlLocation & location,AidlTypeSpecifier * type,const std::string & name)523 AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
524                                                  AidlTypeSpecifier* type, const std::string& name)
525     : AidlVariableDeclaration(location, type, name, AidlConstantValue::Default(*type)) {
526   default_user_specified_ = false;
527 }
528 
AidlVariableDeclaration(const AidlLocation & location,AidlTypeSpecifier * type,const std::string & name,AidlConstantValue * default_value)529 AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
530                                                  AidlTypeSpecifier* type, const std::string& name,
531                                                  AidlConstantValue* default_value)
532     : AidlNode(location),
533       type_(type),
534       name_(name),
535       default_user_specified_(true),
536       default_value_(default_value) {}
537 
CheckValid(const AidlTypenames & typenames) const538 bool AidlVariableDeclaration::CheckValid(const AidlTypenames& typenames) const {
539   bool valid = true;
540   valid &= type_->CheckValid(typenames);
541 
542   if (type_->GetName() == "void") {
543     AIDL_ERROR(this) << "Declaration " << name_
544                      << " is void, but declarations cannot be of void type.";
545     valid = false;
546   }
547 
548   if (default_value_ == nullptr) return valid;
549   valid &= default_value_->CheckValid();
550 
551   if (!valid) return false;
552 
553   return !ValueString(AidlConstantValueDecorator).empty();
554 }
555 
ToString() const556 string AidlVariableDeclaration::ToString() const {
557   string ret = type_->Signature() + " " + name_;
558   if (default_value_ != nullptr && default_user_specified_) {
559     ret += " = " + ValueString(AidlConstantValueDecorator);
560   }
561   return ret;
562 }
563 
Signature() const564 string AidlVariableDeclaration::Signature() const {
565   return type_->Signature() + " " + name_;
566 }
567 
ValueString(const ConstantValueDecorator & decorator) const568 std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
569   if (default_value_ != nullptr) {
570     return default_value_->ValueString(GetType(), decorator);
571   } else {
572     return "";
573   }
574 }
575 
AidlArgument(const AidlLocation & location,AidlArgument::Direction direction,AidlTypeSpecifier * type,const std::string & name)576 AidlArgument::AidlArgument(const AidlLocation& location, AidlArgument::Direction direction,
577                            AidlTypeSpecifier* type, const std::string& name)
578     : AidlVariableDeclaration(location, type, name),
579       direction_(direction),
580       direction_specified_(true) {}
581 
AidlArgument(const AidlLocation & location,AidlTypeSpecifier * type,const std::string & name)582 AidlArgument::AidlArgument(const AidlLocation& location, AidlTypeSpecifier* type,
583                            const std::string& name)
584     : AidlVariableDeclaration(location, type, name),
585       direction_(AidlArgument::IN_DIR),
586       direction_specified_(false) {}
587 
GetDirectionSpecifier() const588 string AidlArgument::GetDirectionSpecifier() const {
589   string ret;
590   if (direction_specified_) {
591     switch(direction_) {
592     case AidlArgument::IN_DIR:
593       ret += "in";
594       break;
595     case AidlArgument::OUT_DIR:
596       ret += "out";
597       break;
598     case AidlArgument::INOUT_DIR:
599       ret += "inout";
600       break;
601     }
602   }
603   return ret;
604 }
605 
ToString() const606 string AidlArgument::ToString() const {
607   if (direction_specified_) {
608     return GetDirectionSpecifier() + " " + AidlVariableDeclaration::ToString();
609   } else {
610     return AidlVariableDeclaration::ToString();
611   }
612 }
613 
Signature() const614 std::string AidlArgument::Signature() const {
615   class AidlInterface;
616   class AidlInterface;
617   class AidlParcelable;
618   class AidlStructuredParcelable;
619   class AidlParcelable;
620   class AidlStructuredParcelable;
621   if (direction_specified_) {
622     return GetDirectionSpecifier() + " " + AidlVariableDeclaration::Signature();
623   } else {
624     return AidlVariableDeclaration::Signature();
625   }
626 }
627 
AidlMember(const AidlLocation & location)628 AidlMember::AidlMember(const AidlLocation& location) : AidlNode(location) {}
629 
AidlConstantDeclaration(const AidlLocation & location,AidlTypeSpecifier * type,const std::string & name,AidlConstantValue * value)630 AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
631                                                  AidlTypeSpecifier* type, const std::string& name,
632                                                  AidlConstantValue* value)
633     : AidlMember(location), type_(type), name_(name), value_(value) {}
634 
CheckValid(const AidlTypenames & typenames) const635 bool AidlConstantDeclaration::CheckValid(const AidlTypenames& typenames) const {
636   bool valid = true;
637   valid &= type_->CheckValid(typenames);
638   valid &= value_->CheckValid();
639   if (!valid) return false;
640 
641   const static set<string> kSupportedConstTypes = {"String", "int"};
642   if (kSupportedConstTypes.find(type_->ToString()) == kSupportedConstTypes.end()) {
643     AIDL_ERROR(this) << "Constant of type " << type_->ToString() << " is not supported.";
644     return false;
645   }
646 
647   return true;
648 }
649 
ToString() const650 string AidlConstantDeclaration::ToString() const {
651   return "const " + type_->ToString() + " " + name_ + " = " +
652          ValueString(AidlConstantValueDecorator);
653 }
654 
Signature() const655 string AidlConstantDeclaration::Signature() const {
656   return type_->Signature() + " " + name_;
657 }
658 
AidlMethod(const AidlLocation & location,bool oneway,AidlTypeSpecifier * type,const std::string & name,std::vector<std::unique_ptr<AidlArgument>> * args,const std::string & comments)659 AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
660                        const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
661                        const std::string& comments)
662     : AidlMethod(location, oneway, type, name, args, comments, 0, true) {
663   has_id_ = false;
664 }
665 
AidlMethod(const AidlLocation & location,bool oneway,AidlTypeSpecifier * type,const std::string & name,std::vector<std::unique_ptr<AidlArgument>> * args,const std::string & comments,int id,bool is_user_defined)666 AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
667                        const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
668                        const std::string& comments, int id, bool is_user_defined)
669     : AidlMember(location),
670       oneway_(oneway),
671       comments_(comments),
672       type_(type),
673       name_(name),
674       arguments_(std::move(*args)),
675       id_(id),
676       is_user_defined_(is_user_defined) {
677   has_id_ = true;
678   delete args;
679   for (const unique_ptr<AidlArgument>& a : arguments_) {
680     if (a->IsIn()) { in_arguments_.push_back(a.get()); }
681     if (a->IsOut()) { out_arguments_.push_back(a.get()); }
682   }
683 }
684 
IsHidden() const685 bool AidlMethod::IsHidden() const {
686   return HasHideComment(GetComments());
687 }
688 
Signature() const689 string AidlMethod::Signature() const {
690   vector<string> arg_signatures;
691   for (const auto& arg : GetArguments()) {
692     arg_signatures.emplace_back(arg->GetType().ToString());
693   }
694   return GetName() + "(" + Join(arg_signatures, ", ") + ")";
695 }
696 
ToString() const697 string AidlMethod::ToString() const {
698   vector<string> arg_strings;
699   for (const auto& arg : GetArguments()) {
700     arg_strings.emplace_back(arg->Signature());
701   }
702   string ret = (IsOneway() ? "oneway " : "") + GetType().Signature() + " " + GetName() + "(" +
703                Join(arg_strings, ", ") + ")";
704   if (HasId()) {
705     ret += " = " + std::to_string(GetId());
706   }
707   return ret;
708 }
709 
AidlDefinedType(const AidlLocation & location,const std::string & name,const std::string & comments,const std::string & package)710 AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
711                                  const std::string& comments, const std::string& package)
712     : AidlAnnotatable(location),
713       name_(name),
714       comments_(comments),
715       package_(package),
716       split_package_(package.empty() ? std::vector<std::string>()
717                                      : android::base::Split(package, ".")) {}
718 
CheckValid(const AidlTypenames & typenames) const719 bool AidlDefinedType::CheckValid(const AidlTypenames& typenames) const {
720   if (!AidlAnnotatable::CheckValid(typenames)) {
721     return false;
722   }
723 
724   return true;
725 }
726 
IsHidden() const727 bool AidlDefinedType::IsHidden() const {
728   return HasHideComment(GetComments());
729 }
730 
GetCanonicalName() const731 std::string AidlDefinedType::GetCanonicalName() const {
732   if (package_.empty()) {
733     return GetName();
734   }
735   return GetPackage() + "." + GetName();
736 }
737 
DumpHeader(CodeWriter * writer) const738 void AidlDefinedType::DumpHeader(CodeWriter* writer) const {
739   if (this->IsHidden()) {
740     AddHideComment(writer);
741   }
742   DumpAnnotations(writer);
743 }
744 
AidlParcelable(const AidlLocation & location,const std::string & name,const std::string & package,const std::string & comments,const std::string & cpp_header,std::vector<std::string> * type_params)745 AidlParcelable::AidlParcelable(const AidlLocation& location, const std::string& name,
746                                const std::string& package, const std::string& comments,
747                                const std::string& cpp_header, std::vector<std::string>* type_params)
748     : AidlDefinedType(location, name, comments, package),
749       AidlParameterizable<std::string>(type_params),
750       cpp_header_(cpp_header) {
751   // Strip off quotation marks if we actually have a cpp header.
752   if (cpp_header_.length() >= 2) {
753     cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
754   }
755 }
756 template <typename T>
AidlParameterizable(const AidlParameterizable & other)757 AidlParameterizable<T>::AidlParameterizable(const AidlParameterizable& other) {
758   // Copying is not supported if it has type parameters.
759   // It doesn't make a problem because only ArrayBase() makes a copy,
760   // and it can be called only if a type is not generic.
761   CHECK(!other.IsGeneric());
762 }
763 
764 template <typename T>
CheckValid() const765 bool AidlParameterizable<T>::CheckValid() const {
766   return true;
767 };
768 
769 template <>
CheckValid() const770 bool AidlParameterizable<std::string>::CheckValid() const {
771   if (!IsGeneric()) {
772     return true;
773   }
774   std::unordered_set<std::string> set(GetTypeParameters().begin(), GetTypeParameters().end());
775   if (set.size() != GetTypeParameters().size()) {
776     AIDL_ERROR(this->AsAidlNode()) << "Every type parameter should be unique.";
777     return false;
778   }
779   return true;
780 }
781 
GetSupportedAnnotations() const782 std::set<AidlAnnotation::Type> AidlParcelable::GetSupportedAnnotations() const {
783   return {AidlAnnotation::Type::VINTF_STABILITY,        AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
784           AidlAnnotation::Type::JAVA_STABLE_PARCELABLE, AidlAnnotation::Type::HIDE,
785           AidlAnnotation::Type::JAVA_PASSTHROUGH,       AidlAnnotation::Type::IMMUTABLE};
786 }
787 
CheckValid(const AidlTypenames & typenames) const788 bool AidlParcelable::CheckValid(const AidlTypenames& typenames) const {
789   if (!AidlDefinedType::CheckValid(typenames)) {
790     return false;
791   }
792   if (!AidlParameterizable<std::string>::CheckValid()) {
793     return false;
794   }
795 
796   return true;
797 }
798 
Dump(CodeWriter * writer) const799 void AidlParcelable::Dump(CodeWriter* writer) const {
800   DumpHeader(writer);
801   writer->Write("parcelable %s ;\n", GetName().c_str());
802 }
803 
AidlStructuredParcelable(const AidlLocation & location,const std::string & name,const std::string & package,const std::string & comments,std::vector<std::unique_ptr<AidlVariableDeclaration>> * variables)804 AidlStructuredParcelable::AidlStructuredParcelable(
805     const AidlLocation& location, const std::string& name, const std::string& package,
806     const std::string& comments, std::vector<std::unique_ptr<AidlVariableDeclaration>>* variables)
807     : AidlParcelable(location, name, package, comments, "" /*cpp_header*/),
808       variables_(std::move(*variables)) {}
809 
Dump(CodeWriter * writer) const810 void AidlStructuredParcelable::Dump(CodeWriter* writer) const {
811   DumpHeader(writer);
812   writer->Write("parcelable %s {\n", GetName().c_str());
813   writer->Indent();
814   for (const auto& field : GetFields()) {
815     if (field->GetType().IsHidden()) {
816       AddHideComment(writer);
817     }
818     writer->Write("%s;\n", field->ToString().c_str());
819   }
820   writer->Dedent();
821   writer->Write("}\n");
822 }
823 
GetSupportedAnnotations() const824 std::set<AidlAnnotation::Type> AidlStructuredParcelable::GetSupportedAnnotations() const {
825   return {AidlAnnotation::Type::VINTF_STABILITY,
826           AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
827           AidlAnnotation::Type::HIDE,
828           AidlAnnotation::Type::JAVA_PASSTHROUGH,
829           AidlAnnotation::Type::JAVA_DEBUG,
830           AidlAnnotation::Type::IMMUTABLE};
831 }
832 
CheckValid(const AidlTypenames & typenames) const833 bool AidlStructuredParcelable::CheckValid(const AidlTypenames& typenames) const {
834   bool success = true;
835   if (!AidlParcelable::CheckValid(typenames)) {
836     return false;
837   }
838 
839   for (const auto& v : GetFields()) {
840     success = success && v->CheckValid(typenames);
841     if (IsImmutable()) {
842       success = success && typenames.CanBeImmutable(v->GetType());
843     }
844   }
845 
846   return success;
847 }
848 
849 // TODO: we should treat every backend all the same in future.
LanguageSpecificCheckValid(const AidlTypenames & typenames,Options::Language lang) const850 bool AidlTypeSpecifier::LanguageSpecificCheckValid(const AidlTypenames& typenames,
851                                                    Options::Language lang) const {
852   if (lang == Options::Language::NDK && IsArray() && GetName() == "IBinder") {
853     AIDL_ERROR(this) << "The NDK backend does not support array of IBinder";
854     return false;
855   }
856   if (lang == Options::Language::NDK && IsArray() && IsNullable()) {
857     if (GetName() == "ParcelFileDescriptor") {
858       AIDL_ERROR(this) << "The NDK backend does not support nullable array of ParcelFileDescriptor";
859       return false;
860     }
861 
862     const auto defined_type = typenames.TryGetDefinedType(GetName());
863     if (defined_type != nullptr && defined_type->AsParcelable() != nullptr) {
864       AIDL_ERROR(this) << "The NDK backend does not support nullable array of parcelable";
865       return false;
866     }
867   }
868   if (lang != Options::Language::JAVA) {
869     if (this->GetName() == "List" && !this->IsGeneric()) {
870       AIDL_ERROR(this) << "Currently, only the Java backend supports non-generic List.";
871       return false;
872     }
873   }
874   if (this->GetName() == "FileDescriptor" && lang == Options::Language::NDK) {
875     AIDL_ERROR(this) << "FileDescriptor isn't supported with the NDK.";
876     return false;
877   }
878   if (this->IsGeneric()) {
879     if (this->GetName() == "List") {
880       if (this->GetTypeParameters().size() != 1) {
881         AIDL_ERROR(this) << "List must have only one type parameter.";
882         return false;
883       }
884       if (lang == Options::Language::CPP) {
885         const string& contained_type = this->GetTypeParameters()[0]->GetName();
886         if (!(contained_type == "String" || contained_type == "IBinder")) {
887           AIDL_ERROR(this) << "List<" << contained_type
888                            << "> is not supported. List in cpp supports only String and IBinder.";
889           return false;
890         }
891       } else if (lang == Options::Language::JAVA) {
892         const string& contained_type = this->GetTypeParameters()[0]->GetName();
893         if (AidlTypenames::IsBuiltinTypename(contained_type)) {
894           if (contained_type != "String" && contained_type != "IBinder" &&
895               contained_type != "ParcelFileDescriptor") {
896             AIDL_ERROR(this) << "List<" << contained_type
897                              << "> is not supported. List in Java supports only String, IBinder, "
898                                 "and ParcelFileDescriptor.";
899             return false;
900           }
901         }
902       }
903     }
904   }
905   if (this->GetName() == "Map" || this->GetName() == "CharSequence") {
906     if (lang != Options::Language::JAVA) {
907       AIDL_ERROR(this) << "Currently, only Java backend supports " << this->GetName() << ".";
908       return false;
909     }
910   }
911   if (lang == Options::Language::JAVA) {
912     const string name = this->GetName();
913     // List[], Map[], CharSequence[] are not supported.
914     if (AidlTypenames::IsBuiltinTypename(name) && this->IsArray()) {
915       if (name == "List" || name == "Map" || name == "CharSequence") {
916         AIDL_ERROR(this) << "List[], Map[], CharSequence[] are not supported.";
917         return false;
918       }
919     }
920   }
921 
922   return true;
923 }
924 
925 // TODO: we should treat every backend all the same in future.
LanguageSpecificCheckValid(const AidlTypenames &,Options::Language lang) const926 bool AidlParcelable::LanguageSpecificCheckValid(const AidlTypenames& /*typenames*/,
927                                                 Options::Language lang) const {
928   if (lang != Options::Language::JAVA) {
929     const AidlParcelable* unstructured_parcelable = this->AsUnstructuredParcelable();
930     if (unstructured_parcelable != nullptr) {
931       if (unstructured_parcelable->GetCppHeader().empty()) {
932         AIDL_ERROR(unstructured_parcelable)
933             << "Unstructured parcelable must have C++ header defined.";
934         return false;
935       }
936     }
937   }
938   return true;
939 }
940 
941 // TODO: we should treat every backend all the same in future.
LanguageSpecificCheckValid(const AidlTypenames & typenames,Options::Language lang) const942 bool AidlStructuredParcelable::LanguageSpecificCheckValid(const AidlTypenames& typenames,
943                                                           Options::Language lang) const {
944   if (!AidlParcelable::LanguageSpecificCheckValid(typenames, lang)) {
945     return false;
946   }
947   for (const auto& v : this->GetFields()) {
948     if (!v->GetType().LanguageSpecificCheckValid(typenames, lang)) {
949       return false;
950     }
951   }
952   return true;
953 }
954 
AidlEnumerator(const AidlLocation & location,const std::string & name,AidlConstantValue * value,const std::string & comments)955 AidlEnumerator::AidlEnumerator(const AidlLocation& location, const std::string& name,
956                                AidlConstantValue* value, const std::string& comments)
957     : AidlNode(location), name_(name), value_(value), comments_(comments) {}
958 
CheckValid(const AidlTypeSpecifier & enum_backing_type) const959 bool AidlEnumerator::CheckValid(const AidlTypeSpecifier& enum_backing_type) const {
960   if (GetValue() == nullptr) {
961     return false;
962   }
963   if (!GetValue()->CheckValid()) {
964     return false;
965   }
966   if (GetValue()->ValueString(enum_backing_type, AidlConstantValueDecorator).empty()) {
967     AIDL_ERROR(this) << "Enumerator type differs from enum backing type.";
968     return false;
969   }
970   return true;
971 }
972 
ValueString(const AidlTypeSpecifier & backing_type,const ConstantValueDecorator & decorator) const973 string AidlEnumerator::ValueString(const AidlTypeSpecifier& backing_type,
974                                    const ConstantValueDecorator& decorator) const {
975   return GetValue()->ValueString(backing_type, decorator);
976 }
977 
AidlEnumDeclaration(const AidlLocation & location,const std::string & name,std::vector<std::unique_ptr<AidlEnumerator>> * enumerators,const std::string & package,const std::string & comments)978 AidlEnumDeclaration::AidlEnumDeclaration(const AidlLocation& location, const std::string& name,
979                                          std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
980                                          const std::string& package, const std::string& comments)
981     : AidlDefinedType(location, name, comments, package), enumerators_(std::move(*enumerators)) {}
982 
SetBackingType(std::unique_ptr<const AidlTypeSpecifier> type)983 void AidlEnumDeclaration::SetBackingType(std::unique_ptr<const AidlTypeSpecifier> type) {
984   backing_type_ = std::move(type);
985 }
986 
Autofill()987 bool AidlEnumDeclaration::Autofill() {
988   const AidlEnumerator* previous = nullptr;
989   for (const auto& enumerator : enumerators_) {
990     if (enumerator->GetValue() == nullptr) {
991       if (previous == nullptr) {
992         enumerator->SetValue(
993             std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "0")));
994       } else {
995         auto prev_value = std::unique_ptr<AidlConstantValue>(
996             AidlConstantValue::ShallowIntegralCopy(*previous->GetValue()));
997         if (prev_value == nullptr) {
998           return false;
999         }
1000         enumerator->SetValue(std::make_unique<AidlBinaryConstExpression>(
1001             GetLocation(), std::move(prev_value), "+",
1002             std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "1"))));
1003       }
1004     }
1005     previous = enumerator.get();
1006   }
1007   return true;
1008 }
1009 
GetSupportedAnnotations() const1010 std::set<AidlAnnotation::Type> AidlEnumDeclaration::GetSupportedAnnotations() const {
1011   return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::BACKING,
1012           AidlAnnotation::Type::HIDE, AidlAnnotation::Type::JAVA_PASSTHROUGH};
1013 }
1014 
CheckValid(const AidlTypenames & typenames) const1015 bool AidlEnumDeclaration::CheckValid(const AidlTypenames& typenames) const {
1016   if (!AidlDefinedType::CheckValid(typenames)) {
1017     return false;
1018   }
1019   if (backing_type_ == nullptr) {
1020     AIDL_ERROR(this) << "Enum declaration missing backing type.";
1021     return false;
1022   }
1023   bool success = true;
1024   for (const auto& enumerator : enumerators_) {
1025     success = success && enumerator->CheckValid(GetBackingType());
1026   }
1027   return success;
1028 }
1029 
Dump(CodeWriter * writer) const1030 void AidlEnumDeclaration::Dump(CodeWriter* writer) const {
1031   DumpHeader(writer);
1032   writer->Write("enum %s {\n", GetName().c_str());
1033   writer->Indent();
1034   for (const auto& enumerator : GetEnumerators()) {
1035     writer->Write("%s = %s,\n", enumerator->GetName().c_str(),
1036                   enumerator->ValueString(GetBackingType(), AidlConstantValueDecorator).c_str());
1037   }
1038   writer->Dedent();
1039   writer->Write("}\n");
1040 }
1041 
1042 // TODO: we should treat every backend all the same in future.
LanguageSpecificCheckValid(const AidlTypenames & typenames,Options::Language lang) const1043 bool AidlInterface::LanguageSpecificCheckValid(const AidlTypenames& typenames,
1044                                                Options::Language lang) const {
1045   for (const auto& m : this->GetMethods()) {
1046     if (!m->GetType().LanguageSpecificCheckValid(typenames, lang)) {
1047       return false;
1048     }
1049     for (const auto& arg : m->GetArguments()) {
1050       if (!arg->GetType().LanguageSpecificCheckValid(typenames, lang)) {
1051         return false;
1052       }
1053     }
1054   }
1055   return true;
1056 }
1057 
AidlInterface(const AidlLocation & location,const std::string & name,const std::string & comments,bool oneway,std::vector<std::unique_ptr<AidlMember>> * members,const std::string & package)1058 AidlInterface::AidlInterface(const AidlLocation& location, const std::string& name,
1059                              const std::string& comments, bool oneway,
1060                              std::vector<std::unique_ptr<AidlMember>>* members,
1061                              const std::string& package)
1062     : AidlDefinedType(location, name, comments, package) {
1063   for (auto& member : *members) {
1064     AidlMember* local = member.release();
1065     AidlMethod* method = local->AsMethod();
1066     AidlConstantDeclaration* constant = local->AsConstantDeclaration();
1067 
1068     CHECK(method == nullptr || constant == nullptr);
1069 
1070     if (method) {
1071       method->ApplyInterfaceOneway(oneway);
1072       methods_.emplace_back(method);
1073     } else if (constant) {
1074       constants_.emplace_back(constant);
1075     } else {
1076       AIDL_FATAL(this) << "Member is neither method nor constant!";
1077     }
1078   }
1079 
1080   delete members;
1081 }
1082 
Dump(CodeWriter * writer) const1083 void AidlInterface::Dump(CodeWriter* writer) const {
1084   DumpHeader(writer);
1085   writer->Write("interface %s {\n", GetName().c_str());
1086   writer->Indent();
1087   for (const auto& method : GetMethods()) {
1088     if (method->IsHidden()) {
1089       AddHideComment(writer);
1090     }
1091     writer->Write("%s;\n", method->ToString().c_str());
1092   }
1093   for (const auto& constdecl : GetConstantDeclarations()) {
1094     if (constdecl->GetType().IsHidden()) {
1095       AddHideComment(writer);
1096     }
1097     writer->Write("%s;\n", constdecl->ToString().c_str());
1098   }
1099   writer->Dedent();
1100   writer->Write("}\n");
1101 }
1102 
GetSupportedAnnotations() const1103 std::set<AidlAnnotation::Type> AidlInterface::GetSupportedAnnotations() const {
1104   return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
1105           AidlAnnotation::Type::HIDE, AidlAnnotation::Type::JAVA_PASSTHROUGH};
1106 }
1107 
CheckValid(const AidlTypenames & typenames) const1108 bool AidlInterface::CheckValid(const AidlTypenames& typenames) const {
1109   if (!AidlDefinedType::CheckValid(typenames)) {
1110     return false;
1111   }
1112   // Has to be a pointer due to deleting copy constructor. No idea why.
1113   map<string, const AidlMethod*> method_names;
1114   for (const auto& m : GetMethods()) {
1115     if (!m->GetType().CheckValid(typenames)) {
1116       return false;
1117     }
1118 
1119     // TODO(b/156872582): Support it when ParcelableHolder supports every backend.
1120     if (m->GetType().GetName() == "ParcelableHolder") {
1121       AIDL_ERROR(m) << "ParcelableHolder cannot be a return type";
1122       return false;
1123     }
1124     if (m->IsOneway() && m->GetType().GetName() != "void") {
1125       AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot return a value";
1126       return false;
1127     }
1128 
1129     set<string> argument_names;
1130     for (const auto& arg : m->GetArguments()) {
1131       auto it = argument_names.find(arg->GetName());
1132       if (it != argument_names.end()) {
1133         AIDL_ERROR(m) << "method '" << m->GetName() << "' has duplicate argument name '"
1134                       << arg->GetName() << "'";
1135         return false;
1136       }
1137       argument_names.insert(arg->GetName());
1138 
1139       if (!arg->GetType().CheckValid(typenames)) {
1140         return false;
1141       }
1142 
1143       // TODO(b/156872582): Support it when ParcelableHolder supports every backend.
1144       if (arg->GetType().GetName() == "ParcelableHolder") {
1145         AIDL_ERROR(arg) << "ParcelableHolder cannot be an argument type";
1146         return false;
1147       }
1148       if (m->IsOneway() && arg->IsOut()) {
1149         AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot have out parameters";
1150         return false;
1151       }
1152       const bool can_be_out = typenames.CanBeOutParameter(arg->GetType());
1153       if (!arg->DirectionWasSpecified() && can_be_out) {
1154         AIDL_ERROR(arg) << "'" << arg->GetType().ToString()
1155                         << "' can be an out type, so you must declare it as in, out, or inout.";
1156         return false;
1157       }
1158 
1159       if (arg->GetDirection() != AidlArgument::IN_DIR && !can_be_out) {
1160         AIDL_ERROR(arg) << "'" << arg->ToString() << "' can only be an in parameter.";
1161         return false;
1162       }
1163 
1164       // check that the name doesn't match a keyword
1165       if (IsJavaKeyword(arg->GetName().c_str())) {
1166         AIDL_ERROR(arg) << "Argument name is a Java or aidl keyword";
1167         return false;
1168       }
1169 
1170       // Reserve a namespace for internal use
1171       if (android::base::StartsWith(arg->GetName(), "_aidl")) {
1172         AIDL_ERROR(arg) << "Argument name cannot begin with '_aidl'";
1173         return false;
1174       }
1175     }
1176 
1177     auto it = method_names.find(m->GetName());
1178     // prevent duplicate methods
1179     if (it == method_names.end()) {
1180       method_names[m->GetName()] = m.get();
1181     } else {
1182       AIDL_ERROR(m) << "attempt to redefine method " << m->GetName() << ":";
1183       AIDL_ERROR(it->second) << "previously defined here.";
1184       return false;
1185     }
1186 
1187     static set<string> reserved_methods{"asBinder()", "getInterfaceHash()", "getInterfaceVersion()",
1188                                         "getTransactionName(int)"};
1189 
1190     if (reserved_methods.find(m->Signature()) != reserved_methods.end()) {
1191       AIDL_ERROR(m) << " method " << m->Signature() << " is reserved for internal use.";
1192       return false;
1193     }
1194   }
1195 
1196   bool success = true;
1197   set<string> constant_names;
1198   for (const std::unique_ptr<AidlConstantDeclaration>& constant : GetConstantDeclarations()) {
1199     if (constant_names.count(constant->GetName()) > 0) {
1200       AIDL_ERROR(constant) << "Found duplicate constant name '" << constant->GetName() << "'";
1201       success = false;
1202     }
1203     constant_names.insert(constant->GetName());
1204     success = success && constant->CheckValid(typenames);
1205   }
1206 
1207   return success;
1208 }
1209 
AidlImport(const AidlLocation & location,const std::string & needed_class)1210 AidlImport::AidlImport(const AidlLocation& location, const std::string& needed_class)
1211     : AidlNode(location), needed_class_(needed_class) {}
1212