blob: f105f5d6ad8f42366cc775413b725e002f740776 [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>
Jiyong Park68bc77a2018-07-19 19:00:45 +090024#include <algorithm>
Jiyong Park1deecc32018-07-17 01:14:41 +090025#include <iostream>
Jiyong Park68bc77a2018-07-19 19:00:45 +090026#include <set>
27#include <sstream>
Casey Dahlindd691812015-09-09 17:59:06 -070028#include <string>
Jiyong Park1deecc32018-07-17 01:14:41 +090029#include <utility>
Christopher Wileyf690be52015-09-14 15:19:10 -070030
Steven Moreland1c4ba202018-08-09 10:49:54 -070031#include <android-base/parsedouble.h>
Roshan Pius9d7810a2016-07-28 08:57:50 -070032#include <android-base/parseint.h>
Elliott Hughes0a620672015-12-04 13:53:18 -080033#include <android-base/strings.h>
Christopher Wileyd76067c2015-10-19 17:00:13 -070034
Dan Willemsen609ba6d2019-12-30 10:44:00 -080035#include "aidl_language_y-module.h"
Christopher Wiley4a2884b2015-10-07 11:27:45 -070036#include "logging.h"
Adam Lesinskiffa16862014-01-23 18:17:42 -080037
Will McVickerd7d18df2019-09-12 13:40:50 -070038#include "aidl.h"
39
Casey Dahlin07b9dde2015-09-10 19:13:49 -070040#ifdef _WIN32
41int isatty(int fd)
42{
43 return (fd == 0);
44}
45#endif
46
Christopher Wiley4a2884b2015-10-07 11:27:45 -070047using android::aidl::IoDelegate;
Christopher Wileyd76067c2015-10-19 17:00:13 -070048using android::base::Join;
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -080049using android::base::Split;
Casey Dahlindd691812015-09-09 17:59:06 -070050using std::cerr;
Jiyong Park1deecc32018-07-17 01:14:41 +090051using std::pair;
Jiyong Park68bc77a2018-07-19 19:00:45 +090052using std::set;
Christopher Wiley4a2884b2015-10-07 11:27:45 -070053using std::string;
54using std::unique_ptr;
Jiyong Parkccf00f82018-07-17 01:39:23 +090055using std::vector;
Adam Lesinskiffa16862014-01-23 18:17:42 -080056
Jeongik Cha047c5ee2019-08-07 23:16:49 +090057namespace {
Jeongik Cha997281d2020-01-16 15:23:59 +090058bool IsJavaKeyword(const char* str) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +090059 static const std::vector<std::string> kJavaKeywords{
60 "abstract", "assert", "boolean", "break", "byte", "case", "catch",
61 "char", "class", "const", "continue", "default", "do", "double",
62 "else", "enum", "extends", "final", "finally", "float", "for",
63 "goto", "if", "implements", "import", "instanceof", "int", "interface",
64 "long", "native", "new", "package", "private", "protected", "public",
65 "return", "short", "static", "strictfp", "super", "switch", "synchronized",
66 "this", "throw", "throws", "transient", "try", "void", "volatile",
67 "while", "true", "false", "null",
68 };
69 return std::find(kJavaKeywords.begin(), kJavaKeywords.end(), str) != kJavaKeywords.end();
70}
Jeongik Cha997281d2020-01-16 15:23:59 +090071
72void AddHideComment(CodeWriter* writer) {
73 writer->Write("/* @hide */\n");
74}
75
76inline bool HasHideComment(const std::string& comment) {
77 return std::regex_search(comment, std::regex("@hide\\b"));
78}
Jeongik Cha047c5ee2019-08-07 23:16:49 +090079} // namespace
80
Devin Mooredf93ebb2020-03-25 14:03:35 -070081AidlLocation::AidlLocation(const std::string& file, Point begin, Point end, Source source)
82 : file_(file), begin_(begin), end_(end), source_(source) {}
Steven Moreland46e9da82018-07-27 15:45:29 -070083
84std::ostream& operator<<(std::ostream& os, const AidlLocation& l) {
Devin Moore5de18ed2020-04-02 13:52:29 -070085 os << l.file_;
86 if (l.LocationKnown()) {
87 os << ":" << l.begin_.line << "." << l.begin_.column << "-";
88 if (l.begin_.line != l.end_.line) {
89 os << l.end_.line << ".";
90 }
91 os << l.end_.column;
Steven Moreland46e9da82018-07-27 15:45:29 -070092 }
Steven Moreland46e9da82018-07-27 15:45:29 -070093 return os;
94}
95
96AidlNode::AidlNode(const AidlLocation& location) : location_(location) {}
97
Mathew Inwoodadb74672019-11-29 14:01:53 +000098std::string AidlNode::PrintLine() const {
Andrei Onea8714b022019-02-01 18:55:54 +000099 std::stringstream ss;
100 ss << location_.file_ << ":" << location_.begin_.line;
101 return ss.str();
102}
103
Mathew Inwoodadb74672019-11-29 14:01:53 +0000104std::string AidlNode::PrintLocation() const {
105 std::stringstream ss;
106 ss << location_.file_ << ":" << location_.begin_.line << ":" << location_.begin_.column << ":"
107 << location_.end_.line << ":" << location_.end_.column;
108 return ss.str();
109}
110
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700111const std::vector<AidlAnnotation::Schema>& AidlAnnotation::AllSchemas() {
112 static const std::vector<Schema> kSchemas{
113 {AidlAnnotation::Type::NULLABLE, "nullable", {}},
114 {AidlAnnotation::Type::UTF8_IN_CPP, "utf8InCpp", {}},
115 {AidlAnnotation::Type::VINTF_STABILITY, "VintfStability", {}},
116 {AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
117 "UnsupportedAppUsage",
118 {{"expectedSignature", "String"},
119 {"implicitMember", "String"},
120 {"maxTargetSdk", "int"},
121 {"publicAlternatives", "String"},
122 {"trackingBug", "long"}}},
123 {AidlAnnotation::Type::JAVA_STABLE_PARCELABLE, "JavaOnlyStableParcelable", {}},
124 {AidlAnnotation::Type::HIDE, "Hide", {}},
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900125 {AidlAnnotation::Type::BACKING, "Backing", {{"type", "String"}}},
126 {AidlAnnotation::Type::JAVA_PASSTHROUGH, "JavaPassthrough", {{"annotation", "String"}}},
Jiyong Park43113fb2020-07-20 16:26:19 +0900127 {AidlAnnotation::Type::JAVA_DEBUG, "JavaDebug", {}},
Jeongik Cha36f76c32020-07-28 00:25:52 +0900128 {AidlAnnotation::Type::IMMUTABLE, "Immutable", {}},
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900129 };
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700130 return kSchemas;
131}
Jiyong Park68bc77a2018-07-19 19:00:45 +0900132
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700133std::string AidlAnnotation::TypeToString(Type type) {
134 for (const Schema& schema : AllSchemas()) {
135 if (type == schema.type) return schema.name;
136 }
137 AIDL_FATAL(AIDL_LOCATION_HERE) << "Unrecognized type: " << static_cast<size_t>(type);
138 __builtin_unreachable();
139}
Andrei Onea9445fc62019-06-27 18:11:59 +0100140
141AidlAnnotation* AidlAnnotation::Parse(
142 const AidlLocation& location, const string& name,
143 std::map<std::string, std::shared_ptr<AidlConstantValue>>* parameter_list) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700144 const Schema* schema = nullptr;
145 for (const Schema& a_schema : AllSchemas()) {
146 if (a_schema.name == name) {
147 schema = &a_schema;
148 }
149 }
150
151 if (schema == nullptr) {
Jiyong Park68bc77a2018-07-19 19:00:45 +0900152 std::ostringstream stream;
Steven Moreland46e9da82018-07-27 15:45:29 -0700153 stream << "'" << name << "' is not a recognized annotation. ";
Jiyong Park68bc77a2018-07-19 19:00:45 +0900154 stream << "It must be one of:";
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700155 for (const Schema& s : AllSchemas()) {
156 stream << " " << s.name;
Jiyong Park68bc77a2018-07-19 19:00:45 +0900157 }
158 stream << ".";
Steven Moreland46e9da82018-07-27 15:45:29 -0700159 AIDL_ERROR(location) << stream.str();
160 return nullptr;
Jiyong Park68bc77a2018-07-19 19:00:45 +0900161 }
Andrei Onea9445fc62019-06-27 18:11:59 +0100162 if (parameter_list == nullptr) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700163 return new AidlAnnotation(location, *schema, {});
Andrei Onea9445fc62019-06-27 18:11:59 +0100164 }
165
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700166 return new AidlAnnotation(location, *schema, std::move(*parameter_list));
Jiyong Park68bc77a2018-07-19 19:00:45 +0900167}
168
Andrei Onea9445fc62019-06-27 18:11:59 +0100169AidlAnnotation::AidlAnnotation(
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700170 const AidlLocation& location, const Schema& schema,
Andrei Onea9445fc62019-06-27 18:11:59 +0100171 std::map<std::string, std::shared_ptr<AidlConstantValue>>&& parameters)
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700172 : AidlNode(location), schema_(schema), parameters_(std::move(parameters)) {}
Andrei Onea9445fc62019-06-27 18:11:59 +0100173
174bool AidlAnnotation::CheckValid() const {
Andrei Onea9445fc62019-06-27 18:11:59 +0100175 for (const auto& name_and_param : parameters_) {
176 const std::string& param_name = name_and_param.first;
177 const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
Will McVickerd7d18df2019-09-12 13:40:50 -0700178 if (!param->CheckValid()) {
179 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
180 << GetName() << ".";
181 return false;
182 }
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700183 auto parameter_mapping_it = schema_.supported_parameters.find(param_name);
184 if (parameter_mapping_it == schema_.supported_parameters.end()) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100185 std::ostringstream stream;
186 stream << "Parameter " << param_name << " not supported ";
Devin Mooredecaf292020-04-30 09:16:40 -0700187 stream << "for annotation " << GetName() << ". ";
Andrei Onea9445fc62019-06-27 18:11:59 +0100188 stream << "It must be one of:";
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700189 for (const auto& kv : schema_.supported_parameters) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100190 stream << " " << kv.first;
191 }
192 AIDL_ERROR(this) << stream.str();
193 return false;
194 }
195 AidlTypeSpecifier type{AIDL_LOCATION_HERE, parameter_mapping_it->second, false, nullptr, ""};
Will McVickerd7d18df2019-09-12 13:40:50 -0700196 const std::string param_value = param->ValueString(type, AidlConstantValueDecorator);
Andrei Onea9445fc62019-06-27 18:11:59 +0100197 // Assume error on empty string.
198 if (param_value == "") {
199 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
200 << GetName() << ".";
201 return false;
202 }
203 }
204 return true;
205}
206
207std::map<std::string, std::string> AidlAnnotation::AnnotationParams(
208 const ConstantValueDecorator& decorator) const {
209 std::map<std::string, std::string> raw_params;
Andrei Onea9445fc62019-06-27 18:11:59 +0100210 for (const auto& name_and_param : parameters_) {
211 const std::string& param_name = name_and_param.first;
212 const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
Devin Mooredecaf292020-04-30 09:16:40 -0700213 if (schema_.supported_parameters.find(param_name) == schema_.supported_parameters.end()) {
214 std::ostringstream stream;
215 stream << "Parameter " << param_name << " not supported ";
216 stream << "for annotation " << GetName() << ". ";
217 stream << "It must be one of:";
218 for (const auto& kv : schema_.supported_parameters) {
219 stream << " " << kv.first;
220 }
221 AIDL_ERROR(this) << stream.str();
222 continue;
223 }
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700224 AidlTypeSpecifier type{AIDL_LOCATION_HERE, schema_.supported_parameters.at(param_name), false,
225 nullptr, ""};
Will McVickerd7d18df2019-09-12 13:40:50 -0700226 if (!param->CheckValid()) {
227 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
228 << GetName() << ".";
Devin Mooredecaf292020-04-30 09:16:40 -0700229 continue;
Will McVickerd7d18df2019-09-12 13:40:50 -0700230 }
231
232 raw_params.emplace(param_name, param->ValueString(type, decorator));
Andrei Onea9445fc62019-06-27 18:11:59 +0100233 }
234 return raw_params;
235}
Steven Moreland46e9da82018-07-27 15:45:29 -0700236
Daniel Norman37d43dd2019-09-09 17:22:34 -0700237std::string AidlAnnotation::ToString(const ConstantValueDecorator& decorator) const {
238 if (parameters_.empty()) {
239 return "@" + GetName();
240 } else {
241 vector<string> param_strings;
242 for (const auto& [name, value] : AnnotationParams(decorator)) {
243 param_strings.emplace_back(name + "=" + value);
244 }
245 return "@" + GetName() + "(" + Join(param_strings, ", ") + ")";
246 }
247}
248
Andrei Onea9445fc62019-06-27 18:11:59 +0100249static const AidlAnnotation* GetAnnotation(const vector<AidlAnnotation>& annotations,
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700250 AidlAnnotation::Type type) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100251 for (const auto& a : annotations) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700252 if (a.GetType() == type) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100253 return &a;
254 }
255 }
256 return nullptr;
257}
258
Steven Moreland46e9da82018-07-27 15:45:29 -0700259AidlAnnotatable::AidlAnnotatable(const AidlLocation& location) : AidlNode(location) {}
260
Jiyong Park68bc77a2018-07-19 19:00:45 +0900261bool AidlAnnotatable::IsNullable() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700262 return GetAnnotation(annotations_, AidlAnnotation::Type::NULLABLE);
Jiyong Park68bc77a2018-07-19 19:00:45 +0900263}
264
Jiyong Park68bc77a2018-07-19 19:00:45 +0900265bool AidlAnnotatable::IsUtf8InCpp() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700266 return GetAnnotation(annotations_, AidlAnnotation::Type::UTF8_IN_CPP);
Jiyong Park68bc77a2018-07-19 19:00:45 +0900267}
268
Steven Morelanda57d0a62019-07-30 09:41:14 -0700269bool AidlAnnotatable::IsVintfStability() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700270 return GetAnnotation(annotations_, AidlAnnotation::Type::VINTF_STABILITY);
Steven Morelanda57d0a62019-07-30 09:41:14 -0700271}
272
Jeongik Cha36f76c32020-07-28 00:25:52 +0900273bool AidlAnnotatable::IsImmutable() const {
274 return GetAnnotation(annotations_, AidlAnnotation::Type::IMMUTABLE);
275}
276
Andrei Onea9445fc62019-06-27 18:11:59 +0100277const AidlAnnotation* AidlAnnotatable::UnsupportedAppUsage() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700278 return GetAnnotation(annotations_, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE);
Jiyong Parka6605ab2018-11-11 14:30:21 +0900279}
280
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900281const AidlAnnotation* AidlAnnotatable::JavaPassthrough() const {
282 return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_PASSTHROUGH);
283}
284
Daniel Norman716d3112019-09-10 13:11:56 -0700285const AidlTypeSpecifier* AidlAnnotatable::BackingType(const AidlTypenames& typenames) const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700286 auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::BACKING);
Daniel Norman85aed542019-08-21 12:01:14 -0700287 if (annotation != nullptr) {
288 auto annotation_params = annotation->AnnotationParams(AidlConstantValueDecorator);
289 if (auto it = annotation_params.find("type"); it != annotation_params.end()) {
290 const string& type = it->second;
Steven Morelande7d5d082020-05-21 20:29:02 +0000291
292 AIDL_FATAL_IF(type.size() < 2, this) << type;
293 AIDL_FATAL_IF(type[0] != '"', this) << type;
294 AIDL_FATAL_IF(type[type.length() - 1] != '"', this) << type;
295 string unquoted_type = type.substr(1, type.length() - 2);
296
Daniel Norman716d3112019-09-10 13:11:56 -0700297 AidlTypeSpecifier* type_specifier =
Steven Morelande7d5d082020-05-21 20:29:02 +0000298 new AidlTypeSpecifier(AIDL_LOCATION_HERE, unquoted_type, false, nullptr, "");
Daniel Norman716d3112019-09-10 13:11:56 -0700299 type_specifier->Resolve(typenames);
300 return type_specifier;
Daniel Norman85aed542019-08-21 12:01:14 -0700301 }
302 }
303 return nullptr;
304}
305
Jeongik Cha88f95a82020-01-15 13:02:16 +0900306bool AidlAnnotatable::IsStableApiParcelable(Options::Language lang) const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700307 return lang == Options::Language::JAVA &&
308 GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_STABLE_PARCELABLE);
Jeongik Cha82317dd2019-02-27 20:26:11 +0900309}
310
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800311bool AidlAnnotatable::IsHide() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700312 return GetAnnotation(annotations_, AidlAnnotation::Type::HIDE);
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800313}
314
Jiyong Park43113fb2020-07-20 16:26:19 +0900315bool AidlAnnotatable::IsJavaDebug() const {
316 return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_DEBUG);
317}
318
Steven Moreland7e4b9502020-02-20 18:10:42 -0800319void AidlAnnotatable::DumpAnnotations(CodeWriter* writer) const {
320 if (annotations_.empty()) return;
321
322 writer->Write("%s\n", AidlAnnotatable::ToString().c_str());
323}
324
Devin Moore24f68572020-02-26 13:20:59 -0800325bool AidlAnnotatable::CheckValid(const AidlTypenames&) const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700326 std::set<AidlAnnotation::Type> supported_annotations = GetSupportedAnnotations();
Andrei Onea9445fc62019-06-27 18:11:59 +0100327 for (const auto& annotation : GetAnnotations()) {
328 if (!annotation.CheckValid()) {
329 return false;
330 }
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700331
332 std::vector<std::string> supported_annot_strings;
333 for (AidlAnnotation::Type type : supported_annotations) {
334 supported_annot_strings.push_back(AidlAnnotation::TypeToString(type));
335 }
336
337 if (supported_annotations.find(annotation.GetType()) == supported_annotations.end()) {
Devin Moore24f68572020-02-26 13:20:59 -0800338 AIDL_ERROR(this) << "'" << annotation.GetName()
339 << "' is not a supported annotation for this node. "
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700340 << "It must be one of: "
341 << android::base::Join(supported_annot_strings, ", ");
Devin Moore24f68572020-02-26 13:20:59 -0800342 return false;
343 }
Andrei Onea9445fc62019-06-27 18:11:59 +0100344 }
Steven Morelanda57d0a62019-07-30 09:41:14 -0700345
Andrei Onea9445fc62019-06-27 18:11:59 +0100346 return true;
347}
348
Jiyong Park68bc77a2018-07-19 19:00:45 +0900349string AidlAnnotatable::ToString() const {
350 vector<string> ret;
351 for (const auto& a : annotations_) {
Daniel Norman37d43dd2019-09-09 17:22:34 -0700352 ret.emplace_back(a.ToString(AidlConstantValueDecorator));
Jiyong Park68bc77a2018-07-19 19:00:45 +0900353 }
354 std::sort(ret.begin(), ret.end());
355 return Join(ret, " ");
356}
357
Steven Moreland46e9da82018-07-27 15:45:29 -0700358AidlTypeSpecifier::AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name,
359 bool is_array,
Jiyong Park1deecc32018-07-17 01:14:41 +0900360 vector<unique_ptr<AidlTypeSpecifier>>* type_params,
Steven Moreland46e9da82018-07-27 15:45:29 -0700361 const string& comments)
362 : AidlAnnotatable(location),
Jeongik Chadf76dc72019-11-28 00:08:47 +0900363 AidlParameterizable<unique_ptr<AidlTypeSpecifier>>(type_params),
Steven Moreland46e9da82018-07-27 15:45:29 -0700364 unresolved_name_(unresolved_name),
Casey Dahlinf7a421c2015-10-05 17:24:28 -0700365 is_array_(is_array),
Jeongik Cha1a7ab642019-07-29 17:31:02 +0900366 comments_(comments),
367 split_name_(Split(unresolved_name, ".")) {}
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700368
Steven Moreland3f658cf2018-08-20 13:40:54 -0700369AidlTypeSpecifier AidlTypeSpecifier::ArrayBase() const {
370 AIDL_FATAL_IF(!is_array_, this);
Jeongik Chadf76dc72019-11-28 00:08:47 +0900371 // Declaring array of generic type cannot happen, it is grammar error.
372 AIDL_FATAL_IF(IsGeneric(), this);
Steven Moreland3f658cf2018-08-20 13:40:54 -0700373
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800374 AidlTypeSpecifier array_base = *this;
375 array_base.is_array_ = false;
376 return array_base;
Steven Moreland3f658cf2018-08-20 13:40:54 -0700377}
378
Jeongik Cha997281d2020-01-16 15:23:59 +0900379bool AidlTypeSpecifier::IsHidden() const {
380 return HasHideComment(GetComments());
381}
382
Jiyong Park1deecc32018-07-17 01:14:41 +0900383string AidlTypeSpecifier::ToString() const {
384 string ret = GetName();
385 if (IsGeneric()) {
386 vector<string> arg_names;
387 for (const auto& ta : GetTypeParameters()) {
Jiyong Parkccf00f82018-07-17 01:39:23 +0900388 arg_names.emplace_back(ta->ToString());
389 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900390 ret += "<" + Join(arg_names, ",") + ">";
Jiyong Parkccf00f82018-07-17 01:39:23 +0900391 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900392 if (IsArray()) {
393 ret += "[]";
394 }
395 return ret;
Jiyong Parkccf00f82018-07-17 01:39:23 +0900396}
397
Jiyong Park02da7422018-07-16 16:00:26 +0900398string AidlTypeSpecifier::Signature() const {
399 string ret = ToString();
400 string annotations = AidlAnnotatable::ToString();
401 if (annotations != "") {
402 ret = annotations + " " + ret;
403 }
404 return ret;
405}
406
Daniel Norman716d3112019-09-10 13:11:56 -0700407bool AidlTypeSpecifier::Resolve(const AidlTypenames& typenames) {
Steven Moreland9731c632019-08-13 10:21:08 -0700408 CHECK(!IsResolved());
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700409 AidlTypenames::ResolvedTypename result = typenames.ResolveTypename(unresolved_name_);
410 if (result.is_resolved) {
411 fully_qualified_name_ = result.canonical_name;
Jeongik Cha1a7ab642019-07-29 17:31:02 +0900412 split_name_ = Split(fully_qualified_name_, ".");
Jiyong Parkccf00f82018-07-17 01:39:23 +0900413 }
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700414 return result.is_resolved;
Casey Dahlin70078e62015-09-30 17:01:30 -0700415}
416
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700417std::set<AidlAnnotation::Type> AidlTypeSpecifier::GetSupportedAnnotations() const {
Devin Moore24f68572020-02-26 13:20:59 -0800418 // kHide and kUnsupportedAppUsage are both method return annotations
419 // which we don't distinguish from other type specifiers.
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700420 return {AidlAnnotation::Type::NULLABLE, AidlAnnotation::Type::UTF8_IN_CPP,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900421 AidlAnnotation::Type::UNSUPPORTED_APP_USAGE, AidlAnnotation::Type::HIDE,
422 AidlAnnotation::Type::JAVA_PASSTHROUGH};
Devin Moore24f68572020-02-26 13:20:59 -0800423}
424
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900425bool AidlTypeSpecifier::CheckValid(const AidlTypenames& typenames) const {
Devin Moore24f68572020-02-26 13:20:59 -0800426 if (!AidlAnnotatable::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100427 return false;
428 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900429 if (IsGeneric()) {
430 const string& type_name = GetName();
Jeongik Chae74c86d2019-12-12 16:54:03 +0900431
432 auto& types = GetTypeParameters();
433 // TODO(b/136048684) Disallow to use primitive types only if it is List or Map.
434 if (type_name == "List" || type_name == "Map") {
435 if (std::any_of(types.begin(), types.end(), [](auto& type_ptr) {
436 return AidlTypenames::IsPrimitiveTypename(type_ptr->GetName());
437 })) {
Devin Moore7b8d5c92020-03-17 14:14:08 -0700438 AIDL_ERROR(this) << "A generic type cannot have any primitive type parameters.";
Jeongik Chae74c86d2019-12-12 16:54:03 +0900439 return false;
440 }
441 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800442 const auto defined_type = typenames.TryGetDefinedType(type_name);
Jeongik Chadf76dc72019-11-28 00:08:47 +0900443 const auto parameterizable =
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800444 defined_type != nullptr ? defined_type->AsParameterizable() : nullptr;
445 const bool is_user_defined_generic_type =
Jeongik Chadf76dc72019-11-28 00:08:47 +0900446 parameterizable != nullptr && parameterizable->IsGeneric();
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800447 const size_t num_params = GetTypeParameters().size();
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900448 if (type_name == "List") {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800449 if (num_params > 1) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900450 AIDL_ERROR(this) << " List cannot have type parameters more than one, but got "
451 << "'" << ToString() << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900452 return false;
453 }
454 } else if (type_name == "Map") {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800455 if (num_params != 0 && num_params != 2) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900456 AIDL_ERROR(this) << "Map must have 0 or 2 type parameters, but got "
457 << "'" << ToString() << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900458 return false;
459 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800460 if (num_params == 2) {
Jeongik Chae48d9942020-01-02 17:39:00 +0900461 const string& key_type = GetTypeParameters()[0]->GetName();
462 if (key_type != "String") {
463 AIDL_ERROR(this) << "The type of key in map must be String, but it is "
464 << "'" << key_type << "'";
465 return false;
466 }
467 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800468 } else if (is_user_defined_generic_type) {
Jeongik Chadf76dc72019-11-28 00:08:47 +0900469 const size_t allowed = parameterizable->GetTypeParameters().size();
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800470 if (num_params != allowed) {
Jeongik Chadf76dc72019-11-28 00:08:47 +0900471 AIDL_ERROR(this) << type_name << " must have " << allowed << " type parameters, but got "
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800472 << num_params;
Jeongik Chadf76dc72019-11-28 00:08:47 +0900473 return false;
474 }
475 } else {
476 AIDL_ERROR(this) << type_name << " is not a generic type.";
477 return false;
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900478 }
479 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900480
Steven Moreland11cb9452020-01-21 16:56:58 -0800481 const bool is_generic_string_list = GetName() == "List" && IsGeneric() &&
482 GetTypeParameters().size() == 1 &&
483 GetTypeParameters()[0]->GetName() == "String";
484 if (IsUtf8InCpp() && (GetName() != "String" && !is_generic_string_list)) {
485 AIDL_ERROR(this) << "@utf8InCpp can only be used on String, String[], and List<String>.";
486 return false;
487 }
488
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900489 if (GetName() == "void") {
490 if (IsArray() || IsNullable() || IsUtf8InCpp()) {
491 AIDL_ERROR(this) << "void type cannot be an array or nullable or utf8 string";
492 return false;
493 }
494 }
495
496 if (IsArray()) {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800497 const auto defined_type = typenames.TryGetDefinedType(GetName());
498 if (defined_type != nullptr && defined_type->AsInterface() != nullptr) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900499 AIDL_ERROR(this) << "Binder type cannot be an array";
500 return false;
501 }
502 }
503
504 if (IsNullable()) {
505 if (AidlTypenames::IsPrimitiveTypename(GetName()) && !IsArray()) {
506 AIDL_ERROR(this) << "Primitive type cannot get nullable annotation";
507 return false;
508 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800509 const auto defined_type = typenames.TryGetDefinedType(GetName());
510 if (defined_type != nullptr && defined_type->AsEnumDeclaration() != nullptr && !IsArray()) {
Daniel Normanee8674f2019-09-20 16:07:00 -0700511 AIDL_ERROR(this) << "Enum type cannot get nullable annotation";
512 return false;
513 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900514 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900515 return true;
516}
517
Steven Moreland860b1942018-08-16 14:59:28 -0700518std::string AidlConstantValueDecorator(const AidlTypeSpecifier& /*type*/,
519 const std::string& raw_value) {
520 return raw_value;
521}
522
Steven Moreland46e9da82018-07-27 15:45:29 -0700523AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
524 AidlTypeSpecifier* type, const std::string& name)
Steven Moreland541788d2020-05-21 22:05:52 +0000525 : AidlVariableDeclaration(location, type, name, AidlConstantValue::Default(*type)) {
526 default_user_specified_ = false;
527}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700528
Steven Moreland46e9da82018-07-27 15:45:29 -0700529AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
530 AidlTypeSpecifier* type, const std::string& name,
531 AidlConstantValue* default_value)
Steven Moreland541788d2020-05-21 22:05:52 +0000532 : AidlNode(location),
533 type_(type),
534 name_(name),
535 default_user_specified_(true),
536 default_value_(default_value) {}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700537
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900538bool AidlVariableDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700539 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900540 valid &= type_->CheckValid(typenames);
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900541
Steven Moreland54be7bd2019-12-05 11:17:53 -0800542 if (type_->GetName() == "void") {
543 AIDL_ERROR(this) << "Declaration " << name_
544 << " is void, but declarations cannot be of void type.";
545 valid = false;
546 }
547
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900548 if (default_value_ == nullptr) return valid;
Steven Moreland25294322018-08-07 18:13:55 -0700549 valid &= default_value_->CheckValid();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700550
Steven Moreland25294322018-08-07 18:13:55 -0700551 if (!valid) return false;
Steven Moreland9ea10e32018-07-19 15:26:09 -0700552
Steven Moreland860b1942018-08-16 14:59:28 -0700553 return !ValueString(AidlConstantValueDecorator).empty();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700554}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700555
556string AidlVariableDeclaration::ToString() const {
Jeongik Cha3271ffa2018-12-04 15:19:20 +0900557 string ret = type_->Signature() + " " + name_;
Steven Moreland541788d2020-05-21 22:05:52 +0000558 if (default_value_ != nullptr && default_user_specified_) {
Steven Moreland860b1942018-08-16 14:59:28 -0700559 ret += " = " + ValueString(AidlConstantValueDecorator);
Steven Moreland9ea10e32018-07-19 15:26:09 -0700560 }
561 return ret;
Steven Moreland5557f1c2018-07-02 13:50:23 -0700562}
563
Jiyong Park02da7422018-07-16 16:00:26 +0900564string AidlVariableDeclaration::Signature() const {
565 return type_->Signature() + " " + name_;
566}
567
Steven Moreland860b1942018-08-16 14:59:28 -0700568std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
Jiyong Parka468e2a2018-08-29 21:25:18 +0900569 if (default_value_ != nullptr) {
Will McVickerd7d18df2019-09-12 13:40:50 -0700570 return default_value_->ValueString(GetType(), decorator);
Jiyong Parka468e2a2018-08-29 21:25:18 +0900571 } else {
572 return "";
573 }
Steven Moreland25294322018-08-07 18:13:55 -0700574}
575
Steven Moreland46e9da82018-07-27 15:45:29 -0700576AidlArgument::AidlArgument(const AidlLocation& location, AidlArgument::Direction direction,
577 AidlTypeSpecifier* type, const std::string& name)
578 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700579 direction_(direction),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700580 direction_specified_(true) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700581
Steven Moreland46e9da82018-07-27 15:45:29 -0700582AidlArgument::AidlArgument(const AidlLocation& location, AidlTypeSpecifier* type,
583 const std::string& name)
584 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700585 direction_(AidlArgument::IN_DIR),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700586 direction_specified_(false) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700587
Jiyong Park02da7422018-07-16 16:00:26 +0900588string AidlArgument::GetDirectionSpecifier() const {
Casey Dahlinc378c992015-09-29 16:50:40 -0700589 string ret;
Casey Dahlinc378c992015-09-29 16:50:40 -0700590 if (direction_specified_) {
591 switch(direction_) {
592 case AidlArgument::IN_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700593 ret += "in";
Casey Dahlinc378c992015-09-29 16:50:40 -0700594 break;
595 case AidlArgument::OUT_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700596 ret += "out";
Casey Dahlinc378c992015-09-29 16:50:40 -0700597 break;
598 case AidlArgument::INOUT_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700599 ret += "inout";
Casey Dahlinc378c992015-09-29 16:50:40 -0700600 break;
601 }
602 }
Casey Dahlinc378c992015-09-29 16:50:40 -0700603 return ret;
604}
Casey Dahlinbc7a50a2015-09-28 19:20:50 -0700605
Jiyong Park02da7422018-07-16 16:00:26 +0900606string AidlArgument::ToString() const {
Devin Mooreeccdb902020-03-24 16:22:40 -0700607 if (direction_specified_) {
608 return GetDirectionSpecifier() + " " + AidlVariableDeclaration::ToString();
609 } else {
610 return AidlVariableDeclaration::ToString();
611 }
Jiyong Park02da7422018-07-16 16:00:26 +0900612}
613
614std::string AidlArgument::Signature() const {
Steven Moreland46e9da82018-07-27 15:45:29 -0700615 class AidlInterface;
616 class AidlInterface;
617 class AidlParcelable;
618 class AidlStructuredParcelable;
619 class AidlParcelable;
620 class AidlStructuredParcelable;
Devin Mooreeccdb902020-03-24 16:22:40 -0700621 if (direction_specified_) {
622 return GetDirectionSpecifier() + " " + AidlVariableDeclaration::Signature();
623 } else {
624 return AidlVariableDeclaration::Signature();
625 }
Jiyong Park02da7422018-07-16 16:00:26 +0900626}
627
Steven Moreland46e9da82018-07-27 15:45:29 -0700628AidlMember::AidlMember(const AidlLocation& location) : AidlNode(location) {}
629
Steven Moreland46e9da82018-07-27 15:45:29 -0700630AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
631 AidlTypeSpecifier* type, const std::string& name,
632 AidlConstantValue* value)
633 : AidlMember(location), type_(type), name_(name), value_(value) {}
Steven Moreland693640b2018-07-19 13:46:27 -0700634
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900635bool AidlConstantDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700636 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900637 valid &= type_->CheckValid(typenames);
Steven Moreland25294322018-08-07 18:13:55 -0700638 valid &= value_->CheckValid();
639 if (!valid) return false;
Steven Moreland693640b2018-07-19 13:46:27 -0700640
Steven Moreland25294322018-08-07 18:13:55 -0700641 const static set<string> kSupportedConstTypes = {"String", "int"};
642 if (kSupportedConstTypes.find(type_->ToString()) == kSupportedConstTypes.end()) {
643 AIDL_ERROR(this) << "Constant of type " << type_->ToString() << " is not supported.";
Steven Moreland693640b2018-07-19 13:46:27 -0700644 return false;
645 }
646
Will McVickerd7d18df2019-09-12 13:40:50 -0700647 return true;
Christopher Wileyd6bdd8d2016-05-03 11:23:13 -0700648}
649
Jiyong Parka428d212018-08-29 22:26:30 +0900650string AidlConstantDeclaration::ToString() const {
651 return "const " + type_->ToString() + " " + name_ + " = " +
652 ValueString(AidlConstantValueDecorator);
653}
654
655string AidlConstantDeclaration::Signature() const {
656 return type_->Signature() + " " + name_;
657}
658
Steven Moreland46e9da82018-07-27 15:45:29 -0700659AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
660 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkb034bf02018-07-30 17:44:33 +0900661 const std::string& comments)
662 : AidlMethod(location, oneway, type, name, args, comments, 0, true) {
663 has_id_ = false;
664}
665
666AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
667 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkb034bf02018-07-30 17:44:33 +0900668 const std::string& comments, int id, bool is_user_defined)
Steven Moreland46e9da82018-07-27 15:45:29 -0700669 : AidlMember(location),
670 oneway_(oneway),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700671 comments_(comments),
672 type_(type),
673 name_(name),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700674 arguments_(std::move(*args)),
Jiyong Parkb034bf02018-07-30 17:44:33 +0900675 id_(id),
676 is_user_defined_(is_user_defined) {
Casey Dahlinf4a93112015-10-05 16:58:09 -0700677 has_id_ = true;
678 delete args;
Christopher Wileyad339272015-10-05 19:11:58 -0700679 for (const unique_ptr<AidlArgument>& a : arguments_) {
680 if (a->IsIn()) { in_arguments_.push_back(a.get()); }
681 if (a->IsOut()) { out_arguments_.push_back(a.get()); }
682 }
Casey Dahlinf4a93112015-10-05 16:58:09 -0700683}
684
Jeongik Cha997281d2020-01-16 15:23:59 +0900685bool AidlMethod::IsHidden() const {
686 return HasHideComment(GetComments());
687}
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700688
Jiyong Park02da7422018-07-16 16:00:26 +0900689string AidlMethod::Signature() const {
690 vector<string> arg_signatures;
691 for (const auto& arg : GetArguments()) {
Jiyong Park309668e2018-07-28 16:55:44 +0900692 arg_signatures.emplace_back(arg->GetType().ToString());
Jiyong Park02da7422018-07-16 16:00:26 +0900693 }
Jiyong Park309668e2018-07-28 16:55:44 +0900694 return GetName() + "(" + Join(arg_signatures, ", ") + ")";
695}
696
697string AidlMethod::ToString() const {
698 vector<string> arg_strings;
699 for (const auto& arg : GetArguments()) {
700 arg_strings.emplace_back(arg->Signature());
701 }
Steven Moreland4ee68632018-12-14 15:52:46 -0800702 string ret = (IsOneway() ? "oneway " : "") + GetType().Signature() + " " + GetName() + "(" +
703 Join(arg_strings, ", ") + ")";
Jiyong Parked65bf42018-08-28 15:43:27 +0900704 if (HasId()) {
705 ret += " = " + std::to_string(GetId());
706 }
707 return ret;
Jiyong Park02da7422018-07-16 16:00:26 +0900708}
709
Steven Moreland46e9da82018-07-27 15:45:29 -0700710AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
Jiyong Park18132182020-06-08 20:24:40 +0900711 const std::string& comments, const std::string& package)
712 : AidlAnnotatable(location),
713 name_(name),
714 comments_(comments),
715 package_(package),
716 split_package_(package.empty() ? std::vector<std::string>()
717 : android::base::Split(package, ".")) {}
Steven Moreland787b0432018-07-03 09:00:58 -0700718
Devin Moore24f68572020-02-26 13:20:59 -0800719bool AidlDefinedType::CheckValid(const AidlTypenames& typenames) const {
720 if (!AidlAnnotatable::CheckValid(typenames)) {
721 return false;
722 }
723
724 return true;
725}
726
Jeongik Cha997281d2020-01-16 15:23:59 +0900727bool AidlDefinedType::IsHidden() const {
728 return HasHideComment(GetComments());
729}
730
Steven Moreland787b0432018-07-03 09:00:58 -0700731std::string AidlDefinedType::GetCanonicalName() const {
732 if (package_.empty()) {
733 return GetName();
734 }
735 return GetPackage() + "." + GetName();
736}
737
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800738void AidlDefinedType::DumpHeader(CodeWriter* writer) const {
739 if (this->IsHidden()) {
740 AddHideComment(writer);
741 }
742 DumpAnnotations(writer);
743}
744
Jiyong Park18132182020-06-08 20:24:40 +0900745AidlParcelable::AidlParcelable(const AidlLocation& location, const std::string& name,
746 const std::string& package, const std::string& comments,
Jeongik Chadf76dc72019-11-28 00:08:47 +0900747 const std::string& cpp_header, std::vector<std::string>* type_params)
Jiyong Park18132182020-06-08 20:24:40 +0900748 : AidlDefinedType(location, name, comments, package),
Jeongik Chadf76dc72019-11-28 00:08:47 +0900749 AidlParameterizable<std::string>(type_params),
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800750 cpp_header_(cpp_header) {
751 // Strip off quotation marks if we actually have a cpp header.
752 if (cpp_header_.length() >= 2) {
753 cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
754 }
Casey Dahlin59401da2015-10-09 18:16:45 -0700755}
Jeongik Chadf76dc72019-11-28 00:08:47 +0900756template <typename T>
757AidlParameterizable<T>::AidlParameterizable(const AidlParameterizable& other) {
758 // Copying is not supported if it has type parameters.
759 // It doesn't make a problem because only ArrayBase() makes a copy,
760 // and it can be called only if a type is not generic.
761 CHECK(!other.IsGeneric());
762}
763
764template <typename T>
765bool AidlParameterizable<T>::CheckValid() const {
766 return true;
767};
768
769template <>
770bool AidlParameterizable<std::string>::CheckValid() const {
771 if (!IsGeneric()) {
772 return true;
773 }
774 std::unordered_set<std::string> set(GetTypeParameters().begin(), GetTypeParameters().end());
775 if (set.size() != GetTypeParameters().size()) {
776 AIDL_ERROR(this->AsAidlNode()) << "Every type parameter should be unique.";
777 return false;
778 }
779 return true;
780}
Casey Dahlin59401da2015-10-09 18:16:45 -0700781
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700782std::set<AidlAnnotation::Type> AidlParcelable::GetSupportedAnnotations() const {
Jeongik Cha36f76c32020-07-28 00:25:52 +0900783 return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900784 AidlAnnotation::Type::JAVA_STABLE_PARCELABLE, AidlAnnotation::Type::HIDE,
Jeongik Cha36f76c32020-07-28 00:25:52 +0900785 AidlAnnotation::Type::JAVA_PASSTHROUGH, AidlAnnotation::Type::IMMUTABLE};
Devin Moore24f68572020-02-26 13:20:59 -0800786}
787
788bool AidlParcelable::CheckValid(const AidlTypenames& typenames) const {
789 if (!AidlDefinedType::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100790 return false;
791 }
Jeongik Chadf76dc72019-11-28 00:08:47 +0900792 if (!AidlParameterizable<std::string>::CheckValid()) {
793 return false;
794 }
Jeongik Cha82317dd2019-02-27 20:26:11 +0900795
796 return true;
797}
798
Jeongik Cha997281d2020-01-16 15:23:59 +0900799void AidlParcelable::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800800 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +0900801 writer->Write("parcelable %s ;\n", GetName().c_str());
802}
803
Steven Moreland5557f1c2018-07-02 13:50:23 -0700804AidlStructuredParcelable::AidlStructuredParcelable(
Jiyong Park18132182020-06-08 20:24:40 +0900805 const AidlLocation& location, const std::string& name, const std::string& package,
Jiyong Parka6605ab2018-11-11 14:30:21 +0900806 const std::string& comments, std::vector<std::unique_ptr<AidlVariableDeclaration>>* variables)
807 : AidlParcelable(location, name, package, comments, "" /*cpp_header*/),
Steven Moreland46e9da82018-07-27 15:45:29 -0700808 variables_(std::move(*variables)) {}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700809
Jeongik Cha997281d2020-01-16 15:23:59 +0900810void AidlStructuredParcelable::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800811 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +0900812 writer->Write("parcelable %s {\n", GetName().c_str());
813 writer->Indent();
814 for (const auto& field : GetFields()) {
Jeongik Cha997281d2020-01-16 15:23:59 +0900815 if (field->GetType().IsHidden()) {
816 AddHideComment(writer);
817 }
Jiyong Parka468e2a2018-08-29 21:25:18 +0900818 writer->Write("%s;\n", field->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +0900819 }
820 writer->Dedent();
821 writer->Write("}\n");
822}
823
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700824std::set<AidlAnnotation::Type> AidlStructuredParcelable::GetSupportedAnnotations() const {
Jeongik Cha36f76c32020-07-28 00:25:52 +0900825 return {AidlAnnotation::Type::VINTF_STABILITY,
826 AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
827 AidlAnnotation::Type::HIDE,
828 AidlAnnotation::Type::JAVA_PASSTHROUGH,
829 AidlAnnotation::Type::JAVA_DEBUG,
830 AidlAnnotation::Type::IMMUTABLE};
Devin Moore24f68572020-02-26 13:20:59 -0800831}
832
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900833bool AidlStructuredParcelable::CheckValid(const AidlTypenames& typenames) const {
Daniel Norman85aed542019-08-21 12:01:14 -0700834 bool success = true;
Devin Moore24f68572020-02-26 13:20:59 -0800835 if (!AidlParcelable::CheckValid(typenames)) {
836 return false;
837 }
Jeongik Cha13066da2020-08-06 15:43:19 +0900838 std::set<std::string> fieldnames;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900839 for (const auto& v : GetFields()) {
Daniel Norman85aed542019-08-21 12:01:14 -0700840 success = success && v->CheckValid(typenames);
Jeongik Cha36f76c32020-07-28 00:25:52 +0900841 if (IsImmutable()) {
842 success = success && typenames.CanBeImmutable(v->GetType());
843 }
Jeongik Cha13066da2020-08-06 15:43:19 +0900844 auto ret = fieldnames.emplace(v->GetName());
845
846 if (!ret.second) {
847 AIDL_ERROR(this) << "The parcelable '" << this->GetName() << "' has duplicate field name '"
848 << v->GetName() << "'";
849 return false;
850 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900851 }
Jeongik Cha36f76c32020-07-28 00:25:52 +0900852
Daniel Norman85aed542019-08-21 12:01:14 -0700853 return success;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900854}
855
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900856// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -0700857bool AidlTypeSpecifier::LanguageSpecificCheckValid(const AidlTypenames& typenames,
858 Options::Language lang) const {
Steven Moreland0185d9b2020-05-15 23:21:22 +0000859 if (lang == Options::Language::NDK && IsArray() && GetName() == "IBinder") {
860 AIDL_ERROR(this) << "The NDK backend does not support array of IBinder";
861 return false;
862 }
Steven Morelandd59e3172020-05-11 16:42:09 -0700863 if (lang == Options::Language::NDK && IsArray() && IsNullable()) {
Steven Moreland0185d9b2020-05-15 23:21:22 +0000864 if (GetName() == "ParcelFileDescriptor") {
865 AIDL_ERROR(this) << "The NDK backend does not support nullable array of ParcelFileDescriptor";
866 return false;
867 }
868
Steven Morelandd59e3172020-05-11 16:42:09 -0700869 const auto defined_type = typenames.TryGetDefinedType(GetName());
870 if (defined_type != nullptr && defined_type->AsParcelable() != nullptr) {
871 AIDL_ERROR(this) << "The NDK backend does not support nullable array of parcelable";
872 return false;
873 }
874 }
Steven Moreland04b07e12020-01-21 18:11:07 -0800875 if (lang != Options::Language::JAVA) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900876 if (this->GetName() == "List" && !this->IsGeneric()) {
Steven Moreland04b07e12020-01-21 18:11:07 -0800877 AIDL_ERROR(this) << "Currently, only the Java backend supports non-generic List.";
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900878 return false;
879 }
880 }
Steven Morelandc8a4ca82020-01-21 17:50:08 -0800881 if (this->GetName() == "FileDescriptor" && lang == Options::Language::NDK) {
882 AIDL_ERROR(this) << "FileDescriptor isn't supported with the NDK.";
883 return false;
884 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900885 if (this->IsGeneric()) {
886 if (this->GetName() == "List") {
887 if (this->GetTypeParameters().size() != 1) {
888 AIDL_ERROR(this) << "List must have only one type parameter.";
889 return false;
890 }
891 if (lang == Options::Language::CPP) {
Devin Moore2ac52f92020-03-23 15:39:36 -0700892 const string& contained_type = this->GetTypeParameters()[0]->GetName();
893 if (!(contained_type == "String" || contained_type == "IBinder")) {
894 AIDL_ERROR(this) << "List<" << contained_type
895 << "> is not supported. List in cpp supports only String and IBinder.";
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900896 return false;
897 }
Jeongik Cha08ca2182019-11-21 14:01:13 +0900898 } else if (lang == Options::Language::JAVA) {
899 const string& contained_type = this->GetTypeParameters()[0]->GetName();
900 if (AidlTypenames::IsBuiltinTypename(contained_type)) {
901 if (contained_type != "String" && contained_type != "IBinder" &&
902 contained_type != "ParcelFileDescriptor") {
Devin Moore2ac52f92020-03-23 15:39:36 -0700903 AIDL_ERROR(this) << "List<" << contained_type
904 << "> is not supported. List in Java supports only String, IBinder, "
905 "and ParcelFileDescriptor.";
Jeongik Cha08ca2182019-11-21 14:01:13 +0900906 return false;
907 }
908 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900909 }
Jeongik Chabb55b5e2020-01-07 23:11:26 +0900910 }
911 }
Jeongik Chab75a4512020-01-10 13:37:04 +0900912 if (this->GetName() == "Map" || this->GetName() == "CharSequence") {
Jeongik Chabb55b5e2020-01-07 23:11:26 +0900913 if (lang != Options::Language::JAVA) {
Jeongik Chab75a4512020-01-10 13:37:04 +0900914 AIDL_ERROR(this) << "Currently, only Java backend supports " << this->GetName() << ".";
Jeongik Chabb55b5e2020-01-07 23:11:26 +0900915 return false;
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900916 }
917 }
Jeongik Cha08ca2182019-11-21 14:01:13 +0900918 if (lang == Options::Language::JAVA) {
919 const string name = this->GetName();
920 // List[], Map[], CharSequence[] are not supported.
921 if (AidlTypenames::IsBuiltinTypename(name) && this->IsArray()) {
922 if (name == "List" || name == "Map" || name == "CharSequence") {
923 AIDL_ERROR(this) << "List[], Map[], CharSequence[] are not supported.";
924 return false;
925 }
926 }
927 }
928
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900929 return true;
930}
931
932// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -0700933bool AidlParcelable::LanguageSpecificCheckValid(const AidlTypenames& /*typenames*/,
934 Options::Language lang) const {
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900935 if (lang != Options::Language::JAVA) {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800936 const AidlParcelable* unstructured_parcelable = this->AsUnstructuredParcelable();
937 if (unstructured_parcelable != nullptr) {
938 if (unstructured_parcelable->GetCppHeader().empty()) {
939 AIDL_ERROR(unstructured_parcelable)
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900940 << "Unstructured parcelable must have C++ header defined.";
941 return false;
942 }
943 }
944 }
945 return true;
946}
947
948// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -0700949bool AidlStructuredParcelable::LanguageSpecificCheckValid(const AidlTypenames& typenames,
950 Options::Language lang) const {
951 if (!AidlParcelable::LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900952 return false;
953 }
954 for (const auto& v : this->GetFields()) {
Steven Morelandd59e3172020-05-11 16:42:09 -0700955 if (!v->GetType().LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900956 return false;
957 }
958 }
959 return true;
960}
961
Daniel Norman85aed542019-08-21 12:01:14 -0700962AidlEnumerator::AidlEnumerator(const AidlLocation& location, const std::string& name,
Daniel Norman2e4112d2019-10-03 10:22:35 -0700963 AidlConstantValue* value, const std::string& comments)
964 : AidlNode(location), name_(name), value_(value), comments_(comments) {}
Daniel Norman85aed542019-08-21 12:01:14 -0700965
966bool AidlEnumerator::CheckValid(const AidlTypeSpecifier& enum_backing_type) const {
967 if (GetValue() == nullptr) {
968 return false;
969 }
970 if (!GetValue()->CheckValid()) {
971 return false;
972 }
Will McVickerd7d18df2019-09-12 13:40:50 -0700973 if (GetValue()->ValueString(enum_backing_type, AidlConstantValueDecorator).empty()) {
Daniel Norman85aed542019-08-21 12:01:14 -0700974 AIDL_ERROR(this) << "Enumerator type differs from enum backing type.";
975 return false;
976 }
977 return true;
978}
979
980string AidlEnumerator::ValueString(const AidlTypeSpecifier& backing_type,
981 const ConstantValueDecorator& decorator) const {
Will McVickerd7d18df2019-09-12 13:40:50 -0700982 return GetValue()->ValueString(backing_type, decorator);
Daniel Norman85aed542019-08-21 12:01:14 -0700983}
984
985AidlEnumDeclaration::AidlEnumDeclaration(const AidlLocation& location, const std::string& name,
986 std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
Jiyong Park18132182020-06-08 20:24:40 +0900987 const std::string& package, const std::string& comments)
Daniel Norman2e4112d2019-10-03 10:22:35 -0700988 : AidlDefinedType(location, name, comments, package), enumerators_(std::move(*enumerators)) {}
Daniel Norman85aed542019-08-21 12:01:14 -0700989
990void AidlEnumDeclaration::SetBackingType(std::unique_ptr<const AidlTypeSpecifier> type) {
991 backing_type_ = std::move(type);
992}
993
Steven Moreland59e53e42019-11-26 20:38:08 -0800994bool AidlEnumDeclaration::Autofill() {
Daniel Normanb28684e2019-10-17 15:31:39 -0700995 const AidlEnumerator* previous = nullptr;
996 for (const auto& enumerator : enumerators_) {
997 if (enumerator->GetValue() == nullptr) {
998 if (previous == nullptr) {
Devin Mooredf93ebb2020-03-25 14:03:35 -0700999 enumerator->SetValue(
1000 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "0")));
Daniel Normanb28684e2019-10-17 15:31:39 -07001001 } else {
Steven Moreland59e53e42019-11-26 20:38:08 -08001002 auto prev_value = std::unique_ptr<AidlConstantValue>(
1003 AidlConstantValue::ShallowIntegralCopy(*previous->GetValue()));
1004 if (prev_value == nullptr) {
1005 return false;
1006 }
Daniel Normanb28684e2019-10-17 15:31:39 -07001007 enumerator->SetValue(std::make_unique<AidlBinaryConstExpression>(
Devin Mooredf93ebb2020-03-25 14:03:35 -07001008 GetLocation(), std::move(prev_value), "+",
1009 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "1"))));
Daniel Normanb28684e2019-10-17 15:31:39 -07001010 }
1011 }
1012 previous = enumerator.get();
1013 }
Steven Moreland59e53e42019-11-26 20:38:08 -08001014 return true;
Daniel Normanb28684e2019-10-17 15:31:39 -07001015}
1016
Steven Moreland0cea4aa2020-04-20 21:06:02 -07001017std::set<AidlAnnotation::Type> AidlEnumDeclaration::GetSupportedAnnotations() const {
1018 return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::BACKING,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09001019 AidlAnnotation::Type::HIDE, AidlAnnotation::Type::JAVA_PASSTHROUGH};
Devin Moore24f68572020-02-26 13:20:59 -08001020}
1021
1022bool AidlEnumDeclaration::CheckValid(const AidlTypenames& typenames) const {
1023 if (!AidlDefinedType::CheckValid(typenames)) {
1024 return false;
1025 }
Daniel Norman85aed542019-08-21 12:01:14 -07001026 if (backing_type_ == nullptr) {
1027 AIDL_ERROR(this) << "Enum declaration missing backing type.";
1028 return false;
1029 }
1030 bool success = true;
1031 for (const auto& enumerator : enumerators_) {
1032 success = success && enumerator->CheckValid(GetBackingType());
1033 }
1034 return success;
1035}
1036
Jeongik Cha997281d2020-01-16 15:23:59 +09001037void AidlEnumDeclaration::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -08001038 DumpHeader(writer);
Daniel Norman37d43dd2019-09-09 17:22:34 -07001039 writer->Write("enum %s {\n", GetName().c_str());
Daniel Norman85aed542019-08-21 12:01:14 -07001040 writer->Indent();
1041 for (const auto& enumerator : GetEnumerators()) {
Daniel Norman85aed542019-08-21 12:01:14 -07001042 writer->Write("%s = %s,\n", enumerator->GetName().c_str(),
1043 enumerator->ValueString(GetBackingType(), AidlConstantValueDecorator).c_str());
1044 }
1045 writer->Dedent();
1046 writer->Write("}\n");
1047}
1048
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001049// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -07001050bool AidlInterface::LanguageSpecificCheckValid(const AidlTypenames& typenames,
1051 Options::Language lang) const {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001052 for (const auto& m : this->GetMethods()) {
Steven Morelandd59e3172020-05-11 16:42:09 -07001053 if (!m->GetType().LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001054 return false;
1055 }
1056 for (const auto& arg : m->GetArguments()) {
Steven Morelandd59e3172020-05-11 16:42:09 -07001057 if (!arg->GetType().LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001058 return false;
1059 }
1060 }
1061 }
1062 return true;
1063}
1064
Steven Moreland46e9da82018-07-27 15:45:29 -07001065AidlInterface::AidlInterface(const AidlLocation& location, const std::string& name,
Casey Dahlinfb7da2e2015-10-08 17:26:09 -07001066 const std::string& comments, bool oneway,
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001067 std::vector<std::unique_ptr<AidlMember>>* members,
Jiyong Park18132182020-06-08 20:24:40 +09001068 const std::string& package)
Steven Morelandacd53472018-12-14 10:17:26 -08001069 : AidlDefinedType(location, name, comments, package) {
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001070 for (auto& member : *members) {
1071 AidlMember* local = member.release();
1072 AidlMethod* method = local->AsMethod();
Steven Moreland693640b2018-07-19 13:46:27 -07001073 AidlConstantDeclaration* constant = local->AsConstantDeclaration();
1074
1075 CHECK(method == nullptr || constant == nullptr);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001076
1077 if (method) {
Steven Moreland8c70ba92018-12-17 10:20:31 -08001078 method->ApplyInterfaceOneway(oneway);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001079 methods_.emplace_back(method);
Steven Moreland693640b2018-07-19 13:46:27 -07001080 } else if (constant) {
1081 constants_.emplace_back(constant);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001082 } else {
Steven Moreland46e9da82018-07-27 15:45:29 -07001083 AIDL_FATAL(this) << "Member is neither method nor constant!";
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001084 }
1085 }
1086
1087 delete members;
Casey Dahlinfb7da2e2015-10-08 17:26:09 -07001088}
1089
Jeongik Cha997281d2020-01-16 15:23:59 +09001090void AidlInterface::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -08001091 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +09001092 writer->Write("interface %s {\n", GetName().c_str());
1093 writer->Indent();
1094 for (const auto& method : GetMethods()) {
Jeongik Cha997281d2020-01-16 15:23:59 +09001095 if (method->IsHidden()) {
1096 AddHideComment(writer);
1097 }
Jiyong Park309668e2018-07-28 16:55:44 +09001098 writer->Write("%s;\n", method->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +09001099 }
Jiyong Parka428d212018-08-29 22:26:30 +09001100 for (const auto& constdecl : GetConstantDeclarations()) {
Jeongik Cha997281d2020-01-16 15:23:59 +09001101 if (constdecl->GetType().IsHidden()) {
1102 AddHideComment(writer);
1103 }
Jiyong Parka428d212018-08-29 22:26:30 +09001104 writer->Write("%s;\n", constdecl->ToString().c_str());
1105 }
Jiyong Park02da7422018-07-16 16:00:26 +09001106 writer->Dedent();
1107 writer->Write("}\n");
1108}
1109
Steven Moreland0cea4aa2020-04-20 21:06:02 -07001110std::set<AidlAnnotation::Type> AidlInterface::GetSupportedAnnotations() const {
1111 return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09001112 AidlAnnotation::Type::HIDE, AidlAnnotation::Type::JAVA_PASSTHROUGH};
Devin Moore24f68572020-02-26 13:20:59 -08001113}
1114
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001115bool AidlInterface::CheckValid(const AidlTypenames& typenames) const {
Devin Moore24f68572020-02-26 13:20:59 -08001116 if (!AidlDefinedType::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +01001117 return false;
1118 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001119 // Has to be a pointer due to deleting copy constructor. No idea why.
1120 map<string, const AidlMethod*> method_names;
1121 for (const auto& m : GetMethods()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001122 if (!m->GetType().CheckValid(typenames)) {
1123 return false;
1124 }
1125
Jeongik Cha649e8a72020-03-27 17:47:40 +09001126 // TODO(b/156872582): Support it when ParcelableHolder supports every backend.
1127 if (m->GetType().GetName() == "ParcelableHolder") {
1128 AIDL_ERROR(m) << "ParcelableHolder cannot be a return type";
1129 return false;
1130 }
Steven Morelandacd53472018-12-14 10:17:26 -08001131 if (m->IsOneway() && m->GetType().GetName() != "void") {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001132 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot return a value";
1133 return false;
1134 }
1135
1136 set<string> argument_names;
1137 for (const auto& arg : m->GetArguments()) {
1138 auto it = argument_names.find(arg->GetName());
1139 if (it != argument_names.end()) {
1140 AIDL_ERROR(m) << "method '" << m->GetName() << "' has duplicate argument name '"
1141 << arg->GetName() << "'";
1142 return false;
1143 }
1144 argument_names.insert(arg->GetName());
1145
1146 if (!arg->GetType().CheckValid(typenames)) {
1147 return false;
1148 }
1149
Jeongik Cha649e8a72020-03-27 17:47:40 +09001150 // TODO(b/156872582): Support it when ParcelableHolder supports every backend.
1151 if (arg->GetType().GetName() == "ParcelableHolder") {
1152 AIDL_ERROR(arg) << "ParcelableHolder cannot be an argument type";
1153 return false;
1154 }
Steven Morelandacd53472018-12-14 10:17:26 -08001155 if (m->IsOneway() && arg->IsOut()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001156 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot have out parameters";
1157 return false;
1158 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001159 const bool can_be_out = typenames.CanBeOutParameter(arg->GetType());
1160 if (!arg->DirectionWasSpecified() && can_be_out) {
1161 AIDL_ERROR(arg) << "'" << arg->GetType().ToString()
1162 << "' can be an out type, so you must declare it as in, out, or inout.";
1163 return false;
1164 }
1165
1166 if (arg->GetDirection() != AidlArgument::IN_DIR && !can_be_out) {
1167 AIDL_ERROR(arg) << "'" << arg->ToString() << "' can only be an in parameter.";
1168 return false;
1169 }
1170
1171 // check that the name doesn't match a keyword
Jeongik Cha997281d2020-01-16 15:23:59 +09001172 if (IsJavaKeyword(arg->GetName().c_str())) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001173 AIDL_ERROR(arg) << "Argument name is a Java or aidl keyword";
1174 return false;
1175 }
1176
1177 // Reserve a namespace for internal use
1178 if (android::base::StartsWith(arg->GetName(), "_aidl")) {
1179 AIDL_ERROR(arg) << "Argument name cannot begin with '_aidl'";
1180 return false;
1181 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001182 }
1183
1184 auto it = method_names.find(m->GetName());
1185 // prevent duplicate methods
1186 if (it == method_names.end()) {
1187 method_names[m->GetName()] = m.get();
1188 } else {
1189 AIDL_ERROR(m) << "attempt to redefine method " << m->GetName() << ":";
1190 AIDL_ERROR(it->second) << "previously defined here.";
1191 return false;
1192 }
1193
Paul Trautrimb77048c2020-01-21 16:39:32 +09001194 static set<string> reserved_methods{"asBinder()", "getInterfaceHash()", "getInterfaceVersion()",
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001195 "getTransactionName(int)"};
1196
1197 if (reserved_methods.find(m->Signature()) != reserved_methods.end()) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001198 AIDL_ERROR(m) << " method " << m->Signature() << " is reserved for internal use.";
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001199 return false;
1200 }
1201 }
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001202
1203 bool success = true;
1204 set<string> constant_names;
1205 for (const std::unique_ptr<AidlConstantDeclaration>& constant : GetConstantDeclarations()) {
1206 if (constant_names.count(constant->GetName()) > 0) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001207 AIDL_ERROR(constant) << "Found duplicate constant name '" << constant->GetName() << "'";
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001208 success = false;
1209 }
1210 constant_names.insert(constant->GetName());
1211 success = success && constant->CheckValid(typenames);
1212 }
1213
1214 return success;
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001215}
1216
Steven Moreland46e9da82018-07-27 15:45:29 -07001217AidlImport::AidlImport(const AidlLocation& location, const std::string& needed_class)
1218 : AidlNode(location), needed_class_(needed_class) {}