blob: 18c27108655099f3fc8b2b5c6a6d3363d5621d4d [file] [log] [blame]
Will McVickerefd970d2019-09-25 15:28:30 -07001/*
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
Adam Lesinskiffa16862014-01-23 18:17:42 -080017#include "aidl_language.h"
Jiyong Park1deecc32018-07-17 01:14:41 +090018#include "aidl_typenames.h"
Jiyong Parke5c45292020-05-26 19:06:24 +090019#include "parser.h"
Christopher Wileyf690be52015-09-14 15:19:10 -070020
Adam Lesinskiffa16862014-01-23 18:17:42 -080021#include <stdio.h>
Adam Lesinskiffa16862014-01-23 18:17:42 -080022#include <stdlib.h>
Christopher Wiley4a2884b2015-10-07 11:27:45 -070023#include <string.h>
Thiébaud Weksteen9ab59122021-09-20 09:37:38 +020024
Jiyong Park68bc77a2018-07-19 19:00:45 +090025#include <algorithm>
Jiyong Park1deecc32018-07-17 01:14:41 +090026#include <iostream>
Jiyong Park68bc77a2018-07-19 19:00:45 +090027#include <set>
28#include <sstream>
Casey Dahlindd691812015-09-09 17:59:06 -070029#include <string>
Jiyong Park1deecc32018-07-17 01:14:41 +090030#include <utility>
Christopher Wileyf690be52015-09-14 15:19:10 -070031
Steven Moreland1c4ba202018-08-09 10:49:54 -070032#include <android-base/parsedouble.h>
Roshan Pius9d7810a2016-07-28 08:57:50 -070033#include <android-base/parseint.h>
Thiébaud Weksteen9ab59122021-09-20 09:37:38 +020034#include <android-base/result.h>
Elliott Hughes0a620672015-12-04 13:53:18 -080035#include <android-base/strings.h>
Christopher Wileyd76067c2015-10-19 17:00:13 -070036
Thiébaud Weksteen9ab59122021-09-20 09:37:38 +020037#include "aidl.h"
Steven Moreland21780812020-09-11 01:29:45 +000038#include "aidl_language_y.h"
Jooyung Hand4fe00e2021-01-11 16:21:53 +090039#include "comments.h"
Christopher Wiley4a2884b2015-10-07 11:27:45 -070040#include "logging.h"
Thiébaud Weksteen5a4db212021-09-02 17:09:34 +020041#include "permission/parser.h"
Adam Lesinskiffa16862014-01-23 18:17:42 -080042
Casey Dahlin07b9dde2015-09-10 19:13:49 -070043#ifdef _WIN32
44int isatty(int fd)
45{
46 return (fd == 0);
47}
48#endif
49
Christopher Wiley4a2884b2015-10-07 11:27:45 -070050using android::aidl::IoDelegate;
Thiébaud Weksteen9ab59122021-09-20 09:37:38 +020051using android::base::Error;
Christopher Wileyd76067c2015-10-19 17:00:13 -070052using android::base::Join;
Thiébaud Weksteen9ab59122021-09-20 09:37:38 +020053using android::base::Result;
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -080054using android::base::Split;
Casey Dahlindd691812015-09-09 17:59:06 -070055using std::cerr;
Jiyong Park1deecc32018-07-17 01:14:41 +090056using std::pair;
Jiyong Park68bc77a2018-07-19 19:00:45 +090057using std::set;
Christopher Wiley4a2884b2015-10-07 11:27:45 -070058using std::string;
59using std::unique_ptr;
Jiyong Parkccf00f82018-07-17 01:39:23 +090060using std::vector;
Adam Lesinskiffa16862014-01-23 18:17:42 -080061
Jeongik Cha047c5ee2019-08-07 23:16:49 +090062namespace {
Jeongik Cha997281d2020-01-16 15:23:59 +090063bool IsJavaKeyword(const char* str) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +090064 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
Jooyung Han8451a202021-01-16 03:07:06 +090078AidlNode::AidlNode(const AidlLocation& location, const Comments& comments)
Jooyung Han5c7e77c2021-01-20 16:00:29 +090079 : location_(location), comments_(comments) {}
Steven Moreland46e9da82018-07-27 15:45:29 -070080
Mathew Inwoodadb74672019-11-29 14:01:53 +000081std::string AidlNode::PrintLine() const {
Andrei Onea8714b022019-02-01 18:55:54 +000082 std::stringstream ss;
83 ss << location_.file_ << ":" << location_.begin_.line;
84 return ss.str();
85}
86
Mathew Inwoodadb74672019-11-29 14:01:53 +000087std::string AidlNode::PrintLocation() const {
88 std::stringstream ss;
89 ss << location_.file_ << ":" << location_.begin_.line << ":" << location_.begin_.column << ":"
90 << location_.end_.line << ":" << location_.end_.column;
91 return ss.str();
92}
93
Jooyung Han8451a202021-01-16 03:07:06 +090094static const AidlTypeSpecifier kStringType{AIDL_LOCATION_HERE, "String", false, nullptr,
95 Comments{}};
96static const AidlTypeSpecifier kStringArrayType{AIDL_LOCATION_HERE, "String", true, nullptr,
97 Comments{}};
98static const AidlTypeSpecifier kIntType{AIDL_LOCATION_HERE, "int", false, nullptr, Comments{}};
99static const AidlTypeSpecifier kLongType{AIDL_LOCATION_HERE, "long", false, nullptr, Comments{}};
100static const AidlTypeSpecifier kBooleanType{AIDL_LOCATION_HERE, "boolean", false, nullptr,
101 Comments{}};
Jooyung Han5c2fcae2020-12-26 00:04:39 +0900102
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700103const std::vector<AidlAnnotation::Schema>& AidlAnnotation::AllSchemas() {
104 static const std::vector<Schema> kSchemas{
Jooyung Han01720ed2021-08-13 07:46:07 +0900105 {AidlAnnotation::Type::NULLABLE,
106 "nullable",
107 CONTEXT_TYPE_SPECIFIER,
108 {{"heap", kBooleanType}}},
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900109 {AidlAnnotation::Type::UTF8_IN_CPP, "utf8InCpp", CONTEXT_TYPE_SPECIFIER, {}},
110 {AidlAnnotation::Type::SENSITIVE_DATA, "SensitiveData", CONTEXT_TYPE_INTERFACE, {}},
111 {AidlAnnotation::Type::VINTF_STABILITY, "VintfStability", CONTEXT_TYPE, {}},
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700112 {AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
113 "UnsupportedAppUsage",
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900114 CONTEXT_TYPE | CONTEXT_MEMBER,
Jooyung Han5c2fcae2020-12-26 00:04:39 +0900115 {{"expectedSignature", kStringType},
116 {"implicitMember", kStringType},
117 {"maxTargetSdk", kIntType},
118 {"publicAlternatives", kStringType},
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900119 {"trackingBug", kLongType}}},
120 {AidlAnnotation::Type::JAVA_STABLE_PARCELABLE,
121 "JavaOnlyStableParcelable",
122 CONTEXT_TYPE_UNSTRUCTURED_PARCELABLE,
123 {}},
124 {AidlAnnotation::Type::HIDE, "Hide", CONTEXT_TYPE | CONTEXT_MEMBER, {}},
125 {AidlAnnotation::Type::BACKING,
126 "Backing",
127 CONTEXT_TYPE_ENUM,
128 {{"type", kStringType, /* required= */ true}}},
Jooyung Han5721a232020-12-24 04:34:55 +0900129 {AidlAnnotation::Type::JAVA_PASSTHROUGH,
130 "JavaPassthrough",
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900131 CONTEXT_ALL,
132 {{"annotation", kStringType, /* required= */ true}},
133 /* repeatable= */ true},
Jiyong Park9aa3d042020-12-04 23:30:02 +0900134 {AidlAnnotation::Type::JAVA_DERIVE,
Jooyung Han5721a232020-12-24 04:34:55 +0900135 "JavaDerive",
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900136 CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION,
137 {{"toString", kBooleanType}, {"equals", kBooleanType}}},
138 {AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE,
139 "JavaOnlyImmutable",
140 CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION |
141 CONTEXT_TYPE_UNSTRUCTURED_PARCELABLE,
142 {}},
143 {AidlAnnotation::Type::FIXED_SIZE, "FixedSize", CONTEXT_TYPE_STRUCTURED_PARCELABLE, {}},
144 {AidlAnnotation::Type::DESCRIPTOR,
145 "Descriptor",
146 CONTEXT_TYPE_INTERFACE,
147 {{"value", kStringType, /* required= */ true}}},
Andrei Homescue61feb52020-08-18 15:44:24 -0700148 {AidlAnnotation::Type::RUST_DERIVE,
149 "RustDerive",
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900150 CONTEXT_TYPE_STRUCTURED_PARCELABLE | CONTEXT_TYPE_UNION,
Jooyung Han5c2fcae2020-12-26 00:04:39 +0900151 {{"Copy", kBooleanType},
152 {"Clone", kBooleanType},
153 {"PartialOrd", kBooleanType},
154 {"Ord", kBooleanType},
155 {"PartialEq", kBooleanType},
156 {"Eq", kBooleanType},
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900157 {"Hash", kBooleanType}}},
Jooyung Hanf8dbbcc2020-12-26 03:05:55 +0900158 {AidlAnnotation::Type::SUPPRESS_WARNINGS,
159 "SuppressWarnings",
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900160 CONTEXT_TYPE | CONTEXT_MEMBER,
161 {{"value", kStringArrayType, /* required= */ true}}},
Thiébaud Weksteen9ab59122021-09-20 09:37:38 +0200162 {AidlAnnotation::Type::ENFORCE,
163 "Enforce",
164 CONTEXT_METHOD,
165 {{"condition", kStringType, /* required= */ true}}},
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900166 };
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700167 return kSchemas;
168}
Jiyong Park68bc77a2018-07-19 19:00:45 +0900169
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700170std::string AidlAnnotation::TypeToString(Type type) {
171 for (const Schema& schema : AllSchemas()) {
172 if (type == schema.type) return schema.name;
173 }
174 AIDL_FATAL(AIDL_LOCATION_HERE) << "Unrecognized type: " << static_cast<size_t>(type);
175 __builtin_unreachable();
176}
Andrei Onea9445fc62019-06-27 18:11:59 +0100177
Jooyung Han442cacf2021-09-13 17:44:56 +0900178std::unique_ptr<AidlAnnotation> AidlAnnotation::Parse(
Andrei Onea9445fc62019-06-27 18:11:59 +0100179 const AidlLocation& location, const string& name,
Jooyung Han442cacf2021-09-13 17:44:56 +0900180 std::map<std::string, std::shared_ptr<AidlConstantValue>> parameter_list,
Jooyung Han8451a202021-01-16 03:07:06 +0900181 const Comments& comments) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700182 const Schema* schema = nullptr;
183 for (const Schema& a_schema : AllSchemas()) {
184 if (a_schema.name == name) {
185 schema = &a_schema;
186 }
187 }
188
189 if (schema == nullptr) {
Jiyong Park68bc77a2018-07-19 19:00:45 +0900190 std::ostringstream stream;
Steven Moreland46e9da82018-07-27 15:45:29 -0700191 stream << "'" << name << "' is not a recognized annotation. ";
Jiyong Park68bc77a2018-07-19 19:00:45 +0900192 stream << "It must be one of:";
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700193 for (const Schema& s : AllSchemas()) {
194 stream << " " << s.name;
Jiyong Park68bc77a2018-07-19 19:00:45 +0900195 }
196 stream << ".";
Steven Moreland46e9da82018-07-27 15:45:29 -0700197 AIDL_ERROR(location) << stream.str();
Jooyung Han442cacf2021-09-13 17:44:56 +0900198 return {};
Andrei Onea9445fc62019-06-27 18:11:59 +0100199 }
200
Jooyung Han442cacf2021-09-13 17:44:56 +0900201 return std::unique_ptr<AidlAnnotation>(
202 new AidlAnnotation(location, *schema, std::move(parameter_list), comments));
Jiyong Park68bc77a2018-07-19 19:00:45 +0900203}
204
Jooyung Han442cacf2021-09-13 17:44:56 +0900205AidlAnnotation::AidlAnnotation(const AidlLocation& location, const Schema& schema,
206 std::map<std::string, std::shared_ptr<AidlConstantValue>> parameters,
207 const Comments& comments)
Jooyung Han5c7e77c2021-01-20 16:00:29 +0900208 : AidlNode(location, comments), schema_(schema), parameters_(std::move(parameters)) {}
Andrei Onea9445fc62019-06-27 18:11:59 +0100209
Jooyung Hanc5688f72021-01-05 15:41:48 +0900210struct ConstReferenceFinder : AidlVisitor {
Jooyung Han9d3cbe22020-12-28 03:02:08 +0900211 const AidlConstantReference* found;
Jooyung Han9d3cbe22020-12-28 03:02:08 +0900212 void Visit(const AidlConstantReference& ref) override {
Jooyung Han690f5842020-12-04 13:02:04 +0900213 if (!found) found = &ref;
214 }
Jooyung Hanc5688f72021-01-05 15:41:48 +0900215 static const AidlConstantReference* Find(const AidlConstantValue& c) {
216 ConstReferenceFinder finder;
217 VisitTopDown(finder, c);
218 return finder.found;
219 }
Jooyung Han690f5842020-12-04 13:02:04 +0900220};
221
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900222// Checks if annotation complies with the schema
223// - every parameter is known and has well-typed value.
224// - every required parameter is present.
Andrei Onea9445fc62019-06-27 18:11:59 +0100225bool AidlAnnotation::CheckValid() const {
Andrei Onea9445fc62019-06-27 18:11:59 +0100226 for (const auto& name_and_param : parameters_) {
227 const std::string& param_name = name_and_param.first;
228 const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
Jooyung Han690f5842020-12-04 13:02:04 +0900229
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900230 const ParamType* param_type = schema_.ParamType(param_name);
231 if (!param_type) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100232 std::ostringstream stream;
233 stream << "Parameter " << param_name << " not supported ";
Devin Mooredecaf292020-04-30 09:16:40 -0700234 stream << "for annotation " << GetName() << ". ";
Andrei Onea9445fc62019-06-27 18:11:59 +0100235 stream << "It must be one of:";
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900236 for (const auto& param : schema_.parameters) {
237 stream << " " << param.name;
Andrei Onea9445fc62019-06-27 18:11:59 +0100238 }
239 AIDL_ERROR(this) << stream.str();
240 return false;
241 }
Jooyung Han690f5842020-12-04 13:02:04 +0900242
Jooyung Hanc5688f72021-01-05 15:41:48 +0900243 const auto& found = ConstReferenceFinder::Find(*param);
244 if (found) {
245 AIDL_ERROR(found) << "Value must be a constant expression but contains reference to "
246 << found->GetFieldName() << ".";
Jooyung Han690f5842020-12-04 13:02:04 +0900247 return false;
248 }
249
250 if (!param->CheckValid()) {
251 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
252 << GetName() << ".";
253 return false;
254 }
255
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900256 const std::string param_value =
257 param->ValueString(param_type->type, AidlConstantValueDecorator);
Andrei Onea9445fc62019-06-27 18:11:59 +0100258 // Assume error on empty string.
259 if (param_value == "") {
260 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
261 << GetName() << ".";
262 return false;
263 }
264 }
Jooyung Han5721a232020-12-24 04:34:55 +0900265 bool success = true;
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900266 for (const auto& param : schema_.parameters) {
267 if (param.required && parameters_.count(param.name) == 0) {
268 AIDL_ERROR(this) << "Missing '" << param.name << "' on @" << GetName() << ".";
Jooyung Han5721a232020-12-24 04:34:55 +0900269 success = false;
270 }
271 }
Thiébaud Weksteen9ab59122021-09-20 09:37:38 +0200272 if (!success) {
273 return false;
274 }
275 // For @Enforce annotations, validates the expression.
276 if (schema_.type == AidlAnnotation::Type::ENFORCE) {
277 auto expr = EnforceExpression();
278 if (!expr.ok()) {
279 AIDL_ERROR(this) << "Unable to parse @Enforce annotation: " << expr.error();
280 return false;
281 }
282 }
283 return true;
284}
285
286Result<unique_ptr<perm::Expression>> AidlAnnotation::EnforceExpression() const {
287 auto perm_expr = ParamValue<std::string>("condition");
288 if (perm_expr.has_value()) {
289 return perm::Parser::Parse(perm_expr.value());
290 }
291 return Error() << "No condition parameter for @Enforce";
Andrei Onea9445fc62019-06-27 18:11:59 +0100292}
293
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900294// Checks if the annotation is applicable to the current context.
295// For example, annotations like @VintfStability, @FixedSize is not applicable to AidlTypeSpecifier
296// nodes.
297bool AidlAnnotation::CheckContext(TargetContext context) const {
298 if (schema_.target_context & static_cast<uint32_t>(context)) {
299 return true;
300 }
301 const static map<TargetContext, string> context_name_map{
302 {CONTEXT_TYPE_INTERFACE, "interface"},
303 {CONTEXT_TYPE_ENUM, "enum"},
304 {CONTEXT_TYPE_STRUCTURED_PARCELABLE, "structured parcelable"},
305 {CONTEXT_TYPE_UNION, "union"},
306 {CONTEXT_TYPE_UNSTRUCTURED_PARCELABLE, "parcelable"},
307 {CONTEXT_CONST, "constant"},
308 {CONTEXT_FIELD, "field"},
309 {CONTEXT_METHOD, "method"},
310 {CONTEXT_TYPE_SPECIFIER, "type"},
311 };
312 vector<string> available;
313 for (const auto& [context, name] : context_name_map) {
314 if (schema_.target_context & context) {
315 available.push_back(name);
316 }
317 }
318 AIDL_ERROR(this) << "@" << GetName() << " is not available. It can annotate {"
319 << Join(available, ", ") << "}.";
320 return false;
321}
322
Andrei Onea9445fc62019-06-27 18:11:59 +0100323std::map<std::string, std::string> AidlAnnotation::AnnotationParams(
324 const ConstantValueDecorator& decorator) const {
325 std::map<std::string, std::string> raw_params;
Andrei Onea9445fc62019-06-27 18:11:59 +0100326 for (const auto& name_and_param : parameters_) {
327 const std::string& param_name = name_and_param.first;
328 const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
Jooyung Han2d6b5c42021-01-09 01:01:06 +0900329 const ParamType* param_type = schema_.ParamType(param_name);
330 AIDL_FATAL_IF(!param_type, this);
331 raw_params.emplace(param_name, param->ValueString(param_type->type, decorator));
Andrei Onea9445fc62019-06-27 18:11:59 +0100332 }
333 return raw_params;
334}
Steven Moreland46e9da82018-07-27 15:45:29 -0700335
Jooyung Han965e31d2020-11-27 12:30:16 +0900336std::string AidlAnnotation::ToString() const {
Daniel Norman37d43dd2019-09-09 17:22:34 -0700337 if (parameters_.empty()) {
338 return "@" + GetName();
339 } else {
340 vector<string> param_strings;
Jooyung Han965e31d2020-11-27 12:30:16 +0900341 for (const auto& [name, value] : AnnotationParams(AidlConstantValueDecorator)) {
Daniel Norman37d43dd2019-09-09 17:22:34 -0700342 param_strings.emplace_back(name + "=" + value);
343 }
344 return "@" + GetName() + "(" + Join(param_strings, ", ") + ")";
345 }
346}
347
Jooyung Hanc5688f72021-01-05 15:41:48 +0900348void AidlAnnotation::TraverseChildren(std::function<void(const AidlNode&)> traverse) const {
349 for (const auto& [name, value] : parameters_) {
350 (void)name;
351 traverse(*value);
352 }
353}
354
Andrei Onea9445fc62019-06-27 18:11:59 +0100355static const AidlAnnotation* GetAnnotation(const vector<AidlAnnotation>& annotations,
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700356 AidlAnnotation::Type type) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100357 for (const auto& a : annotations) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700358 if (a.GetType() == type) {
Jooyung Hand902a972020-10-23 17:32:44 +0900359 AIDL_FATAL_IF(a.Repeatable(), a)
360 << "Trying to get a single annotation when it is repeatable.";
Andrei Onea9445fc62019-06-27 18:11:59 +0100361 return &a;
362 }
363 }
364 return nullptr;
365}
366
Jooyung Han8451a202021-01-16 03:07:06 +0900367AidlAnnotatable::AidlAnnotatable(const AidlLocation& location, const Comments& comments)
Jooyung Han5c7e77c2021-01-20 16:00:29 +0900368 : AidlCommentable(location, comments) {}
Steven Moreland46e9da82018-07-27 15:45:29 -0700369
Jiyong Park68bc77a2018-07-19 19:00:45 +0900370bool AidlAnnotatable::IsNullable() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700371 return GetAnnotation(annotations_, AidlAnnotation::Type::NULLABLE);
Jiyong Park68bc77a2018-07-19 19:00:45 +0900372}
373
Jooyung Han01720ed2021-08-13 07:46:07 +0900374bool AidlAnnotatable::IsHeapNullable() const {
375 auto annot = GetAnnotation(annotations_, AidlAnnotation::Type::NULLABLE);
376 if (annot) {
377 return annot->ParamValue<bool>("heap").value_or(false);
378 }
379 return false;
380}
381
Jiyong Park68bc77a2018-07-19 19:00:45 +0900382bool AidlAnnotatable::IsUtf8InCpp() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700383 return GetAnnotation(annotations_, AidlAnnotation::Type::UTF8_IN_CPP);
Jiyong Park68bc77a2018-07-19 19:00:45 +0900384}
385
Steven Morelanda7764e52020-10-27 17:29:29 +0000386bool AidlAnnotatable::IsSensitiveData() const {
387 return GetAnnotation(annotations_, AidlAnnotation::Type::SENSITIVE_DATA);
388}
389
Steven Morelanda57d0a62019-07-30 09:41:14 -0700390bool AidlAnnotatable::IsVintfStability() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700391 return GetAnnotation(annotations_, AidlAnnotation::Type::VINTF_STABILITY);
Steven Morelanda57d0a62019-07-30 09:41:14 -0700392}
393
Jeongik Chad0a10272020-08-06 16:33:36 +0900394bool AidlAnnotatable::IsJavaOnlyImmutable() const {
395 return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE);
Jeongik Cha36f76c32020-07-28 00:25:52 +0900396}
397
Devin Moorec7e47a32020-08-07 10:55:25 -0700398bool AidlAnnotatable::IsFixedSize() const {
399 return GetAnnotation(annotations_, AidlAnnotation::Type::FIXED_SIZE);
400}
401
Andrei Onea9445fc62019-06-27 18:11:59 +0100402const AidlAnnotation* AidlAnnotatable::UnsupportedAppUsage() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700403 return GetAnnotation(annotations_, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE);
Jiyong Parka6605ab2018-11-11 14:30:21 +0900404}
405
Andrei Homescue61feb52020-08-18 15:44:24 -0700406const AidlAnnotation* AidlAnnotatable::RustDerive() const {
407 return GetAnnotation(annotations_, AidlAnnotation::Type::RUST_DERIVE);
408}
409
Jooyung Han672557b2020-12-24 05:18:00 +0900410const AidlAnnotation* AidlAnnotatable::BackingType() const {
411 return GetAnnotation(annotations_, AidlAnnotation::Type::BACKING);
Daniel Norman85aed542019-08-21 12:01:14 -0700412}
413
Jooyung Hanf8dbbcc2020-12-26 03:05:55 +0900414std::vector<std::string> AidlAnnotatable::SuppressWarnings() const {
415 auto annot = GetAnnotation(annotations_, AidlAnnotation::Type::SUPPRESS_WARNINGS);
416 if (annot) {
417 auto names = annot->ParamValue<std::vector<std::string>>("value");
418 AIDL_FATAL_IF(!names.has_value(), this);
419 return std::move(names.value());
420 }
421 return {};
422}
423
Thiébaud Weksteen5a4db212021-09-02 17:09:34 +0200424// Parses the @Enforce annotation expression.
425std::unique_ptr<perm::Expression> AidlAnnotatable::EnforceExpression(
426 const AidlNode& context) const {
427 auto annot = GetAnnotation(annotations_, AidlAnnotation::Type::ENFORCE);
428 if (annot) {
Thiébaud Weksteen9ab59122021-09-20 09:37:38 +0200429 auto perm_expr = annot->EnforceExpression();
430 if (!perm_expr.ok()) {
431 // This should have been caught during validation.
432 AIDL_FATAL(context) << "Unable to parse @Enforce annotation: " << perm_expr.error();
Thiébaud Weksteen5a4db212021-09-02 17:09:34 +0200433 }
Thiébaud Weksteen9ab59122021-09-20 09:37:38 +0200434 return std::move(perm_expr.value());
Thiébaud Weksteen5a4db212021-09-02 17:09:34 +0200435 }
436 return {};
437}
438
Jeongik Cha88f95a82020-01-15 13:02:16 +0900439bool AidlAnnotatable::IsStableApiParcelable(Options::Language lang) const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700440 return lang == Options::Language::JAVA &&
441 GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_STABLE_PARCELABLE);
Jeongik Cha82317dd2019-02-27 20:26:11 +0900442}
443
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800444bool AidlAnnotatable::IsHide() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700445 return GetAnnotation(annotations_, AidlAnnotation::Type::HIDE);
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800446}
447
Jooyung Han829ec7c2020-12-02 12:07:36 +0900448bool AidlAnnotatable::JavaDerive(const std::string& method) const {
449 auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_DERIVE);
450 if (annotation != nullptr) {
Jooyung Hanb3c77ed2020-12-26 02:02:45 +0900451 return annotation->ParamValue<bool>(method).value_or(false);
Jooyung Han829ec7c2020-12-02 12:07:36 +0900452 }
453 return false;
Jiyong Park43113fb2020-07-20 16:26:19 +0900454}
455
Jiyong Park27fd7fd2020-08-27 16:25:09 +0900456std::string AidlAnnotatable::GetDescriptor() const {
457 auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::DESCRIPTOR);
458 if (annotation != nullptr) {
Jooyung Hanb3c77ed2020-12-26 02:02:45 +0900459 return annotation->ParamValue<std::string>("value").value();
Jiyong Park27fd7fd2020-08-27 16:25:09 +0900460 }
461 return "";
462}
463
Devin Moore24f68572020-02-26 13:20:59 -0800464bool AidlAnnotatable::CheckValid(const AidlTypenames&) const {
Andrei Onea9445fc62019-06-27 18:11:59 +0100465 for (const auto& annotation : GetAnnotations()) {
Jooyung Hand902a972020-10-23 17:32:44 +0900466 if (!annotation.CheckValid()) {
467 return false;
468 }
469 }
470
471 std::map<AidlAnnotation::Type, AidlLocation> declared;
472 for (const auto& annotation : GetAnnotations()) {
473 const auto& [iter, inserted] = declared.emplace(annotation.GetType(), annotation.GetLocation());
474 if (!inserted && !annotation.Repeatable()) {
475 AIDL_ERROR(this) << "'" << annotation.GetName()
476 << "' is repeated, but not allowed. Previous location: " << iter->second;
477 return false;
478 }
Andrei Onea9445fc62019-06-27 18:11:59 +0100479 }
Steven Morelanda57d0a62019-07-30 09:41:14 -0700480
Andrei Onea9445fc62019-06-27 18:11:59 +0100481 return true;
482}
483
Jiyong Park68bc77a2018-07-19 19:00:45 +0900484string AidlAnnotatable::ToString() const {
485 vector<string> ret;
486 for (const auto& a : annotations_) {
Jooyung Han965e31d2020-11-27 12:30:16 +0900487 ret.emplace_back(a.ToString());
Jiyong Park68bc77a2018-07-19 19:00:45 +0900488 }
489 std::sort(ret.begin(), ret.end());
490 return Join(ret, " ");
491}
492
Steven Moreland46e9da82018-07-27 15:45:29 -0700493AidlTypeSpecifier::AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name,
494 bool is_array,
Jiyong Park1deecc32018-07-17 01:14:41 +0900495 vector<unique_ptr<AidlTypeSpecifier>>* type_params,
Jooyung Han8451a202021-01-16 03:07:06 +0900496 const Comments& comments)
Jooyung Han5c7e77c2021-01-20 16:00:29 +0900497 : AidlAnnotatable(location, comments),
Jeongik Chadf76dc72019-11-28 00:08:47 +0900498 AidlParameterizable<unique_ptr<AidlTypeSpecifier>>(type_params),
Steven Moreland46e9da82018-07-27 15:45:29 -0700499 unresolved_name_(unresolved_name),
Casey Dahlinf7a421c2015-10-05 17:24:28 -0700500 is_array_(is_array),
Jeongik Cha1a7ab642019-07-29 17:31:02 +0900501 split_name_(Split(unresolved_name, ".")) {}
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700502
Jooyung Hand2fa0232020-10-19 02:51:41 +0900503const AidlTypeSpecifier& AidlTypeSpecifier::ArrayBase() const {
Steven Moreland3f658cf2018-08-20 13:40:54 -0700504 AIDL_FATAL_IF(!is_array_, this);
Jeongik Chadf76dc72019-11-28 00:08:47 +0900505 // Declaring array of generic type cannot happen, it is grammar error.
506 AIDL_FATAL_IF(IsGeneric(), this);
Steven Moreland3f658cf2018-08-20 13:40:54 -0700507
Jooyung Hand2fa0232020-10-19 02:51:41 +0900508 if (!array_base_) {
509 array_base_.reset(new AidlTypeSpecifier(*this));
510 array_base_->is_array_ = false;
511 }
512 return *array_base_;
Steven Moreland3f658cf2018-08-20 13:40:54 -0700513}
514
Jooyung Han965e31d2020-11-27 12:30:16 +0900515string AidlTypeSpecifier::Signature() const {
Jiyong Park1deecc32018-07-17 01:14:41 +0900516 string ret = GetName();
517 if (IsGeneric()) {
518 vector<string> arg_names;
519 for (const auto& ta : GetTypeParameters()) {
Jooyung Han965e31d2020-11-27 12:30:16 +0900520 arg_names.emplace_back(ta->Signature());
Jiyong Parkccf00f82018-07-17 01:39:23 +0900521 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900522 ret += "<" + Join(arg_names, ",") + ">";
Jiyong Parkccf00f82018-07-17 01:39:23 +0900523 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900524 if (IsArray()) {
525 ret += "[]";
526 }
527 return ret;
Jiyong Parkccf00f82018-07-17 01:39:23 +0900528}
529
Jooyung Han965e31d2020-11-27 12:30:16 +0900530string AidlTypeSpecifier::ToString() const {
531 string ret = Signature();
Jiyong Park02da7422018-07-16 16:00:26 +0900532 string annotations = AidlAnnotatable::ToString();
533 if (annotations != "") {
534 ret = annotations + " " + ret;
535 }
536 return ret;
537}
538
Jooyung Han13f1fa52021-06-11 18:06:12 +0900539// When `scope` is specified, name is resolved first based on it.
540// `scope` can be null for built-in types and fully-qualified types.
541bool AidlTypeSpecifier::Resolve(const AidlTypenames& typenames, const AidlScope* scope) {
Steven Moreland21780812020-09-11 01:29:45 +0000542 AIDL_FATAL_IF(IsResolved(), this);
Jooyung Han13f1fa52021-06-11 18:06:12 +0900543 std::string name = unresolved_name_;
544 if (scope) {
545 name = scope->ResolveName(name);
546 }
547 AidlTypenames::ResolvedTypename result = typenames.ResolveTypename(name);
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700548 if (result.is_resolved) {
549 fully_qualified_name_ = result.canonical_name;
Jeongik Cha1a7ab642019-07-29 17:31:02 +0900550 split_name_ = Split(fully_qualified_name_, ".");
Jooyung Hane9bb9de2020-11-01 22:16:57 +0900551 defined_type_ = result.defined_type;
Jiyong Parkccf00f82018-07-17 01:39:23 +0900552 }
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700553 return result.is_resolved;
Casey Dahlin70078e62015-09-30 17:01:30 -0700554}
555
Jooyung Hane9bb9de2020-11-01 22:16:57 +0900556const AidlDefinedType* AidlTypeSpecifier::GetDefinedType() const {
557 return defined_type_;
558}
559
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900560bool AidlTypeSpecifier::CheckValid(const AidlTypenames& typenames) const {
Devin Moore24f68572020-02-26 13:20:59 -0800561 if (!AidlAnnotatable::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100562 return false;
563 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900564 if (IsGeneric()) {
Jooyung Hand09a21d2021-02-15 18:56:55 +0900565 const auto& types = GetTypeParameters();
566 for (const auto& arg : types) {
567 if (!arg->CheckValid(typenames)) {
568 return false;
569 }
570 }
Jeongik Chae74c86d2019-12-12 16:54:03 +0900571
Jooyung Hand09a21d2021-02-15 18:56:55 +0900572 const string& type_name = GetName();
Jeongik Chae74c86d2019-12-12 16:54:03 +0900573 // TODO(b/136048684) Disallow to use primitive types only if it is List or Map.
574 if (type_name == "List" || type_name == "Map") {
Jooyung Hane87cdd02020-12-11 16:47:35 +0900575 if (std::any_of(types.begin(), types.end(), [&](auto& type_ptr) {
Jooyung Han1f35ef32021-02-15 19:08:05 +0900576 return !type_ptr->IsArray() &&
577 (typenames.GetEnumDeclaration(*type_ptr) ||
578 AidlTypenames::IsPrimitiveTypename(type_ptr->GetName()));
Jeongik Chae74c86d2019-12-12 16:54:03 +0900579 })) {
Devin Moore7b8d5c92020-03-17 14:14:08 -0700580 AIDL_ERROR(this) << "A generic type cannot have any primitive type parameters.";
Jeongik Chae74c86d2019-12-12 16:54:03 +0900581 return false;
582 }
583 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800584 const auto defined_type = typenames.TryGetDefinedType(type_name);
Jeongik Chadf76dc72019-11-28 00:08:47 +0900585 const auto parameterizable =
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800586 defined_type != nullptr ? defined_type->AsParameterizable() : nullptr;
587 const bool is_user_defined_generic_type =
Jeongik Chadf76dc72019-11-28 00:08:47 +0900588 parameterizable != nullptr && parameterizable->IsGeneric();
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800589 const size_t num_params = GetTypeParameters().size();
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900590 if (type_name == "List") {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800591 if (num_params > 1) {
Jooyung Han965e31d2020-11-27 12:30:16 +0900592 AIDL_ERROR(this) << "List can only have one type parameter, but got: '" << Signature()
Steven Morelandebc3c5d2020-09-30 23:40:33 +0000593 << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900594 return false;
595 }
Jooyung Han55f96ad2020-12-13 10:08:33 +0900596 const AidlTypeSpecifier& contained_type = *GetTypeParameters()[0];
Jooyung Hancea89002021-02-15 17:04:04 +0900597 if (contained_type.IsArray()) {
598 AIDL_ERROR(this)
599 << "List of arrays is not supported. List<T> supports parcelable/union, String, "
600 "IBinder, and ParcelFileDescriptor.";
601 return false;
602 }
Jooyung Han55f96ad2020-12-13 10:08:33 +0900603 const string& contained_type_name = contained_type.GetName();
604 if (AidlTypenames::IsBuiltinTypename(contained_type_name)) {
605 if (contained_type_name != "String" && contained_type_name != "IBinder" &&
606 contained_type_name != "ParcelFileDescriptor") {
607 AIDL_ERROR(this) << "List<" << contained_type_name
608 << "> is not supported. List<T> supports parcelable/union, String, "
609 "IBinder, and ParcelFileDescriptor.";
610 return false;
611 }
612 } else { // Defined types
613 if (typenames.GetInterface(contained_type)) {
614 AIDL_ERROR(this) << "List<" << contained_type_name
615 << "> is not supported. List<T> supports parcelable/union, String, "
616 "IBinder, and ParcelFileDescriptor.";
617 return false;
618 }
619 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900620 } else if (type_name == "Map") {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800621 if (num_params != 0 && num_params != 2) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900622 AIDL_ERROR(this) << "Map must have 0 or 2 type parameters, but got "
Jooyung Han965e31d2020-11-27 12:30:16 +0900623 << "'" << Signature() << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900624 return false;
625 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800626 if (num_params == 2) {
Jooyung Hanaab242a2021-02-15 19:01:15 +0900627 const string& key_type = GetTypeParameters()[0]->Signature();
Jeongik Chae48d9942020-01-02 17:39:00 +0900628 if (key_type != "String") {
629 AIDL_ERROR(this) << "The type of key in map must be String, but it is "
630 << "'" << key_type << "'";
631 return false;
632 }
633 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800634 } else if (is_user_defined_generic_type) {
Jeongik Chadf76dc72019-11-28 00:08:47 +0900635 const size_t allowed = parameterizable->GetTypeParameters().size();
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800636 if (num_params != allowed) {
Jeongik Chadf76dc72019-11-28 00:08:47 +0900637 AIDL_ERROR(this) << type_name << " must have " << allowed << " type parameters, but got "
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800638 << num_params;
Jeongik Chadf76dc72019-11-28 00:08:47 +0900639 return false;
640 }
641 } else {
642 AIDL_ERROR(this) << type_name << " is not a generic type.";
643 return false;
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900644 }
645 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900646
Steven Moreland11cb9452020-01-21 16:56:58 -0800647 const bool is_generic_string_list = GetName() == "List" && IsGeneric() &&
648 GetTypeParameters().size() == 1 &&
649 GetTypeParameters()[0]->GetName() == "String";
650 if (IsUtf8InCpp() && (GetName() != "String" && !is_generic_string_list)) {
651 AIDL_ERROR(this) << "@utf8InCpp can only be used on String, String[], and List<String>.";
652 return false;
653 }
654
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900655 if (GetName() == "void") {
656 if (IsArray() || IsNullable() || IsUtf8InCpp()) {
657 AIDL_ERROR(this) << "void type cannot be an array or nullable or utf8 string";
658 return false;
659 }
660 }
661
662 if (IsArray()) {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800663 const auto defined_type = typenames.TryGetDefinedType(GetName());
664 if (defined_type != nullptr && defined_type->AsInterface() != nullptr) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900665 AIDL_ERROR(this) << "Binder type cannot be an array";
666 return false;
667 }
Steven Moreland8042d2d2020-09-30 23:31:32 +0000668 if (GetName() == "ParcelableHolder") {
669 AIDL_ERROR(this) << "Arrays of ParcelableHolder are not supported.";
670 return false;
671 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900672 }
673
674 if (IsNullable()) {
675 if (AidlTypenames::IsPrimitiveTypename(GetName()) && !IsArray()) {
676 AIDL_ERROR(this) << "Primitive type cannot get nullable annotation";
677 return false;
678 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800679 const auto defined_type = typenames.TryGetDefinedType(GetName());
680 if (defined_type != nullptr && defined_type->AsEnumDeclaration() != nullptr && !IsArray()) {
Daniel Normanee8674f2019-09-20 16:07:00 -0700681 AIDL_ERROR(this) << "Enum type cannot get nullable annotation";
682 return false;
683 }
Jeongik Chaf6ec8982020-10-15 00:10:30 +0900684 if (GetName() == "ParcelableHolder") {
685 AIDL_ERROR(this) << "ParcelableHolder cannot be nullable.";
686 return false;
687 }
Jooyung Han01720ed2021-08-13 07:46:07 +0900688 if (IsHeapNullable()) {
689 if (!defined_type || IsArray() || !defined_type->AsParcelable()) {
690 AIDL_ERROR(this) << "@nullable(heap=true) is available to parcelables.";
691 return false;
692 }
693 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900694 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900695 return true;
696}
697
Jooyung Hanfdaae1d2020-12-14 13:16:15 +0900698std::string AidlConstantValueDecorator(const AidlTypeSpecifier& type,
Steven Moreland860b1942018-08-16 14:59:28 -0700699 const std::string& raw_value) {
Jooyung Hanfdaae1d2020-12-14 13:16:15 +0900700 if (type.IsArray()) {
701 return raw_value;
702 }
703
704 if (auto defined_type = type.GetDefinedType(); defined_type) {
705 auto enum_type = defined_type->AsEnumDeclaration();
706 AIDL_FATAL_IF(!enum_type, type) << "Invalid type for \"" << raw_value << "\"";
707 return type.GetName() + "." + raw_value.substr(raw_value.find_last_of('.') + 1);
708 }
Steven Moreland860b1942018-08-16 14:59:28 -0700709 return raw_value;
710}
711
Steven Moreland46e9da82018-07-27 15:45:29 -0700712AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
713 AidlTypeSpecifier* type, const std::string& name)
Steven Moreland541788d2020-05-21 22:05:52 +0000714 : AidlVariableDeclaration(location, type, name, AidlConstantValue::Default(*type)) {
715 default_user_specified_ = false;
716}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700717
Steven Moreland46e9da82018-07-27 15:45:29 -0700718AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
719 AidlTypeSpecifier* type, const std::string& name,
720 AidlConstantValue* default_value)
Jooyung Han8aeef8c2021-01-11 12:16:19 +0900721 : AidlMember(location, type->GetComments()),
Steven Moreland541788d2020-05-21 22:05:52 +0000722 type_(type),
723 name_(name),
724 default_user_specified_(true),
725 default_value_(default_value) {}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700726
Jooyung Han53fb4242020-12-17 16:03:49 +0900727bool AidlVariableDeclaration::HasUsefulDefaultValue() const {
728 if (GetDefaultValue()) {
729 return true;
730 }
731 // null is accepted as a valid default value in all backends
732 if (GetType().IsNullable()) {
733 return true;
734 }
735 return false;
736}
737
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900738bool AidlVariableDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700739 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900740 valid &= type_->CheckValid(typenames);
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900741
Steven Moreland54be7bd2019-12-05 11:17:53 -0800742 if (type_->GetName() == "void") {
743 AIDL_ERROR(this) << "Declaration " << name_
744 << " is void, but declarations cannot be of void type.";
745 valid = false;
746 }
747
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900748 if (default_value_ == nullptr) return valid;
Steven Moreland25294322018-08-07 18:13:55 -0700749 valid &= default_value_->CheckValid();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700750
Steven Moreland25294322018-08-07 18:13:55 -0700751 if (!valid) return false;
Steven Moreland9ea10e32018-07-19 15:26:09 -0700752
Steven Moreland860b1942018-08-16 14:59:28 -0700753 return !ValueString(AidlConstantValueDecorator).empty();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700754}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700755
Jooyung Hanacae85d2020-10-28 16:39:09 +0900756string AidlVariableDeclaration::GetCapitalizedName() const {
757 AIDL_FATAL_IF(name_.size() <= 0, *this) << "Name can't be empty.";
758 string str = name_;
759 str[0] = static_cast<char>(toupper(str[0]));
760 return str;
761}
762
Steven Moreland5557f1c2018-07-02 13:50:23 -0700763string AidlVariableDeclaration::ToString() const {
Jooyung Han965e31d2020-11-27 12:30:16 +0900764 string ret = type_->ToString() + " " + name_;
Steven Moreland541788d2020-05-21 22:05:52 +0000765 if (default_value_ != nullptr && default_user_specified_) {
Steven Moreland860b1942018-08-16 14:59:28 -0700766 ret += " = " + ValueString(AidlConstantValueDecorator);
Steven Moreland9ea10e32018-07-19 15:26:09 -0700767 }
768 return ret;
Steven Moreland5557f1c2018-07-02 13:50:23 -0700769}
770
Jiyong Park02da7422018-07-16 16:00:26 +0900771string AidlVariableDeclaration::Signature() const {
772 return type_->Signature() + " " + name_;
773}
774
Steven Moreland860b1942018-08-16 14:59:28 -0700775std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
Jiyong Parka468e2a2018-08-29 21:25:18 +0900776 if (default_value_ != nullptr) {
Will McVickerd7d18df2019-09-12 13:40:50 -0700777 return default_value_->ValueString(GetType(), decorator);
Jiyong Parka468e2a2018-08-29 21:25:18 +0900778 } else {
779 return "";
780 }
Steven Moreland25294322018-08-07 18:13:55 -0700781}
782
Jooyung Hanc5688f72021-01-05 15:41:48 +0900783void AidlVariableDeclaration::TraverseChildren(
784 std::function<void(const AidlNode&)> traverse) const {
785 traverse(GetType());
786 if (IsDefaultUserSpecified()) {
787 traverse(*GetDefaultValue());
788 }
789}
790
Steven Moreland46e9da82018-07-27 15:45:29 -0700791AidlArgument::AidlArgument(const AidlLocation& location, AidlArgument::Direction direction,
792 AidlTypeSpecifier* type, const std::string& name)
793 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700794 direction_(direction),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700795 direction_specified_(true) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700796
Steven Moreland46e9da82018-07-27 15:45:29 -0700797AidlArgument::AidlArgument(const AidlLocation& location, AidlTypeSpecifier* type,
798 const std::string& name)
799 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700800 direction_(AidlArgument::IN_DIR),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700801 direction_specified_(false) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700802
Jooyung Han020d8d12021-02-26 17:23:02 +0900803static std::string to_string(AidlArgument::Direction direction) {
804 switch (direction) {
805 case AidlArgument::IN_DIR:
806 return "in";
807 case AidlArgument::OUT_DIR:
808 return "out";
809 case AidlArgument::INOUT_DIR:
810 return "inout";
811 }
812}
813
Jiyong Park02da7422018-07-16 16:00:26 +0900814string AidlArgument::GetDirectionSpecifier() const {
Casey Dahlinc378c992015-09-29 16:50:40 -0700815 string ret;
Casey Dahlinc378c992015-09-29 16:50:40 -0700816 if (direction_specified_) {
Jooyung Han020d8d12021-02-26 17:23:02 +0900817 ret = to_string(direction_);
Casey Dahlinc378c992015-09-29 16:50:40 -0700818 }
Casey Dahlinc378c992015-09-29 16:50:40 -0700819 return ret;
820}
Casey Dahlinbc7a50a2015-09-28 19:20:50 -0700821
Jiyong Park02da7422018-07-16 16:00:26 +0900822string AidlArgument::ToString() const {
Devin Mooreeccdb902020-03-24 16:22:40 -0700823 if (direction_specified_) {
824 return GetDirectionSpecifier() + " " + AidlVariableDeclaration::ToString();
825 } else {
826 return AidlVariableDeclaration::ToString();
827 }
Jiyong Park02da7422018-07-16 16:00:26 +0900828}
829
Jooyung Han020d8d12021-02-26 17:23:02 +0900830static std::string FormatDirections(const std::set<AidlArgument::Direction>& directions) {
831 std::vector<std::string> out;
832 for (const auto& d : directions) {
833 out.push_back(to_string(d));
834 }
835
836 if (out.size() <= 1) { // [] => "" or [A] => "A"
837 return Join(out, "");
838 } else if (out.size() == 2) { // [A,B] => "A or B"
839 return Join(out, " or ");
840 } else { // [A,B,C] => "A, B, or C"
841 out.back() = "or " + out.back();
842 return Join(out, ", ");
843 }
844}
845
846bool AidlArgument::CheckValid(const AidlTypenames& typenames) const {
847 if (!GetType().CheckValid(typenames)) {
848 return false;
849 }
850
851 const auto& aspect = typenames.GetArgumentAspect(GetType());
852
853 if (aspect.possible_directions.size() == 0) {
854 AIDL_ERROR(this) << aspect.name << " cannot be an argument type";
855 return false;
856 }
857
858 // when direction is not specified, "in" is assumed and should be the only possible direction
859 if (!DirectionWasSpecified() && aspect.possible_directions != std::set{AidlArgument::IN_DIR}) {
860 AIDL_ERROR(this) << "The direction of '" << GetName() << "' is not specified. " << aspect.name
861 << " can be an " << FormatDirections(aspect.possible_directions)
862 << " parameter.";
863 return false;
864 }
865
866 if (aspect.possible_directions.count(GetDirection()) == 0) {
867 AIDL_ERROR(this) << "'" << GetName() << "' can't be an " << GetDirectionSpecifier()
868 << " parameter because " << aspect.name << " can only be an "
869 << FormatDirections(aspect.possible_directions) << " parameter.";
870 return false;
871 }
872
873 return true;
874}
875
Jooyung Han8aeef8c2021-01-11 12:16:19 +0900876bool AidlCommentable::IsHidden() const {
Jooyung Han24effbf2021-01-16 10:24:03 +0900877 return android::aidl::HasHideInComments(GetComments());
Jooyung Han8aeef8c2021-01-11 12:16:19 +0900878}
879
880bool AidlCommentable::IsDeprecated() const {
Jooyung Hand4fe00e2021-01-11 16:21:53 +0900881 return android::aidl::FindDeprecated(GetComments()).has_value();
Jooyung Han8aeef8c2021-01-11 12:16:19 +0900882}
883
Jooyung Han8451a202021-01-16 03:07:06 +0900884AidlMember::AidlMember(const AidlLocation& location, const Comments& comments)
Jooyung Han2aedb112021-09-29 09:37:59 +0900885 : AidlAnnotatable(location, comments) {}
Steven Moreland46e9da82018-07-27 15:45:29 -0700886
Steven Moreland46e9da82018-07-27 15:45:29 -0700887AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
888 AidlTypeSpecifier* type, const std::string& name,
889 AidlConstantValue* value)
Jooyung Han8aeef8c2021-01-11 12:16:19 +0900890 : AidlMember(location, type->GetComments()), type_(type), name_(name), value_(value) {}
Steven Moreland693640b2018-07-19 13:46:27 -0700891
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900892bool AidlConstantDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700893 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900894 valid &= type_->CheckValid(typenames);
Steven Moreland25294322018-08-07 18:13:55 -0700895 valid &= value_->CheckValid();
896 if (!valid) return false;
Steven Moreland693640b2018-07-19 13:46:27 -0700897
Steven Morelande689da22020-11-10 02:06:30 +0000898 const static set<string> kSupportedConstTypes = {"String", "byte", "int", "long"};
Jooyung Han965e31d2020-11-27 12:30:16 +0900899 if (kSupportedConstTypes.find(type_->Signature()) == kSupportedConstTypes.end()) {
900 AIDL_ERROR(this) << "Constant of type " << type_->Signature() << " is not supported.";
Steven Moreland693640b2018-07-19 13:46:27 -0700901 return false;
902 }
903
Will McVickerd7d18df2019-09-12 13:40:50 -0700904 return true;
Christopher Wileyd6bdd8d2016-05-03 11:23:13 -0700905}
906
Jiyong Parka428d212018-08-29 22:26:30 +0900907string AidlConstantDeclaration::ToString() const {
Jooyung Hanb3ca6302020-11-27 14:13:27 +0900908 return "const " + type_->ToString() + " " + name_ + " = " +
909 ValueString(AidlConstantValueDecorator);
Jiyong Parka428d212018-08-29 22:26:30 +0900910}
911
912string AidlConstantDeclaration::Signature() const {
913 return type_->Signature() + " " + name_;
914}
915
Steven Moreland46e9da82018-07-27 15:45:29 -0700916AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
917 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jooyung Han8451a202021-01-16 03:07:06 +0900918 const Comments& comments)
Jiyong Parkb034bf02018-07-30 17:44:33 +0900919 : AidlMethod(location, oneway, type, name, args, comments, 0, true) {
920 has_id_ = false;
921}
922
923AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
924 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jooyung Han8451a202021-01-16 03:07:06 +0900925 const Comments& comments, int id, bool is_user_defined)
Jooyung Han8aeef8c2021-01-11 12:16:19 +0900926 : AidlMember(location, comments),
Steven Moreland46e9da82018-07-27 15:45:29 -0700927 oneway_(oneway),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700928 type_(type),
929 name_(name),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700930 arguments_(std::move(*args)),
Jiyong Parkb034bf02018-07-30 17:44:33 +0900931 id_(id),
932 is_user_defined_(is_user_defined) {
Casey Dahlinf4a93112015-10-05 16:58:09 -0700933 has_id_ = true;
934 delete args;
Christopher Wileyad339272015-10-05 19:11:58 -0700935 for (const unique_ptr<AidlArgument>& a : arguments_) {
936 if (a->IsIn()) { in_arguments_.push_back(a.get()); }
937 if (a->IsOut()) { out_arguments_.push_back(a.get()); }
938 }
Casey Dahlinf4a93112015-10-05 16:58:09 -0700939}
940
Jiyong Park02da7422018-07-16 16:00:26 +0900941string AidlMethod::Signature() const {
942 vector<string> arg_signatures;
943 for (const auto& arg : GetArguments()) {
Jooyung Han965e31d2020-11-27 12:30:16 +0900944 arg_signatures.emplace_back(arg->GetType().Signature());
Jiyong Park02da7422018-07-16 16:00:26 +0900945 }
Jiyong Park309668e2018-07-28 16:55:44 +0900946 return GetName() + "(" + Join(arg_signatures, ", ") + ")";
947}
948
949string AidlMethod::ToString() const {
950 vector<string> arg_strings;
951 for (const auto& arg : GetArguments()) {
Jooyung Han965e31d2020-11-27 12:30:16 +0900952 arg_strings.emplace_back(arg->ToString());
Jiyong Park309668e2018-07-28 16:55:44 +0900953 }
Jooyung Han965e31d2020-11-27 12:30:16 +0900954 string ret = (IsOneway() ? "oneway " : "") + GetType().ToString() + " " + GetName() + "(" +
Steven Moreland4ee68632018-12-14 15:52:46 -0800955 Join(arg_strings, ", ") + ")";
Jiyong Parked65bf42018-08-28 15:43:27 +0900956 if (HasId()) {
957 ret += " = " + std::to_string(GetId());
958 }
959 return ret;
Jiyong Park02da7422018-07-16 16:00:26 +0900960}
961
Steven Moreland46e9da82018-07-27 15:45:29 -0700962AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
Jooyung Han8451a202021-01-16 03:07:06 +0900963 const Comments& comments, const std::string& package,
Jooyung Han829ec7c2020-12-02 12:07:36 +0900964 std::vector<std::unique_ptr<AidlMember>>* members)
Jooyung Han2aedb112021-09-29 09:37:59 +0900965 : AidlMember(location, comments), AidlScope(this), name_(name), package_(package) {
Jooyung Han93f48f02021-06-05 00:11:16 +0900966 // adjust name/package when name is fully qualified (for preprocessed files)
967 if (package_.empty() && name_.find('.') != std::string::npos) {
968 // Note that this logic is absolutely wrong. Given a parcelable
969 // org.some.Foo.Bar, the class name is Foo.Bar, but this code will claim that
970 // the class is just Bar. However, this was the way it was done in the past.
971 //
972 // See b/17415692
973 auto pos = name.rfind('.');
974 // name is the last part.
975 name_ = name.substr(pos + 1);
976 // package is the initial parts (except the last).
977 package_ = name.substr(0, pos);
978 }
Jooyung Han829ec7c2020-12-02 12:07:36 +0900979 if (members) {
980 for (auto& m : *members) {
Jooyung Hanbaa71062021-09-29 09:06:03 +0900981 if (auto constant = AidlCast<AidlConstantDeclaration>(*m); constant) {
Jooyung Han829ec7c2020-12-02 12:07:36 +0900982 constants_.emplace_back(constant);
Jooyung Hanbaa71062021-09-29 09:06:03 +0900983 } else if (auto variable = AidlCast<AidlVariableDeclaration>(*m); variable) {
Jooyung Han829ec7c2020-12-02 12:07:36 +0900984 variables_.emplace_back(variable);
Jooyung Hanbaa71062021-09-29 09:06:03 +0900985 } else if (auto method = AidlCast<AidlMethod>(*m); method) {
Jooyung Han829ec7c2020-12-02 12:07:36 +0900986 methods_.emplace_back(method);
Jooyung Han2aedb112021-09-29 09:37:59 +0900987 } else if (auto type = AidlCast<AidlDefinedType>(*m); type) {
988 type->SetEnclosingScope(this);
989 types_.emplace_back(type);
Jooyung Han829ec7c2020-12-02 12:07:36 +0900990 } else {
Jooyung Hanbaa71062021-09-29 09:06:03 +0900991 AIDL_FATAL(*m) << "Unknown member type.";
Jooyung Han829ec7c2020-12-02 12:07:36 +0900992 }
993 members_.push_back(m.release());
994 }
995 delete members;
996 }
997}
Steven Moreland787b0432018-07-03 09:00:58 -0700998
Jooyung Han808a2a02020-12-28 16:46:54 +0900999bool AidlDefinedType::CheckValid(const AidlTypenames& typenames) const {
Devin Moore24f68572020-02-26 13:20:59 -08001000 if (!AidlAnnotatable::CheckValid(typenames)) {
1001 return false;
1002 }
Jooyung Han829ec7c2020-12-02 12:07:36 +09001003 if (!CheckValidWithMembers(typenames)) {
1004 return false;
1005 }
Devin Moore24f68572020-02-26 13:20:59 -08001006 return true;
1007}
1008
Steven Moreland787b0432018-07-03 09:00:58 -07001009std::string AidlDefinedType::GetCanonicalName() const {
1010 if (package_.empty()) {
1011 return GetName();
1012 }
Jooyung Han2aedb112021-09-29 09:37:59 +09001013 if (auto parent = GetParentType(); parent) {
1014 return parent->GetCanonicalName() + "." + GetName();
1015 }
Steven Moreland787b0432018-07-03 09:00:58 -07001016 return GetPackage() + "." + GetName();
1017}
1018
Jooyung Han829ec7c2020-12-02 12:07:36 +09001019bool AidlDefinedType::CheckValidWithMembers(const AidlTypenames& typenames) const {
1020 bool success = true;
1021
Jooyung Han2aedb112021-09-29 09:37:59 +09001022 for (const auto& t : GetNestedTypes()) {
1023 success = success && t->CheckValid(typenames);
1024 }
1025
Jooyung Han7fc5de02021-09-30 22:26:27 +09001026 if (auto parameterizable = AsParameterizable();
1027 parameterizable && parameterizable->IsGeneric() && !GetNestedTypes().empty()) {
1028 AIDL_ERROR(this) << "Generic types can't have nested types.";
1029 return false;
1030 }
1031
Jooyung Han2aedb112021-09-29 09:37:59 +09001032 std::set<std::string> nested_type_names;
1033 for (const auto& t : GetNestedTypes()) {
1034 bool duplicated = !nested_type_names.emplace(t->GetName()).second;
1035 if (duplicated) {
1036 AIDL_ERROR(t) << "Redefinition of '" << t->GetName() << "'.";
1037 success = false;
1038 }
1039 // nested type can't have a parent name
1040 if (t->GetName() == GetName()) {
1041 AIDL_ERROR(t) << "Nested type '" << GetName() << "' has the same name as its parent.";
1042 success = false;
1043 }
Jooyung Han2b1487d2021-09-30 09:57:01 +09001044 // Having unstructured parcelables as nested types doesn't make sense because they are defined
1045 // somewhere else in native languages (e.g. C++, Java...).
1046 if (AidlCast<AidlParcelable>(*t)) {
1047 AIDL_ERROR(t) << "'" << t->GetName()
1048 << "' is nested. Unstructured parcelables should be at the root scope.";
1049 return false;
1050 }
Jooyung Han2aedb112021-09-29 09:37:59 +09001051 // For now we don't allow "interface" to be nested
1052 if (AidlCast<AidlInterface>(*t)) {
1053 AIDL_ERROR(t) << "'" << t->GetName()
1054 << "' is nested. Interfaces should be at the root scope.";
1055 return false;
1056 }
1057 }
1058
Jooyung Han829ec7c2020-12-02 12:07:36 +09001059 for (const auto& v : GetFields()) {
1060 const bool field_valid = v->CheckValid(typenames);
1061 success = success && field_valid;
1062 }
1063
1064 // field names should be unique
1065 std::set<std::string> fieldnames;
1066 for (const auto& v : GetFields()) {
1067 bool duplicated = !fieldnames.emplace(v->GetName()).second;
1068 if (duplicated) {
1069 AIDL_ERROR(v) << "'" << GetName() << "' has duplicate field name '" << v->GetName() << "'";
1070 success = false;
1071 }
1072 }
1073
1074 // immutable parcelables should have immutable fields.
1075 if (IsJavaOnlyImmutable()) {
1076 for (const auto& v : GetFields()) {
1077 if (!typenames.CanBeJavaOnlyImmutable(v->GetType())) {
1078 AIDL_ERROR(v) << "The @JavaOnlyImmutable '" << GetName() << "' has a "
1079 << "non-immutable field named '" << v->GetName() << "'.";
1080 success = false;
1081 }
1082 }
1083 }
1084
1085 set<string> constant_names;
1086 for (const auto& constant : GetConstantDeclarations()) {
1087 if (constant_names.count(constant->GetName()) > 0) {
1088 AIDL_ERROR(constant) << "Found duplicate constant name '" << constant->GetName() << "'";
1089 success = false;
1090 }
1091 constant_names.insert(constant->GetName());
1092 success = success && constant->CheckValid(typenames);
1093 }
1094
1095 return success;
1096}
1097
1098bool AidlDefinedType::CheckValidForGetterNames() const {
1099 bool success = true;
1100 std::set<std::string> getters;
1101 for (const auto& v : GetFields()) {
1102 bool duplicated = !getters.emplace(v->GetCapitalizedName()).second;
1103 if (duplicated) {
1104 AIDL_ERROR(v) << "'" << GetName() << "' has duplicate field name '" << v->GetName()
1105 << "' after capitalizing the first letter";
1106 success = false;
1107 }
1108 }
1109 return success;
1110}
1111
Jooyung Han2aedb112021-09-29 09:37:59 +09001112const AidlDefinedType* AidlDefinedType::GetParentType() const {
1113 AIDL_FATAL_IF(GetEnclosingScope() == nullptr, this) << "Scope is not set.";
1114 return AidlCast<AidlDefinedType>(GetEnclosingScope()->GetNode());
1115}
1116
1117// Resolve `name` in the current scope. If not found, delegate to the parent
Jooyung Han13f1fa52021-06-11 18:06:12 +09001118std::string AidlDefinedType::ResolveName(const std::string& name) const {
Jooyung Han2aedb112021-09-29 09:37:59 +09001119 // For example, in the following, t1's type Baz means x.Foo.Bar.Baz
1120 // while t2's type is y.Baz.
Jooyung Han13f1fa52021-06-11 18:06:12 +09001121 // package x;
Jooyung Han2aedb112021-09-29 09:37:59 +09001122 // import y.Baz;
Jooyung Han13f1fa52021-06-11 18:06:12 +09001123 // parcelable Foo {
1124 // parcelable Bar {
Jooyung Han2aedb112021-09-29 09:37:59 +09001125 // enum Baz { ... }
1126 // Baz t1; // -> should be x.Foo.Bar.Baz
Jooyung Han13f1fa52021-06-11 18:06:12 +09001127 // }
Jooyung Han2aedb112021-09-29 09:37:59 +09001128 // Baz t2; // -> should be y.Baz
1129 // Bar.Baz t3; // -> should be x.Foo.Bar.Baz
Jooyung Han13f1fa52021-06-11 18:06:12 +09001130 // }
1131 AIDL_FATAL_IF(!GetEnclosingScope(), this)
1132 << "Type should have an enclosing scope.(e.g. AidlDocument)";
Jooyung Han2aedb112021-09-29 09:37:59 +09001133 if (AidlTypenames::IsBuiltinTypename(name)) {
1134 return name;
1135 }
1136
1137 const auto first_dot = name.find_first_of('.');
1138 // For "Outer.Inner", we look up "Outer" in the import list.
1139 const std::string class_name =
1140 (first_dot == std::string::npos) ? name : name.substr(0, first_dot);
1141 // Keep ".Inner", to make a fully-qualified name
1142 const std::string nested_type = (first_dot == std::string::npos) ? "" : name.substr(first_dot);
1143
1144 // check if it is a nested type
1145 for (const auto& type : GetNestedTypes()) {
1146 if (type->GetName() == class_name) {
1147 return type->GetCanonicalName() + nested_type;
1148 }
1149 }
1150
Jooyung Han13f1fa52021-06-11 18:06:12 +09001151 return GetEnclosingScope()->ResolveName(name);
1152}
1153
Jooyung Hanbaa71062021-09-29 09:06:03 +09001154template <>
1155const AidlDefinedType* AidlCast<AidlDefinedType>(const AidlNode& node) {
1156 struct Visitor : AidlVisitor {
1157 const AidlDefinedType* defined_type = nullptr;
1158 void Visit(const AidlInterface& t) override { defined_type = &t; }
1159 void Visit(const AidlEnumDeclaration& t) override { defined_type = &t; }
1160 void Visit(const AidlStructuredParcelable& t) override { defined_type = &t; }
1161 void Visit(const AidlUnionDecl& t) override { defined_type = &t; }
1162 void Visit(const AidlParcelable& t) override { defined_type = &t; }
1163 } v;
1164 node.DispatchVisit(v);
1165 return v.defined_type;
Jooyung Han35784982021-06-29 06:26:12 +09001166}
1167
1168const AidlDocument& AidlDefinedType::GetDocument() const {
1169 // TODO(b/182508839): resolve with nested types when we support nested types
1170 auto scope = GetEnclosingScope();
1171 AIDL_FATAL_IF(!scope, this) << "no scope defined.";
1172 auto doc = AidlCast<AidlDocument>(scope->GetNode());
1173 AIDL_FATAL_IF(!doc, this) << "scope is not a document.";
1174 return *doc;
1175}
1176
Jiyong Park18132182020-06-08 20:24:40 +09001177AidlParcelable::AidlParcelable(const AidlLocation& location, const std::string& name,
Jooyung Han8451a202021-01-16 03:07:06 +09001178 const std::string& package, const Comments& comments,
Jooyung Han829ec7c2020-12-02 12:07:36 +09001179 const std::string& cpp_header, std::vector<std::string>* type_params,
1180 std::vector<std::unique_ptr<AidlMember>>* members)
1181 : AidlDefinedType(location, name, comments, package, members),
Jeongik Chadf76dc72019-11-28 00:08:47 +09001182 AidlParameterizable<std::string>(type_params),
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -08001183 cpp_header_(cpp_header) {
1184 // Strip off quotation marks if we actually have a cpp header.
1185 if (cpp_header_.length() >= 2) {
1186 cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
1187 }
Casey Dahlin59401da2015-10-09 18:16:45 -07001188}
Jeongik Chadf76dc72019-11-28 00:08:47 +09001189template <typename T>
1190AidlParameterizable<T>::AidlParameterizable(const AidlParameterizable& other) {
1191 // Copying is not supported if it has type parameters.
1192 // It doesn't make a problem because only ArrayBase() makes a copy,
1193 // and it can be called only if a type is not generic.
Steven Moreland21780812020-09-11 01:29:45 +00001194 AIDL_FATAL_IF(other.IsGeneric(), AIDL_LOCATION_HERE);
Jeongik Chadf76dc72019-11-28 00:08:47 +09001195}
1196
1197template <typename T>
1198bool AidlParameterizable<T>::CheckValid() const {
1199 return true;
1200};
1201
1202template <>
1203bool AidlParameterizable<std::string>::CheckValid() const {
1204 if (!IsGeneric()) {
1205 return true;
1206 }
1207 std::unordered_set<std::string> set(GetTypeParameters().begin(), GetTypeParameters().end());
1208 if (set.size() != GetTypeParameters().size()) {
1209 AIDL_ERROR(this->AsAidlNode()) << "Every type parameter should be unique.";
1210 return false;
1211 }
1212 return true;
1213}
Casey Dahlin59401da2015-10-09 18:16:45 -07001214
Jooyung Han808a2a02020-12-28 16:46:54 +09001215bool AidlParcelable::CheckValid(const AidlTypenames& typenames) const {
1216 if (!AidlDefinedType::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +01001217 return false;
1218 }
Jeongik Chadf76dc72019-11-28 00:08:47 +09001219 if (!AidlParameterizable<std::string>::CheckValid()) {
1220 return false;
1221 }
Jeongik Cha82317dd2019-02-27 20:26:11 +09001222
1223 return true;
1224}
1225
Steven Moreland5557f1c2018-07-02 13:50:23 -07001226AidlStructuredParcelable::AidlStructuredParcelable(
Jiyong Park18132182020-06-08 20:24:40 +09001227 const AidlLocation& location, const std::string& name, const std::string& package,
Jooyung Han8451a202021-01-16 03:07:06 +09001228 const Comments& comments, std::vector<std::string>* type_params,
Jooyung Han829ec7c2020-12-02 12:07:36 +09001229 std::vector<std::unique_ptr<AidlMember>>* members)
1230 : AidlParcelable(location, name, package, comments, "" /*cpp_header*/, type_params, members) {}
Steven Moreland5557f1c2018-07-02 13:50:23 -07001231
Jooyung Han808a2a02020-12-28 16:46:54 +09001232bool AidlStructuredParcelable::CheckValid(const AidlTypenames& typenames) const {
1233 if (!AidlParcelable::CheckValid(typenames)) {
Devin Moore24f68572020-02-26 13:20:59 -08001234 return false;
1235 }
Jeongik Cha13066da2020-08-06 15:43:19 +09001236
Jooyung Han59af9cc2020-10-25 21:44:14 +09001237 bool success = true;
Jeongik Cha36f76c32020-07-28 00:25:52 +09001238
Jooyung Hand4057c42020-10-23 13:28:22 +09001239 if (IsFixedSize()) {
1240 for (const auto& v : GetFields()) {
1241 if (!typenames.CanBeFixedSize(v->GetType())) {
1242 AIDL_ERROR(v) << "The @FixedSize parcelable '" << this->GetName() << "' has a "
1243 << "non-fixed size field named " << v->GetName() << ".";
1244 success = false;
1245 }
1246 }
1247 }
1248
1249 if (IsJavaOnlyImmutable()) {
Jooyung Han59af9cc2020-10-25 21:44:14 +09001250 // Immutable parcelables provide getters
Jooyung Han829ec7c2020-12-02 12:07:36 +09001251 if (!CheckValidForGetterNames()) {
Jooyung Han59af9cc2020-10-25 21:44:14 +09001252 success = false;
Jooyung Hand4057c42020-10-23 13:28:22 +09001253 }
1254 }
1255
Daniel Norman85aed542019-08-21 12:01:14 -07001256 return success;
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001257}
1258
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001259// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -07001260bool AidlTypeSpecifier::LanguageSpecificCheckValid(const AidlTypenames& typenames,
1261 Options::Language lang) const {
Jooyung Hand09a21d2021-02-15 18:56:55 +09001262 if (IsGeneric()) {
1263 const auto& types = GetTypeParameters();
1264 for (const auto& arg : types) {
1265 if (!arg->LanguageSpecificCheckValid(typenames, lang)) {
1266 return false;
1267 }
1268 }
1269 }
1270
Andrei Homescub62afd92020-05-11 19:24:59 -07001271 if ((lang == Options::Language::NDK || lang == Options::Language::RUST) && IsArray() &&
1272 GetName() == "IBinder") {
Jooyung Han9435e9a2021-01-06 10:16:31 +09001273 AIDL_ERROR(this) << "The " << to_string(lang) << " backend does not support array of IBinder";
Steven Moreland0185d9b2020-05-15 23:21:22 +00001274 return false;
1275 }
Jeongik Cha8f02a532020-10-14 00:16:28 +09001276 if (lang == Options::Language::RUST && GetName() == "ParcelableHolder") {
1277 // TODO(b/146611855): Remove it when Rust backend supports ParcelableHolder
1278 AIDL_ERROR(this) << "The Rust backend does not support ParcelableHolder yet.";
Jeongik Cha225519b2020-08-29 01:55:32 +09001279 return false;
1280 }
Andrei Homescub62afd92020-05-11 19:24:59 -07001281 if ((lang == Options::Language::NDK || lang == Options::Language::RUST) && IsArray() &&
1282 IsNullable()) {
Steven Moreland0185d9b2020-05-15 23:21:22 +00001283 if (GetName() == "ParcelFileDescriptor") {
Jooyung Han9435e9a2021-01-06 10:16:31 +09001284 AIDL_ERROR(this) << "The " << to_string(lang)
Andrei Homescub62afd92020-05-11 19:24:59 -07001285 << " backend does not support nullable array of ParcelFileDescriptor";
Steven Moreland0185d9b2020-05-15 23:21:22 +00001286 return false;
1287 }
1288
Steven Morelandd59e3172020-05-11 16:42:09 -07001289 const auto defined_type = typenames.TryGetDefinedType(GetName());
1290 if (defined_type != nullptr && defined_type->AsParcelable() != nullptr) {
Jooyung Han9435e9a2021-01-06 10:16:31 +09001291 AIDL_ERROR(this) << "The " << to_string(lang)
Andrei Homescub62afd92020-05-11 19:24:59 -07001292 << " backend does not support nullable array of parcelable";
Steven Morelandd59e3172020-05-11 16:42:09 -07001293 return false;
1294 }
1295 }
Andrei Homescub62afd92020-05-11 19:24:59 -07001296 if (this->GetName() == "FileDescriptor" &&
1297 (lang == Options::Language::NDK || lang == Options::Language::RUST)) {
Jooyung Han9435e9a2021-01-06 10:16:31 +09001298 AIDL_ERROR(this) << "FileDescriptor isn't supported by the " << to_string(lang) << " backend.";
Steven Morelandc8a4ca82020-01-21 17:50:08 -08001299 return false;
1300 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001301 if (this->IsGeneric()) {
1302 if (this->GetName() == "List") {
Jooyung Han55f96ad2020-12-13 10:08:33 +09001303 if (lang == Options::Language::NDK) {
1304 const AidlTypeSpecifier& contained_type = *GetTypeParameters()[0];
1305 const string& contained_type_name = contained_type.GetName();
Jooyung Hane87cdd02020-12-11 16:47:35 +09001306 if (typenames.GetInterface(contained_type)) {
1307 AIDL_ERROR(this) << "List<" << contained_type_name
1308 << "> is not supported. List in NDK doesn't support interface.";
1309 return false;
1310 }
1311 if (contained_type_name == "IBinder") {
1312 AIDL_ERROR(this) << "List<" << contained_type_name
1313 << "> is not supported. List in NDK doesn't support IBinder.";
1314 return false;
Jeongik Cha08ca2182019-11-21 14:01:13 +09001315 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001316 }
Jeongik Chabb55b5e2020-01-07 23:11:26 +09001317 }
1318 }
Devin Moore6a01ca12020-08-28 10:24:19 -07001319
1320 if (this->IsArray()) {
1321 if (this->GetName() == "List" || this->GetName() == "Map" ||
1322 this->GetName() == "CharSequence") {
1323 AIDL_ERROR(this) << this->GetName() << "[] is not supported.";
Jeongik Chabb55b5e2020-01-07 23:11:26 +09001324 return false;
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001325 }
1326 }
Devin Moore6a01ca12020-08-28 10:24:19 -07001327
1328 if (lang != Options::Language::JAVA) {
1329 if (this->GetName() == "List" && !this->IsGeneric()) {
1330 AIDL_ERROR(this) << "Currently, only the Java backend supports non-generic List.";
1331 return false;
1332 }
1333 if (this->GetName() == "Map" || this->GetName() == "CharSequence") {
1334 AIDL_ERROR(this) << "Currently, only Java backend supports " << this->GetName() << ".";
1335 return false;
Jeongik Cha08ca2182019-11-21 14:01:13 +09001336 }
1337 }
1338
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001339 return true;
1340}
1341
1342// TODO: we should treat every backend all the same in future.
Jooyung Han589cfb02021-09-28 17:26:04 +09001343bool AidlDefinedType::LanguageSpecificCheckValid(const AidlTypenames& typenames,
1344 Options::Language lang) const {
1345 struct Visitor : AidlVisitor {
1346 Visitor(const AidlTypenames& typenames, Options::Language lang)
1347 : typenames(typenames), lang(lang) {}
1348 void Visit(const AidlTypeSpecifier& type) override {
1349 success = success && type.LanguageSpecificCheckValid(typenames, lang);
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001350 }
Jooyung Han589cfb02021-09-28 17:26:04 +09001351 const AidlTypenames& typenames;
1352 Options::Language lang;
1353 bool success = true;
1354 } v(typenames, lang);
1355 VisitTopDown(v, *this);
1356 return v.success;
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001357}
1358
Daniel Norman85aed542019-08-21 12:01:14 -07001359AidlEnumerator::AidlEnumerator(const AidlLocation& location, const std::string& name,
Jooyung Han8451a202021-01-16 03:07:06 +09001360 AidlConstantValue* value, const Comments& comments)
Jooyung Han5c7e77c2021-01-20 16:00:29 +09001361 : AidlCommentable(location, comments),
Jooyung Han29813842020-12-08 01:28:03 +09001362 name_(name),
1363 value_(value),
Jooyung Han29813842020-12-08 01:28:03 +09001364 value_user_specified_(value != nullptr) {}
Daniel Norman85aed542019-08-21 12:01:14 -07001365
1366bool AidlEnumerator::CheckValid(const AidlTypeSpecifier& enum_backing_type) const {
1367 if (GetValue() == nullptr) {
1368 return false;
1369 }
1370 if (!GetValue()->CheckValid()) {
1371 return false;
1372 }
Will McVickerd7d18df2019-09-12 13:40:50 -07001373 if (GetValue()->ValueString(enum_backing_type, AidlConstantValueDecorator).empty()) {
Daniel Norman85aed542019-08-21 12:01:14 -07001374 AIDL_ERROR(this) << "Enumerator type differs from enum backing type.";
1375 return false;
1376 }
1377 return true;
1378}
1379
1380string AidlEnumerator::ValueString(const AidlTypeSpecifier& backing_type,
1381 const ConstantValueDecorator& decorator) const {
Will McVickerd7d18df2019-09-12 13:40:50 -07001382 return GetValue()->ValueString(backing_type, decorator);
Daniel Norman85aed542019-08-21 12:01:14 -07001383}
1384
1385AidlEnumDeclaration::AidlEnumDeclaration(const AidlLocation& location, const std::string& name,
1386 std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
Jooyung Han8451a202021-01-16 03:07:06 +09001387 const std::string& package, const Comments& comments)
Jooyung Han829ec7c2020-12-02 12:07:36 +09001388 : AidlDefinedType(location, name, comments, package, nullptr),
Jooyung Han29813842020-12-08 01:28:03 +09001389 enumerators_(std::move(*enumerators)) {
Jooyung Han672557b2020-12-24 05:18:00 +09001390 // Fill missing enumerator values with <prev + 1>
1391 // This can't be done in Autofill() because type/ref resolution depends on this.
1392 // For example, with enum E { A, B = A }, B's value 'A' is a reference which can't be
1393 // resolved if A has no value set.
Daniel Normanb28684e2019-10-17 15:31:39 -07001394 const AidlEnumerator* previous = nullptr;
1395 for (const auto& enumerator : enumerators_) {
1396 if (enumerator->GetValue() == nullptr) {
Jooyung Han29813842020-12-08 01:28:03 +09001397 auto loc = enumerator->GetLocation();
Daniel Normanb28684e2019-10-17 15:31:39 -07001398 if (previous == nullptr) {
Devin Mooredf93ebb2020-03-25 14:03:35 -07001399 enumerator->SetValue(
Jooyung Han29813842020-12-08 01:28:03 +09001400 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(loc, "0")));
Daniel Normanb28684e2019-10-17 15:31:39 -07001401 } else {
Jooyung Hand0c8af02021-01-06 18:08:01 +09001402 auto prev_value = std::make_unique<AidlConstantReference>(loc, previous->GetName());
Daniel Normanb28684e2019-10-17 15:31:39 -07001403 enumerator->SetValue(std::make_unique<AidlBinaryConstExpression>(
Jooyung Han29813842020-12-08 01:28:03 +09001404 loc, std::move(prev_value), "+",
1405 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(loc, "1"))));
Daniel Normanb28684e2019-10-17 15:31:39 -07001406 }
1407 }
1408 previous = enumerator.get();
1409 }
1410}
1411
Jooyung Han672557b2020-12-24 05:18:00 +09001412bool AidlEnumDeclaration::Autofill(const AidlTypenames& typenames) {
1413 if (auto annot = BackingType(); annot != nullptr) {
Jooyung Hanb3c77ed2020-12-26 02:02:45 +09001414 // Autofill() is called before the grand CheckValid(). But AidlAnnotation::ParamValue()
1415 // calls AidlConstantValue::evaluate() which requires CheckValid() to be called before. So we
Jooyung Han672557b2020-12-24 05:18:00 +09001416 // need to call CheckValid().
1417 if (!annot->CheckValid()) {
1418 return false;
1419 }
Jooyung Hanb3c77ed2020-12-26 02:02:45 +09001420 auto type = annot->ParamValue<std::string>("type").value();
1421 backing_type_ =
Jooyung Han8451a202021-01-16 03:07:06 +09001422 std::make_unique<AidlTypeSpecifier>(annot->GetLocation(), type, false, nullptr, Comments{});
Jooyung Han672557b2020-12-24 05:18:00 +09001423 } else {
1424 // Default to byte type for enums.
1425 backing_type_ =
Jooyung Han8451a202021-01-16 03:07:06 +09001426 std::make_unique<AidlTypeSpecifier>(AIDL_LOCATION_HERE, "byte", false, nullptr, Comments{});
Jooyung Han672557b2020-12-24 05:18:00 +09001427 }
1428 // Autofill() is called after type resolution, we resolve the backing type manually.
Jooyung Han13f1fa52021-06-11 18:06:12 +09001429 if (!backing_type_->Resolve(typenames, nullptr)) {
Jooyung Han672557b2020-12-24 05:18:00 +09001430 AIDL_ERROR(this) << "Invalid backing type: " << backing_type_->GetName();
1431 }
1432 return true;
1433}
1434
Jooyung Han808a2a02020-12-28 16:46:54 +09001435bool AidlEnumDeclaration::CheckValid(const AidlTypenames& typenames) const {
1436 if (!AidlDefinedType::CheckValid(typenames)) {
Devin Moore24f68572020-02-26 13:20:59 -08001437 return false;
1438 }
Jooyung Han829ec7c2020-12-02 12:07:36 +09001439 if (!GetMembers().empty()) {
1440 AIDL_ERROR(this) << "Enum doesn't support fields/constants/methods.";
1441 return false;
1442 }
Daniel Norman85aed542019-08-21 12:01:14 -07001443 if (backing_type_ == nullptr) {
1444 AIDL_ERROR(this) << "Enum declaration missing backing type.";
1445 return false;
1446 }
1447 bool success = true;
1448 for (const auto& enumerator : enumerators_) {
1449 success = success && enumerator->CheckValid(GetBackingType());
1450 }
Jooyung Han3b990182020-12-22 17:44:31 +09001451
Jooyung Han808a2a02020-12-28 16:46:54 +09001452 return success;
Daniel Norman85aed542019-08-21 12:01:14 -07001453}
1454
Jooyung Han2946afc2020-10-05 20:29:16 +09001455AidlUnionDecl::AidlUnionDecl(const AidlLocation& location, const std::string& name,
Jooyung Han8451a202021-01-16 03:07:06 +09001456 const std::string& package, const Comments& comments,
Jooyung Han829ec7c2020-12-02 12:07:36 +09001457 std::vector<std::string>* type_params,
1458 std::vector<std::unique_ptr<AidlMember>>* members)
1459 : AidlParcelable(location, name, package, comments, "" /*cpp_header*/, type_params, members) {}
Jooyung Han2946afc2020-10-05 20:29:16 +09001460
Jooyung Han808a2a02020-12-28 16:46:54 +09001461bool AidlUnionDecl::CheckValid(const AidlTypenames& typenames) const {
Jooyung Han59af9cc2020-10-25 21:44:14 +09001462 // visit parents
Jooyung Han808a2a02020-12-28 16:46:54 +09001463 if (!AidlParcelable::CheckValid(typenames)) {
Jooyung Hanfe89f122020-10-14 03:49:18 +09001464 return false;
1465 }
Jooyung Han59af9cc2020-10-25 21:44:14 +09001466
1467 // unions provide getters always
Jooyung Han829ec7c2020-12-02 12:07:36 +09001468 if (!CheckValidForGetterNames()) {
Jooyung Han59af9cc2020-10-25 21:44:14 +09001469 return false;
Jooyung Hanfe89f122020-10-14 03:49:18 +09001470 }
1471
1472 // now, visit self!
1473 bool success = true;
1474
1475 // TODO(b/170807936) do we need to allow ParcelableHolder in union?
1476 for (const auto& v : GetFields()) {
1477 if (v->GetType().GetName() == "ParcelableHolder") {
1478 AIDL_ERROR(*v) << "A union can't have a member of ParcelableHolder '" << v->GetName() << "'";
1479 success = false;
1480 }
1481 }
1482
Jooyung Hanfe89f122020-10-14 03:49:18 +09001483 if (GetFields().empty()) {
1484 AIDL_ERROR(*this) << "The union '" << this->GetName() << "' has no fields.";
1485 return false;
1486 }
1487
Jooyung Han53fb4242020-12-17 16:03:49 +09001488 // first member should have useful default value (implicit or explicit)
1489 const auto& first = GetFields()[0];
1490 if (!first->HasUsefulDefaultValue()) {
1491 // Most types can be initialized without a default value. For example,
1492 // interface types are inherently nullable. But, enum types should have
1493 // an explicit default value.
1494 if (!first->GetType().IsArray() && typenames.GetEnumDeclaration(first->GetType())) {
1495 AIDL_ERROR(first)
1496 << "The union's first member should have a useful default value. Enum types can be "
1497 "initialized with a reference. (e.g. ... = MyEnum.FOO;)";
1498 return false;
1499 }
1500 // In Java, array types are initialized as null without a default value. To be sure that default
1501 // initialized unions are accepted by other backends we require arrays also have a default
1502 // value.
1503 if (first->GetType().IsArray()) {
1504 AIDL_ERROR(first)
1505 << "The union's first member should have a useful default value. Arrays can be "
1506 "initialized with values(e.g. ... = { values... };) or marked as @nullable.";
1507 return false;
1508 }
1509 }
1510
Jooyung Hanfe89f122020-10-14 03:49:18 +09001511 return success;
1512}
1513
Steven Moreland46e9da82018-07-27 15:45:29 -07001514AidlInterface::AidlInterface(const AidlLocation& location, const std::string& name,
Jooyung Han8451a202021-01-16 03:07:06 +09001515 const Comments& comments, bool oneway, const std::string& package,
Jooyung Han829ec7c2020-12-02 12:07:36 +09001516 std::vector<std::unique_ptr<AidlMember>>* members)
1517 : AidlDefinedType(location, name, comments, package, members) {
1518 for (auto& m : GetMethods()) {
1519 m.get()->ApplyInterfaceOneway(oneway);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001520 }
Casey Dahlinfb7da2e2015-10-08 17:26:09 -07001521}
1522
Jooyung Han808a2a02020-12-28 16:46:54 +09001523bool AidlInterface::CheckValid(const AidlTypenames& typenames) const {
1524 if (!AidlDefinedType::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +01001525 return false;
1526 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001527 // Has to be a pointer due to deleting copy constructor. No idea why.
1528 map<string, const AidlMethod*> method_names;
1529 for (const auto& m : GetMethods()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001530 if (!m->GetType().CheckValid(typenames)) {
1531 return false;
1532 }
1533
Jeongik Cha649e8a72020-03-27 17:47:40 +09001534 // TODO(b/156872582): Support it when ParcelableHolder supports every backend.
1535 if (m->GetType().GetName() == "ParcelableHolder") {
1536 AIDL_ERROR(m) << "ParcelableHolder cannot be a return type";
1537 return false;
1538 }
Steven Morelandacd53472018-12-14 10:17:26 -08001539 if (m->IsOneway() && m->GetType().GetName() != "void") {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001540 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot return a value";
1541 return false;
1542 }
1543
1544 set<string> argument_names;
1545 for (const auto& arg : m->GetArguments()) {
1546 auto it = argument_names.find(arg->GetName());
1547 if (it != argument_names.end()) {
1548 AIDL_ERROR(m) << "method '" << m->GetName() << "' has duplicate argument name '"
1549 << arg->GetName() << "'";
1550 return false;
1551 }
1552 argument_names.insert(arg->GetName());
1553
Jooyung Han020d8d12021-02-26 17:23:02 +09001554 if (!arg->CheckValid(typenames)) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001555 return false;
1556 }
1557
Steven Morelandacd53472018-12-14 10:17:26 -08001558 if (m->IsOneway() && arg->IsOut()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001559 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot have out parameters";
1560 return false;
1561 }
Jooyung Han15fd6c62020-10-23 13:54:46 +09001562
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001563 // check that the name doesn't match a keyword
Jeongik Cha997281d2020-01-16 15:23:59 +09001564 if (IsJavaKeyword(arg->GetName().c_str())) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001565 AIDL_ERROR(arg) << "Argument name is a Java or aidl keyword";
1566 return false;
1567 }
1568
1569 // Reserve a namespace for internal use
1570 if (android::base::StartsWith(arg->GetName(), "_aidl")) {
1571 AIDL_ERROR(arg) << "Argument name cannot begin with '_aidl'";
1572 return false;
1573 }
Jooyung Hanfa181932021-06-12 07:56:53 +09001574
1575 if (arg->GetType().GetName() == "void") {
1576 AIDL_ERROR(arg->GetType())
1577 << "'void' is an invalid type for the parameter '" << arg->GetName() << "'";
1578 return false;
1579 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001580 }
1581
1582 auto it = method_names.find(m->GetName());
1583 // prevent duplicate methods
1584 if (it == method_names.end()) {
1585 method_names[m->GetName()] = m.get();
1586 } else {
1587 AIDL_ERROR(m) << "attempt to redefine method " << m->GetName() << ":";
1588 AIDL_ERROR(it->second) << "previously defined here.";
1589 return false;
1590 }
1591
Paul Trautrimb77048c2020-01-21 16:39:32 +09001592 static set<string> reserved_methods{"asBinder()", "getInterfaceHash()", "getInterfaceVersion()",
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001593 "getTransactionName(int)"};
1594
1595 if (reserved_methods.find(m->Signature()) != reserved_methods.end()) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001596 AIDL_ERROR(m) << " method " << m->Signature() << " is reserved for internal use.";
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001597 return false;
1598 }
1599 }
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001600
1601 bool success = true;
1602 set<string> constant_names;
Jooyung Han3f347ca2020-12-01 12:41:50 +09001603 for (const auto& constant : GetConstantDeclarations()) {
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001604 if (constant_names.count(constant->GetName()) > 0) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001605 AIDL_ERROR(constant) << "Found duplicate constant name '" << constant->GetName() << "'";
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001606 success = false;
1607 }
1608 constant_names.insert(constant->GetName());
1609 success = success && constant->CheckValid(typenames);
1610 }
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001611 return success;
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001612}
1613
Jiyong Park27fd7fd2020-08-27 16:25:09 +09001614std::string AidlInterface::GetDescriptor() const {
1615 std::string annotatedDescriptor = AidlAnnotatable::GetDescriptor();
1616 if (annotatedDescriptor != "") {
1617 return annotatedDescriptor;
1618 }
1619 return GetCanonicalName();
1620}
1621
Jooyung Han132cf802021-01-15 02:17:32 +09001622AidlImport::AidlImport(const AidlLocation& location, const std::string& needed_class,
Jooyung Han8451a202021-01-16 03:07:06 +09001623 const Comments& comments)
Jooyung Han5c7e77c2021-01-20 16:00:29 +09001624 : AidlNode(location, comments), needed_class_(needed_class) {}
Jooyung Han29813842020-12-08 01:28:03 +09001625
Jooyung Han13f1fa52021-06-11 18:06:12 +09001626AidlDocument::AidlDocument(const AidlLocation& location, const Comments& comments,
1627 std::vector<std::unique_ptr<AidlImport>> imports,
Jooyung Han35784982021-06-29 06:26:12 +09001628 std::vector<std::unique_ptr<AidlDefinedType>> defined_types,
1629 bool is_preprocessed)
Jooyung Han13f1fa52021-06-11 18:06:12 +09001630 : AidlCommentable(location, comments),
Jooyung Han35784982021-06-29 06:26:12 +09001631 AidlScope(this),
Jooyung Han13f1fa52021-06-11 18:06:12 +09001632 imports_(std::move(imports)),
Jooyung Han35784982021-06-29 06:26:12 +09001633 defined_types_(std::move(defined_types)),
1634 is_preprocessed_(is_preprocessed) {
Jooyung Han13f1fa52021-06-11 18:06:12 +09001635 for (const auto& t : defined_types_) {
1636 t->SetEnclosingScope(this);
1637 }
1638}
1639
1640// Resolves type name in the current document.
1641// - built-in types
1642// - imported types
1643// - top-level type
1644std::string AidlDocument::ResolveName(const std::string& name) const {
1645 if (AidlTypenames::IsBuiltinTypename(name)) {
1646 return name;
1647 }
1648
1649 const auto first_dot = name.find_first_of('.');
1650 // For "Outer.Inner", we look up "Outer" in the import list.
Jooyung Han29813842020-12-08 01:28:03 +09001651 const std::string class_name =
Jooyung Han13f1fa52021-06-11 18:06:12 +09001652 (first_dot == std::string::npos) ? name : name.substr(0, first_dot);
1653 // Keep ".Inner", to make a fully-qualified name
1654 const std::string nested_type = (first_dot == std::string::npos) ? "" : name.substr(first_dot);
1655
Jooyung Han29813842020-12-08 01:28:03 +09001656 for (const auto& import : Imports()) {
Jooyung Han13f1fa52021-06-11 18:06:12 +09001657 if (import->SimpleName() == class_name) {
1658 return import->GetNeededClass() + nested_type;
Jooyung Han29813842020-12-08 01:28:03 +09001659 }
1660 }
Jooyung Han13f1fa52021-06-11 18:06:12 +09001661
1662 // check if it is a top-level type.
1663 for (const auto& type : DefinedTypes()) {
1664 if (type->GetName() == class_name) {
1665 return type->GetCanonicalName() + nested_type;
1666 }
Jooyung Han29813842020-12-08 01:28:03 +09001667 }
Jooyung Han13f1fa52021-06-11 18:06:12 +09001668
1669 // name itself might be fully-qualified name.
1670 return name;
Steven Moreland26318532020-12-23 20:08:36 +00001671}