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