• 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::NDK_STABLE_PARCELABLE,
147        "NdkOnlyStableParcelable",
148        CONTEXT_TYPE_UNSTRUCTURED_PARCELABLE,
149        {}},
150       {AidlAnnotation::Type::BACKING,
151        "Backing",
152        CONTEXT_TYPE_ENUM,
153        {{"type", kStringType, /* required= */ true}}},
154       {AidlAnnotation::Type::JAVA_PASSTHROUGH,
155        "JavaPassthrough",
156        CONTEXT_ALL,
157        {{"annotation", kStringType, /* required= */ true}},
158        /* repeatable= */ true},
159       {AidlAnnotation::Type::JAVA_DERIVE,
160        "JavaDerive",
161        CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION | CONTEXT_TYPE_ENUM,
162        {{"toString", kBooleanType}, {"equals", kBooleanType}}},
163       {AidlAnnotation::Type::JAVA_DEFAULT, "JavaDefault", CONTEXT_TYPE_INTERFACE, {}},
164       {AidlAnnotation::Type::JAVA_DELEGATOR, "JavaDelegator", CONTEXT_TYPE_INTERFACE, {}},
165       {AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE,
166        "JavaOnlyImmutable",
167        CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION |
168            CONTEXT_TYPE_UNSTRUCTURED_PARCELABLE,
169        {}},
170       {AidlAnnotation::Type::JAVA_SUPPRESS_LINT,
171        "JavaSuppressLint",
172        CONTEXT_ALL,
173        {{"value", kStringArrayType, /* required= */ true}}},
174       {AidlAnnotation::Type::FIXED_SIZE,
175        "FixedSize",
176        CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION,
177        {}},
178       {AidlAnnotation::Type::DESCRIPTOR,
179        "Descriptor",
180        CONTEXT_TYPE_INTERFACE,
181        {{"value", kStringType, /* required= */ true}}},
182       {AidlAnnotation::Type::RUST_DERIVE,
183        "RustDerive",
184        CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION,
185        {{"Copy", kBooleanType},
186         {"Clone", kBooleanType},
187         {"PartialOrd", kBooleanType},
188         {"Ord", kBooleanType},
189         {"PartialEq", kBooleanType},
190         {"Eq", kBooleanType},
191         {"Hash", kBooleanType}}},
192       {AidlAnnotation::Type::SUPPRESS_WARNINGS,
193        "SuppressWarnings",
194        CONTEXT_TYPE | CONTEXT_MEMBER,
195        {{"value", kStringArrayType, /* required= */ true}}},
196       {AidlAnnotation::Type::PERMISSION_ENFORCE,
197        "EnforcePermission",
198        CONTEXT_TYPE_INTERFACE | CONTEXT_METHOD,
199        {{"value", kStringType}, {"anyOf", kStringArrayType}, {"allOf", kStringArrayType}}},
200       {AidlAnnotation::Type::PERMISSION_MANUAL,
201        "PermissionManuallyEnforced",
202        CONTEXT_TYPE_INTERFACE | CONTEXT_METHOD,
203        {}},
204       {AidlAnnotation::Type::PERMISSION_NONE,
205        "RequiresNoPermission",
206        CONTEXT_TYPE_INTERFACE | CONTEXT_METHOD,
207        {}},
208       {AidlAnnotation::Type::PROPAGATE_ALLOW_BLOCKING,
209        "PropagateAllowBlocking",
210        CONTEXT_METHOD,
211        {}},
212   };
213   return kSchemas;
214 }
215 
TypeToString(Type type)216 std::string AidlAnnotation::TypeToString(Type type) {
217   for (const Schema& schema : AllSchemas()) {
218     if (type == schema.type) return schema.name;
219   }
220   AIDL_FATAL(AIDL_LOCATION_HERE) << "Unrecognized type: " << static_cast<size_t>(type);
221   __builtin_unreachable();
222 }
223 
Parse(const AidlLocation & location,const string & name,std::map<std::string,std::shared_ptr<AidlConstantValue>> parameter_list,const Comments & comments)224 std::unique_ptr<AidlAnnotation> AidlAnnotation::Parse(
225     const AidlLocation& location, const string& name,
226     std::map<std::string, std::shared_ptr<AidlConstantValue>> parameter_list,
227     const Comments& comments) {
228   const Schema* schema = nullptr;
229   for (const Schema& a_schema : AllSchemas()) {
230     if (a_schema.name == name) {
231       schema = &a_schema;
232     }
233   }
234 
235   if (schema == nullptr) {
236     std::ostringstream stream;
237     stream << "'" << name << "' is not a recognized annotation. ";
238     stream << "It must be one of:";
239     for (const Schema& s : AllSchemas()) {
240       stream << " " << s.name;
241     }
242     stream << ".";
243     AIDL_ERROR(location) << stream.str();
244     return {};
245   }
246 
247   return std::unique_ptr<AidlAnnotation>(
248       new AidlAnnotation(location, *schema, std::move(parameter_list), comments));
249 }
250 
AidlAnnotation(const AidlLocation & location,const Schema & schema,std::map<std::string,std::shared_ptr<AidlConstantValue>> parameters,const Comments & comments)251 AidlAnnotation::AidlAnnotation(const AidlLocation& location, const Schema& schema,
252                                std::map<std::string, std::shared_ptr<AidlConstantValue>> parameters,
253                                const Comments& comments)
254     : AidlNode(location, comments), schema_(schema), parameters_(std::move(parameters)) {}
255 
256 struct ConstReferenceFinder : AidlVisitor {
257   const AidlConstantReference* found = nullptr;
VisitConstReferenceFinder258   void Visit(const AidlConstantReference& ref) override {
259     if (!found) found = &ref;
260   }
FindConstReferenceFinder261   static const AidlConstantReference* Find(const AidlConstantValue& c) {
262     ConstReferenceFinder finder;
263     VisitTopDown(finder, c);
264     return finder.found;
265   }
266 };
267 
268 // Checks if annotation complies with the schema
269 // - every parameter is known and has well-typed value.
270 // - every required parameter is present.
CheckValid() const271 bool AidlAnnotation::CheckValid() const {
272   for (const auto& name_and_param : parameters_) {
273     const std::string& param_name = name_and_param.first;
274     const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
275 
276     const ParamType* param_type = schema_.ParamType(param_name);
277     if (!param_type) {
278       std::ostringstream stream;
279       stream << "Parameter " << param_name << " not supported ";
280       stream << "for annotation " << GetName() << ". ";
281       stream << "It must be one of:";
282       for (const auto& param : schema_.parameters) {
283         stream << " " << param.name;
284       }
285       AIDL_ERROR(this) << stream.str();
286       return false;
287     }
288 
289     const auto& found = ConstReferenceFinder::Find(*param);
290     if (found) {
291       AIDL_ERROR(found) << "Value must be a constant expression but contains reference to "
292                         << found->GetFieldName() << ".";
293       return false;
294     }
295 
296     if (!param->CheckValid()) {
297       AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
298                        << GetName() << ".";
299       return false;
300     }
301 
302     const std::string param_value =
303         param->ValueString(param_type->type, AidlConstantValueDecorator);
304     // Assume error on empty string.
305     if (param_value == "") {
306       AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
307                        << GetName() << ".";
308       return false;
309     }
310   }
311   bool success = true;
312   for (const auto& param : schema_.parameters) {
313     if (param.required && parameters_.count(param.name) == 0) {
314       AIDL_ERROR(this) << "Missing '" << param.name << "' on @" << GetName() << ".";
315       success = false;
316     }
317   }
318   if (!success) {
319     return false;
320   }
321   // For @Enforce annotations, validates the expression.
322   if (schema_.type == AidlAnnotation::Type::PERMISSION_ENFORCE) {
323     auto expr = EnforceExpression();
324     if (!expr.ok()) {
325       AIDL_ERROR(this) << "Unable to parse @EnforcePermission annotation: " << expr.error();
326       return false;
327     }
328   }
329   return true;
330 }
331 
EnforceExpression() const332 Result<unique_ptr<android::aidl::perm::Expression>> AidlAnnotation::EnforceExpression() const {
333   auto single = ParamValue<std::string>("value");
334   auto anyOf = ParamValue<std::vector<std::string>>("anyOf");
335   auto allOf = ParamValue<std::vector<std::string>>("allOf");
336   if (single.has_value()) {
337     return std::make_unique<android::aidl::perm::Expression>(single.value());
338   } else if (anyOf.has_value()) {
339     auto v = android::aidl::perm::AnyOf{anyOf.value()};
340     return std::make_unique<android::aidl::perm::Expression>(v);
341   } else if (allOf.has_value()) {
342     auto v = android::aidl::perm::AllOf{allOf.value()};
343     return std::make_unique<android::aidl::perm::Expression>(v);
344   }
345   return Error() << "No parameter for @EnforcePermission";
346 }
347 
348 // Checks if the annotation is applicable to the current context.
349 // For example, annotations like @VintfStability, @FixedSize is not applicable to AidlTypeSpecifier
350 // nodes.
CheckContext(TargetContext context) const351 bool AidlAnnotation::CheckContext(TargetContext context) const {
352   if (schema_.target_context & static_cast<uint32_t>(context)) {
353     return true;
354   }
355   const static map<TargetContext, string> context_name_map{
356       {CONTEXT_TYPE_INTERFACE, "interface"},
357       {CONTEXT_TYPE_ENUM, "enum"},
358       {CONTEXT_TYPE_STRUCTURED_PARCELABLE, "parcelable definition"},
359       {CONTEXT_TYPE_UNION, "union"},
360       {CONTEXT_TYPE_UNSTRUCTURED_PARCELABLE, "parcelable declaration"},
361       {CONTEXT_CONST, "constant"},
362       {CONTEXT_FIELD, "field"},
363       {CONTEXT_METHOD, "method"},
364       {CONTEXT_TYPE_SPECIFIER, "type"},
365   };
366   vector<string> available;
367   for (const auto& [context, name] : context_name_map) {
368     if (schema_.target_context & context) {
369       available.push_back(name);
370     }
371   }
372   AIDL_ERROR(this) << "@" << GetName()
373                    << " is not available. It can only annotate: " << Join(available, ", ") << ".";
374   return false;
375 }
376 
AnnotationParams(const ConstantValueDecorator & decorator) const377 std::map<std::string, std::string> AidlAnnotation::AnnotationParams(
378     const ConstantValueDecorator& decorator) const {
379   std::map<std::string, std::string> raw_params;
380   for (const auto& name_and_param : parameters_) {
381     const std::string& param_name = name_and_param.first;
382     const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
383     const ParamType* param_type = schema_.ParamType(param_name);
384     AIDL_FATAL_IF(!param_type, this);
385     raw_params.emplace(param_name, param->ValueString(param_type->type, decorator));
386   }
387   return raw_params;
388 }
389 
ToString() const390 std::string AidlAnnotation::ToString() const {
391   if (parameters_.empty()) {
392     return "@" + GetName();
393   } else {
394     vector<string> param_strings;
395     for (const auto& [name, value] : AnnotationParams(AidlConstantValueDecorator)) {
396       param_strings.emplace_back(name + "=" + value);
397     }
398     return "@" + GetName() + "(" + Join(param_strings, ", ") + ")";
399   }
400 }
401 
TraverseChildren(std::function<void (const AidlNode &)> traverse) const402 void AidlAnnotation::TraverseChildren(std::function<void(const AidlNode&)> traverse) const {
403   for (const auto& [name, value] : parameters_) {
404     (void)name;
405     traverse(*value);
406   }
407 }
408 
GetAnnotation(const vector<std::unique_ptr<AidlAnnotation>> & annotations,AidlAnnotation::Type type)409 static const AidlAnnotation* GetAnnotation(
410     const vector<std::unique_ptr<AidlAnnotation>>& annotations, AidlAnnotation::Type type) {
411   for (const auto& a : annotations) {
412     if (a->GetType() == type) {
413       AIDL_FATAL_IF(a->Repeatable(), a)
414           << "Trying to get a single annotation when it is repeatable.";
415       return a.get();
416     }
417   }
418   return nullptr;
419 }
420 
GetScopedAnnotation(const AidlDefinedType & defined_type,AidlAnnotation::Type type)421 static const AidlAnnotation* GetScopedAnnotation(const AidlDefinedType& defined_type,
422                                                  AidlAnnotation::Type type) {
423   const AidlAnnotation* annotation = GetAnnotation(defined_type.GetAnnotations(), type);
424   if (annotation) {
425     return annotation;
426   }
427   const AidlDefinedType* enclosing_type = defined_type.GetParentType();
428   if (enclosing_type) {
429     return GetScopedAnnotation(*enclosing_type, type);
430   }
431   return nullptr;
432 }
433 
AidlAnnotatable(const AidlLocation & location,const Comments & comments)434 AidlAnnotatable::AidlAnnotatable(const AidlLocation& location, const Comments& comments)
435     : AidlCommentable(location, comments) {}
436 
IsNullable() const437 bool AidlAnnotatable::IsNullable() const {
438   return GetAnnotation(annotations_, AidlAnnotation::Type::NULLABLE);
439 }
440 
IsHeapNullable() const441 bool AidlAnnotatable::IsHeapNullable() const {
442   auto annot = GetAnnotation(annotations_, AidlAnnotation::Type::NULLABLE);
443   if (annot) {
444     return annot->ParamValue<bool>("heap").value_or(false);
445   }
446   return false;
447 }
448 
IsUtf8InCpp() const449 bool AidlAnnotatable::IsUtf8InCpp() const {
450   return GetAnnotation(annotations_, AidlAnnotation::Type::UTF8_IN_CPP);
451 }
452 
IsSensitiveData() const453 bool AidlAnnotatable::IsSensitiveData() const {
454   return GetAnnotation(annotations_, AidlAnnotation::Type::SENSITIVE_DATA);
455 }
456 
IsVintfStability() const457 bool AidlAnnotatable::IsVintfStability() const {
458   auto defined_type = AidlCast<AidlDefinedType>(*this);
459   AIDL_FATAL_IF(!defined_type, *this) << "@VintfStability is not attached to a type";
460   return GetScopedAnnotation(*defined_type, AidlAnnotation::Type::VINTF_STABILITY);
461 }
462 
IsJavaOnlyImmutable() const463 bool AidlAnnotatable::IsJavaOnlyImmutable() const {
464   return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE);
465 }
466 
IsFixedSize() const467 bool AidlAnnotatable::IsFixedSize() const {
468   return GetAnnotation(annotations_, AidlAnnotation::Type::FIXED_SIZE);
469 }
470 
UnsupportedAppUsage() const471 const AidlAnnotation* AidlAnnotatable::UnsupportedAppUsage() const {
472   return GetAnnotation(annotations_, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE);
473 }
474 
RustDerive() const475 std::vector<std::string> AidlAnnotatable::RustDerive() const {
476   std::vector<std::string> ret;
477   if (const auto* ann = GetAnnotation(annotations_, AidlAnnotation::Type::RUST_DERIVE)) {
478     for (const auto& name_and_param : ann->AnnotationParams(AidlConstantValueDecorator)) {
479       if (name_and_param.second == "true") {
480         ret.push_back(name_and_param.first);
481       }
482     }
483   }
484   return ret;
485 }
486 
BackingType() const487 const AidlAnnotation* AidlAnnotatable::BackingType() const {
488   return GetAnnotation(annotations_, AidlAnnotation::Type::BACKING);
489 }
490 
SuppressWarnings() const491 std::vector<std::string> AidlAnnotatable::SuppressWarnings() const {
492   auto annot = GetAnnotation(annotations_, AidlAnnotation::Type::SUPPRESS_WARNINGS);
493   if (annot) {
494     auto names = annot->ParamValue<std::vector<std::string>>("value");
495     AIDL_FATAL_IF(!names.has_value(), this);
496     return std::move(names.value());
497   }
498   return {};
499 }
500 
501 // Parses the @Enforce annotation expression.
EnforceExpression() const502 std::unique_ptr<android::aidl::perm::Expression> AidlAnnotatable::EnforceExpression() const {
503   auto annot = GetAnnotation(annotations_, AidlAnnotation::Type::PERMISSION_ENFORCE);
504   if (annot) {
505     auto perm_expr = annot->EnforceExpression();
506     if (!perm_expr.ok()) {
507       // This should have been caught during validation.
508       AIDL_FATAL(this) << "Unable to parse @EnforcePermission annotation: " << perm_expr.error();
509     }
510     return std::move(perm_expr.value());
511   }
512   return {};
513 }
514 
IsPermissionManual() const515 bool AidlAnnotatable::IsPermissionManual() const {
516   return GetAnnotation(annotations_, AidlAnnotation::Type::PERMISSION_MANUAL);
517 }
518 
IsPermissionNone() const519 bool AidlAnnotatable::IsPermissionNone() const {
520   return GetAnnotation(annotations_, AidlAnnotation::Type::PERMISSION_NONE);
521 }
522 
IsPermissionAnnotated() const523 bool AidlAnnotatable::IsPermissionAnnotated() const {
524   return IsPermissionNone() || IsPermissionManual() || EnforceExpression();
525 }
526 
IsPropagateAllowBlocking() const527 bool AidlAnnotatable::IsPropagateAllowBlocking() const {
528   return GetAnnotation(annotations_, AidlAnnotation::Type::PROPAGATE_ALLOW_BLOCKING);
529 }
530 
IsStableApiParcelable(Options::Language lang) const531 bool AidlAnnotatable::IsStableApiParcelable(Options::Language lang) const {
532   if (lang == Options::Language::JAVA)
533     return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_STABLE_PARCELABLE);
534   if (lang == Options::Language::NDK)
535     return GetAnnotation(annotations_, AidlAnnotation::Type::NDK_STABLE_PARCELABLE);
536   return false;
537 }
538 
JavaDerive(const std::string & method) const539 bool AidlAnnotatable::JavaDerive(const std::string& method) const {
540   auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_DERIVE);
541   if (annotation != nullptr) {
542     return annotation->ParamValue<bool>(method).value_or(false);
543   }
544   return false;
545 }
546 
IsJavaDefault() const547 bool AidlAnnotatable::IsJavaDefault() const {
548   return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_DEFAULT);
549 }
550 
IsJavaDelegator() const551 bool AidlAnnotatable::IsJavaDelegator() const {
552   return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_DELEGATOR);
553 }
554 
GetDescriptor() const555 std::string AidlAnnotatable::GetDescriptor() const {
556   auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::DESCRIPTOR);
557   if (annotation != nullptr) {
558     return annotation->ParamValue<std::string>("value").value();
559   }
560   return "";
561 }
562 
CheckValid(const AidlTypenames &) const563 bool AidlAnnotatable::CheckValid(const AidlTypenames&) const {
564   for (const auto& annotation : GetAnnotations()) {
565     if (!annotation->CheckValid()) {
566       return false;
567     }
568   }
569 
570   std::map<AidlAnnotation::Type, AidlLocation> declared;
571   for (const auto& annotation : GetAnnotations()) {
572     const auto& [iter, inserted] =
573         declared.emplace(annotation->GetType(), annotation->GetLocation());
574     if (!inserted && !annotation->Repeatable()) {
575       AIDL_ERROR(this) << "'" << annotation->GetName()
576                        << "' is repeated, but not allowed. Previous location: " << iter->second;
577       return false;
578     }
579   }
580 
581   return true;
582 }
583 
ToString() const584 string AidlAnnotatable::ToString() const {
585   vector<string> ret;
586   for (const auto& a : annotations_) {
587     ret.emplace_back(a->ToString());
588   }
589   std::sort(ret.begin(), ret.end());
590   return Join(ret, " ");
591 }
592 
AidlTypeSpecifier(const AidlLocation & location,const string & unresolved_name,std::optional<ArrayType> array,vector<unique_ptr<AidlTypeSpecifier>> * type_params,const Comments & comments)593 AidlTypeSpecifier::AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name,
594                                      std::optional<ArrayType> array,
595                                      vector<unique_ptr<AidlTypeSpecifier>>* type_params,
596                                      const Comments& comments)
597     : AidlAnnotatable(location, comments),
598       AidlParameterizable<unique_ptr<AidlTypeSpecifier>>(type_params),
599       unresolved_name_(unresolved_name),
600       array_(std::move(array)),
601       split_name_(Split(unresolved_name, ".")) {}
602 
ViewAsArrayBase(std::function<void (const AidlTypeSpecifier &)> func) const603 void AidlTypeSpecifier::ViewAsArrayBase(std::function<void(const AidlTypeSpecifier&)> func) const {
604   AIDL_FATAL_IF(!array_.has_value(), this);
605   // Declaring array of generic type cannot happen, it is grammar error.
606   AIDL_FATAL_IF(IsGeneric(), this);
607 
608   bool is_mutated = mutated_;
609   mutated_ = true;
610   // mutate the array type to its base by removing a single dimension
611   // e.g.) T[] => T, T[N][M] => T[M] (note that, M is removed)
612   if (IsFixedSizeArray() && std::get<FixedSizeArray>(*array_).dimensions.size() > 1) {
613     auto& dimensions = std::get<FixedSizeArray>(*array_).dimensions;
614     auto dim = std::move(dimensions.front());
615     dimensions.erase(dimensions.begin());
616     func(*this);
617     dimensions.insert(dimensions.begin(), std::move(dim));
618   } else {
619     ArrayType array_type = std::move(array_.value());
620     array_ = std::nullopt;
621     func(*this);
622     array_ = std::move(array_type);
623   }
624   mutated_ = is_mutated;
625 }
626 
MakeArray(ArrayType array_type)627 bool AidlTypeSpecifier::MakeArray(ArrayType array_type) {
628   // T becomes T[] or T[N]
629   if (!IsArray()) {
630     array_ = std::move(array_type);
631     return true;
632   }
633   // T[N] becomes T[N][M]
634   if (auto fixed_size_array = std::get_if<FixedSizeArray>(&array_type);
635       fixed_size_array != nullptr && IsFixedSizeArray()) {
636     // concat dimensions
637     for (auto& dim : fixed_size_array->dimensions) {
638       std::get<FixedSizeArray>(*array_).dimensions.push_back(std::move(dim));
639     }
640     return true;
641   }
642   return false;
643 }
644 
GetDimensionInts() const645 std::vector<int32_t> FixedSizeArray::GetDimensionInts() const {
646   std::vector<int32_t> ints;
647   for (const auto& dim : dimensions) {
648     ints.push_back(dim->EvaluatedValue<int32_t>());
649   }
650   return ints;
651 }
652 
GetFixedSizeArrayDimensions() const653 std::vector<int32_t> AidlTypeSpecifier::GetFixedSizeArrayDimensions() const {
654   AIDL_FATAL_IF(!IsFixedSizeArray(), "not a fixed-size array");
655   return std::get<FixedSizeArray>(GetArray()).GetDimensionInts();
656 }
657 
Signature() const658 string AidlTypeSpecifier::Signature() const {
659   string ret = GetName();
660   if (IsGeneric()) {
661     vector<string> arg_names;
662     for (const auto& ta : GetTypeParameters()) {
663       arg_names.emplace_back(ta->Signature());
664     }
665     ret += "<" + Join(arg_names, ",") + ">";
666   }
667   if (IsArray()) {
668     if (IsFixedSizeArray()) {
669       for (const auto& dim : GetFixedSizeArrayDimensions()) {
670         ret += "[" + std::to_string(dim) + "]";
671       }
672     } else {
673       ret += "[]";
674     }
675   }
676   return ret;
677 }
678 
ToString() const679 string AidlTypeSpecifier::ToString() const {
680   string ret = Signature();
681   string annotations = AidlAnnotatable::ToString();
682   if (annotations != "") {
683     ret = annotations + " " + ret;
684   }
685   return ret;
686 }
687 
688 // When `scope` is specified, name is resolved first based on it.
689 // `scope` can be null for built-in types and fully-qualified types.
Resolve(const AidlTypenames & typenames,const AidlScope * scope)690 bool AidlTypeSpecifier::Resolve(const AidlTypenames& typenames, const AidlScope* scope) {
691   AIDL_FATAL_IF(IsResolved(), this);
692   std::string name = unresolved_name_;
693   if (scope) {
694     name = scope->ResolveName(name);
695   }
696   AidlTypenames::ResolvedTypename result = typenames.ResolveTypename(name);
697   if (result.is_resolved) {
698     fully_qualified_name_ = result.canonical_name;
699     split_name_ = Split(fully_qualified_name_, ".");
700     defined_type_ = result.defined_type;
701   }
702   return result.is_resolved;
703 }
704 
GetDefinedType() const705 const AidlDefinedType* AidlTypeSpecifier::GetDefinedType() const {
706   return defined_type_;
707 }
708 
CheckValid(const AidlTypenames & typenames) const709 bool AidlTypeSpecifier::CheckValid(const AidlTypenames& typenames) const {
710   if (!AidlAnnotatable::CheckValid(typenames)) {
711     return false;
712   }
713   if (IsGeneric()) {
714     const auto& types = GetTypeParameters();
715     for (const auto& arg : types) {
716       if (!arg->CheckValid(typenames)) {
717         return false;
718       }
719     }
720 
721     const string& type_name = GetName();
722     // TODO(b/136048684) Disallow to use primitive types only if it is List or Map.
723     if (type_name == "List" || type_name == "Map") {
724       if (std::any_of(types.begin(), types.end(), [&](auto& type_ptr) {
725             return !type_ptr->IsArray() &&
726                    (typenames.GetEnumDeclaration(*type_ptr) ||
727                     AidlTypenames::IsPrimitiveTypename(type_ptr->GetName()));
728           })) {
729         AIDL_ERROR(this) << "A generic type cannot have any primitive type parameters.";
730         return false;
731       }
732     }
733     const auto defined_type = typenames.TryGetDefinedType(type_name);
734     const auto parameterizable =
735         defined_type != nullptr ? defined_type->AsParameterizable() : nullptr;
736     const bool is_user_defined_generic_type =
737         parameterizable != nullptr && parameterizable->IsGeneric();
738     const size_t num_params = GetTypeParameters().size();
739     if (type_name == "List") {
740       if (num_params > 1) {
741         AIDL_ERROR(this) << "List can only have one type parameter, but got: '" << Signature()
742                          << "'";
743         return false;
744       }
745       static const char* kListUsage =
746           "List<T> supports interface/parcelable/union, String, IBinder, and ParcelFileDescriptor.";
747       const AidlTypeSpecifier& contained_type = *GetTypeParameters()[0];
748       if (contained_type.IsArray()) {
749         AIDL_ERROR(this) << "List of arrays is not supported. " << kListUsage;
750         return false;
751       }
752       const string& contained_type_name = contained_type.GetName();
753       if (AidlTypenames::IsBuiltinTypename(contained_type_name)) {
754         if (contained_type_name != "String" && contained_type_name != "IBinder" &&
755             contained_type_name != "ParcelFileDescriptor") {
756           AIDL_ERROR(this) << "List<" << contained_type_name << "> is not supported. "
757                            << kListUsage;
758           return false;
759         }
760       }
761     } else if (type_name == "Map") {
762       if (num_params != 0 && num_params != 2) {
763         AIDL_ERROR(this) << "Map must have 0 or 2 type parameters, but got "
764                          << "'" << Signature() << "'";
765         return false;
766       }
767       if (num_params == 2) {
768         const string& key_type = GetTypeParameters()[0]->Signature();
769         if (key_type != "String") {
770           AIDL_ERROR(this) << "The type of key in map must be String, but it is "
771                            << "'" << key_type << "'";
772           return false;
773         }
774       }
775     } else if (is_user_defined_generic_type) {
776       const size_t allowed = parameterizable->GetTypeParameters().size();
777       if (num_params != allowed) {
778         AIDL_ERROR(this) << type_name << " must have " << allowed << " type parameters, but got "
779                          << num_params;
780         return false;
781       }
782     } else {
783       AIDL_ERROR(this) << type_name << " is not a generic type.";
784       return false;
785     }
786   }
787 
788   const bool is_generic_string_list = GetName() == "List" && IsGeneric() &&
789                                       GetTypeParameters().size() == 1 &&
790                                       GetTypeParameters()[0]->GetName() == "String";
791   if (IsUtf8InCpp() && (GetName() != "String" && !is_generic_string_list)) {
792     AIDL_ERROR(this) << "@utf8InCpp can only be used on String, String[], and List<String>.";
793     return false;
794   }
795 
796   if (GetName() == "void") {
797     if (IsArray() || IsNullable() || IsUtf8InCpp()) {
798       AIDL_ERROR(this) << "void type cannot be an array or nullable or utf8 string";
799       return false;
800     }
801   }
802 
803   if (IsArray()) {
804     if (GetName() == "ParcelableHolder" || GetName() == "List" || GetName() == "Map" ||
805         GetName() == "CharSequence") {
806       AIDL_ERROR(this) << "Arrays of " << GetName() << " are not supported.";
807       return false;
808     }
809   }
810 
811   if (IsNullable()) {
812     if (AidlTypenames::IsPrimitiveTypename(GetName()) && !IsArray()) {
813       AIDL_ERROR(this) << "Primitive type cannot get nullable annotation";
814       return false;
815     }
816     const auto defined_type = typenames.TryGetDefinedType(GetName());
817     if (defined_type != nullptr && defined_type->AsEnumDeclaration() != nullptr && !IsArray()) {
818       AIDL_ERROR(this) << "Enum type cannot get nullable annotation";
819       return false;
820     }
821     if (GetName() == "ParcelableHolder") {
822       AIDL_ERROR(this) << "ParcelableHolder cannot be nullable.";
823       return false;
824     }
825     if (IsHeapNullable()) {
826       if (!defined_type || IsArray() || !defined_type->AsParcelable()) {
827         AIDL_ERROR(this) << "@nullable(heap=true) is available to parcelables.";
828         return false;
829       }
830     }
831   }
832 
833   if (IsFixedSizeArray()) {
834     for (const auto& dim : std::get<FixedSizeArray>(GetArray()).dimensions) {
835       if (!dim->Evaluate()) {
836         return false;
837       }
838       if (dim->GetType() > AidlConstantValue::Type::INT32) {
839         AIDL_ERROR(this) << "Array size must be a positive number: " << dim->Literal();
840         return false;
841       }
842       auto value = dim->EvaluatedValue<int32_t>();
843       if (value < 0) {
844         AIDL_ERROR(this) << "Array size must be a positive number: " << value;
845         return false;
846       }
847     }
848   }
849   return true;
850 }
851 
TraverseChildren(std::function<void (const AidlNode &)> traverse) const852 void AidlTypeSpecifier::TraverseChildren(std::function<void(const AidlNode&)> traverse) const {
853   AidlAnnotatable::TraverseChildren(traverse);
854   if (IsGeneric()) {
855     for (const auto& tp : GetTypeParameters()) {
856       traverse(*tp);
857     }
858   }
859   if (IsFixedSizeArray()) {
860     for (const auto& dim : std::get<FixedSizeArray>(GetArray()).dimensions) {
861       traverse(*dim);
862     }
863   }
864 }
865 
AidlConstantValueDecorator(const AidlTypeSpecifier & type,const std::variant<std::string,std::vector<std::string>> & raw_value)866 std::string AidlConstantValueDecorator(
867     const AidlTypeSpecifier& type,
868     const std::variant<std::string, std::vector<std::string>>& raw_value) {
869   if (type.IsArray()) {
870     const auto& values = std::get<std::vector<std::string>>(raw_value);
871     return "{" + Join(values, ", ") + "}";
872   }
873   const std::string& value = std::get<std::string>(raw_value);
874   if (auto defined_type = type.GetDefinedType(); defined_type) {
875     auto enum_type = defined_type->AsEnumDeclaration();
876     AIDL_FATAL_IF(!enum_type, type) << "Invalid type for \"" << value << "\"";
877     return type.GetName() + "." + value.substr(value.find_last_of('.') + 1);
878   }
879   return value;
880 }
881 
AidlVariableDeclaration(const AidlLocation & location,AidlTypeSpecifier * type,const std::string & name)882 AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
883                                                  AidlTypeSpecifier* type, const std::string& name)
884     : AidlVariableDeclaration(location, type, name, AidlConstantValue::Default(*type)) {
885   default_user_specified_ = false;
886 }
887 
AidlVariableDeclaration(const AidlLocation & location,AidlTypeSpecifier * type,const std::string & name,AidlConstantValue * default_value)888 AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
889                                                  AidlTypeSpecifier* type, const std::string& name,
890                                                  AidlConstantValue* default_value)
891     : AidlMember(location, type->GetComments()),
892       type_(type),
893       name_(name),
894       default_user_specified_(true),
895       default_value_(default_value) {}
896 
HasUsefulDefaultValue() const897 bool AidlVariableDeclaration::HasUsefulDefaultValue() const {
898   if (GetDefaultValue()) {
899     return true;
900   }
901   // null is accepted as a valid default value in all backends
902   if (GetType().IsNullable()) {
903     return true;
904   }
905   return false;
906 }
907 
CheckValid(const AidlTypenames & typenames) const908 bool AidlVariableDeclaration::CheckValid(const AidlTypenames& typenames) const {
909   bool valid = true;
910   valid &= type_->CheckValid(typenames);
911 
912   if (type_->GetName() == "void") {
913     AIDL_ERROR(this) << "Declaration " << name_
914                      << " is void, but declarations cannot be of void type.";
915     valid = false;
916   }
917 
918   if (default_value_ == nullptr) return valid;
919   valid &= default_value_->CheckValid();
920 
921   if (!valid) return false;
922 
923   return !ValueString(AidlConstantValueDecorator).empty();
924 }
925 
GetCapitalizedName() const926 string AidlVariableDeclaration::GetCapitalizedName() const {
927   AIDL_FATAL_IF(name_.size() <= 0, *this) << "Name can't be empty.";
928   string str = name_;
929   str[0] = static_cast<char>(toupper(str[0]));
930   return str;
931 }
932 
ToString() const933 string AidlVariableDeclaration::ToString() const {
934   string ret = type_->ToString() + " " + name_;
935   if (default_value_ != nullptr && default_user_specified_) {
936     ret += " = " + ValueString(AidlConstantValueDecorator);
937   }
938   return ret;
939 }
940 
Signature() const941 string AidlVariableDeclaration::Signature() const {
942   return type_->Signature() + " " + name_;
943 }
944 
ValueString(const ConstantValueDecorator & decorator) const945 std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
946   if (default_value_ != nullptr) {
947     return default_value_->ValueString(GetType(), decorator);
948   } else {
949     return "";
950   }
951 }
952 
TraverseChildren(std::function<void (const AidlNode &)> traverse) const953 void AidlVariableDeclaration::TraverseChildren(
954     std::function<void(const AidlNode&)> traverse) const {
955   traverse(GetType());
956   if (auto default_value = GetDefaultValue(); default_value) {
957     traverse(*default_value);
958   }
959 }
960 
AidlArgument(const AidlLocation & location,AidlArgument::Direction direction,AidlTypeSpecifier * type,const std::string & name)961 AidlArgument::AidlArgument(const AidlLocation& location, AidlArgument::Direction direction,
962                            AidlTypeSpecifier* type, const std::string& name)
963     : AidlVariableDeclaration(location, type, name),
964       direction_(direction),
965       direction_specified_(true) {}
966 
AidlArgument(const AidlLocation & location,AidlTypeSpecifier * type,const std::string & name)967 AidlArgument::AidlArgument(const AidlLocation& location, AidlTypeSpecifier* type,
968                            const std::string& name)
969     : AidlVariableDeclaration(location, type, name),
970       direction_(AidlArgument::IN_DIR),
971       direction_specified_(false) {}
972 
to_string(AidlArgument::Direction direction)973 static std::string to_string(AidlArgument::Direction direction) {
974   switch (direction) {
975     case AidlArgument::IN_DIR:
976       return "in";
977     case AidlArgument::OUT_DIR:
978       return "out";
979     case AidlArgument::INOUT_DIR:
980       return "inout";
981   }
982 }
983 
GetDirectionSpecifier() const984 string AidlArgument::GetDirectionSpecifier() const {
985   string ret;
986   if (direction_specified_) {
987     ret = to_string(direction_);
988   }
989   return ret;
990 }
991 
ToString() const992 string AidlArgument::ToString() const {
993   if (direction_specified_) {
994     return GetDirectionSpecifier() + " " + AidlVariableDeclaration::ToString();
995   } else {
996     return AidlVariableDeclaration::ToString();
997   }
998 }
999 
FormatDirections(const std::set<AidlArgument::Direction> & directions)1000 static std::string FormatDirections(const std::set<AidlArgument::Direction>& directions) {
1001   std::vector<std::string> out;
1002   for (const auto& d : directions) {
1003     out.push_back(to_string(d));
1004   }
1005 
1006   if (out.size() <= 1) {  // [] => "" or [A] => "A"
1007     return Join(out, "");
1008   } else if (out.size() == 2) {  // [A,B] => "A or B"
1009     return Join(out, " or ");
1010   } else {  // [A,B,C] => "A, B, or C"
1011     out.back() = "or " + out.back();
1012     return Join(out, ", ");
1013   }
1014 }
1015 
CheckValid(const AidlTypenames & typenames) const1016 bool AidlArgument::CheckValid(const AidlTypenames& typenames) const {
1017   if (!GetType().CheckValid(typenames)) {
1018     return false;
1019   }
1020 
1021   const auto& aspect = typenames.GetArgumentAspect(GetType());
1022 
1023   if (aspect.possible_directions.size() == 0) {
1024     AIDL_ERROR(this) << aspect.name << " cannot be an argument type";
1025     return false;
1026   }
1027 
1028   // when direction is not specified, "in" is assumed and should be the only possible direction
1029   if (!DirectionWasSpecified() && aspect.possible_directions != std::set{AidlArgument::IN_DIR}) {
1030     AIDL_ERROR(this) << "The direction of '" << GetName() << "' is not specified. " << aspect.name
1031                      << " can be an " << FormatDirections(aspect.possible_directions)
1032                      << " parameter.";
1033     return false;
1034   }
1035 
1036   if (aspect.possible_directions.count(GetDirection()) == 0) {
1037     AIDL_ERROR(this) << "'" << GetName() << "' can't be an " << GetDirectionSpecifier()
1038                      << " parameter because " << aspect.name << " can only be an "
1039                      << FormatDirections(aspect.possible_directions) << " parameter.";
1040     return false;
1041   }
1042 
1043   return true;
1044 }
1045 
IsHidden() const1046 bool AidlCommentable::IsHidden() const {
1047   return android::aidl::HasHideInComments(GetComments());
1048 }
1049 
IsDeprecated() const1050 bool AidlCommentable::IsDeprecated() const {
1051   return android::aidl::FindDeprecated(GetComments()).has_value();
1052 }
1053 
AidlMember(const AidlLocation & location,const Comments & comments)1054 AidlMember::AidlMember(const AidlLocation& location, const Comments& comments)
1055     : AidlAnnotatable(location, comments) {}
1056 
AidlConstantDeclaration(const AidlLocation & location,AidlTypeSpecifier * type,const std::string & name,AidlConstantValue * value)1057 AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
1058                                                  AidlTypeSpecifier* type, const std::string& name,
1059                                                  AidlConstantValue* value)
1060     : AidlMember(location, type->GetComments()), type_(type), name_(name), value_(value) {}
1061 
CheckValid(const AidlTypenames & typenames) const1062 bool AidlConstantDeclaration::CheckValid(const AidlTypenames& typenames) const {
1063   bool valid = true;
1064   valid &= type_->CheckValid(typenames);
1065   valid &= value_->CheckValid();
1066   valid = valid && !ValueString(AidlConstantValueDecorator).empty();
1067   if (!valid) return false;
1068 
1069   const static set<string> kSupportedConstTypes = {"String", "byte",  "int",
1070                                                    "long",   "float", "double"};
1071   if (kSupportedConstTypes.find(type_->Signature()) == kSupportedConstTypes.end()) {
1072     AIDL_ERROR(this) << "Constant of type " << type_->Signature() << " is not supported.";
1073     return false;
1074   }
1075 
1076   return true;
1077 }
1078 
ToString() const1079 string AidlConstantDeclaration::ToString() const {
1080   return "const " + type_->ToString() + " " + name_ + " = " +
1081          ValueString(AidlConstantValueDecorator);
1082 }
1083 
Signature() const1084 string AidlConstantDeclaration::Signature() const {
1085   return type_->Signature() + " " + name_;
1086 }
1087 
AidlMethod(const AidlLocation & location,bool oneway,AidlTypeSpecifier * type,const std::string & name,std::vector<std::unique_ptr<AidlArgument>> * args,const Comments & comments)1088 AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
1089                        const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
1090                        const Comments& comments)
1091     : AidlMethod(location, oneway, type, name, args, comments, 0) {
1092   has_id_ = false;
1093 }
1094 
AidlMethod(const AidlLocation & location,bool oneway,AidlTypeSpecifier * type,const std::string & name,std::vector<std::unique_ptr<AidlArgument>> * args,const Comments & comments,int id)1095 AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
1096                        const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
1097                        const Comments& comments, int id)
1098     : AidlMember(location, comments),
1099       oneway_(oneway),
1100       type_(type),
1101       name_(name),
1102       arguments_(std::move(*args)),
1103       id_(id) {
1104   has_id_ = true;
1105   delete args;
1106   for (const unique_ptr<AidlArgument>& a : arguments_) {
1107     if (a->IsIn()) { in_arguments_.push_back(a.get()); }
1108     if (a->IsOut()) { out_arguments_.push_back(a.get()); }
1109   }
1110 }
1111 
Signature() const1112 string AidlMethod::Signature() const {
1113   vector<string> arg_signatures;
1114   for (const auto& arg : GetArguments()) {
1115     arg_signatures.emplace_back(arg->GetType().Signature());
1116   }
1117   return GetName() + "(" + Join(arg_signatures, ", ") + ")";
1118 }
1119 
ToString() const1120 string AidlMethod::ToString() const {
1121   vector<string> arg_strings;
1122   for (const auto& arg : GetArguments()) {
1123     arg_strings.emplace_back(arg->ToString());
1124   }
1125   string ret = (IsOneway() ? "oneway " : "") + GetType().ToString() + " " + GetName() + "(" +
1126                Join(arg_strings, ", ") + ")";
1127   if (HasId()) {
1128     ret += " = " + std::to_string(GetId());
1129   }
1130   return ret;
1131 }
1132 
CheckValid(const AidlTypenames & typenames) const1133 bool AidlMethod::CheckValid(const AidlTypenames& typenames) const {
1134   if (!GetType().CheckValid(typenames)) {
1135     return false;
1136   }
1137 
1138   // TODO(b/156872582): Support it when ParcelableHolder supports every backend.
1139   if (GetType().GetName() == "ParcelableHolder") {
1140     AIDL_ERROR(this) << "ParcelableHolder cannot be a return type";
1141     return false;
1142   }
1143   if (IsOneway() && GetType().GetName() != "void") {
1144     AIDL_ERROR(this) << "oneway method '" << GetName() << "' cannot return a value";
1145     return false;
1146   }
1147 
1148   set<string> argument_names;
1149   for (const auto& arg : GetArguments()) {
1150     auto it = argument_names.find(arg->GetName());
1151     if (it != argument_names.end()) {
1152       AIDL_ERROR(this) << "method '" << GetName() << "' has duplicate argument name '"
1153                        << arg->GetName() << "'";
1154       return false;
1155     }
1156     argument_names.insert(arg->GetName());
1157 
1158     if (!arg->CheckValid(typenames)) {
1159       return false;
1160     }
1161 
1162     if (IsOneway() && arg->IsOut()) {
1163       AIDL_ERROR(this) << "oneway method '" << this->GetName() << "' cannot have out parameters";
1164       return false;
1165     }
1166 
1167     // check that the name doesn't match a keyword
1168     if (IsJavaKeyword(arg->GetName().c_str())) {
1169       AIDL_ERROR(arg) << "Argument name is a Java or aidl keyword";
1170       return false;
1171     }
1172 
1173     // Reserve a namespace for internal use
1174     if (android::base::StartsWith(arg->GetName(), "_aidl")) {
1175       AIDL_ERROR(arg) << "Argument name cannot begin with '_aidl'";
1176       return false;
1177     }
1178 
1179     if (arg->GetType().GetName() == "void") {
1180       AIDL_ERROR(arg->GetType()) << "'void' is an invalid type for the parameter '"
1181                                  << arg->GetName() << "'";
1182       return false;
1183     }
1184   }
1185   return true;
1186 }
1187 
AidlDefinedType(const AidlLocation & location,const std::string & name,const Comments & comments,const std::string & package,std::vector<std::unique_ptr<AidlMember>> * members)1188 AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
1189                                  const Comments& comments, const std::string& package,
1190                                  std::vector<std::unique_ptr<AidlMember>>* members)
1191     : AidlMember(location, comments), AidlScope(this), name_(name), package_(package) {
1192   // adjust name/package when name is fully qualified (for preprocessed files)
1193   if (package_.empty() && name_.find('.') != std::string::npos) {
1194     // Note that this logic is absolutely wrong.  Given a parcelable
1195     // org.some.Foo.Bar, the class name is Foo.Bar, but this code will claim that
1196     // the class is just Bar.  However, this was the way it was done in the past.
1197     //
1198     // See b/17415692
1199     auto pos = name.rfind('.');
1200     // name is the last part.
1201     name_ = name.substr(pos + 1);
1202     // package is the initial parts (except the last).
1203     package_ = name.substr(0, pos);
1204   }
1205   if (members) {
1206     for (auto& m : *members) {
1207       if (auto constant = AidlCast<AidlConstantDeclaration>(*m); constant) {
1208         constants_.emplace_back(constant);
1209       } else if (auto variable = AidlCast<AidlVariableDeclaration>(*m); variable) {
1210         variables_.emplace_back(variable);
1211       } else if (auto method = AidlCast<AidlMethod>(*m); method) {
1212         methods_.emplace_back(method);
1213       } else if (auto type = AidlCast<AidlDefinedType>(*m); type) {
1214         type->SetEnclosingScope(this);
1215         types_.emplace_back(type);
1216       } else {
1217         AIDL_FATAL(*m) << "Unknown member type.";
1218       }
1219       members_.push_back(m.release());
1220     }
1221     delete members;
1222   }
1223 }
1224 
CheckValid(const AidlTypenames & typenames) const1225 bool AidlDefinedType::CheckValid(const AidlTypenames& typenames) const {
1226   if (!AidlAnnotatable::CheckValid(typenames)) {
1227     return false;
1228   }
1229   if (!CheckValidWithMembers(typenames)) {
1230     return false;
1231   }
1232   return true;
1233 }
1234 
GetCanonicalName() const1235 std::string AidlDefinedType::GetCanonicalName() const {
1236   if (auto parent = GetParentType(); parent) {
1237     return parent->GetCanonicalName() + "." + GetName();
1238   }
1239   if (package_.empty()) {
1240     return GetName();
1241   }
1242   return GetPackage() + "." + GetName();
1243 }
1244 
CheckValidWithMembers(const AidlTypenames & typenames) const1245 bool AidlDefinedType::CheckValidWithMembers(const AidlTypenames& typenames) const {
1246   bool success = true;
1247 
1248   for (const auto& t : GetNestedTypes()) {
1249     success = success && t->CheckValid(typenames);
1250   }
1251 
1252   if (auto parameterizable = AsParameterizable();
1253       parameterizable && parameterizable->IsGeneric() && !GetNestedTypes().empty()) {
1254     AIDL_ERROR(this) << "Generic types can't have nested types.";
1255     return false;
1256   }
1257 
1258   std::set<std::string> nested_type_names;
1259   for (const auto& t : GetNestedTypes()) {
1260     bool duplicated = !nested_type_names.emplace(t->GetName()).second;
1261     if (duplicated) {
1262       AIDL_ERROR(t) << "Redefinition of '" << t->GetName() << "'.";
1263       success = false;
1264     }
1265     // nested type can't have a parent name
1266     if (t->GetName() == GetName()) {
1267       AIDL_ERROR(t) << "Nested type '" << GetName() << "' has the same name as its parent.";
1268       success = false;
1269     }
1270     // Having unstructured parcelables as nested types doesn't make sense because they are defined
1271     // somewhere else in native languages (e.g. C++, Java...).
1272     if (AidlCast<AidlParcelable>(*t)) {
1273       AIDL_ERROR(t) << "'" << t->GetName()
1274                     << "' is nested. Unstructured parcelables should be at the root scope.";
1275       return false;
1276     }
1277   }
1278 
1279   if (!TopologicalVisit(GetNestedTypes(), [](auto&) {})) {
1280     AIDL_ERROR(this) << GetName()
1281                      << " has nested types with cyclic references. C++ and NDK backends don't "
1282                         "support cyclic references.";
1283     return false;
1284   }
1285 
1286   for (const auto& v : GetFields()) {
1287     const bool field_valid = v->CheckValid(typenames);
1288     success = success && field_valid;
1289   }
1290 
1291   // field names should be unique
1292   std::set<std::string> fieldnames;
1293   for (const auto& v : GetFields()) {
1294     bool duplicated = !fieldnames.emplace(v->GetName()).second;
1295     if (duplicated) {
1296       AIDL_ERROR(v) << "'" << GetName() << "' has duplicate field name '" << v->GetName() << "'";
1297       success = false;
1298     }
1299   }
1300 
1301   // immutable parcelables should have immutable fields.
1302   if (IsJavaOnlyImmutable()) {
1303     for (const auto& v : GetFields()) {
1304       if (!typenames.CanBeJavaOnlyImmutable(v->GetType())) {
1305         AIDL_ERROR(v) << "The @JavaOnlyImmutable '" << GetName() << "' has a "
1306                       << "non-immutable field named '" << v->GetName() << "'.";
1307         success = false;
1308       }
1309     }
1310   }
1311 
1312   // Rust derive fields must be transitive
1313   const std::vector<std::string> rust_derives = RustDerive();
1314   for (const auto& v : GetFields()) {
1315     const AidlDefinedType* field = typenames.TryGetDefinedType(v->GetType().GetName());
1316     if (!field) continue;
1317 
1318     // could get this from CONTEXT_*, but we don't currently save this info when we validated
1319     // contexts
1320     if (!field->AsStructuredParcelable() && !field->AsUnionDeclaration()) continue;
1321 
1322     auto subs = field->RustDerive();
1323     for (const std::string& derive : rust_derives) {
1324       if (std::find(subs.begin(), subs.end(), derive) == subs.end()) {
1325         AIDL_ERROR(v) << "Field " << v->GetName() << " of type with @RustDerive " << derive
1326                       << " also needs to derive this";
1327         success = false;
1328       }
1329     }
1330   }
1331 
1332   set<string> constant_names;
1333   for (const auto& constant : GetConstantDeclarations()) {
1334     if (constant_names.count(constant->GetName()) > 0) {
1335       AIDL_ERROR(constant) << "Found duplicate constant name '" << constant->GetName() << "'";
1336       success = false;
1337     }
1338     constant_names.insert(constant->GetName());
1339     success = success && constant->CheckValid(typenames);
1340   }
1341 
1342   return success;
1343 }
1344 
CheckValidForGetterNames() const1345 bool AidlDefinedType::CheckValidForGetterNames() const {
1346   bool success = true;
1347   std::set<std::string> getters;
1348   for (const auto& v : GetFields()) {
1349     bool duplicated = !getters.emplace(v->GetCapitalizedName()).second;
1350     if (duplicated) {
1351       AIDL_ERROR(v) << "'" << GetName() << "' has duplicate field name '" << v->GetName()
1352                     << "' after capitalizing the first letter";
1353       success = false;
1354     }
1355   }
1356   return success;
1357 }
1358 
GetParentType() const1359 const AidlDefinedType* AidlDefinedType::GetParentType() const {
1360   AIDL_FATAL_IF(GetEnclosingScope() == nullptr, this) << "Scope is not set.";
1361   return AidlCast<AidlDefinedType>(GetEnclosingScope()->GetNode());
1362 }
1363 
GetRootType() const1364 const AidlDefinedType* AidlDefinedType::GetRootType() const {
1365   const AidlDefinedType* root = this;
1366   for (auto parent = root->GetParentType(); parent; parent = parent->GetParentType()) {
1367     root = parent;
1368   }
1369   return root;
1370 }
1371 
1372 // Resolve `name` in the current scope. If not found, delegate to the parent
ResolveName(const std::string & name) const1373 std::string AidlDefinedType::ResolveName(const std::string& name) const {
1374   // For example, in the following, t1's type Baz means x.Foo.Bar.Baz
1375   // while t2's type is y.Baz.
1376   // package x;
1377   // import y.Baz;
1378   // parcelable Foo {
1379   //   parcelable Bar {
1380   //     enum Baz { ... }
1381   //     Baz t1; // -> should be x.Foo.Bar.Baz
1382   //   }
1383   //   Baz t2; // -> should be y.Baz
1384   //   Bar.Baz t3; // -> should be x.Foo.Bar.Baz
1385   // }
1386   AIDL_FATAL_IF(!GetEnclosingScope(), this)
1387       << "Type should have an enclosing scope.(e.g. AidlDocument)";
1388   if (AidlTypenames::IsBuiltinTypename(name)) {
1389     return name;
1390   }
1391 
1392   const auto first_dot = name.find_first_of('.');
1393   // For "Outer.Inner", we look up "Outer" in the import list.
1394   const std::string class_name =
1395       (first_dot == std::string::npos) ? name : name.substr(0, first_dot);
1396   // Keep ".Inner", to make a fully-qualified name
1397   const std::string nested_type = (first_dot == std::string::npos) ? "" : name.substr(first_dot);
1398 
1399   // check if it is a nested type
1400   for (const auto& type : GetNestedTypes()) {
1401     if (type->GetName() == class_name) {
1402       return type->GetCanonicalName() + nested_type;
1403     }
1404   }
1405 
1406   return GetEnclosingScope()->ResolveName(name);
1407 }
1408 
1409 template <>
AidlCast(const AidlNode & node)1410 const AidlDefinedType* AidlCast<AidlDefinedType>(const AidlNode& node) {
1411   struct Visitor : AidlVisitor {
1412     const AidlDefinedType* defined_type = nullptr;
1413     void Visit(const AidlInterface& t) override { defined_type = &t; }
1414     void Visit(const AidlEnumDeclaration& t) override { defined_type = &t; }
1415     void Visit(const AidlStructuredParcelable& t) override { defined_type = &t; }
1416     void Visit(const AidlUnionDecl& t) override { defined_type = &t; }
1417     void Visit(const AidlParcelable& t) override { defined_type = &t; }
1418   } v;
1419   node.DispatchVisit(v);
1420   return v.defined_type;
1421 }
1422 
GetDocument() const1423 const AidlDocument& AidlDefinedType::GetDocument() const {
1424   const AidlDefinedType* root = GetRootType();
1425   auto scope = root->GetEnclosingScope();
1426   AIDL_FATAL_IF(!scope, this) << "no scope defined.";
1427   auto doc = AidlCast<AidlDocument>(scope->GetNode());
1428   AIDL_FATAL_IF(!doc, this) << "root scope is not a document.";
1429   return *doc;
1430 }
1431 
AidlParcelable(const AidlLocation & location,const std::string & name,const std::string & package,const Comments & comments,const AidlUnstructuredHeaders & headers,std::vector<std::string> * type_params,std::vector<std::unique_ptr<AidlMember>> * members)1432 AidlParcelable::AidlParcelable(const AidlLocation& location, const std::string& name,
1433                                const std::string& package, const Comments& comments,
1434                                const AidlUnstructuredHeaders& headers,
1435                                std::vector<std::string>* type_params,
1436                                std::vector<std::unique_ptr<AidlMember>>* members)
1437     : AidlDefinedType(location, name, comments, package, members),
1438       AidlParameterizable<std::string>(type_params),
1439       headers_(headers) {
1440   // Strip off quotation marks if we actually have headers.
1441   if (headers_.cpp.length() >= 2) {
1442     headers_.cpp = headers_.cpp.substr(1, headers_.cpp.length() - 2);
1443   }
1444   if (headers_.ndk.length() >= 2) {
1445     headers_.ndk = headers_.ndk.substr(1, headers_.ndk.length() - 2);
1446   }
1447 }
1448 
1449 template <typename T>
CheckValid() const1450 bool AidlParameterizable<T>::CheckValid() const {
1451   return true;
1452 };
1453 
1454 template <>
CheckValid() const1455 bool AidlParameterizable<std::string>::CheckValid() const {
1456   if (!IsGeneric()) {
1457     return true;
1458   }
1459   std::unordered_set<std::string> set(GetTypeParameters().begin(), GetTypeParameters().end());
1460   if (set.size() != GetTypeParameters().size()) {
1461     AIDL_ERROR(this->AsAidlNode()) << "Every type parameter should be unique.";
1462     return false;
1463   }
1464   return true;
1465 }
1466 
CheckValid(const AidlTypenames & typenames) const1467 bool AidlParcelable::CheckValid(const AidlTypenames& typenames) const {
1468   if (!AidlDefinedType::CheckValid(typenames)) {
1469     return false;
1470   }
1471   if (!AidlParameterizable<std::string>::CheckValid()) {
1472     return false;
1473   }
1474 
1475   bool success = true;
1476   if (IsFixedSize()) {
1477     for (const auto& v : GetFields()) {
1478       if (!typenames.CanBeFixedSize(v->GetType())) {
1479         AIDL_ERROR(v) << "The @FixedSize parcelable '" << this->GetName() << "' has a "
1480                       << "non-fixed size field named " << v->GetName() << ".";
1481         success = false;
1482       }
1483     }
1484   }
1485 
1486   return success;
1487 }
1488 
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)1489 AidlStructuredParcelable::AidlStructuredParcelable(
1490     const AidlLocation& location, const std::string& name, const std::string& package,
1491     const Comments& comments, std::vector<std::string>* type_params,
1492     std::vector<std::unique_ptr<AidlMember>>* members)
1493     : AidlParcelable(location, name, package, comments, {} /*headers*/, type_params, members) {}
1494 
CheckValid(const AidlTypenames & typenames) const1495 bool AidlStructuredParcelable::CheckValid(const AidlTypenames& typenames) const {
1496   if (!AidlParcelable::CheckValid(typenames)) {
1497     return false;
1498   }
1499 
1500   bool success = true;
1501 
1502   if (IsJavaOnlyImmutable()) {
1503     // Immutable parcelables provide getters
1504     if (!CheckValidForGetterNames()) {
1505       success = false;
1506     }
1507   }
1508 
1509   return success;
1510 }
1511 
1512 // TODO: we should treat every backend all the same in future.
LanguageSpecificCheckValid(Options::Language lang) const1513 bool AidlTypeSpecifier::LanguageSpecificCheckValid(Options::Language lang) const {
1514   if (this->GetName() == "FileDescriptor" &&
1515       (lang == Options::Language::NDK || lang == Options::Language::RUST)) {
1516     AIDL_ERROR(this) << "FileDescriptor isn't supported by the " << to_string(lang) << " backend.";
1517     return false;
1518   }
1519 
1520   if (lang != Options::Language::JAVA) {
1521     if (this->GetName() == "List" && !this->IsGeneric()) {
1522       AIDL_ERROR(this) << "Currently, only the Java backend supports non-generic List.";
1523       return false;
1524     }
1525     if (this->GetName() == "Map" || this->GetName() == "CharSequence") {
1526       AIDL_ERROR(this) << "Currently, only Java backend supports " << this->GetName() << ".";
1527       return false;
1528     }
1529   }
1530 
1531   return true;
1532 }
1533 
1534 // TODO: we should treat every backend all the same in future.
LanguageSpecificCheckValid(Options::Language lang) const1535 bool AidlDefinedType::LanguageSpecificCheckValid(Options::Language lang) const {
1536   struct Visitor : AidlVisitor {
1537     Visitor(Options::Language lang) : lang(lang) {}
1538     void Visit(const AidlTypeSpecifier& type) override {
1539       success = success && type.LanguageSpecificCheckValid(lang);
1540     }
1541     Options::Language lang;
1542     bool success = true;
1543   } v(lang);
1544   VisitTopDown(v, *this);
1545   return v.success;
1546 }
1547 
AidlEnumerator(const AidlLocation & location,const std::string & name,AidlConstantValue * value,const Comments & comments)1548 AidlEnumerator::AidlEnumerator(const AidlLocation& location, const std::string& name,
1549                                AidlConstantValue* value, const Comments& comments)
1550     : AidlCommentable(location, comments),
1551       name_(name),
1552       value_(value),
1553       value_user_specified_(value != nullptr) {}
1554 
CheckValid(const AidlTypeSpecifier & enum_backing_type) const1555 bool AidlEnumerator::CheckValid(const AidlTypeSpecifier& enum_backing_type) const {
1556   if (GetValue() == nullptr) {
1557     return false;
1558   }
1559   if (!GetValue()->CheckValid()) {
1560     return false;
1561   }
1562   if (GetValue()->ValueString(enum_backing_type, AidlConstantValueDecorator).empty()) {
1563     AIDL_ERROR(this) << "Enumerator type differs from enum backing type.";
1564     return false;
1565   }
1566   return true;
1567 }
1568 
ValueString(const AidlTypeSpecifier & backing_type,const ConstantValueDecorator & decorator) const1569 string AidlEnumerator::ValueString(const AidlTypeSpecifier& backing_type,
1570                                    const ConstantValueDecorator& decorator) const {
1571   return GetValue()->ValueString(backing_type, decorator);
1572 }
1573 
AidlEnumDeclaration(const AidlLocation & location,const std::string & name,std::vector<std::unique_ptr<AidlEnumerator>> * enumerators,const std::string & package,const Comments & comments)1574 AidlEnumDeclaration::AidlEnumDeclaration(const AidlLocation& location, const std::string& name,
1575                                          std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
1576                                          const std::string& package, const Comments& comments)
1577     : AidlDefinedType(location, name, comments, package, nullptr),
1578       enumerators_(std::move(*enumerators)) {
1579   // Fill missing enumerator values with <prev + 1>
1580   // This can't be done in Autofill() because type/ref resolution depends on this.
1581   // For example, with enum E { A, B = A }, B's value 'A' is a reference which can't be
1582   // resolved if A has no value set.
1583   const AidlEnumerator* previous = nullptr;
1584   for (const auto& enumerator : enumerators_) {
1585     if (enumerator->GetValue() == nullptr) {
1586       auto loc = enumerator->GetLocation();
1587       if (previous == nullptr) {
1588         enumerator->SetValue(
1589             std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(loc, "0")));
1590       } else {
1591         auto prev_value = std::make_unique<AidlConstantReference>(loc, previous->GetName());
1592         enumerator->SetValue(std::make_unique<AidlBinaryConstExpression>(
1593             loc, std::move(prev_value), "+",
1594             std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(loc, "1"))));
1595       }
1596     }
1597     previous = enumerator.get();
1598   }
1599 }
1600 
Autofill(const AidlTypenames & typenames)1601 bool AidlEnumDeclaration::Autofill(const AidlTypenames& typenames) {
1602   if (auto annot = BackingType(); annot != nullptr) {
1603     // Autofill() is called before the grand CheckValid(). But AidlAnnotation::ParamValue()
1604     // calls AidlConstantValue::evaluate() which requires CheckValid() to be called before. So we
1605     // need to call CheckValid().
1606     if (!annot->CheckValid()) {
1607       return false;
1608     }
1609     auto type = annot->ParamValue<std::string>("type").value();
1610     backing_type_ = typenames.MakeResolvedType(annot->GetLocation(), type, false);
1611   } else {
1612     // Default to byte type for enums.
1613     backing_type_ = typenames.MakeResolvedType(GetLocation(), "byte", false);
1614   }
1615 
1616   // we only support/test a few backing types, so make sure this is a supported
1617   // one (otherwise boolean might work, which isn't supported/tested in all
1618   // backends)
1619   static std::set<string> kBackingTypes = {"byte", "int", "long"};
1620   if (kBackingTypes.find(backing_type_->GetName()) == kBackingTypes.end()) {
1621     AIDL_ERROR(this) << "Invalid backing type: " << backing_type_->GetName()
1622                      << ". Backing type must be one of: " << Join(kBackingTypes, ", ");
1623     return false;
1624   }
1625   return true;
1626 }
1627 
CheckValid(const AidlTypenames & typenames) const1628 bool AidlEnumDeclaration::CheckValid(const AidlTypenames& typenames) const {
1629   if (!AidlDefinedType::CheckValid(typenames)) {
1630     return false;
1631   }
1632   if (!GetMembers().empty()) {
1633     AIDL_ERROR(this) << "Enum doesn't support fields/constants/methods.";
1634     return false;
1635   }
1636   if (backing_type_ == nullptr) {
1637     AIDL_ERROR(this) << "Enum declaration missing backing type.";
1638     return false;
1639   }
1640   bool success = true;
1641   for (const auto& enumerator : enumerators_) {
1642     success = success && enumerator->CheckValid(GetBackingType());
1643   }
1644 
1645   return success;
1646 }
1647 
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)1648 AidlUnionDecl::AidlUnionDecl(const AidlLocation& location, const std::string& name,
1649                              const std::string& package, const Comments& comments,
1650                              std::vector<std::string>* type_params,
1651                              std::vector<std::unique_ptr<AidlMember>>* members)
1652     : AidlParcelable(location, name, package, comments, {} /*headers*/, type_params, members) {}
1653 
CheckValid(const AidlTypenames & typenames) const1654 bool AidlUnionDecl::CheckValid(const AidlTypenames& typenames) const {
1655   // visit parents
1656   if (!AidlParcelable::CheckValid(typenames)) {
1657     return false;
1658   }
1659 
1660   // unions provide getters always
1661   if (!CheckValidForGetterNames()) {
1662     return false;
1663   }
1664 
1665   // now, visit self!
1666   bool success = true;
1667 
1668   // TODO(b/170807936) do we need to allow ParcelableHolder in union?
1669   for (const auto& v : GetFields()) {
1670     if (v->GetType().GetName() == "ParcelableHolder") {
1671       AIDL_ERROR(*v) << "A union can't have a member of ParcelableHolder '" << v->GetName() << "'";
1672       success = false;
1673     }
1674   }
1675 
1676   if (GetFields().empty()) {
1677     AIDL_ERROR(*this) << "The union '" << this->GetName() << "' has no fields.";
1678     return false;
1679   }
1680 
1681   // first member should have useful default value (implicit or explicit)
1682   const auto& first = GetFields()[0];
1683   if (!first->HasUsefulDefaultValue()) {
1684     // Most types can be initialized without a default value. For example,
1685     // interface types are inherently nullable. But, enum types should have
1686     // an explicit default value.
1687     if (!first->GetType().IsArray() && typenames.GetEnumDeclaration(first->GetType())) {
1688       AIDL_ERROR(first)
1689           << "The union's first member should have a useful default value. Enum types can be "
1690              "initialized with a reference. (e.g. ... = MyEnum.FOO;)";
1691       return false;
1692     }
1693     // In Java, array types are initialized as null without a default value. To be sure that default
1694     // initialized unions are accepted by other backends we require arrays also have a default
1695     // value.
1696     if (first->GetType().IsArray()) {
1697       AIDL_ERROR(first)
1698           << "The union's first member should have a useful default value. Arrays can be "
1699              "initialized with values(e.g. ... = { values... };) or marked as @nullable.";
1700       return false;
1701     }
1702   }
1703 
1704   return success;
1705 }
1706 
AidlInterface(const AidlLocation & location,const std::string & name,const Comments & comments,bool oneway,const std::string & package,std::vector<std::unique_ptr<AidlMember>> * members)1707 AidlInterface::AidlInterface(const AidlLocation& location, const std::string& name,
1708                              const Comments& comments, bool oneway, const std::string& package,
1709                              std::vector<std::unique_ptr<AidlMember>>* members)
1710     : AidlDefinedType(location, name, comments, package, members) {
1711   for (auto& m : GetMethods()) {
1712     m.get()->ApplyInterfaceOneway(oneway);
1713   }
1714 }
1715 
CheckValid(const AidlTypenames & typenames) const1716 bool AidlInterface::CheckValid(const AidlTypenames& typenames) const {
1717   if (!AidlDefinedType::CheckValid(typenames)) {
1718     return false;
1719   }
1720   // Has to be a pointer due to deleting copy constructor. No idea why.
1721   map<string, const AidlMethod*> method_names;
1722   for (const auto& m : GetMethods()) {
1723     if (!m->CheckValid(typenames)) {
1724       return false;
1725     }
1726 
1727     auto it = method_names.find(m->GetName());
1728     // prevent duplicate methods
1729     if (it == method_names.end()) {
1730       method_names[m->GetName()] = m.get();
1731     } else {
1732       AIDL_ERROR(m) << "attempt to redefine method " << m->GetName() << ":";
1733       AIDL_ERROR(it->second) << "previously defined here.";
1734       return false;
1735     }
1736 
1737     static set<string> reserved_methods{"asBinder()", "getInterfaceHash()", "getInterfaceVersion()",
1738                                         "getTransactionName(int)"};
1739 
1740     if (reserved_methods.find(m->Signature()) != reserved_methods.end()) {
1741       AIDL_ERROR(m) << " method " << m->Signature() << " is reserved for internal use.";
1742       return false;
1743     }
1744 
1745     if (!CheckValidPermissionAnnotations(*m.get())) {
1746       return false;
1747     }
1748   }
1749 
1750   return true;
1751 }
1752 
CheckValidPermissionAnnotations(const AidlMethod & m) const1753 bool AidlInterface::CheckValidPermissionAnnotations(const AidlMethod& m) const {
1754   if (IsPermissionAnnotated() && m.GetType().IsPermissionAnnotated()) {
1755     AIDL_ERROR(m) << "The interface " << GetName()
1756                   << " uses a permission annotation but the method " << m.GetName()
1757                   << " is also annotated.\n"
1758                   << "Consider distributing the annotation to each method.";
1759     return false;
1760   }
1761   return true;
1762 }
1763 
UsesPermissions() const1764 bool AidlInterface::UsesPermissions() const {
1765   if (EnforceExpression()) {
1766     return true;
1767   }
1768   for (auto& m : GetMethods()) {
1769     if (m->GetType().EnforceExpression()) {
1770       return true;
1771     }
1772   }
1773   return false;
1774 }
1775 
GetDescriptor() const1776 std::string AidlInterface::GetDescriptor() const {
1777   std::string annotatedDescriptor = AidlAnnotatable::GetDescriptor();
1778   if (annotatedDescriptor != "") {
1779     return annotatedDescriptor;
1780   }
1781   return GetCanonicalName();
1782 }
1783 
AidlDocument(const AidlLocation & location,const Comments & comments,std::vector<string> imports,std::vector<std::unique_ptr<AidlDefinedType>> defined_types,bool is_preprocessed)1784 AidlDocument::AidlDocument(const AidlLocation& location, const Comments& comments,
1785                            std::vector<string> imports,
1786                            std::vector<std::unique_ptr<AidlDefinedType>> defined_types,
1787                            bool is_preprocessed)
1788     : AidlCommentable(location, comments),
1789       AidlScope(this),
1790       imports_(std::move(imports)),
1791       defined_types_(std::move(defined_types)),
1792       is_preprocessed_(is_preprocessed) {
1793   for (const auto& t : defined_types_) {
1794     t->SetEnclosingScope(this);
1795   }
1796 }
1797 
1798 // Resolves type name in the current document.
1799 // - built-in types
1800 // - imported types
1801 // - top-level type
ResolveName(const std::string & name) const1802 std::string AidlDocument::ResolveName(const std::string& name) const {
1803   if (AidlTypenames::IsBuiltinTypename(name)) {
1804     return name;
1805   }
1806 
1807   const auto first_dot = name.find_first_of('.');
1808   // For "Outer.Inner", we look up "Outer" in the import list.
1809   const std::string class_name =
1810       (first_dot == std::string::npos) ? name : name.substr(0, first_dot);
1811   // Keep ".Inner", to make a fully-qualified name
1812   const std::string nested_type = (first_dot == std::string::npos) ? "" : name.substr(first_dot);
1813 
1814   for (const auto& import : Imports()) {
1815     if (SimpleName(import) == class_name) {
1816       return import + nested_type;
1817     }
1818   }
1819 
1820   // check if it is a top-level type.
1821   for (const auto& type : DefinedTypes()) {
1822     if (type->GetName() == class_name) {
1823       return type->GetCanonicalName() + nested_type;
1824     }
1825   }
1826 
1827   // name itself might be fully-qualified name.
1828   return name;
1829 }
1830