• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "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 
25 #include <algorithm>
26 #include <iostream>
27 #include <set>
28 #include <sstream>
29 #include <string>
30 #include <utility>
31 
32 #include <android-base/parsedouble.h>
33 #include <android-base/parseint.h>
34 #include <android-base/result.h>
35 #include <android-base/strings.h>
36 
37 #include "aidl.h"
38 #include "aidl_language_y.h"
39 #include "comments.h"
40 #include "logging.h"
41 #include "permission.h"
42 
43 #ifdef _WIN32
isatty(int fd)44 int isatty(int  fd)
45 {
46     return (fd == 0);
47 }
48 #endif
49 
50 using android::aidl::IoDelegate;
51 using android::base::Error;
52 using android::base::Join;
53 using android::base::Result;
54 using android::base::Split;
55 using std::cerr;
56 using std::pair;
57 using std::set;
58 using std::string;
59 using std::unique_ptr;
60 using std::vector;
61 
62 namespace {
IsJavaKeyword(const char * str)63 bool IsJavaKeyword(const char* str) {
64   static const std::vector<std::string> kJavaKeywords{
65       "abstract", "assert", "boolean",    "break",     "byte",       "case",      "catch",
66       "char",     "class",  "const",      "continue",  "default",    "do",        "double",
67       "else",     "enum",   "extends",    "final",     "finally",    "float",     "for",
68       "goto",     "if",     "implements", "import",    "instanceof", "int",       "interface",
69       "long",     "native", "new",        "package",   "private",    "protected", "public",
70       "return",   "short",  "static",     "strictfp",  "super",      "switch",    "synchronized",
71       "this",     "throw",  "throws",     "transient", "try",        "void",      "volatile",
72       "while",    "true",   "false",      "null",
73   };
74   return std::find(kJavaKeywords.begin(), kJavaKeywords.end(), str) != kJavaKeywords.end();
75 }
76 }  // namespace
77 
~AidlNode()78 AidlNode::~AidlNode() {
79   if (!visited_) {
80     unvisited_locations_.push_back(location_);
81   }
82 }
83 
ClearUnvisitedNodes()84 void AidlNode::ClearUnvisitedNodes() {
85   unvisited_locations_.clear();
86 }
87 
GetLocationsOfUnvisitedNodes()88 const std::vector<AidlLocation>& AidlNode::GetLocationsOfUnvisitedNodes() {
89   return unvisited_locations_;
90 }
91 
MarkVisited() const92 void AidlNode::MarkVisited() const {
93   visited_ = true;
94 }
95 
AidlNode(const AidlLocation & location,const Comments & comments)96 AidlNode::AidlNode(const AidlLocation& location, const Comments& comments)
97     : location_(location), comments_(comments) {}
98 
PrintLine() const99 std::string AidlNode::PrintLine() const {
100   std::stringstream ss;
101   ss << location_.file_ << ":" << location_.begin_.line;
102   return ss.str();
103 }
104 
PrintLocation() const105 std::string AidlNode::PrintLocation() const {
106   std::stringstream ss;
107   ss << location_.file_ << ":" << location_.begin_.line << ":" << location_.begin_.column << ":"
108      << location_.end_.line << ":" << location_.end_.column;
109   return ss.str();
110 }
111 
112 std::vector<AidlLocation> AidlNode::unvisited_locations_;
113 
114 static const AidlTypeSpecifier kStringType{AIDL_LOCATION_HERE, "String", /*array=*/std::nullopt,
115                                            nullptr, Comments{}};
116 static const AidlTypeSpecifier kStringArrayType{AIDL_LOCATION_HERE, "String", DynamicArray{},
117                                                 nullptr, Comments{}};
118 static const AidlTypeSpecifier kIntType{AIDL_LOCATION_HERE, "int", /*array=*/std::nullopt, nullptr,
119                                         Comments{}};
120 static const AidlTypeSpecifier kLongType{AIDL_LOCATION_HERE, "long", /*array=*/std::nullopt,
121                                          nullptr, Comments{}};
122 static const AidlTypeSpecifier kBooleanType{AIDL_LOCATION_HERE, "boolean", /*array=*/std::nullopt,
123                                             nullptr, Comments{}};
124 
AllSchemas()125 const std::vector<AidlAnnotation::Schema>& AidlAnnotation::AllSchemas() {
126   static const std::vector<Schema> kSchemas{
127       {AidlAnnotation::Type::NULLABLE,
128        "nullable",
129        CONTEXT_TYPE_SPECIFIER,
130        {{"heap", kBooleanType}}},
131       {AidlAnnotation::Type::UTF8_IN_CPP, "utf8InCpp", CONTEXT_TYPE_SPECIFIER, {}},
132       {AidlAnnotation::Type::SENSITIVE_DATA, "SensitiveData", CONTEXT_TYPE_INTERFACE, {}},
133       {AidlAnnotation::Type::VINTF_STABILITY, "VintfStability", CONTEXT_TYPE, {}},
134       {AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
135        "UnsupportedAppUsage",
136        CONTEXT_TYPE | CONTEXT_MEMBER,
137        {{"expectedSignature", kStringType},
138         {"implicitMember", kStringType},
139         {"maxTargetSdk", kIntType},
140         {"publicAlternatives", kStringType},
141         {"trackingBug", kLongType}}},
142       {AidlAnnotation::Type::JAVA_STABLE_PARCELABLE,
143        "JavaOnlyStableParcelable",
144        CONTEXT_TYPE_UNSTRUCTURED_PARCELABLE,
145        {}},
146       {AidlAnnotation::Type::BACKING,
147        "Backing",
148        CONTEXT_TYPE_ENUM,
149        {{"type", kStringType, /* required= */ true}}},
150       {AidlAnnotation::Type::JAVA_PASSTHROUGH,
151        "JavaPassthrough",
152        CONTEXT_ALL,
153        {{"annotation", kStringType, /* required= */ true}},
154        /* repeatable= */ true},
155       {AidlAnnotation::Type::JAVA_DERIVE,
156        "JavaDerive",
157        CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION | CONTEXT_TYPE_ENUM,
158        {{"toString", kBooleanType}, {"equals", kBooleanType}}},
159       {AidlAnnotation::Type::JAVA_DEFAULT, "JavaDefault", CONTEXT_TYPE_INTERFACE, {}},
160       {AidlAnnotation::Type::JAVA_DELEGATOR, "JavaDelegator", CONTEXT_TYPE_INTERFACE, {}},
161       {AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE,
162        "JavaOnlyImmutable",
163        CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION |
164            CONTEXT_TYPE_UNSTRUCTURED_PARCELABLE,
165        {}},
166       {AidlAnnotation::Type::JAVA_SUPPRESS_LINT,
167        "JavaSuppressLint",
168        CONTEXT_ALL,
169        {{"value", kStringArrayType, /* required= */ true}}},
170       {AidlAnnotation::Type::FIXED_SIZE,
171        "FixedSize",
172        CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION,
173        {}},
174       {AidlAnnotation::Type::DESCRIPTOR,
175        "Descriptor",
176        CONTEXT_TYPE_INTERFACE,
177        {{"value", kStringType, /* required= */ true}}},
178       {AidlAnnotation::Type::RUST_DERIVE,
179        "RustDerive",
180        CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION,
181        {{"Copy", kBooleanType},
182         {"Clone", kBooleanType},
183         {"PartialOrd", kBooleanType},
184         {"Ord", kBooleanType},
185         {"PartialEq", kBooleanType},
186         {"Eq", kBooleanType},
187         {"Hash", kBooleanType}}},
188       {AidlAnnotation::Type::SUPPRESS_WARNINGS,
189        "SuppressWarnings",
190        CONTEXT_TYPE | CONTEXT_MEMBER,
191        {{"value", kStringArrayType, /* required= */ true}}},
192       {AidlAnnotation::Type::PERMISSION_ENFORCE,
193        "EnforcePermission",
194        CONTEXT_TYPE_INTERFACE | CONTEXT_METHOD,
195        {{"value", kStringType}, {"anyOf", kStringArrayType}, {"allOf", kStringArrayType}}},
196       {AidlAnnotation::Type::PERMISSION_MANUAL,
197        "PermissionManuallyEnforced",
198        CONTEXT_TYPE_INTERFACE | CONTEXT_METHOD,
199        {}},
200       {AidlAnnotation::Type::PERMISSION_NONE,
201        "RequiresNoPermission",
202        CONTEXT_TYPE_INTERFACE | CONTEXT_METHOD,
203        {}},
204       {AidlAnnotation::Type::PROPAGATE_ALLOW_BLOCKING,
205        "PropagateAllowBlocking",
206        CONTEXT_METHOD,
207        {}},
208   };
209   return kSchemas;
210 }
211 
TypeToString(Type type)212 std::string AidlAnnotation::TypeToString(Type type) {
213   for (const Schema& schema : AllSchemas()) {
214     if (type == schema.type) return schema.name;
215   }
216   AIDL_FATAL(AIDL_LOCATION_HERE) << "Unrecognized type: " << static_cast<size_t>(type);
217   __builtin_unreachable();
218 }
219 
Parse(const AidlLocation & location,const string & name,std::map<std::string,std::shared_ptr<AidlConstantValue>> parameter_list,const Comments & comments)220 std::unique_ptr<AidlAnnotation> AidlAnnotation::Parse(
221     const AidlLocation& location, const string& name,
222     std::map<std::string, std::shared_ptr<AidlConstantValue>> parameter_list,
223     const Comments& comments) {
224   const Schema* schema = nullptr;
225   for (const Schema& a_schema : AllSchemas()) {
226     if (a_schema.name == name) {
227       schema = &a_schema;
228     }
229   }
230 
231   if (schema == nullptr) {
232     std::ostringstream stream;
233     stream << "'" << name << "' is not a recognized annotation. ";
234     stream << "It must be one of:";
235     for (const Schema& s : AllSchemas()) {
236       stream << " " << s.name;
237     }
238     stream << ".";
239     AIDL_ERROR(location) << stream.str();
240     return {};
241   }
242 
243   return std::unique_ptr<AidlAnnotation>(
244       new AidlAnnotation(location, *schema, std::move(parameter_list), comments));
245 }
246 
AidlAnnotation(const AidlLocation & location,const Schema & schema,std::map<std::string,std::shared_ptr<AidlConstantValue>> parameters,const Comments & comments)247 AidlAnnotation::AidlAnnotation(const AidlLocation& location, const Schema& schema,
248                                std::map<std::string, std::shared_ptr<AidlConstantValue>> parameters,
249                                const Comments& comments)
250     : AidlNode(location, comments), schema_(schema), parameters_(std::move(parameters)) {}
251 
252 struct ConstReferenceFinder : AidlVisitor {
253   const AidlConstantReference* found;
VisitConstReferenceFinder254   void Visit(const AidlConstantReference& ref) override {
255     if (!found) found = &ref;
256   }
FindConstReferenceFinder257   static const AidlConstantReference* Find(const AidlConstantValue& c) {
258     ConstReferenceFinder finder;
259     VisitTopDown(finder, c);
260     return finder.found;
261   }
262 };
263 
264 // Checks if annotation complies with the schema
265 // - every parameter is known and has well-typed value.
266 // - every required parameter is present.
CheckValid() const267 bool AidlAnnotation::CheckValid() const {
268   for (const auto& name_and_param : parameters_) {
269     const std::string& param_name = name_and_param.first;
270     const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
271 
272     const ParamType* param_type = schema_.ParamType(param_name);
273     if (!param_type) {
274       std::ostringstream stream;
275       stream << "Parameter " << param_name << " not supported ";
276       stream << "for annotation " << GetName() << ". ";
277       stream << "It must be one of:";
278       for (const auto& param : schema_.parameters) {
279         stream << " " << param.name;
280       }
281       AIDL_ERROR(this) << stream.str();
282       return false;
283     }
284 
285     const auto& found = ConstReferenceFinder::Find(*param);
286     if (found) {
287       AIDL_ERROR(found) << "Value must be a constant expression but contains reference to "
288                         << found->GetFieldName() << ".";
289       return false;
290     }
291 
292     if (!param->CheckValid()) {
293       AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
294                        << GetName() << ".";
295       return false;
296     }
297 
298     const std::string param_value =
299         param->ValueString(param_type->type, AidlConstantValueDecorator);
300     // Assume error on empty string.
301     if (param_value == "") {
302       AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
303                        << GetName() << ".";
304       return false;
305     }
306   }
307   bool success = true;
308   for (const auto& param : schema_.parameters) {
309     if (param.required && parameters_.count(param.name) == 0) {
310       AIDL_ERROR(this) << "Missing '" << param.name << "' on @" << GetName() << ".";
311       success = false;
312     }
313   }
314   if (!success) {
315     return false;
316   }
317   // For @Enforce annotations, validates the expression.
318   if (schema_.type == AidlAnnotation::Type::PERMISSION_ENFORCE) {
319     auto expr = EnforceExpression();
320     if (!expr.ok()) {
321       AIDL_ERROR(this) << "Unable to parse @EnforcePermission annotation: " << expr.error();
322       return false;
323     }
324   }
325   return true;
326 }
327 
EnforceExpression() const328 Result<unique_ptr<android::aidl::perm::Expression>> AidlAnnotation::EnforceExpression() const {
329   auto single = ParamValue<std::string>("value");
330   auto anyOf = ParamValue<std::vector<std::string>>("anyOf");
331   auto allOf = ParamValue<std::vector<std::string>>("allOf");
332   if (single.has_value()) {
333     return std::make_unique<android::aidl::perm::Expression>(single.value());
334   } else if (anyOf.has_value()) {
335     auto v = android::aidl::perm::AnyOf{anyOf.value()};
336     return std::make_unique<android::aidl::perm::Expression>(v);
337   } else if (allOf.has_value()) {
338     auto v = android::aidl::perm::AllOf{allOf.value()};
339     return std::make_unique<android::aidl::perm::Expression>(v);
340   }
341   return Error() << "No parameter for @EnforcePermission";
342 }
343 
344 // Checks if the annotation is applicable to the current context.
345 // For example, annotations like @VintfStability, @FixedSize is not applicable to AidlTypeSpecifier
346 // nodes.
CheckContext(TargetContext context) const347 bool AidlAnnotation::CheckContext(TargetContext context) const {
348   if (schema_.target_context & static_cast<uint32_t>(context)) {
349     return true;
350   }
351   const static map<TargetContext, string> context_name_map{
352       {CONTEXT_TYPE_INTERFACE, "interface"},
353       {CONTEXT_TYPE_ENUM, "enum"},
354       {CONTEXT_TYPE_STRUCTURED_PARCELABLE, "structured parcelable"},
355       {CONTEXT_TYPE_UNION, "union"},
356       {CONTEXT_TYPE_UNSTRUCTURED_PARCELABLE, "parcelable"},
357       {CONTEXT_CONST, "constant"},
358       {CONTEXT_FIELD, "field"},
359       {CONTEXT_METHOD, "method"},
360       {CONTEXT_TYPE_SPECIFIER, "type"},
361   };
362   vector<string> available;
363   for (const auto& [context, name] : context_name_map) {
364     if (schema_.target_context & context) {
365       available.push_back(name);
366     }
367   }
368   AIDL_ERROR(this) << "@" << GetName() << " is not available. It can annotate {"
369                    << Join(available, ", ") << "}.";
370   return false;
371 }
372 
AnnotationParams(const ConstantValueDecorator & decorator) const373 std::map<std::string, std::string> AidlAnnotation::AnnotationParams(
374     const ConstantValueDecorator& decorator) const {
375   std::map<std::string, std::string> raw_params;
376   for (const auto& name_and_param : parameters_) {
377     const std::string& param_name = name_and_param.first;
378     const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
379     const ParamType* param_type = schema_.ParamType(param_name);
380     AIDL_FATAL_IF(!param_type, this);
381     raw_params.emplace(param_name, param->ValueString(param_type->type, decorator));
382   }
383   return raw_params;
384 }
385 
ToString() const386 std::string AidlAnnotation::ToString() const {
387   if (parameters_.empty()) {
388     return "@" + GetName();
389   } else {
390     vector<string> param_strings;
391     for (const auto& [name, value] : AnnotationParams(AidlConstantValueDecorator)) {
392       param_strings.emplace_back(name + "=" + value);
393     }
394     return "@" + GetName() + "(" + Join(param_strings, ", ") + ")";
395   }
396 }
397 
TraverseChildren(std::function<void (const AidlNode &)> traverse) const398 void AidlAnnotation::TraverseChildren(std::function<void(const AidlNode&)> traverse) const {
399   for (const auto& [name, value] : parameters_) {
400     (void)name;
401     traverse(*value);
402   }
403 }
404 
GetAnnotation(const vector<std::unique_ptr<AidlAnnotation>> & annotations,AidlAnnotation::Type type)405 static const AidlAnnotation* GetAnnotation(
406     const vector<std::unique_ptr<AidlAnnotation>>& annotations, AidlAnnotation::Type type) {
407   for (const auto& a : annotations) {
408     if (a->GetType() == type) {
409       AIDL_FATAL_IF(a->Repeatable(), a)
410           << "Trying to get a single annotation when it is repeatable.";
411       return a.get();
412     }
413   }
414   return nullptr;
415 }
416 
GetScopedAnnotation(const AidlDefinedType & defined_type,AidlAnnotation::Type type)417 static const AidlAnnotation* GetScopedAnnotation(const AidlDefinedType& defined_type,
418                                                  AidlAnnotation::Type type) {
419   const AidlAnnotation* annotation = GetAnnotation(defined_type.GetAnnotations(), type);
420   if (annotation) {
421     return annotation;
422   }
423   const AidlDefinedType* enclosing_type = defined_type.GetParentType();
424   if (enclosing_type) {
425     return GetScopedAnnotation(*enclosing_type, type);
426   }
427   return nullptr;
428 }
429 
AidlAnnotatable(const AidlLocation & location,const Comments & comments)430 AidlAnnotatable::AidlAnnotatable(const AidlLocation& location, const Comments& comments)
431     : AidlCommentable(location, comments) {}
432 
IsNullable() const433 bool AidlAnnotatable::IsNullable() const {
434   return GetAnnotation(annotations_, AidlAnnotation::Type::NULLABLE);
435 }
436 
IsHeapNullable() const437 bool AidlAnnotatable::IsHeapNullable() const {
438   auto annot = GetAnnotation(annotations_, AidlAnnotation::Type::NULLABLE);
439   if (annot) {
440     return annot->ParamValue<bool>("heap").value_or(false);
441   }
442   return false;
443 }
444 
IsUtf8InCpp() const445 bool AidlAnnotatable::IsUtf8InCpp() const {
446   return GetAnnotation(annotations_, AidlAnnotation::Type::UTF8_IN_CPP);
447 }
448 
IsSensitiveData() const449 bool AidlAnnotatable::IsSensitiveData() const {
450   return GetAnnotation(annotations_, AidlAnnotation::Type::SENSITIVE_DATA);
451 }
452 
IsVintfStability() const453 bool AidlAnnotatable::IsVintfStability() const {
454   auto defined_type = AidlCast<AidlDefinedType>(*this);
455   AIDL_FATAL_IF(!defined_type, *this) << "@VintfStability is not attached to a type";
456   return GetScopedAnnotation(*defined_type, AidlAnnotation::Type::VINTF_STABILITY);
457 }
458 
IsJavaOnlyImmutable() const459 bool AidlAnnotatable::IsJavaOnlyImmutable() const {
460   return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE);
461 }
462 
IsFixedSize() const463 bool AidlAnnotatable::IsFixedSize() const {
464   return GetAnnotation(annotations_, AidlAnnotation::Type::FIXED_SIZE);
465 }
466 
UnsupportedAppUsage() const467 const AidlAnnotation* AidlAnnotatable::UnsupportedAppUsage() const {
468   return GetAnnotation(annotations_, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE);
469 }
470 
RustDerive() const471 const AidlAnnotation* AidlAnnotatable::RustDerive() const {
472   return GetAnnotation(annotations_, AidlAnnotation::Type::RUST_DERIVE);
473 }
474 
BackingType() const475 const AidlAnnotation* AidlAnnotatable::BackingType() const {
476   return GetAnnotation(annotations_, AidlAnnotation::Type::BACKING);
477 }
478 
SuppressWarnings() const479 std::vector<std::string> AidlAnnotatable::SuppressWarnings() const {
480   auto annot = GetAnnotation(annotations_, AidlAnnotation::Type::SUPPRESS_WARNINGS);
481   if (annot) {
482     auto names = annot->ParamValue<std::vector<std::string>>("value");
483     AIDL_FATAL_IF(!names.has_value(), this);
484     return std::move(names.value());
485   }
486   return {};
487 }
488 
489 // Parses the @Enforce annotation expression.
EnforceExpression() const490 std::unique_ptr<android::aidl::perm::Expression> AidlAnnotatable::EnforceExpression() const {
491   auto annot = GetAnnotation(annotations_, AidlAnnotation::Type::PERMISSION_ENFORCE);
492   if (annot) {
493     auto perm_expr = annot->EnforceExpression();
494     if (!perm_expr.ok()) {
495       // This should have been caught during validation.
496       AIDL_FATAL(this) << "Unable to parse @EnforcePermission annotation: " << perm_expr.error();
497     }
498     return std::move(perm_expr.value());
499   }
500   return {};
501 }
502 
IsPermissionManual() const503 bool AidlAnnotatable::IsPermissionManual() const {
504   return GetAnnotation(annotations_, AidlAnnotation::Type::PERMISSION_MANUAL);
505 }
506 
IsPermissionNone() const507 bool AidlAnnotatable::IsPermissionNone() const {
508   return GetAnnotation(annotations_, AidlAnnotation::Type::PERMISSION_NONE);
509 }
510 
IsPropagateAllowBlocking() const511 bool AidlAnnotatable::IsPropagateAllowBlocking() const {
512   return GetAnnotation(annotations_, AidlAnnotation::Type::PROPAGATE_ALLOW_BLOCKING);
513 }
514 
IsStableApiParcelable(Options::Language lang) const515 bool AidlAnnotatable::IsStableApiParcelable(Options::Language lang) const {
516   return lang == Options::Language::JAVA &&
517          GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_STABLE_PARCELABLE);
518 }
519 
JavaDerive(const std::string & method) const520 bool AidlAnnotatable::JavaDerive(const std::string& method) const {
521   auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_DERIVE);
522   if (annotation != nullptr) {
523     return annotation->ParamValue<bool>(method).value_or(false);
524   }
525   return false;
526 }
527 
IsJavaDefault() const528 bool AidlAnnotatable::IsJavaDefault() const {
529   return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_DEFAULT);
530 }
531 
IsJavaDelegator() const532 bool AidlAnnotatable::IsJavaDelegator() const {
533   return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_DELEGATOR);
534 }
535 
GetDescriptor() const536 std::string AidlAnnotatable::GetDescriptor() const {
537   auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::DESCRIPTOR);
538   if (annotation != nullptr) {
539     return annotation->ParamValue<std::string>("value").value();
540   }
541   return "";
542 }
543 
CheckValid(const AidlTypenames &) const544 bool AidlAnnotatable::CheckValid(const AidlTypenames&) const {
545   for (const auto& annotation : GetAnnotations()) {
546     if (!annotation->CheckValid()) {
547       return false;
548     }
549   }
550 
551   std::map<AidlAnnotation::Type, AidlLocation> declared;
552   for (const auto& annotation : GetAnnotations()) {
553     const auto& [iter, inserted] =
554         declared.emplace(annotation->GetType(), annotation->GetLocation());
555     if (!inserted && !annotation->Repeatable()) {
556       AIDL_ERROR(this) << "'" << annotation->GetName()
557                        << "' is repeated, but not allowed. Previous location: " << iter->second;
558       return false;
559     }
560   }
561 
562   return true;
563 }
564 
ToString() const565 string AidlAnnotatable::ToString() const {
566   vector<string> ret;
567   for (const auto& a : annotations_) {
568     ret.emplace_back(a->ToString());
569   }
570   std::sort(ret.begin(), ret.end());
571   return Join(ret, " ");
572 }
573 
AidlTypeSpecifier(const AidlLocation & location,const string & unresolved_name,std::optional<ArrayType> array,vector<unique_ptr<AidlTypeSpecifier>> * type_params,const Comments & comments)574 AidlTypeSpecifier::AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name,
575                                      std::optional<ArrayType> array,
576                                      vector<unique_ptr<AidlTypeSpecifier>>* type_params,
577                                      const Comments& comments)
578     : AidlAnnotatable(location, comments),
579       AidlParameterizable<unique_ptr<AidlTypeSpecifier>>(type_params),
580       unresolved_name_(unresolved_name),
581       array_(std::move(array)),
582       split_name_(Split(unresolved_name, ".")) {}
583 
ViewAsArrayBase(std::function<void (const AidlTypeSpecifier &)> func) const584 void AidlTypeSpecifier::ViewAsArrayBase(std::function<void(const AidlTypeSpecifier&)> func) const {
585   AIDL_FATAL_IF(!array_.has_value(), this);
586   // Declaring array of generic type cannot happen, it is grammar error.
587   AIDL_FATAL_IF(IsGeneric(), this);
588 
589   bool is_mutated = mutated_;
590   mutated_ = true;
591   // mutate the array type to its base by removing a single dimension
592   // e.g.) T[] => T, T[N][M] => T[M] (note that, M is removed)
593   if (IsFixedSizeArray() && std::get<FixedSizeArray>(*array_).dimensions.size() > 1) {
594     auto& dimensions = std::get<FixedSizeArray>(*array_).dimensions;
595     auto dim = std::move(dimensions.front());
596     dimensions.erase(dimensions.begin());
597     func(*this);
598     dimensions.insert(dimensions.begin(), std::move(dim));
599   } else {
600     ArrayType array_type = std::move(array_.value());
601     array_ = std::nullopt;
602     func(*this);
603     array_ = std::move(array_type);
604   }
605   mutated_ = is_mutated;
606 }
607 
MakeArray(ArrayType array_type)608 bool AidlTypeSpecifier::MakeArray(ArrayType array_type) {
609   // T becomes T[] or T[N]
610   if (!IsArray()) {
611     array_ = std::move(array_type);
612     return true;
613   }
614   // T[N] becomes T[N][M]
615   if (auto fixed_size_array = std::get_if<FixedSizeArray>(&array_type);
616       fixed_size_array != nullptr && IsFixedSizeArray()) {
617     // concat dimensions
618     for (auto& dim : fixed_size_array->dimensions) {
619       std::get<FixedSizeArray>(*array_).dimensions.push_back(std::move(dim));
620     }
621     return true;
622   }
623   return false;
624 }
625 
GetFixedSizeArrayDimensions() const626 std::vector<int32_t> AidlTypeSpecifier::GetFixedSizeArrayDimensions() const {
627   AIDL_FATAL_IF(!IsFixedSizeArray(), "not a fixed-size array");
628   std::vector<int32_t> dimensions;
629   for (const auto& dim : std::get<FixedSizeArray>(GetArray()).dimensions) {
630     dimensions.push_back(dim->EvaluatedValue<int32_t>());
631   }
632   return dimensions;
633 }
634 
Signature() const635 string AidlTypeSpecifier::Signature() const {
636   string ret = GetName();
637   if (IsGeneric()) {
638     vector<string> arg_names;
639     for (const auto& ta : GetTypeParameters()) {
640       arg_names.emplace_back(ta->Signature());
641     }
642     ret += "<" + Join(arg_names, ",") + ">";
643   }
644   if (IsArray()) {
645     if (IsFixedSizeArray()) {
646       for (const auto& dim : GetFixedSizeArrayDimensions()) {
647         ret += "[" + std::to_string(dim) + "]";
648       }
649     } else {
650       ret += "[]";
651     }
652   }
653   return ret;
654 }
655 
ToString() const656 string AidlTypeSpecifier::ToString() const {
657   string ret = Signature();
658   string annotations = AidlAnnotatable::ToString();
659   if (annotations != "") {
660     ret = annotations + " " + ret;
661   }
662   return ret;
663 }
664 
665 // When `scope` is specified, name is resolved first based on it.
666 // `scope` can be null for built-in types and fully-qualified types.
Resolve(const AidlTypenames & typenames,const AidlScope * scope)667 bool AidlTypeSpecifier::Resolve(const AidlTypenames& typenames, const AidlScope* scope) {
668   AIDL_FATAL_IF(IsResolved(), this);
669   std::string name = unresolved_name_;
670   if (scope) {
671     name = scope->ResolveName(name);
672   }
673   AidlTypenames::ResolvedTypename result = typenames.ResolveTypename(name);
674   if (result.is_resolved) {
675     fully_qualified_name_ = result.canonical_name;
676     split_name_ = Split(fully_qualified_name_, ".");
677     defined_type_ = result.defined_type;
678   }
679   return result.is_resolved;
680 }
681 
GetDefinedType() const682 const AidlDefinedType* AidlTypeSpecifier::GetDefinedType() const {
683   return defined_type_;
684 }
685 
CheckValid(const AidlTypenames & typenames) const686 bool AidlTypeSpecifier::CheckValid(const AidlTypenames& typenames) const {
687   if (!AidlAnnotatable::CheckValid(typenames)) {
688     return false;
689   }
690   if (IsGeneric()) {
691     const auto& types = GetTypeParameters();
692     for (const auto& arg : types) {
693       if (!arg->CheckValid(typenames)) {
694         return false;
695       }
696     }
697 
698     const string& type_name = GetName();
699     // TODO(b/136048684) Disallow to use primitive types only if it is List or Map.
700     if (type_name == "List" || type_name == "Map") {
701       if (std::any_of(types.begin(), types.end(), [&](auto& type_ptr) {
702             return !type_ptr->IsArray() &&
703                    (typenames.GetEnumDeclaration(*type_ptr) ||
704                     AidlTypenames::IsPrimitiveTypename(type_ptr->GetName()));
705           })) {
706         AIDL_ERROR(this) << "A generic type cannot have any primitive type parameters.";
707         return false;
708       }
709     }
710     const auto defined_type = typenames.TryGetDefinedType(type_name);
711     const auto parameterizable =
712         defined_type != nullptr ? defined_type->AsParameterizable() : nullptr;
713     const bool is_user_defined_generic_type =
714         parameterizable != nullptr && parameterizable->IsGeneric();
715     const size_t num_params = GetTypeParameters().size();
716     if (type_name == "List") {
717       if (num_params > 1) {
718         AIDL_ERROR(this) << "List can only have one type parameter, but got: '" << Signature()
719                          << "'";
720         return false;
721       }
722       static const char* kListUsage =
723           "List<T> supports interface/parcelable/union, String, IBinder, and ParcelFileDescriptor.";
724       const AidlTypeSpecifier& contained_type = *GetTypeParameters()[0];
725       if (contained_type.IsArray()) {
726         AIDL_ERROR(this) << "List of arrays is not supported. " << kListUsage;
727         return false;
728       }
729       const string& contained_type_name = contained_type.GetName();
730       if (AidlTypenames::IsBuiltinTypename(contained_type_name)) {
731         if (contained_type_name != "String" && contained_type_name != "IBinder" &&
732             contained_type_name != "ParcelFileDescriptor") {
733           AIDL_ERROR(this) << "List<" << contained_type_name << "> is not supported. "
734                            << kListUsage;
735           return false;
736         }
737       }
738     } else if (type_name == "Map") {
739       if (num_params != 0 && num_params != 2) {
740         AIDL_ERROR(this) << "Map must have 0 or 2 type parameters, but got "
741                          << "'" << Signature() << "'";
742         return false;
743       }
744       if (num_params == 2) {
745         const string& key_type = GetTypeParameters()[0]->Signature();
746         if (key_type != "String") {
747           AIDL_ERROR(this) << "The type of key in map must be String, but it is "
748                            << "'" << key_type << "'";
749           return false;
750         }
751       }
752     } else if (is_user_defined_generic_type) {
753       const size_t allowed = parameterizable->GetTypeParameters().size();
754       if (num_params != allowed) {
755         AIDL_ERROR(this) << type_name << " must have " << allowed << " type parameters, but got "
756                          << num_params;
757         return false;
758       }
759     } else {
760       AIDL_ERROR(this) << type_name << " is not a generic type.";
761       return false;
762     }
763   }
764 
765   const bool is_generic_string_list = GetName() == "List" && IsGeneric() &&
766                                       GetTypeParameters().size() == 1 &&
767                                       GetTypeParameters()[0]->GetName() == "String";
768   if (IsUtf8InCpp() && (GetName() != "String" && !is_generic_string_list)) {
769     AIDL_ERROR(this) << "@utf8InCpp can only be used on String, String[], and List<String>.";
770     return false;
771   }
772 
773   if (GetName() == "void") {
774     if (IsArray() || IsNullable() || IsUtf8InCpp()) {
775       AIDL_ERROR(this) << "void type cannot be an array or nullable or utf8 string";
776       return false;
777     }
778   }
779 
780   if (IsArray()) {
781     if (GetName() == "ParcelableHolder" || GetName() == "List" || GetName() == "Map" ||
782         GetName() == "CharSequence") {
783       AIDL_ERROR(this) << "Arrays of " << GetName() << " are not supported.";
784       return false;
785     }
786   }
787 
788   if (IsNullable()) {
789     if (AidlTypenames::IsPrimitiveTypename(GetName()) && !IsArray()) {
790       AIDL_ERROR(this) << "Primitive type cannot get nullable annotation";
791       return false;
792     }
793     const auto defined_type = typenames.TryGetDefinedType(GetName());
794     if (defined_type != nullptr && defined_type->AsEnumDeclaration() != nullptr && !IsArray()) {
795       AIDL_ERROR(this) << "Enum type cannot get nullable annotation";
796       return false;
797     }
798     if (GetName() == "ParcelableHolder") {
799       AIDL_ERROR(this) << "ParcelableHolder cannot be nullable.";
800       return false;
801     }
802     if (IsHeapNullable()) {
803       if (!defined_type || IsArray() || !defined_type->AsParcelable()) {
804         AIDL_ERROR(this) << "@nullable(heap=true) is available to parcelables.";
805         return false;
806       }
807     }
808   }
809 
810   if (IsFixedSizeArray()) {
811     for (const auto& dim : std::get<FixedSizeArray>(GetArray()).dimensions) {
812       if (!dim->Evaluate()) {
813         return false;
814       }
815       if (dim->GetType() > AidlConstantValue::Type::INT32) {
816         AIDL_ERROR(this) << "Array size must be a positive number: " << dim->Literal();
817         return false;
818       }
819       auto value = dim->EvaluatedValue<int32_t>();
820       if (value < 0) {
821         AIDL_ERROR(this) << "Array size must be a positive number: " << value;
822         return false;
823       }
824     }
825   }
826   return true;
827 }
828 
TraverseChildren(std::function<void (const AidlNode &)> traverse) const829 void AidlTypeSpecifier::TraverseChildren(std::function<void(const AidlNode&)> traverse) const {
830   AidlAnnotatable::TraverseChildren(traverse);
831   if (IsGeneric()) {
832     for (const auto& tp : GetTypeParameters()) {
833       traverse(*tp);
834     }
835   }
836   if (IsFixedSizeArray()) {
837     for (const auto& dim : std::get<FixedSizeArray>(GetArray()).dimensions) {
838       traverse(*dim);
839     }
840   }
841 }
842 
AidlConstantValueDecorator(const AidlTypeSpecifier & type,const std::variant<std::string,std::vector<std::string>> & raw_value)843 std::string AidlConstantValueDecorator(
844     const AidlTypeSpecifier& type,
845     const std::variant<std::string, std::vector<std::string>>& raw_value) {
846   if (type.IsArray()) {
847     const auto& values = std::get<std::vector<std::string>>(raw_value);
848     return "{" + Join(values, ", ") + "}";
849   }
850   const std::string& value = std::get<std::string>(raw_value);
851   if (auto defined_type = type.GetDefinedType(); defined_type) {
852     auto enum_type = defined_type->AsEnumDeclaration();
853     AIDL_FATAL_IF(!enum_type, type) << "Invalid type for \"" << value << "\"";
854     return type.GetName() + "." + value.substr(value.find_last_of('.') + 1);
855   }
856   return value;
857 }
858 
AidlVariableDeclaration(const AidlLocation & location,AidlTypeSpecifier * type,const std::string & name)859 AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
860                                                  AidlTypeSpecifier* type, const std::string& name)
861     : AidlVariableDeclaration(location, type, name, AidlConstantValue::Default(*type)) {
862   default_user_specified_ = false;
863 }
864 
AidlVariableDeclaration(const AidlLocation & location,AidlTypeSpecifier * type,const std::string & name,AidlConstantValue * default_value)865 AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
866                                                  AidlTypeSpecifier* type, const std::string& name,
867                                                  AidlConstantValue* default_value)
868     : AidlMember(location, type->GetComments()),
869       type_(type),
870       name_(name),
871       default_user_specified_(true),
872       default_value_(default_value) {}
873 
HasUsefulDefaultValue() const874 bool AidlVariableDeclaration::HasUsefulDefaultValue() const {
875   if (GetDefaultValue()) {
876     return true;
877   }
878   // null is accepted as a valid default value in all backends
879   if (GetType().IsNullable()) {
880     return true;
881   }
882   return false;
883 }
884 
CheckValid(const AidlTypenames & typenames) const885 bool AidlVariableDeclaration::CheckValid(const AidlTypenames& typenames) const {
886   bool valid = true;
887   valid &= type_->CheckValid(typenames);
888 
889   if (type_->GetName() == "void") {
890     AIDL_ERROR(this) << "Declaration " << name_
891                      << " is void, but declarations cannot be of void type.";
892     valid = false;
893   }
894 
895   if (default_value_ == nullptr) return valid;
896   valid &= default_value_->CheckValid();
897 
898   if (!valid) return false;
899 
900   return !ValueString(AidlConstantValueDecorator).empty();
901 }
902 
GetCapitalizedName() const903 string AidlVariableDeclaration::GetCapitalizedName() const {
904   AIDL_FATAL_IF(name_.size() <= 0, *this) << "Name can't be empty.";
905   string str = name_;
906   str[0] = static_cast<char>(toupper(str[0]));
907   return str;
908 }
909 
ToString() const910 string AidlVariableDeclaration::ToString() const {
911   string ret = type_->ToString() + " " + name_;
912   if (default_value_ != nullptr && default_user_specified_) {
913     ret += " = " + ValueString(AidlConstantValueDecorator);
914   }
915   return ret;
916 }
917 
Signature() const918 string AidlVariableDeclaration::Signature() const {
919   return type_->Signature() + " " + name_;
920 }
921 
ValueString(const ConstantValueDecorator & decorator) const922 std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
923   if (default_value_ != nullptr) {
924     return default_value_->ValueString(GetType(), decorator);
925   } else {
926     return "";
927   }
928 }
929 
TraverseChildren(std::function<void (const AidlNode &)> traverse) const930 void AidlVariableDeclaration::TraverseChildren(
931     std::function<void(const AidlNode&)> traverse) const {
932   traverse(GetType());
933   if (auto default_value = GetDefaultValue(); default_value) {
934     traverse(*default_value);
935   }
936 }
937 
AidlArgument(const AidlLocation & location,AidlArgument::Direction direction,AidlTypeSpecifier * type,const std::string & name)938 AidlArgument::AidlArgument(const AidlLocation& location, AidlArgument::Direction direction,
939                            AidlTypeSpecifier* type, const std::string& name)
940     : AidlVariableDeclaration(location, type, name),
941       direction_(direction),
942       direction_specified_(true) {}
943 
AidlArgument(const AidlLocation & location,AidlTypeSpecifier * type,const std::string & name)944 AidlArgument::AidlArgument(const AidlLocation& location, AidlTypeSpecifier* type,
945                            const std::string& name)
946     : AidlVariableDeclaration(location, type, name),
947       direction_(AidlArgument::IN_DIR),
948       direction_specified_(false) {}
949 
to_string(AidlArgument::Direction direction)950 static std::string to_string(AidlArgument::Direction direction) {
951   switch (direction) {
952     case AidlArgument::IN_DIR:
953       return "in";
954     case AidlArgument::OUT_DIR:
955       return "out";
956     case AidlArgument::INOUT_DIR:
957       return "inout";
958   }
959 }
960 
GetDirectionSpecifier() const961 string AidlArgument::GetDirectionSpecifier() const {
962   string ret;
963   if (direction_specified_) {
964     ret = to_string(direction_);
965   }
966   return ret;
967 }
968 
ToString() const969 string AidlArgument::ToString() const {
970   if (direction_specified_) {
971     return GetDirectionSpecifier() + " " + AidlVariableDeclaration::ToString();
972   } else {
973     return AidlVariableDeclaration::ToString();
974   }
975 }
976 
FormatDirections(const std::set<AidlArgument::Direction> & directions)977 static std::string FormatDirections(const std::set<AidlArgument::Direction>& directions) {
978   std::vector<std::string> out;
979   for (const auto& d : directions) {
980     out.push_back(to_string(d));
981   }
982 
983   if (out.size() <= 1) {  // [] => "" or [A] => "A"
984     return Join(out, "");
985   } else if (out.size() == 2) {  // [A,B] => "A or B"
986     return Join(out, " or ");
987   } else {  // [A,B,C] => "A, B, or C"
988     out.back() = "or " + out.back();
989     return Join(out, ", ");
990   }
991 }
992 
CheckValid(const AidlTypenames & typenames) const993 bool AidlArgument::CheckValid(const AidlTypenames& typenames) const {
994   if (!GetType().CheckValid(typenames)) {
995     return false;
996   }
997 
998   const auto& aspect = typenames.GetArgumentAspect(GetType());
999 
1000   if (aspect.possible_directions.size() == 0) {
1001     AIDL_ERROR(this) << aspect.name << " cannot be an argument type";
1002     return false;
1003   }
1004 
1005   // when direction is not specified, "in" is assumed and should be the only possible direction
1006   if (!DirectionWasSpecified() && aspect.possible_directions != std::set{AidlArgument::IN_DIR}) {
1007     AIDL_ERROR(this) << "The direction of '" << GetName() << "' is not specified. " << aspect.name
1008                      << " can be an " << FormatDirections(aspect.possible_directions)
1009                      << " parameter.";
1010     return false;
1011   }
1012 
1013   if (aspect.possible_directions.count(GetDirection()) == 0) {
1014     AIDL_ERROR(this) << "'" << GetName() << "' can't be an " << GetDirectionSpecifier()
1015                      << " parameter because " << aspect.name << " can only be an "
1016                      << FormatDirections(aspect.possible_directions) << " parameter.";
1017     return false;
1018   }
1019 
1020   return true;
1021 }
1022 
IsHidden() const1023 bool AidlCommentable::IsHidden() const {
1024   return android::aidl::HasHideInComments(GetComments());
1025 }
1026 
IsDeprecated() const1027 bool AidlCommentable::IsDeprecated() const {
1028   return android::aidl::FindDeprecated(GetComments()).has_value();
1029 }
1030 
AidlMember(const AidlLocation & location,const Comments & comments)1031 AidlMember::AidlMember(const AidlLocation& location, const Comments& comments)
1032     : AidlAnnotatable(location, comments) {}
1033 
AidlConstantDeclaration(const AidlLocation & location,AidlTypeSpecifier * type,const std::string & name,AidlConstantValue * value)1034 AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
1035                                                  AidlTypeSpecifier* type, const std::string& name,
1036                                                  AidlConstantValue* value)
1037     : AidlMember(location, type->GetComments()), type_(type), name_(name), value_(value) {}
1038 
CheckValid(const AidlTypenames & typenames) const1039 bool AidlConstantDeclaration::CheckValid(const AidlTypenames& typenames) const {
1040   bool valid = true;
1041   valid &= type_->CheckValid(typenames);
1042   valid &= value_->CheckValid();
1043   if (!valid) return false;
1044 
1045   const static set<string> kSupportedConstTypes = {"String", "byte", "int", "long"};
1046   if (kSupportedConstTypes.find(type_->Signature()) == kSupportedConstTypes.end()) {
1047     AIDL_ERROR(this) << "Constant of type " << type_->Signature() << " is not supported.";
1048     return false;
1049   }
1050 
1051   return true;
1052 }
1053 
ToString() const1054 string AidlConstantDeclaration::ToString() const {
1055   return "const " + type_->ToString() + " " + name_ + " = " +
1056          ValueString(AidlConstantValueDecorator);
1057 }
1058 
Signature() const1059 string AidlConstantDeclaration::Signature() const {
1060   return type_->Signature() + " " + name_;
1061 }
1062 
AidlMethod(const AidlLocation & location,bool oneway,AidlTypeSpecifier * type,const std::string & name,std::vector<std::unique_ptr<AidlArgument>> * args,const Comments & comments)1063 AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
1064                        const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
1065                        const Comments& comments)
1066     : AidlMethod(location, oneway, type, name, args, comments, 0) {
1067   has_id_ = false;
1068 }
1069 
AidlMethod(const AidlLocation & location,bool oneway,AidlTypeSpecifier * type,const std::string & name,std::vector<std::unique_ptr<AidlArgument>> * args,const Comments & comments,int id)1070 AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
1071                        const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
1072                        const Comments& comments, int id)
1073     : AidlMember(location, comments),
1074       oneway_(oneway),
1075       type_(type),
1076       name_(name),
1077       arguments_(std::move(*args)),
1078       id_(id) {
1079   has_id_ = true;
1080   delete args;
1081   for (const unique_ptr<AidlArgument>& a : arguments_) {
1082     if (a->IsIn()) { in_arguments_.push_back(a.get()); }
1083     if (a->IsOut()) { out_arguments_.push_back(a.get()); }
1084   }
1085 }
1086 
Signature() const1087 string AidlMethod::Signature() const {
1088   vector<string> arg_signatures;
1089   for (const auto& arg : GetArguments()) {
1090     arg_signatures.emplace_back(arg->GetType().Signature());
1091   }
1092   return GetName() + "(" + Join(arg_signatures, ", ") + ")";
1093 }
1094 
ToString() const1095 string AidlMethod::ToString() const {
1096   vector<string> arg_strings;
1097   for (const auto& arg : GetArguments()) {
1098     arg_strings.emplace_back(arg->ToString());
1099   }
1100   string ret = (IsOneway() ? "oneway " : "") + GetType().ToString() + " " + GetName() + "(" +
1101                Join(arg_strings, ", ") + ")";
1102   if (HasId()) {
1103     ret += " = " + std::to_string(GetId());
1104   }
1105   return ret;
1106 }
1107 
CheckValid(const AidlTypenames & typenames) const1108 bool AidlMethod::CheckValid(const AidlTypenames& typenames) const {
1109   if (!GetType().CheckValid(typenames)) {
1110     return false;
1111   }
1112 
1113   // TODO(b/156872582): Support it when ParcelableHolder supports every backend.
1114   if (GetType().GetName() == "ParcelableHolder") {
1115     AIDL_ERROR(this) << "ParcelableHolder cannot be a return type";
1116     return false;
1117   }
1118   if (IsOneway() && GetType().GetName() != "void") {
1119     AIDL_ERROR(this) << "oneway method '" << GetName() << "' cannot return a value";
1120     return false;
1121   }
1122 
1123   set<string> argument_names;
1124   for (const auto& arg : GetArguments()) {
1125     auto it = argument_names.find(arg->GetName());
1126     if (it != argument_names.end()) {
1127       AIDL_ERROR(this) << "method '" << GetName() << "' has duplicate argument name '"
1128                        << arg->GetName() << "'";
1129       return false;
1130     }
1131     argument_names.insert(arg->GetName());
1132 
1133     if (!arg->CheckValid(typenames)) {
1134       return false;
1135     }
1136 
1137     if (IsOneway() && arg->IsOut()) {
1138       AIDL_ERROR(this) << "oneway method '" << this->GetName() << "' cannot have out parameters";
1139       return false;
1140     }
1141 
1142     // check that the name doesn't match a keyword
1143     if (IsJavaKeyword(arg->GetName().c_str())) {
1144       AIDL_ERROR(arg) << "Argument name is a Java or aidl keyword";
1145       return false;
1146     }
1147 
1148     // Reserve a namespace for internal use
1149     if (android::base::StartsWith(arg->GetName(), "_aidl")) {
1150       AIDL_ERROR(arg) << "Argument name cannot begin with '_aidl'";
1151       return false;
1152     }
1153 
1154     if (arg->GetType().GetName() == "void") {
1155       AIDL_ERROR(arg->GetType()) << "'void' is an invalid type for the parameter '"
1156                                  << arg->GetName() << "'";
1157       return false;
1158     }
1159   }
1160   return true;
1161 }
1162 
AidlDefinedType(const AidlLocation & location,const std::string & name,const Comments & comments,const std::string & package,std::vector<std::unique_ptr<AidlMember>> * members)1163 AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
1164                                  const Comments& comments, const std::string& package,
1165                                  std::vector<std::unique_ptr<AidlMember>>* members)
1166     : AidlMember(location, comments), AidlScope(this), name_(name), package_(package) {
1167   // adjust name/package when name is fully qualified (for preprocessed files)
1168   if (package_.empty() && name_.find('.') != std::string::npos) {
1169     // Note that this logic is absolutely wrong.  Given a parcelable
1170     // org.some.Foo.Bar, the class name is Foo.Bar, but this code will claim that
1171     // the class is just Bar.  However, this was the way it was done in the past.
1172     //
1173     // See b/17415692
1174     auto pos = name.rfind('.');
1175     // name is the last part.
1176     name_ = name.substr(pos + 1);
1177     // package is the initial parts (except the last).
1178     package_ = name.substr(0, pos);
1179   }
1180   if (members) {
1181     for (auto& m : *members) {
1182       if (auto constant = AidlCast<AidlConstantDeclaration>(*m); constant) {
1183         constants_.emplace_back(constant);
1184       } else if (auto variable = AidlCast<AidlVariableDeclaration>(*m); variable) {
1185         variables_.emplace_back(variable);
1186       } else if (auto method = AidlCast<AidlMethod>(*m); method) {
1187         methods_.emplace_back(method);
1188       } else if (auto type = AidlCast<AidlDefinedType>(*m); type) {
1189         type->SetEnclosingScope(this);
1190         types_.emplace_back(type);
1191       } else {
1192         AIDL_FATAL(*m) << "Unknown member type.";
1193       }
1194       members_.push_back(m.release());
1195     }
1196     delete members;
1197   }
1198 }
1199 
CheckValid(const AidlTypenames & typenames) const1200 bool AidlDefinedType::CheckValid(const AidlTypenames& typenames) const {
1201   if (!AidlAnnotatable::CheckValid(typenames)) {
1202     return false;
1203   }
1204   if (!CheckValidWithMembers(typenames)) {
1205     return false;
1206   }
1207   return true;
1208 }
1209 
GetCanonicalName() const1210 std::string AidlDefinedType::GetCanonicalName() const {
1211   if (auto parent = GetParentType(); parent) {
1212     return parent->GetCanonicalName() + "." + GetName();
1213   }
1214   if (package_.empty()) {
1215     return GetName();
1216   }
1217   return GetPackage() + "." + GetName();
1218 }
1219 
CheckValidWithMembers(const AidlTypenames & typenames) const1220 bool AidlDefinedType::CheckValidWithMembers(const AidlTypenames& typenames) const {
1221   bool success = true;
1222 
1223   for (const auto& t : GetNestedTypes()) {
1224     success = success && t->CheckValid(typenames);
1225   }
1226 
1227   if (auto parameterizable = AsParameterizable();
1228       parameterizable && parameterizable->IsGeneric() && !GetNestedTypes().empty()) {
1229     AIDL_ERROR(this) << "Generic types can't have nested types.";
1230     return false;
1231   }
1232 
1233   std::set<std::string> nested_type_names;
1234   for (const auto& t : GetNestedTypes()) {
1235     bool duplicated = !nested_type_names.emplace(t->GetName()).second;
1236     if (duplicated) {
1237       AIDL_ERROR(t) << "Redefinition of '" << t->GetName() << "'.";
1238       success = false;
1239     }
1240     // nested type can't have a parent name
1241     if (t->GetName() == GetName()) {
1242       AIDL_ERROR(t) << "Nested type '" << GetName() << "' has the same name as its parent.";
1243       success = false;
1244     }
1245     // Having unstructured parcelables as nested types doesn't make sense because they are defined
1246     // somewhere else in native languages (e.g. C++, Java...).
1247     if (AidlCast<AidlParcelable>(*t)) {
1248       AIDL_ERROR(t) << "'" << t->GetName()
1249                     << "' is nested. Unstructured parcelables should be at the root scope.";
1250       return false;
1251     }
1252   }
1253 
1254   if (!TopologicalVisit(GetNestedTypes(), [](auto&) {})) {
1255     AIDL_ERROR(this) << GetName()
1256                      << " has nested types with cyclic references. C++ and NDK backends don't "
1257                         "support cyclic references.";
1258     return false;
1259   }
1260 
1261   for (const auto& v : GetFields()) {
1262     const bool field_valid = v->CheckValid(typenames);
1263     success = success && field_valid;
1264   }
1265 
1266   // field names should be unique
1267   std::set<std::string> fieldnames;
1268   for (const auto& v : GetFields()) {
1269     bool duplicated = !fieldnames.emplace(v->GetName()).second;
1270     if (duplicated) {
1271       AIDL_ERROR(v) << "'" << GetName() << "' has duplicate field name '" << v->GetName() << "'";
1272       success = false;
1273     }
1274   }
1275 
1276   // immutable parcelables should have immutable fields.
1277   if (IsJavaOnlyImmutable()) {
1278     for (const auto& v : GetFields()) {
1279       if (!typenames.CanBeJavaOnlyImmutable(v->GetType())) {
1280         AIDL_ERROR(v) << "The @JavaOnlyImmutable '" << GetName() << "' has a "
1281                       << "non-immutable field named '" << v->GetName() << "'.";
1282         success = false;
1283       }
1284     }
1285   }
1286 
1287   set<string> constant_names;
1288   for (const auto& constant : GetConstantDeclarations()) {
1289     if (constant_names.count(constant->GetName()) > 0) {
1290       AIDL_ERROR(constant) << "Found duplicate constant name '" << constant->GetName() << "'";
1291       success = false;
1292     }
1293     constant_names.insert(constant->GetName());
1294     success = success && constant->CheckValid(typenames);
1295   }
1296 
1297   return success;
1298 }
1299 
CheckValidForGetterNames() const1300 bool AidlDefinedType::CheckValidForGetterNames() const {
1301   bool success = true;
1302   std::set<std::string> getters;
1303   for (const auto& v : GetFields()) {
1304     bool duplicated = !getters.emplace(v->GetCapitalizedName()).second;
1305     if (duplicated) {
1306       AIDL_ERROR(v) << "'" << GetName() << "' has duplicate field name '" << v->GetName()
1307                     << "' after capitalizing the first letter";
1308       success = false;
1309     }
1310   }
1311   return success;
1312 }
1313 
GetParentType() const1314 const AidlDefinedType* AidlDefinedType::GetParentType() const {
1315   AIDL_FATAL_IF(GetEnclosingScope() == nullptr, this) << "Scope is not set.";
1316   return AidlCast<AidlDefinedType>(GetEnclosingScope()->GetNode());
1317 }
1318 
GetRootType() const1319 const AidlDefinedType* AidlDefinedType::GetRootType() const {
1320   const AidlDefinedType* root = this;
1321   for (auto parent = root->GetParentType(); parent; parent = parent->GetParentType()) {
1322     root = parent;
1323   }
1324   return root;
1325 }
1326 
1327 // Resolve `name` in the current scope. If not found, delegate to the parent
ResolveName(const std::string & name) const1328 std::string AidlDefinedType::ResolveName(const std::string& name) const {
1329   // For example, in the following, t1's type Baz means x.Foo.Bar.Baz
1330   // while t2's type is y.Baz.
1331   // package x;
1332   // import y.Baz;
1333   // parcelable Foo {
1334   //   parcelable Bar {
1335   //     enum Baz { ... }
1336   //     Baz t1; // -> should be x.Foo.Bar.Baz
1337   //   }
1338   //   Baz t2; // -> should be y.Baz
1339   //   Bar.Baz t3; // -> should be x.Foo.Bar.Baz
1340   // }
1341   AIDL_FATAL_IF(!GetEnclosingScope(), this)
1342       << "Type should have an enclosing scope.(e.g. AidlDocument)";
1343   if (AidlTypenames::IsBuiltinTypename(name)) {
1344     return name;
1345   }
1346 
1347   const auto first_dot = name.find_first_of('.');
1348   // For "Outer.Inner", we look up "Outer" in the import list.
1349   const std::string class_name =
1350       (first_dot == std::string::npos) ? name : name.substr(0, first_dot);
1351   // Keep ".Inner", to make a fully-qualified name
1352   const std::string nested_type = (first_dot == std::string::npos) ? "" : name.substr(first_dot);
1353 
1354   // check if it is a nested type
1355   for (const auto& type : GetNestedTypes()) {
1356     if (type->GetName() == class_name) {
1357       return type->GetCanonicalName() + nested_type;
1358     }
1359   }
1360 
1361   return GetEnclosingScope()->ResolveName(name);
1362 }
1363 
1364 template <>
AidlCast(const AidlNode & node)1365 const AidlDefinedType* AidlCast<AidlDefinedType>(const AidlNode& node) {
1366   struct Visitor : AidlVisitor {
1367     const AidlDefinedType* defined_type = nullptr;
1368     void Visit(const AidlInterface& t) override { defined_type = &t; }
1369     void Visit(const AidlEnumDeclaration& t) override { defined_type = &t; }
1370     void Visit(const AidlStructuredParcelable& t) override { defined_type = &t; }
1371     void Visit(const AidlUnionDecl& t) override { defined_type = &t; }
1372     void Visit(const AidlParcelable& t) override { defined_type = &t; }
1373   } v;
1374   node.DispatchVisit(v);
1375   return v.defined_type;
1376 }
1377 
GetDocument() const1378 const AidlDocument& AidlDefinedType::GetDocument() const {
1379   const AidlDefinedType* root = GetRootType();
1380   auto scope = root->GetEnclosingScope();
1381   AIDL_FATAL_IF(!scope, this) << "no scope defined.";
1382   auto doc = AidlCast<AidlDocument>(scope->GetNode());
1383   AIDL_FATAL_IF(!doc, this) << "root scope is not a document.";
1384   return *doc;
1385 }
1386 
AidlParcelable(const AidlLocation & location,const std::string & name,const std::string & package,const Comments & comments,const std::string & cpp_header,std::vector<std::string> * type_params,std::vector<std::unique_ptr<AidlMember>> * members)1387 AidlParcelable::AidlParcelable(const AidlLocation& location, const std::string& name,
1388                                const std::string& package, const Comments& comments,
1389                                const std::string& cpp_header, std::vector<std::string>* type_params,
1390                                std::vector<std::unique_ptr<AidlMember>>* members)
1391     : AidlDefinedType(location, name, comments, package, members),
1392       AidlParameterizable<std::string>(type_params),
1393       cpp_header_(cpp_header) {
1394   // Strip off quotation marks if we actually have a cpp header.
1395   if (cpp_header_.length() >= 2) {
1396     cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
1397   }
1398 }
1399 
1400 template <typename T>
CheckValid() const1401 bool AidlParameterizable<T>::CheckValid() const {
1402   return true;
1403 };
1404 
1405 template <>
CheckValid() const1406 bool AidlParameterizable<std::string>::CheckValid() const {
1407   if (!IsGeneric()) {
1408     return true;
1409   }
1410   std::unordered_set<std::string> set(GetTypeParameters().begin(), GetTypeParameters().end());
1411   if (set.size() != GetTypeParameters().size()) {
1412     AIDL_ERROR(this->AsAidlNode()) << "Every type parameter should be unique.";
1413     return false;
1414   }
1415   return true;
1416 }
1417 
CheckValid(const AidlTypenames & typenames) const1418 bool AidlParcelable::CheckValid(const AidlTypenames& typenames) const {
1419   if (!AidlDefinedType::CheckValid(typenames)) {
1420     return false;
1421   }
1422   if (!AidlParameterizable<std::string>::CheckValid()) {
1423     return false;
1424   }
1425 
1426   bool success = true;
1427   if (IsFixedSize()) {
1428     for (const auto& v : GetFields()) {
1429       if (!typenames.CanBeFixedSize(v->GetType())) {
1430         AIDL_ERROR(v) << "The @FixedSize parcelable '" << this->GetName() << "' has a "
1431                       << "non-fixed size field named " << v->GetName() << ".";
1432         success = false;
1433       }
1434     }
1435   }
1436 
1437   return success;
1438 }
1439 
AidlStructuredParcelable(const AidlLocation & location,const std::string & name,const std::string & package,const Comments & comments,std::vector<std::string> * type_params,std::vector<std::unique_ptr<AidlMember>> * members)1440 AidlStructuredParcelable::AidlStructuredParcelable(
1441     const AidlLocation& location, const std::string& name, const std::string& package,
1442     const Comments& comments, std::vector<std::string>* type_params,
1443     std::vector<std::unique_ptr<AidlMember>>* members)
1444     : AidlParcelable(location, name, package, comments, "" /*cpp_header*/, type_params, members) {}
1445 
CheckValid(const AidlTypenames & typenames) const1446 bool AidlStructuredParcelable::CheckValid(const AidlTypenames& typenames) const {
1447   if (!AidlParcelable::CheckValid(typenames)) {
1448     return false;
1449   }
1450 
1451   bool success = true;
1452 
1453   if (IsJavaOnlyImmutable()) {
1454     // Immutable parcelables provide getters
1455     if (!CheckValidForGetterNames()) {
1456       success = false;
1457     }
1458   }
1459 
1460   return success;
1461 }
1462 
1463 // TODO: we should treat every backend all the same in future.
LanguageSpecificCheckValid(Options::Language lang) const1464 bool AidlTypeSpecifier::LanguageSpecificCheckValid(Options::Language lang) const {
1465   if (this->GetName() == "FileDescriptor" &&
1466       (lang == Options::Language::NDK || lang == Options::Language::RUST)) {
1467     AIDL_ERROR(this) << "FileDescriptor isn't supported by the " << to_string(lang) << " backend.";
1468     return false;
1469   }
1470 
1471   if (lang != Options::Language::JAVA) {
1472     if (this->GetName() == "List" && !this->IsGeneric()) {
1473       AIDL_ERROR(this) << "Currently, only the Java backend supports non-generic List.";
1474       return false;
1475     }
1476     if (this->GetName() == "Map" || this->GetName() == "CharSequence") {
1477       AIDL_ERROR(this) << "Currently, only Java backend supports " << this->GetName() << ".";
1478       return false;
1479     }
1480   }
1481 
1482   return true;
1483 }
1484 
1485 // TODO: we should treat every backend all the same in future.
LanguageSpecificCheckValid(Options::Language lang) const1486 bool AidlDefinedType::LanguageSpecificCheckValid(Options::Language lang) const {
1487   struct Visitor : AidlVisitor {
1488     Visitor(Options::Language lang) : lang(lang) {}
1489     void Visit(const AidlTypeSpecifier& type) override {
1490       success = success && type.LanguageSpecificCheckValid(lang);
1491     }
1492     Options::Language lang;
1493     bool success = true;
1494   } v(lang);
1495   VisitTopDown(v, *this);
1496   return v.success;
1497 }
1498 
AidlEnumerator(const AidlLocation & location,const std::string & name,AidlConstantValue * value,const Comments & comments)1499 AidlEnumerator::AidlEnumerator(const AidlLocation& location, const std::string& name,
1500                                AidlConstantValue* value, const Comments& comments)
1501     : AidlCommentable(location, comments),
1502       name_(name),
1503       value_(value),
1504       value_user_specified_(value != nullptr) {}
1505 
CheckValid(const AidlTypeSpecifier & enum_backing_type) const1506 bool AidlEnumerator::CheckValid(const AidlTypeSpecifier& enum_backing_type) const {
1507   if (GetValue() == nullptr) {
1508     return false;
1509   }
1510   if (!GetValue()->CheckValid()) {
1511     return false;
1512   }
1513   if (GetValue()->ValueString(enum_backing_type, AidlConstantValueDecorator).empty()) {
1514     AIDL_ERROR(this) << "Enumerator type differs from enum backing type.";
1515     return false;
1516   }
1517   return true;
1518 }
1519 
ValueString(const AidlTypeSpecifier & backing_type,const ConstantValueDecorator & decorator) const1520 string AidlEnumerator::ValueString(const AidlTypeSpecifier& backing_type,
1521                                    const ConstantValueDecorator& decorator) const {
1522   return GetValue()->ValueString(backing_type, decorator);
1523 }
1524 
AidlEnumDeclaration(const AidlLocation & location,const std::string & name,std::vector<std::unique_ptr<AidlEnumerator>> * enumerators,const std::string & package,const Comments & comments)1525 AidlEnumDeclaration::AidlEnumDeclaration(const AidlLocation& location, const std::string& name,
1526                                          std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
1527                                          const std::string& package, const Comments& comments)
1528     : AidlDefinedType(location, name, comments, package, nullptr),
1529       enumerators_(std::move(*enumerators)) {
1530   // Fill missing enumerator values with <prev + 1>
1531   // This can't be done in Autofill() because type/ref resolution depends on this.
1532   // For example, with enum E { A, B = A }, B's value 'A' is a reference which can't be
1533   // resolved if A has no value set.
1534   const AidlEnumerator* previous = nullptr;
1535   for (const auto& enumerator : enumerators_) {
1536     if (enumerator->GetValue() == nullptr) {
1537       auto loc = enumerator->GetLocation();
1538       if (previous == nullptr) {
1539         enumerator->SetValue(
1540             std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(loc, "0")));
1541       } else {
1542         auto prev_value = std::make_unique<AidlConstantReference>(loc, previous->GetName());
1543         enumerator->SetValue(std::make_unique<AidlBinaryConstExpression>(
1544             loc, std::move(prev_value), "+",
1545             std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(loc, "1"))));
1546       }
1547     }
1548     previous = enumerator.get();
1549   }
1550 }
1551 
Autofill(const AidlTypenames & typenames)1552 bool AidlEnumDeclaration::Autofill(const AidlTypenames& typenames) {
1553   if (auto annot = BackingType(); annot != nullptr) {
1554     // Autofill() is called before the grand CheckValid(). But AidlAnnotation::ParamValue()
1555     // calls AidlConstantValue::evaluate() which requires CheckValid() to be called before. So we
1556     // need to call CheckValid().
1557     if (!annot->CheckValid()) {
1558       return false;
1559     }
1560     auto type = annot->ParamValue<std::string>("type").value();
1561     backing_type_ = typenames.MakeResolvedType(annot->GetLocation(), type, false);
1562   } else {
1563     // Default to byte type for enums.
1564     backing_type_ = typenames.MakeResolvedType(GetLocation(), "byte", false);
1565   }
1566 
1567   // we only support/test a few backing types, so make sure this is a supported
1568   // one (otherwise boolean might work, which isn't supported/tested in all
1569   // backends)
1570   static std::set<string> kBackingTypes = {"byte", "int", "long"};
1571   if (kBackingTypes.find(backing_type_->GetName()) == kBackingTypes.end()) {
1572     AIDL_ERROR(this) << "Invalid backing type: " << backing_type_->GetName()
1573                      << ". Backing type must be one of: " << Join(kBackingTypes, ", ");
1574     return false;
1575   }
1576   return true;
1577 }
1578 
CheckValid(const AidlTypenames & typenames) const1579 bool AidlEnumDeclaration::CheckValid(const AidlTypenames& typenames) const {
1580   if (!AidlDefinedType::CheckValid(typenames)) {
1581     return false;
1582   }
1583   if (!GetMembers().empty()) {
1584     AIDL_ERROR(this) << "Enum doesn't support fields/constants/methods.";
1585     return false;
1586   }
1587   if (backing_type_ == nullptr) {
1588     AIDL_ERROR(this) << "Enum declaration missing backing type.";
1589     return false;
1590   }
1591   bool success = true;
1592   for (const auto& enumerator : enumerators_) {
1593     success = success && enumerator->CheckValid(GetBackingType());
1594   }
1595 
1596   return success;
1597 }
1598 
AidlUnionDecl(const AidlLocation & location,const std::string & name,const std::string & package,const Comments & comments,std::vector<std::string> * type_params,std::vector<std::unique_ptr<AidlMember>> * members)1599 AidlUnionDecl::AidlUnionDecl(const AidlLocation& location, const std::string& name,
1600                              const std::string& package, const Comments& comments,
1601                              std::vector<std::string>* type_params,
1602                              std::vector<std::unique_ptr<AidlMember>>* members)
1603     : AidlParcelable(location, name, package, comments, "" /*cpp_header*/, type_params, members) {}
1604 
CheckValid(const AidlTypenames & typenames) const1605 bool AidlUnionDecl::CheckValid(const AidlTypenames& typenames) const {
1606   // visit parents
1607   if (!AidlParcelable::CheckValid(typenames)) {
1608     return false;
1609   }
1610 
1611   // unions provide getters always
1612   if (!CheckValidForGetterNames()) {
1613     return false;
1614   }
1615 
1616   // now, visit self!
1617   bool success = true;
1618 
1619   // TODO(b/170807936) do we need to allow ParcelableHolder in union?
1620   for (const auto& v : GetFields()) {
1621     if (v->GetType().GetName() == "ParcelableHolder") {
1622       AIDL_ERROR(*v) << "A union can't have a member of ParcelableHolder '" << v->GetName() << "'";
1623       success = false;
1624     }
1625   }
1626 
1627   if (GetFields().empty()) {
1628     AIDL_ERROR(*this) << "The union '" << this->GetName() << "' has no fields.";
1629     return false;
1630   }
1631 
1632   // first member should have useful default value (implicit or explicit)
1633   const auto& first = GetFields()[0];
1634   if (!first->HasUsefulDefaultValue()) {
1635     // Most types can be initialized without a default value. For example,
1636     // interface types are inherently nullable. But, enum types should have
1637     // an explicit default value.
1638     if (!first->GetType().IsArray() && typenames.GetEnumDeclaration(first->GetType())) {
1639       AIDL_ERROR(first)
1640           << "The union's first member should have a useful default value. Enum types can be "
1641              "initialized with a reference. (e.g. ... = MyEnum.FOO;)";
1642       return false;
1643     }
1644     // In Java, array types are initialized as null without a default value. To be sure that default
1645     // initialized unions are accepted by other backends we require arrays also have a default
1646     // value.
1647     if (first->GetType().IsArray()) {
1648       AIDL_ERROR(first)
1649           << "The union's first member should have a useful default value. Arrays can be "
1650              "initialized with values(e.g. ... = { values... };) or marked as @nullable.";
1651       return false;
1652     }
1653   }
1654 
1655   return success;
1656 }
1657 
AidlInterface(const AidlLocation & location,const std::string & name,const Comments & comments,bool oneway,const std::string & package,std::vector<std::unique_ptr<AidlMember>> * members)1658 AidlInterface::AidlInterface(const AidlLocation& location, const std::string& name,
1659                              const Comments& comments, bool oneway, const std::string& package,
1660                              std::vector<std::unique_ptr<AidlMember>>* members)
1661     : AidlDefinedType(location, name, comments, package, members) {
1662   for (auto& m : GetMethods()) {
1663     m.get()->ApplyInterfaceOneway(oneway);
1664   }
1665 }
1666 
CheckValid(const AidlTypenames & typenames) const1667 bool AidlInterface::CheckValid(const AidlTypenames& typenames) const {
1668   if (!AidlDefinedType::CheckValid(typenames)) {
1669     return false;
1670   }
1671   // Has to be a pointer due to deleting copy constructor. No idea why.
1672   map<string, const AidlMethod*> method_names;
1673   for (const auto& m : GetMethods()) {
1674     if (!m->CheckValid(typenames)) {
1675       return false;
1676     }
1677 
1678     auto it = method_names.find(m->GetName());
1679     // prevent duplicate methods
1680     if (it == method_names.end()) {
1681       method_names[m->GetName()] = m.get();
1682     } else {
1683       AIDL_ERROR(m) << "attempt to redefine method " << m->GetName() << ":";
1684       AIDL_ERROR(it->second) << "previously defined here.";
1685       return false;
1686     }
1687 
1688     static set<string> reserved_methods{"asBinder()", "getInterfaceHash()", "getInterfaceVersion()",
1689                                         "getTransactionName(int)"};
1690 
1691     if (reserved_methods.find(m->Signature()) != reserved_methods.end()) {
1692       AIDL_ERROR(m) << " method " << m->Signature() << " is reserved for internal use.";
1693       return false;
1694     }
1695 
1696     if (!CheckValidPermissionAnnotations(*m.get())) {
1697       return false;
1698     }
1699   }
1700 
1701   bool success = true;
1702   set<string> constant_names;
1703   for (const auto& constant : GetConstantDeclarations()) {
1704     if (constant_names.count(constant->GetName()) > 0) {
1705       AIDL_ERROR(constant) << "Found duplicate constant name '" << constant->GetName() << "'";
1706       success = false;
1707     }
1708     constant_names.insert(constant->GetName());
1709     success = success && constant->CheckValid(typenames);
1710   }
1711   return success;
1712 }
1713 
CheckValidPermissionAnnotations(const AidlMethod & m) const1714 bool AidlInterface::CheckValidPermissionAnnotations(const AidlMethod& m) const {
1715   if (IsPermissionNone() || IsPermissionManual()) {
1716     if (m.GetType().IsPermissionNone() || m.GetType().IsPermissionManual() ||
1717         m.GetType().EnforceExpression()) {
1718       std::string interface_annotation = IsPermissionNone()
1719                                              ? "requiring no permission"
1720                                              : "manually implementing permission checks";
1721       AIDL_ERROR(m) << "The interface " << GetName() << " is annotated as " << interface_annotation
1722                     << " but the method " << m.GetName() << " is also annotated.\n"
1723                     << "Consider distributing the annotation to each method.";
1724       return false;
1725     }
1726   } else if (EnforceExpression()) {
1727     if (m.GetType().IsPermissionNone() || m.GetType().IsPermissionManual()) {
1728       AIDL_ERROR(m) << "The interface " << GetName()
1729                     << " enforces permissions using annotations"
1730                        " but the method "
1731                     << m.GetName() << " is also annotated.\n"
1732                     << "Consider distributing the annotation to each method.";
1733       return false;
1734     }
1735   }
1736   return true;
1737 }
1738 
GetDescriptor() const1739 std::string AidlInterface::GetDescriptor() const {
1740   std::string annotatedDescriptor = AidlAnnotatable::GetDescriptor();
1741   if (annotatedDescriptor != "") {
1742     return annotatedDescriptor;
1743   }
1744   return GetCanonicalName();
1745 }
1746 
AidlDocument(const AidlLocation & location,const Comments & comments,std::vector<string> imports,std::vector<std::unique_ptr<AidlDefinedType>> defined_types,bool is_preprocessed)1747 AidlDocument::AidlDocument(const AidlLocation& location, const Comments& comments,
1748                            std::vector<string> imports,
1749                            std::vector<std::unique_ptr<AidlDefinedType>> defined_types,
1750                            bool is_preprocessed)
1751     : AidlCommentable(location, comments),
1752       AidlScope(this),
1753       imports_(std::move(imports)),
1754       defined_types_(std::move(defined_types)),
1755       is_preprocessed_(is_preprocessed) {
1756   for (const auto& t : defined_types_) {
1757     t->SetEnclosingScope(this);
1758   }
1759 }
1760 
1761 // Resolves type name in the current document.
1762 // - built-in types
1763 // - imported types
1764 // - top-level type
ResolveName(const std::string & name) const1765 std::string AidlDocument::ResolveName(const std::string& name) const {
1766   if (AidlTypenames::IsBuiltinTypename(name)) {
1767     return name;
1768   }
1769 
1770   const auto first_dot = name.find_first_of('.');
1771   // For "Outer.Inner", we look up "Outer" in the import list.
1772   const std::string class_name =
1773       (first_dot == std::string::npos) ? name : name.substr(0, first_dot);
1774   // Keep ".Inner", to make a fully-qualified name
1775   const std::string nested_type = (first_dot == std::string::npos) ? "" : name.substr(first_dot);
1776 
1777   for (const auto& import : Imports()) {
1778     if (SimpleName(import) == class_name) {
1779       return import + nested_type;
1780     }
1781   }
1782 
1783   // check if it is a top-level type.
1784   for (const auto& type : DefinedTypes()) {
1785     if (type->GetName() == class_name) {
1786       return type->GetCanonicalName() + nested_type;
1787     }
1788   }
1789 
1790   // name itself might be fully-qualified name.
1791   return name;
1792 }
1793