blob: 82adaf8dd63c56eaf8268d16c6a921a51d3f27b6 [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
Steven Moreland21780812020-09-11 01:29:45 +000035#include "aidl_language_y.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
Steven Moreland21780812020-09-11 01:29:45 +000072inline std::string CapitalizeFirstLetter(const AidlNode& context, const std::string& str) {
73 AIDL_FATAL_IF(str.size() <= 0, context) << "Input cannot be empty.";
Jeongik Cha91180252020-07-31 15:43:11 +090074 std::ostringstream out;
75 out << static_cast<char>(toupper(str[0])) << str.substr(1);
76 return out.str();
77}
78
Jeongik Cha997281d2020-01-16 15:23:59 +090079void AddHideComment(CodeWriter* writer) {
80 writer->Write("/* @hide */\n");
81}
82
83inline bool HasHideComment(const std::string& comment) {
84 return std::regex_search(comment, std::regex("@hide\\b"));
85}
Jeongik Cha047c5ee2019-08-07 23:16:49 +090086} // namespace
87
Devin Mooredf93ebb2020-03-25 14:03:35 -070088AidlLocation::AidlLocation(const std::string& file, Point begin, Point end, Source source)
89 : file_(file), begin_(begin), end_(end), source_(source) {}
Steven Moreland46e9da82018-07-27 15:45:29 -070090
91std::ostream& operator<<(std::ostream& os, const AidlLocation& l) {
Devin Moore5de18ed2020-04-02 13:52:29 -070092 os << l.file_;
93 if (l.LocationKnown()) {
94 os << ":" << l.begin_.line << "." << l.begin_.column << "-";
95 if (l.begin_.line != l.end_.line) {
96 os << l.end_.line << ".";
97 }
98 os << l.end_.column;
Steven Moreland46e9da82018-07-27 15:45:29 -070099 }
Steven Moreland46e9da82018-07-27 15:45:29 -0700100 return os;
101}
102
103AidlNode::AidlNode(const AidlLocation& location) : location_(location) {}
104
Mathew Inwoodadb74672019-11-29 14:01:53 +0000105std::string AidlNode::PrintLine() const {
Andrei Onea8714b022019-02-01 18:55:54 +0000106 std::stringstream ss;
107 ss << location_.file_ << ":" << location_.begin_.line;
108 return ss.str();
109}
110
Mathew Inwoodadb74672019-11-29 14:01:53 +0000111std::string AidlNode::PrintLocation() const {
112 std::stringstream ss;
113 ss << location_.file_ << ":" << location_.begin_.line << ":" << location_.begin_.column << ":"
114 << location_.end_.line << ":" << location_.end_.column;
115 return ss.str();
116}
117
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700118const std::vector<AidlAnnotation::Schema>& AidlAnnotation::AllSchemas() {
119 static const std::vector<Schema> kSchemas{
Jooyung Hand902a972020-10-23 17:32:44 +0900120 {AidlAnnotation::Type::NULLABLE, "nullable", {}, false},
121 {AidlAnnotation::Type::UTF8_IN_CPP, "utf8InCpp", {}, false},
122 {AidlAnnotation::Type::VINTF_STABILITY, "VintfStability", {}, false},
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700123 {AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
124 "UnsupportedAppUsage",
125 {{"expectedSignature", "String"},
126 {"implicitMember", "String"},
127 {"maxTargetSdk", "int"},
128 {"publicAlternatives", "String"},
Jooyung Hand902a972020-10-23 17:32:44 +0900129 {"trackingBug", "long"}},
130 false},
131 {AidlAnnotation::Type::JAVA_STABLE_PARCELABLE, "JavaOnlyStableParcelable", {}, false},
132 {AidlAnnotation::Type::HIDE, "Hide", {}, false},
133 {AidlAnnotation::Type::BACKING, "Backing", {{"type", "String"}}, false},
134 {AidlAnnotation::Type::JAVA_PASSTHROUGH, "JavaPassthrough", {{"annotation", "String"}}, true},
135 {AidlAnnotation::Type::JAVA_DEBUG, "JavaDebug", {}, false},
136 {AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE, "JavaOnlyImmutable", {}, false},
137 {AidlAnnotation::Type::FIXED_SIZE, "FixedSize", {}, false},
138 {AidlAnnotation::Type::DESCRIPTOR, "Descriptor", {{"value", "String"}}, false},
Andrei Homescue61feb52020-08-18 15:44:24 -0700139 {AidlAnnotation::Type::RUST_DERIVE,
140 "RustDerive",
141 {{"Copy", "boolean"},
142 {"Clone", "boolean"},
143 {"PartialOrd", "boolean"},
144 {"Ord", "boolean"},
145 {"PartialEq", "boolean"},
146 {"Eq", "boolean"},
Jooyung Hand902a972020-10-23 17:32:44 +0900147 {"Hash", "boolean"}},
148 false},
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900149 };
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700150 return kSchemas;
151}
Jiyong Park68bc77a2018-07-19 19:00:45 +0900152
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700153std::string AidlAnnotation::TypeToString(Type type) {
154 for (const Schema& schema : AllSchemas()) {
155 if (type == schema.type) return schema.name;
156 }
157 AIDL_FATAL(AIDL_LOCATION_HERE) << "Unrecognized type: " << static_cast<size_t>(type);
158 __builtin_unreachable();
159}
Andrei Onea9445fc62019-06-27 18:11:59 +0100160
161AidlAnnotation* AidlAnnotation::Parse(
162 const AidlLocation& location, const string& name,
163 std::map<std::string, std::shared_ptr<AidlConstantValue>>* parameter_list) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700164 const Schema* schema = nullptr;
165 for (const Schema& a_schema : AllSchemas()) {
166 if (a_schema.name == name) {
167 schema = &a_schema;
168 }
169 }
170
171 if (schema == nullptr) {
Jiyong Park68bc77a2018-07-19 19:00:45 +0900172 std::ostringstream stream;
Steven Moreland46e9da82018-07-27 15:45:29 -0700173 stream << "'" << name << "' is not a recognized annotation. ";
Jiyong Park68bc77a2018-07-19 19:00:45 +0900174 stream << "It must be one of:";
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700175 for (const Schema& s : AllSchemas()) {
176 stream << " " << s.name;
Jiyong Park68bc77a2018-07-19 19:00:45 +0900177 }
178 stream << ".";
Steven Moreland46e9da82018-07-27 15:45:29 -0700179 AIDL_ERROR(location) << stream.str();
180 return nullptr;
Jiyong Park68bc77a2018-07-19 19:00:45 +0900181 }
Andrei Onea9445fc62019-06-27 18:11:59 +0100182 if (parameter_list == nullptr) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700183 return new AidlAnnotation(location, *schema, {});
Andrei Onea9445fc62019-06-27 18:11:59 +0100184 }
185
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700186 return new AidlAnnotation(location, *schema, std::move(*parameter_list));
Jiyong Park68bc77a2018-07-19 19:00:45 +0900187}
188
Andrei Onea9445fc62019-06-27 18:11:59 +0100189AidlAnnotation::AidlAnnotation(
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700190 const AidlLocation& location, const Schema& schema,
Andrei Onea9445fc62019-06-27 18:11:59 +0100191 std::map<std::string, std::shared_ptr<AidlConstantValue>>&& parameters)
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700192 : AidlNode(location), schema_(schema), parameters_(std::move(parameters)) {}
Andrei Onea9445fc62019-06-27 18:11:59 +0100193
194bool AidlAnnotation::CheckValid() const {
Andrei Onea9445fc62019-06-27 18:11:59 +0100195 for (const auto& name_and_param : parameters_) {
196 const std::string& param_name = name_and_param.first;
197 const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
Will McVickerd7d18df2019-09-12 13:40:50 -0700198 if (!param->CheckValid()) {
199 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
200 << GetName() << ".";
201 return false;
202 }
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700203 auto parameter_mapping_it = schema_.supported_parameters.find(param_name);
204 if (parameter_mapping_it == schema_.supported_parameters.end()) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100205 std::ostringstream stream;
206 stream << "Parameter " << param_name << " not supported ";
Devin Mooredecaf292020-04-30 09:16:40 -0700207 stream << "for annotation " << GetName() << ". ";
Andrei Onea9445fc62019-06-27 18:11:59 +0100208 stream << "It must be one of:";
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700209 for (const auto& kv : schema_.supported_parameters) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100210 stream << " " << kv.first;
211 }
212 AIDL_ERROR(this) << stream.str();
213 return false;
214 }
215 AidlTypeSpecifier type{AIDL_LOCATION_HERE, parameter_mapping_it->second, false, nullptr, ""};
Will McVickerd7d18df2019-09-12 13:40:50 -0700216 const std::string param_value = param->ValueString(type, AidlConstantValueDecorator);
Andrei Onea9445fc62019-06-27 18:11:59 +0100217 // Assume error on empty string.
218 if (param_value == "") {
219 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
220 << GetName() << ".";
221 return false;
222 }
223 }
224 return true;
225}
226
227std::map<std::string, std::string> AidlAnnotation::AnnotationParams(
228 const ConstantValueDecorator& decorator) const {
229 std::map<std::string, std::string> raw_params;
Andrei Onea9445fc62019-06-27 18:11:59 +0100230 for (const auto& name_and_param : parameters_) {
231 const std::string& param_name = name_and_param.first;
232 const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
Devin Mooredecaf292020-04-30 09:16:40 -0700233 if (schema_.supported_parameters.find(param_name) == schema_.supported_parameters.end()) {
234 std::ostringstream stream;
235 stream << "Parameter " << param_name << " not supported ";
236 stream << "for annotation " << GetName() << ". ";
237 stream << "It must be one of:";
238 for (const auto& kv : schema_.supported_parameters) {
239 stream << " " << kv.first;
240 }
241 AIDL_ERROR(this) << stream.str();
242 continue;
243 }
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700244 AidlTypeSpecifier type{AIDL_LOCATION_HERE, schema_.supported_parameters.at(param_name), false,
245 nullptr, ""};
Will McVickerd7d18df2019-09-12 13:40:50 -0700246 if (!param->CheckValid()) {
247 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
248 << GetName() << ".";
Devin Mooredecaf292020-04-30 09:16:40 -0700249 continue;
Will McVickerd7d18df2019-09-12 13:40:50 -0700250 }
251
252 raw_params.emplace(param_name, param->ValueString(type, decorator));
Andrei Onea9445fc62019-06-27 18:11:59 +0100253 }
254 return raw_params;
255}
Steven Moreland46e9da82018-07-27 15:45:29 -0700256
Daniel Norman37d43dd2019-09-09 17:22:34 -0700257std::string AidlAnnotation::ToString(const ConstantValueDecorator& decorator) const {
258 if (parameters_.empty()) {
259 return "@" + GetName();
260 } else {
261 vector<string> param_strings;
262 for (const auto& [name, value] : AnnotationParams(decorator)) {
263 param_strings.emplace_back(name + "=" + value);
264 }
265 return "@" + GetName() + "(" + Join(param_strings, ", ") + ")";
266 }
267}
268
Andrei Onea9445fc62019-06-27 18:11:59 +0100269static const AidlAnnotation* GetAnnotation(const vector<AidlAnnotation>& annotations,
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700270 AidlAnnotation::Type type) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100271 for (const auto& a : annotations) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700272 if (a.GetType() == type) {
Jooyung Hand902a972020-10-23 17:32:44 +0900273 AIDL_FATAL_IF(a.Repeatable(), a)
274 << "Trying to get a single annotation when it is repeatable.";
Andrei Onea9445fc62019-06-27 18:11:59 +0100275 return &a;
276 }
277 }
278 return nullptr;
279}
280
Steven Moreland46e9da82018-07-27 15:45:29 -0700281AidlAnnotatable::AidlAnnotatable(const AidlLocation& location) : AidlNode(location) {}
282
Jiyong Park68bc77a2018-07-19 19:00:45 +0900283bool AidlAnnotatable::IsNullable() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700284 return GetAnnotation(annotations_, AidlAnnotation::Type::NULLABLE);
Jiyong Park68bc77a2018-07-19 19:00:45 +0900285}
286
Jiyong Park68bc77a2018-07-19 19:00:45 +0900287bool AidlAnnotatable::IsUtf8InCpp() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700288 return GetAnnotation(annotations_, AidlAnnotation::Type::UTF8_IN_CPP);
Jiyong Park68bc77a2018-07-19 19:00:45 +0900289}
290
Steven Morelanda57d0a62019-07-30 09:41:14 -0700291bool AidlAnnotatable::IsVintfStability() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700292 return GetAnnotation(annotations_, AidlAnnotation::Type::VINTF_STABILITY);
Steven Morelanda57d0a62019-07-30 09:41:14 -0700293}
294
Jeongik Chad0a10272020-08-06 16:33:36 +0900295bool AidlAnnotatable::IsJavaOnlyImmutable() const {
296 return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE);
Jeongik Cha36f76c32020-07-28 00:25:52 +0900297}
298
Devin Moorec7e47a32020-08-07 10:55:25 -0700299bool AidlAnnotatable::IsFixedSize() const {
300 return GetAnnotation(annotations_, AidlAnnotation::Type::FIXED_SIZE);
301}
302
Andrei Onea9445fc62019-06-27 18:11:59 +0100303const AidlAnnotation* AidlAnnotatable::UnsupportedAppUsage() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700304 return GetAnnotation(annotations_, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE);
Jiyong Parka6605ab2018-11-11 14:30:21 +0900305}
306
Andrei Homescue61feb52020-08-18 15:44:24 -0700307const AidlAnnotation* AidlAnnotatable::RustDerive() const {
308 return GetAnnotation(annotations_, AidlAnnotation::Type::RUST_DERIVE);
309}
310
Daniel Norman716d3112019-09-10 13:11:56 -0700311const AidlTypeSpecifier* AidlAnnotatable::BackingType(const AidlTypenames& typenames) const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700312 auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::BACKING);
Daniel Norman85aed542019-08-21 12:01:14 -0700313 if (annotation != nullptr) {
314 auto annotation_params = annotation->AnnotationParams(AidlConstantValueDecorator);
315 if (auto it = annotation_params.find("type"); it != annotation_params.end()) {
316 const string& type = it->second;
Steven Morelande7d5d082020-05-21 20:29:02 +0000317
318 AIDL_FATAL_IF(type.size() < 2, this) << type;
319 AIDL_FATAL_IF(type[0] != '"', this) << type;
320 AIDL_FATAL_IF(type[type.length() - 1] != '"', this) << type;
321 string unquoted_type = type.substr(1, type.length() - 2);
322
Daniel Norman716d3112019-09-10 13:11:56 -0700323 AidlTypeSpecifier* type_specifier =
Steven Morelande7d5d082020-05-21 20:29:02 +0000324 new AidlTypeSpecifier(AIDL_LOCATION_HERE, unquoted_type, false, nullptr, "");
Daniel Norman716d3112019-09-10 13:11:56 -0700325 type_specifier->Resolve(typenames);
326 return type_specifier;
Daniel Norman85aed542019-08-21 12:01:14 -0700327 }
328 }
329 return nullptr;
330}
331
Jeongik Cha88f95a82020-01-15 13:02:16 +0900332bool AidlAnnotatable::IsStableApiParcelable(Options::Language lang) const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700333 return lang == Options::Language::JAVA &&
334 GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_STABLE_PARCELABLE);
Jeongik Cha82317dd2019-02-27 20:26:11 +0900335}
336
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800337bool AidlAnnotatable::IsHide() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700338 return GetAnnotation(annotations_, AidlAnnotation::Type::HIDE);
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800339}
340
Jiyong Park43113fb2020-07-20 16:26:19 +0900341bool AidlAnnotatable::IsJavaDebug() const {
342 return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_DEBUG);
343}
344
Jiyong Park27fd7fd2020-08-27 16:25:09 +0900345std::string AidlAnnotatable::GetDescriptor() const {
346 auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::DESCRIPTOR);
347 if (annotation != nullptr) {
348 auto params = annotation->AnnotationParams(AidlConstantValueDecorator);
349 if (auto it = params.find("value"); it != params.end()) {
350 const string& value = it->second;
351
352 AIDL_FATAL_IF(value.size() < 2, this) << value;
353 AIDL_FATAL_IF(value[0] != '"', this) << value;
354 AIDL_FATAL_IF(value[value.length() - 1] != '"', this) << value;
355 std::string unquoted_value = value.substr(1, value.length() - 2);
356 return unquoted_value;
357 }
358 }
359 return "";
360}
361
Steven Moreland7e4b9502020-02-20 18:10:42 -0800362void AidlAnnotatable::DumpAnnotations(CodeWriter* writer) const {
363 if (annotations_.empty()) return;
364
365 writer->Write("%s\n", AidlAnnotatable::ToString().c_str());
366}
367
Devin Moore24f68572020-02-26 13:20:59 -0800368bool AidlAnnotatable::CheckValid(const AidlTypenames&) const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700369 std::set<AidlAnnotation::Type> supported_annotations = GetSupportedAnnotations();
Andrei Onea9445fc62019-06-27 18:11:59 +0100370 for (const auto& annotation : GetAnnotations()) {
Jooyung Hand902a972020-10-23 17:32:44 +0900371 // check if it is allowed for this node
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700372 if (supported_annotations.find(annotation.GetType()) == supported_annotations.end()) {
Jooyung Hand902a972020-10-23 17:32:44 +0900373 std::vector<std::string> supported_annot_strings;
374 for (AidlAnnotation::Type type : supported_annotations) {
375 supported_annot_strings.push_back(AidlAnnotation::TypeToString(type));
376 }
Devin Moore24f68572020-02-26 13:20:59 -0800377 AIDL_ERROR(this) << "'" << annotation.GetName()
378 << "' is not a supported annotation for this node. "
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700379 << "It must be one of: "
380 << android::base::Join(supported_annot_strings, ", ");
Devin Moore24f68572020-02-26 13:20:59 -0800381 return false;
382 }
Jooyung Hand902a972020-10-23 17:32:44 +0900383 // CheckValid() only if it is okay to be here
384 if (!annotation.CheckValid()) {
385 return false;
386 }
387 }
388
389 std::map<AidlAnnotation::Type, AidlLocation> declared;
390 for (const auto& annotation : GetAnnotations()) {
391 const auto& [iter, inserted] = declared.emplace(annotation.GetType(), annotation.GetLocation());
392 if (!inserted && !annotation.Repeatable()) {
393 AIDL_ERROR(this) << "'" << annotation.GetName()
394 << "' is repeated, but not allowed. Previous location: " << iter->second;
395 return false;
396 }
Andrei Onea9445fc62019-06-27 18:11:59 +0100397 }
Steven Morelanda57d0a62019-07-30 09:41:14 -0700398
Andrei Onea9445fc62019-06-27 18:11:59 +0100399 return true;
400}
401
Jiyong Park68bc77a2018-07-19 19:00:45 +0900402string AidlAnnotatable::ToString() const {
403 vector<string> ret;
404 for (const auto& a : annotations_) {
Daniel Norman37d43dd2019-09-09 17:22:34 -0700405 ret.emplace_back(a.ToString(AidlConstantValueDecorator));
Jiyong Park68bc77a2018-07-19 19:00:45 +0900406 }
407 std::sort(ret.begin(), ret.end());
408 return Join(ret, " ");
409}
410
Steven Moreland46e9da82018-07-27 15:45:29 -0700411AidlTypeSpecifier::AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name,
412 bool is_array,
Jiyong Park1deecc32018-07-17 01:14:41 +0900413 vector<unique_ptr<AidlTypeSpecifier>>* type_params,
Steven Moreland46e9da82018-07-27 15:45:29 -0700414 const string& comments)
415 : AidlAnnotatable(location),
Jeongik Chadf76dc72019-11-28 00:08:47 +0900416 AidlParameterizable<unique_ptr<AidlTypeSpecifier>>(type_params),
Steven Moreland46e9da82018-07-27 15:45:29 -0700417 unresolved_name_(unresolved_name),
Casey Dahlinf7a421c2015-10-05 17:24:28 -0700418 is_array_(is_array),
Jeongik Cha1a7ab642019-07-29 17:31:02 +0900419 comments_(comments),
420 split_name_(Split(unresolved_name, ".")) {}
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700421
Jooyung Hand2fa0232020-10-19 02:51:41 +0900422const AidlTypeSpecifier& AidlTypeSpecifier::ArrayBase() const {
Steven Moreland3f658cf2018-08-20 13:40:54 -0700423 AIDL_FATAL_IF(!is_array_, this);
Jeongik Chadf76dc72019-11-28 00:08:47 +0900424 // Declaring array of generic type cannot happen, it is grammar error.
425 AIDL_FATAL_IF(IsGeneric(), this);
Steven Moreland3f658cf2018-08-20 13:40:54 -0700426
Jooyung Hand2fa0232020-10-19 02:51:41 +0900427 if (!array_base_) {
428 array_base_.reset(new AidlTypeSpecifier(*this));
429 array_base_->is_array_ = false;
430 }
431 return *array_base_;
Steven Moreland3f658cf2018-08-20 13:40:54 -0700432}
433
Jeongik Cha997281d2020-01-16 15:23:59 +0900434bool AidlTypeSpecifier::IsHidden() const {
435 return HasHideComment(GetComments());
436}
437
Jiyong Park1deecc32018-07-17 01:14:41 +0900438string AidlTypeSpecifier::ToString() const {
439 string ret = GetName();
440 if (IsGeneric()) {
441 vector<string> arg_names;
442 for (const auto& ta : GetTypeParameters()) {
Jiyong Parkccf00f82018-07-17 01:39:23 +0900443 arg_names.emplace_back(ta->ToString());
444 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900445 ret += "<" + Join(arg_names, ",") + ">";
Jiyong Parkccf00f82018-07-17 01:39:23 +0900446 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900447 if (IsArray()) {
448 ret += "[]";
449 }
450 return ret;
Jiyong Parkccf00f82018-07-17 01:39:23 +0900451}
452
Jiyong Park02da7422018-07-16 16:00:26 +0900453string AidlTypeSpecifier::Signature() const {
454 string ret = ToString();
455 string annotations = AidlAnnotatable::ToString();
456 if (annotations != "") {
457 ret = annotations + " " + ret;
458 }
459 return ret;
460}
461
Daniel Norman716d3112019-09-10 13:11:56 -0700462bool AidlTypeSpecifier::Resolve(const AidlTypenames& typenames) {
Steven Moreland21780812020-09-11 01:29:45 +0000463 AIDL_FATAL_IF(IsResolved(), this);
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700464 AidlTypenames::ResolvedTypename result = typenames.ResolveTypename(unresolved_name_);
465 if (result.is_resolved) {
466 fully_qualified_name_ = result.canonical_name;
Jeongik Cha1a7ab642019-07-29 17:31:02 +0900467 split_name_ = Split(fully_qualified_name_, ".");
Jiyong Parkccf00f82018-07-17 01:39:23 +0900468 }
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700469 return result.is_resolved;
Casey Dahlin70078e62015-09-30 17:01:30 -0700470}
471
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700472std::set<AidlAnnotation::Type> AidlTypeSpecifier::GetSupportedAnnotations() const {
Devin Moore24f68572020-02-26 13:20:59 -0800473 // kHide and kUnsupportedAppUsage are both method return annotations
474 // which we don't distinguish from other type specifiers.
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700475 return {AidlAnnotation::Type::NULLABLE, AidlAnnotation::Type::UTF8_IN_CPP,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900476 AidlAnnotation::Type::UNSUPPORTED_APP_USAGE, AidlAnnotation::Type::HIDE,
477 AidlAnnotation::Type::JAVA_PASSTHROUGH};
Devin Moore24f68572020-02-26 13:20:59 -0800478}
479
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900480bool AidlTypeSpecifier::CheckValid(const AidlTypenames& typenames) const {
Devin Moore24f68572020-02-26 13:20:59 -0800481 if (!AidlAnnotatable::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100482 return false;
483 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900484 if (IsGeneric()) {
485 const string& type_name = GetName();
Jeongik Chae74c86d2019-12-12 16:54:03 +0900486
487 auto& types = GetTypeParameters();
488 // TODO(b/136048684) Disallow to use primitive types only if it is List or Map.
489 if (type_name == "List" || type_name == "Map") {
490 if (std::any_of(types.begin(), types.end(), [](auto& type_ptr) {
491 return AidlTypenames::IsPrimitiveTypename(type_ptr->GetName());
492 })) {
Devin Moore7b8d5c92020-03-17 14:14:08 -0700493 AIDL_ERROR(this) << "A generic type cannot have any primitive type parameters.";
Jeongik Chae74c86d2019-12-12 16:54:03 +0900494 return false;
495 }
496 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800497 const auto defined_type = typenames.TryGetDefinedType(type_name);
Jeongik Chadf76dc72019-11-28 00:08:47 +0900498 const auto parameterizable =
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800499 defined_type != nullptr ? defined_type->AsParameterizable() : nullptr;
500 const bool is_user_defined_generic_type =
Jeongik Chadf76dc72019-11-28 00:08:47 +0900501 parameterizable != nullptr && parameterizable->IsGeneric();
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800502 const size_t num_params = GetTypeParameters().size();
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900503 if (type_name == "List") {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800504 if (num_params > 1) {
Steven Morelandebc3c5d2020-09-30 23:40:33 +0000505 AIDL_ERROR(this) << "List can only have one type parameter, but got: '" << ToString()
506 << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900507 return false;
508 }
509 } else if (type_name == "Map") {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800510 if (num_params != 0 && num_params != 2) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900511 AIDL_ERROR(this) << "Map must have 0 or 2 type parameters, but got "
512 << "'" << ToString() << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900513 return false;
514 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800515 if (num_params == 2) {
Jeongik Chae48d9942020-01-02 17:39:00 +0900516 const string& key_type = GetTypeParameters()[0]->GetName();
517 if (key_type != "String") {
518 AIDL_ERROR(this) << "The type of key in map must be String, but it is "
519 << "'" << key_type << "'";
520 return false;
521 }
522 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800523 } else if (is_user_defined_generic_type) {
Jeongik Chadf76dc72019-11-28 00:08:47 +0900524 const size_t allowed = parameterizable->GetTypeParameters().size();
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800525 if (num_params != allowed) {
Jeongik Chadf76dc72019-11-28 00:08:47 +0900526 AIDL_ERROR(this) << type_name << " must have " << allowed << " type parameters, but got "
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800527 << num_params;
Jeongik Chadf76dc72019-11-28 00:08:47 +0900528 return false;
529 }
530 } else {
531 AIDL_ERROR(this) << type_name << " is not a generic type.";
532 return false;
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900533 }
534 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900535
Steven Moreland11cb9452020-01-21 16:56:58 -0800536 const bool is_generic_string_list = GetName() == "List" && IsGeneric() &&
537 GetTypeParameters().size() == 1 &&
538 GetTypeParameters()[0]->GetName() == "String";
539 if (IsUtf8InCpp() && (GetName() != "String" && !is_generic_string_list)) {
540 AIDL_ERROR(this) << "@utf8InCpp can only be used on String, String[], and List<String>.";
541 return false;
542 }
543
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900544 if (GetName() == "void") {
545 if (IsArray() || IsNullable() || IsUtf8InCpp()) {
546 AIDL_ERROR(this) << "void type cannot be an array or nullable or utf8 string";
547 return false;
548 }
549 }
550
551 if (IsArray()) {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800552 const auto defined_type = typenames.TryGetDefinedType(GetName());
553 if (defined_type != nullptr && defined_type->AsInterface() != nullptr) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900554 AIDL_ERROR(this) << "Binder type cannot be an array";
555 return false;
556 }
Steven Moreland8042d2d2020-09-30 23:31:32 +0000557 if (GetName() == "ParcelableHolder") {
558 AIDL_ERROR(this) << "Arrays of ParcelableHolder are not supported.";
559 return false;
560 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900561 }
562
563 if (IsNullable()) {
564 if (AidlTypenames::IsPrimitiveTypename(GetName()) && !IsArray()) {
565 AIDL_ERROR(this) << "Primitive type cannot get nullable annotation";
566 return false;
567 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800568 const auto defined_type = typenames.TryGetDefinedType(GetName());
569 if (defined_type != nullptr && defined_type->AsEnumDeclaration() != nullptr && !IsArray()) {
Daniel Normanee8674f2019-09-20 16:07:00 -0700570 AIDL_ERROR(this) << "Enum type cannot get nullable annotation";
571 return false;
572 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900573 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900574 return true;
575}
576
Steven Moreland860b1942018-08-16 14:59:28 -0700577std::string AidlConstantValueDecorator(const AidlTypeSpecifier& /*type*/,
578 const std::string& raw_value) {
579 return raw_value;
580}
581
Steven Moreland46e9da82018-07-27 15:45:29 -0700582AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
583 AidlTypeSpecifier* type, const std::string& name)
Steven Moreland541788d2020-05-21 22:05:52 +0000584 : AidlVariableDeclaration(location, type, name, AidlConstantValue::Default(*type)) {
585 default_user_specified_ = false;
586}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700587
Steven Moreland46e9da82018-07-27 15:45:29 -0700588AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
589 AidlTypeSpecifier* type, const std::string& name,
590 AidlConstantValue* default_value)
Steven Moreland541788d2020-05-21 22:05:52 +0000591 : AidlNode(location),
592 type_(type),
593 name_(name),
594 default_user_specified_(true),
595 default_value_(default_value) {}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700596
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900597bool AidlVariableDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700598 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900599 valid &= type_->CheckValid(typenames);
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900600
Steven Moreland54be7bd2019-12-05 11:17:53 -0800601 if (type_->GetName() == "void") {
602 AIDL_ERROR(this) << "Declaration " << name_
603 << " is void, but declarations cannot be of void type.";
604 valid = false;
605 }
606
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900607 if (default_value_ == nullptr) return valid;
Steven Moreland25294322018-08-07 18:13:55 -0700608 valid &= default_value_->CheckValid();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700609
Steven Moreland25294322018-08-07 18:13:55 -0700610 if (!valid) return false;
Steven Moreland9ea10e32018-07-19 15:26:09 -0700611
Steven Moreland860b1942018-08-16 14:59:28 -0700612 return !ValueString(AidlConstantValueDecorator).empty();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700613}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700614
615string AidlVariableDeclaration::ToString() const {
Jeongik Cha3271ffa2018-12-04 15:19:20 +0900616 string ret = type_->Signature() + " " + name_;
Steven Moreland541788d2020-05-21 22:05:52 +0000617 if (default_value_ != nullptr && default_user_specified_) {
Steven Moreland860b1942018-08-16 14:59:28 -0700618 ret += " = " + ValueString(AidlConstantValueDecorator);
Steven Moreland9ea10e32018-07-19 15:26:09 -0700619 }
620 return ret;
Steven Moreland5557f1c2018-07-02 13:50:23 -0700621}
622
Jiyong Park02da7422018-07-16 16:00:26 +0900623string AidlVariableDeclaration::Signature() const {
624 return type_->Signature() + " " + name_;
625}
626
Steven Moreland860b1942018-08-16 14:59:28 -0700627std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
Jiyong Parka468e2a2018-08-29 21:25:18 +0900628 if (default_value_ != nullptr) {
Will McVickerd7d18df2019-09-12 13:40:50 -0700629 return default_value_->ValueString(GetType(), decorator);
Jiyong Parka468e2a2018-08-29 21:25:18 +0900630 } else {
631 return "";
632 }
Steven Moreland25294322018-08-07 18:13:55 -0700633}
634
Steven Moreland46e9da82018-07-27 15:45:29 -0700635AidlArgument::AidlArgument(const AidlLocation& location, AidlArgument::Direction direction,
636 AidlTypeSpecifier* type, const std::string& name)
637 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700638 direction_(direction),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700639 direction_specified_(true) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700640
Steven Moreland46e9da82018-07-27 15:45:29 -0700641AidlArgument::AidlArgument(const AidlLocation& location, AidlTypeSpecifier* type,
642 const std::string& name)
643 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700644 direction_(AidlArgument::IN_DIR),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700645 direction_specified_(false) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700646
Jiyong Park02da7422018-07-16 16:00:26 +0900647string AidlArgument::GetDirectionSpecifier() const {
Casey Dahlinc378c992015-09-29 16:50:40 -0700648 string ret;
Casey Dahlinc378c992015-09-29 16:50:40 -0700649 if (direction_specified_) {
650 switch(direction_) {
651 case AidlArgument::IN_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700652 ret += "in";
Casey Dahlinc378c992015-09-29 16:50:40 -0700653 break;
654 case AidlArgument::OUT_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700655 ret += "out";
Casey Dahlinc378c992015-09-29 16:50:40 -0700656 break;
657 case AidlArgument::INOUT_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700658 ret += "inout";
Casey Dahlinc378c992015-09-29 16:50:40 -0700659 break;
660 }
661 }
Casey Dahlinc378c992015-09-29 16:50:40 -0700662 return ret;
663}
Casey Dahlinbc7a50a2015-09-28 19:20:50 -0700664
Jiyong Park02da7422018-07-16 16:00:26 +0900665string AidlArgument::ToString() const {
Devin Mooreeccdb902020-03-24 16:22:40 -0700666 if (direction_specified_) {
667 return GetDirectionSpecifier() + " " + AidlVariableDeclaration::ToString();
668 } else {
669 return AidlVariableDeclaration::ToString();
670 }
Jiyong Park02da7422018-07-16 16:00:26 +0900671}
672
673std::string AidlArgument::Signature() const {
Steven Moreland46e9da82018-07-27 15:45:29 -0700674 class AidlInterface;
675 class AidlInterface;
676 class AidlParcelable;
677 class AidlStructuredParcelable;
678 class AidlParcelable;
679 class AidlStructuredParcelable;
Devin Mooreeccdb902020-03-24 16:22:40 -0700680 if (direction_specified_) {
681 return GetDirectionSpecifier() + " " + AidlVariableDeclaration::Signature();
682 } else {
683 return AidlVariableDeclaration::Signature();
684 }
Jiyong Park02da7422018-07-16 16:00:26 +0900685}
686
Steven Moreland46e9da82018-07-27 15:45:29 -0700687AidlMember::AidlMember(const AidlLocation& location) : AidlNode(location) {}
688
Steven Moreland46e9da82018-07-27 15:45:29 -0700689AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
690 AidlTypeSpecifier* type, const std::string& name,
691 AidlConstantValue* value)
692 : AidlMember(location), type_(type), name_(name), value_(value) {}
Steven Moreland693640b2018-07-19 13:46:27 -0700693
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900694bool AidlConstantDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700695 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900696 valid &= type_->CheckValid(typenames);
Steven Moreland25294322018-08-07 18:13:55 -0700697 valid &= value_->CheckValid();
698 if (!valid) return false;
Steven Moreland693640b2018-07-19 13:46:27 -0700699
Steven Moreland25294322018-08-07 18:13:55 -0700700 const static set<string> kSupportedConstTypes = {"String", "int"};
701 if (kSupportedConstTypes.find(type_->ToString()) == kSupportedConstTypes.end()) {
702 AIDL_ERROR(this) << "Constant of type " << type_->ToString() << " is not supported.";
Steven Moreland693640b2018-07-19 13:46:27 -0700703 return false;
704 }
705
Will McVickerd7d18df2019-09-12 13:40:50 -0700706 return true;
Christopher Wileyd6bdd8d2016-05-03 11:23:13 -0700707}
708
Jiyong Parka428d212018-08-29 22:26:30 +0900709string AidlConstantDeclaration::ToString() const {
710 return "const " + type_->ToString() + " " + name_ + " = " +
711 ValueString(AidlConstantValueDecorator);
712}
713
714string AidlConstantDeclaration::Signature() const {
715 return type_->Signature() + " " + name_;
716}
717
Steven Moreland46e9da82018-07-27 15:45:29 -0700718AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
719 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkb034bf02018-07-30 17:44:33 +0900720 const std::string& comments)
721 : AidlMethod(location, oneway, type, name, args, comments, 0, true) {
722 has_id_ = false;
723}
724
725AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
726 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkb034bf02018-07-30 17:44:33 +0900727 const std::string& comments, int id, bool is_user_defined)
Steven Moreland46e9da82018-07-27 15:45:29 -0700728 : AidlMember(location),
729 oneway_(oneway),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700730 comments_(comments),
731 type_(type),
732 name_(name),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700733 arguments_(std::move(*args)),
Jiyong Parkb034bf02018-07-30 17:44:33 +0900734 id_(id),
735 is_user_defined_(is_user_defined) {
Casey Dahlinf4a93112015-10-05 16:58:09 -0700736 has_id_ = true;
737 delete args;
Christopher Wileyad339272015-10-05 19:11:58 -0700738 for (const unique_ptr<AidlArgument>& a : arguments_) {
739 if (a->IsIn()) { in_arguments_.push_back(a.get()); }
740 if (a->IsOut()) { out_arguments_.push_back(a.get()); }
741 }
Casey Dahlinf4a93112015-10-05 16:58:09 -0700742}
743
Jeongik Cha997281d2020-01-16 15:23:59 +0900744bool AidlMethod::IsHidden() const {
745 return HasHideComment(GetComments());
746}
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700747
Jiyong Park02da7422018-07-16 16:00:26 +0900748string AidlMethod::Signature() const {
749 vector<string> arg_signatures;
750 for (const auto& arg : GetArguments()) {
Jiyong Park309668e2018-07-28 16:55:44 +0900751 arg_signatures.emplace_back(arg->GetType().ToString());
Jiyong Park02da7422018-07-16 16:00:26 +0900752 }
Jiyong Park309668e2018-07-28 16:55:44 +0900753 return GetName() + "(" + Join(arg_signatures, ", ") + ")";
754}
755
756string AidlMethod::ToString() const {
757 vector<string> arg_strings;
758 for (const auto& arg : GetArguments()) {
759 arg_strings.emplace_back(arg->Signature());
760 }
Steven Moreland4ee68632018-12-14 15:52:46 -0800761 string ret = (IsOneway() ? "oneway " : "") + GetType().Signature() + " " + GetName() + "(" +
762 Join(arg_strings, ", ") + ")";
Jiyong Parked65bf42018-08-28 15:43:27 +0900763 if (HasId()) {
764 ret += " = " + std::to_string(GetId());
765 }
766 return ret;
Jiyong Park02da7422018-07-16 16:00:26 +0900767}
768
Steven Moreland46e9da82018-07-27 15:45:29 -0700769AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
Jiyong Park18132182020-06-08 20:24:40 +0900770 const std::string& comments, const std::string& package)
771 : AidlAnnotatable(location),
772 name_(name),
773 comments_(comments),
774 package_(package),
775 split_package_(package.empty() ? std::vector<std::string>()
776 : android::base::Split(package, ".")) {}
Steven Moreland787b0432018-07-03 09:00:58 -0700777
Devin Moore24f68572020-02-26 13:20:59 -0800778bool AidlDefinedType::CheckValid(const AidlTypenames& typenames) const {
779 if (!AidlAnnotatable::CheckValid(typenames)) {
780 return false;
781 }
782
783 return true;
784}
785
Jeongik Cha997281d2020-01-16 15:23:59 +0900786bool AidlDefinedType::IsHidden() const {
787 return HasHideComment(GetComments());
788}
789
Steven Moreland787b0432018-07-03 09:00:58 -0700790std::string AidlDefinedType::GetCanonicalName() const {
791 if (package_.empty()) {
792 return GetName();
793 }
794 return GetPackage() + "." + GetName();
795}
796
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800797void AidlDefinedType::DumpHeader(CodeWriter* writer) const {
798 if (this->IsHidden()) {
799 AddHideComment(writer);
800 }
801 DumpAnnotations(writer);
802}
803
Jiyong Park18132182020-06-08 20:24:40 +0900804AidlParcelable::AidlParcelable(const AidlLocation& location, const std::string& name,
805 const std::string& package, const std::string& comments,
Jeongik Chadf76dc72019-11-28 00:08:47 +0900806 const std::string& cpp_header, std::vector<std::string>* type_params)
Jiyong Park18132182020-06-08 20:24:40 +0900807 : AidlDefinedType(location, name, comments, package),
Jeongik Chadf76dc72019-11-28 00:08:47 +0900808 AidlParameterizable<std::string>(type_params),
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800809 cpp_header_(cpp_header) {
810 // Strip off quotation marks if we actually have a cpp header.
811 if (cpp_header_.length() >= 2) {
812 cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
813 }
Casey Dahlin59401da2015-10-09 18:16:45 -0700814}
Jeongik Chadf76dc72019-11-28 00:08:47 +0900815template <typename T>
816AidlParameterizable<T>::AidlParameterizable(const AidlParameterizable& other) {
817 // Copying is not supported if it has type parameters.
818 // It doesn't make a problem because only ArrayBase() makes a copy,
819 // and it can be called only if a type is not generic.
Steven Moreland21780812020-09-11 01:29:45 +0000820 AIDL_FATAL_IF(other.IsGeneric(), AIDL_LOCATION_HERE);
Jeongik Chadf76dc72019-11-28 00:08:47 +0900821}
822
823template <typename T>
824bool AidlParameterizable<T>::CheckValid() const {
825 return true;
826};
827
828template <>
829bool AidlParameterizable<std::string>::CheckValid() const {
830 if (!IsGeneric()) {
831 return true;
832 }
833 std::unordered_set<std::string> set(GetTypeParameters().begin(), GetTypeParameters().end());
834 if (set.size() != GetTypeParameters().size()) {
835 AIDL_ERROR(this->AsAidlNode()) << "Every type parameter should be unique.";
836 return false;
837 }
838 return true;
839}
Casey Dahlin59401da2015-10-09 18:16:45 -0700840
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700841std::set<AidlAnnotation::Type> AidlParcelable::GetSupportedAnnotations() const {
Jeongik Cha36f76c32020-07-28 00:25:52 +0900842 return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900843 AidlAnnotation::Type::JAVA_STABLE_PARCELABLE, AidlAnnotation::Type::HIDE,
Jeongik Chad0a10272020-08-06 16:33:36 +0900844 AidlAnnotation::Type::JAVA_PASSTHROUGH, AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE};
Devin Moore24f68572020-02-26 13:20:59 -0800845}
846
847bool AidlParcelable::CheckValid(const AidlTypenames& typenames) const {
848 if (!AidlDefinedType::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100849 return false;
850 }
Jeongik Chadf76dc72019-11-28 00:08:47 +0900851 if (!AidlParameterizable<std::string>::CheckValid()) {
852 return false;
853 }
Jeongik Cha82317dd2019-02-27 20:26:11 +0900854
855 return true;
856}
857
Jeongik Cha997281d2020-01-16 15:23:59 +0900858void AidlParcelable::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800859 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +0900860 writer->Write("parcelable %s ;\n", GetName().c_str());
861}
862
Steven Moreland5557f1c2018-07-02 13:50:23 -0700863AidlStructuredParcelable::AidlStructuredParcelable(
Jiyong Park18132182020-06-08 20:24:40 +0900864 const AidlLocation& location, const std::string& name, const std::string& package,
Devin Moore53fc99c2020-08-12 08:07:52 -0700865 const std::string& comments, std::vector<std::unique_ptr<AidlVariableDeclaration>>* variables,
866 std::vector<std::string>* type_params)
867 : AidlParcelable(location, name, package, comments, "" /*cpp_header*/, type_params),
Steven Moreland46e9da82018-07-27 15:45:29 -0700868 variables_(std::move(*variables)) {}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700869
Jeongik Cha997281d2020-01-16 15:23:59 +0900870void AidlStructuredParcelable::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800871 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +0900872 writer->Write("parcelable %s {\n", GetName().c_str());
873 writer->Indent();
874 for (const auto& field : GetFields()) {
Jeongik Cha997281d2020-01-16 15:23:59 +0900875 if (field->GetType().IsHidden()) {
876 AddHideComment(writer);
877 }
Jiyong Parka468e2a2018-08-29 21:25:18 +0900878 writer->Write("%s;\n", field->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +0900879 }
880 writer->Dedent();
881 writer->Write("}\n");
882}
883
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700884std::set<AidlAnnotation::Type> AidlStructuredParcelable::GetSupportedAnnotations() const {
Jeongik Cha36f76c32020-07-28 00:25:52 +0900885 return {AidlAnnotation::Type::VINTF_STABILITY,
886 AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
887 AidlAnnotation::Type::HIDE,
888 AidlAnnotation::Type::JAVA_PASSTHROUGH,
889 AidlAnnotation::Type::JAVA_DEBUG,
Devin Moorec7e47a32020-08-07 10:55:25 -0700890 AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE,
Andrei Homescue61feb52020-08-18 15:44:24 -0700891 AidlAnnotation::Type::FIXED_SIZE,
892 AidlAnnotation::Type::RUST_DERIVE};
Devin Moore24f68572020-02-26 13:20:59 -0800893}
894
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900895bool AidlStructuredParcelable::CheckValid(const AidlTypenames& typenames) const {
Daniel Norman85aed542019-08-21 12:01:14 -0700896 bool success = true;
Devin Moore24f68572020-02-26 13:20:59 -0800897 if (!AidlParcelable::CheckValid(typenames)) {
898 return false;
899 }
Jooyung Hand4057c42020-10-23 13:28:22 +0900900
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900901 for (const auto& v : GetFields()) {
Steven Moreland265f3d42020-09-24 19:06:54 +0000902 const bool field_valid = v->CheckValid(typenames);
903 success = success && field_valid;
Jooyung Hand4057c42020-10-23 13:28:22 +0900904 }
Jeongik Cha13066da2020-08-06 15:43:19 +0900905
Jooyung Hand4057c42020-10-23 13:28:22 +0900906 std::set<std::string> fieldnames;
907 for (const auto& v : GetFields()) {
908 bool duplicated = !fieldnames.emplace(v->GetName()).second;
Jeongik Cha91180252020-07-31 15:43:11 +0900909 if (duplicated) {
Jeongik Cha13066da2020-08-06 15:43:19 +0900910 AIDL_ERROR(this) << "The parcelable '" << this->GetName() << "' has duplicate field name '"
Jooyung Hand4057c42020-10-23 13:28:22 +0900911 << v->GetName() << "'";
Jeongik Cha13066da2020-08-06 15:43:19 +0900912 return false;
913 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900914 }
Jeongik Cha36f76c32020-07-28 00:25:52 +0900915
Jooyung Hand4057c42020-10-23 13:28:22 +0900916 if (IsFixedSize()) {
917 for (const auto& v : GetFields()) {
918 if (!typenames.CanBeFixedSize(v->GetType())) {
919 AIDL_ERROR(v) << "The @FixedSize parcelable '" << this->GetName() << "' has a "
920 << "non-fixed size field named " << v->GetName() << ".";
921 success = false;
922 }
923 }
924 }
925
926 if (IsJavaOnlyImmutable()) {
927 std::set<std::string> getters;
928 for (const auto& v : GetFields()) {
929 if (!typenames.CanBeJavaOnlyImmutable(v->GetType())) {
930 AIDL_ERROR(v) << "The @JavaOnlyImmutable parcelable '" << this->GetName() << "' has a "
931 << "non-immutable field named '" << v->GetName() << "'.";
932 success = false;
933 }
934 bool duplicated = !getters.emplace(CapitalizeFirstLetter(*v, v->GetName())).second;
935 if (duplicated) {
936 AIDL_ERROR(this) << "The parcelable '" << this->GetName() << "' has duplicate field name '"
937 << v->GetName() << "' after capitalizing the first letter";
938 return false;
939 }
940 }
941 }
942
Daniel Norman85aed542019-08-21 12:01:14 -0700943 return success;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900944}
945
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900946// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -0700947bool AidlTypeSpecifier::LanguageSpecificCheckValid(const AidlTypenames& typenames,
948 Options::Language lang) const {
Andrei Homescub62afd92020-05-11 19:24:59 -0700949 if ((lang == Options::Language::NDK || lang == Options::Language::RUST) && IsArray() &&
950 GetName() == "IBinder") {
951 AIDL_ERROR(this) << "The " << Options::LanguageToString(lang)
952 << " backend does not support array of IBinder";
Steven Moreland0185d9b2020-05-15 23:21:22 +0000953 return false;
954 }
Jeongik Cha8f02a532020-10-14 00:16:28 +0900955 if (lang == Options::Language::RUST && GetName() == "ParcelableHolder") {
956 // TODO(b/146611855): Remove it when Rust backend supports ParcelableHolder
957 AIDL_ERROR(this) << "The Rust backend does not support ParcelableHolder yet.";
Jeongik Cha225519b2020-08-29 01:55:32 +0900958 return false;
959 }
Andrei Homescub62afd92020-05-11 19:24:59 -0700960 if ((lang == Options::Language::NDK || lang == Options::Language::RUST) && IsArray() &&
961 IsNullable()) {
Steven Moreland0185d9b2020-05-15 23:21:22 +0000962 if (GetName() == "ParcelFileDescriptor") {
Andrei Homescub62afd92020-05-11 19:24:59 -0700963 AIDL_ERROR(this) << "The " << Options::LanguageToString(lang)
964 << " backend does not support nullable array of ParcelFileDescriptor";
Steven Moreland0185d9b2020-05-15 23:21:22 +0000965 return false;
966 }
967
Steven Morelandd59e3172020-05-11 16:42:09 -0700968 const auto defined_type = typenames.TryGetDefinedType(GetName());
969 if (defined_type != nullptr && defined_type->AsParcelable() != nullptr) {
Andrei Homescub62afd92020-05-11 19:24:59 -0700970 AIDL_ERROR(this) << "The " << Options::LanguageToString(lang)
971 << " backend does not support nullable array of parcelable";
Steven Morelandd59e3172020-05-11 16:42:09 -0700972 return false;
973 }
974 }
Andrei Homescub62afd92020-05-11 19:24:59 -0700975 if (this->GetName() == "FileDescriptor" &&
976 (lang == Options::Language::NDK || lang == Options::Language::RUST)) {
977 AIDL_ERROR(this) << "FileDescriptor isn't supported by the " << Options::LanguageToString(lang)
978 << " backend.";
Steven Morelandc8a4ca82020-01-21 17:50:08 -0800979 return false;
980 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900981 if (this->IsGeneric()) {
982 if (this->GetName() == "List") {
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900983 if (lang == Options::Language::CPP) {
Devin Moore2ac52f92020-03-23 15:39:36 -0700984 const string& contained_type = this->GetTypeParameters()[0]->GetName();
985 if (!(contained_type == "String" || contained_type == "IBinder")) {
986 AIDL_ERROR(this) << "List<" << contained_type
987 << "> is not supported. List in cpp supports only String and IBinder.";
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900988 return false;
989 }
Jeongik Cha08ca2182019-11-21 14:01:13 +0900990 } else if (lang == Options::Language::JAVA) {
991 const string& contained_type = this->GetTypeParameters()[0]->GetName();
992 if (AidlTypenames::IsBuiltinTypename(contained_type)) {
993 if (contained_type != "String" && contained_type != "IBinder" &&
994 contained_type != "ParcelFileDescriptor") {
Devin Moore2ac52f92020-03-23 15:39:36 -0700995 AIDL_ERROR(this) << "List<" << contained_type
996 << "> is not supported. List in Java supports only String, IBinder, "
997 "and ParcelFileDescriptor.";
Jeongik Cha08ca2182019-11-21 14:01:13 +0900998 return false;
999 }
1000 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001001 }
Jeongik Chabb55b5e2020-01-07 23:11:26 +09001002 }
1003 }
Devin Moore6a01ca12020-08-28 10:24:19 -07001004
1005 if (this->IsArray()) {
1006 if (this->GetName() == "List" || this->GetName() == "Map" ||
1007 this->GetName() == "CharSequence") {
1008 AIDL_ERROR(this) << this->GetName() << "[] is not supported.";
Jeongik Chabb55b5e2020-01-07 23:11:26 +09001009 return false;
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001010 }
1011 }
Devin Moore6a01ca12020-08-28 10:24:19 -07001012
1013 if (lang != Options::Language::JAVA) {
1014 if (this->GetName() == "List" && !this->IsGeneric()) {
1015 AIDL_ERROR(this) << "Currently, only the Java backend supports non-generic List.";
1016 return false;
1017 }
1018 if (this->GetName() == "Map" || this->GetName() == "CharSequence") {
1019 AIDL_ERROR(this) << "Currently, only Java backend supports " << this->GetName() << ".";
1020 return false;
Jeongik Cha08ca2182019-11-21 14:01:13 +09001021 }
1022 }
1023
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001024 return true;
1025}
1026
1027// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -07001028bool AidlParcelable::LanguageSpecificCheckValid(const AidlTypenames& /*typenames*/,
1029 Options::Language lang) const {
Andrei Homescub62afd92020-05-11 19:24:59 -07001030 if (lang == Options::Language::CPP || lang == Options::Language::NDK) {
Steven Moreland0d9c26e2020-01-22 08:52:08 -08001031 const AidlParcelable* unstructured_parcelable = this->AsUnstructuredParcelable();
1032 if (unstructured_parcelable != nullptr) {
1033 if (unstructured_parcelable->GetCppHeader().empty()) {
1034 AIDL_ERROR(unstructured_parcelable)
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001035 << "Unstructured parcelable must have C++ header defined.";
1036 return false;
1037 }
1038 }
1039 }
1040 return true;
1041}
1042
1043// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -07001044bool AidlStructuredParcelable::LanguageSpecificCheckValid(const AidlTypenames& typenames,
1045 Options::Language lang) const {
1046 if (!AidlParcelable::LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001047 return false;
1048 }
1049 for (const auto& v : this->GetFields()) {
Steven Morelandd59e3172020-05-11 16:42:09 -07001050 if (!v->GetType().LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001051 return false;
1052 }
1053 }
1054 return true;
1055}
1056
Daniel Norman85aed542019-08-21 12:01:14 -07001057AidlEnumerator::AidlEnumerator(const AidlLocation& location, const std::string& name,
Daniel Norman2e4112d2019-10-03 10:22:35 -07001058 AidlConstantValue* value, const std::string& comments)
1059 : AidlNode(location), name_(name), value_(value), comments_(comments) {}
Daniel Norman85aed542019-08-21 12:01:14 -07001060
1061bool AidlEnumerator::CheckValid(const AidlTypeSpecifier& enum_backing_type) const {
1062 if (GetValue() == nullptr) {
1063 return false;
1064 }
1065 if (!GetValue()->CheckValid()) {
1066 return false;
1067 }
Will McVickerd7d18df2019-09-12 13:40:50 -07001068 if (GetValue()->ValueString(enum_backing_type, AidlConstantValueDecorator).empty()) {
Daniel Norman85aed542019-08-21 12:01:14 -07001069 AIDL_ERROR(this) << "Enumerator type differs from enum backing type.";
1070 return false;
1071 }
1072 return true;
1073}
1074
1075string AidlEnumerator::ValueString(const AidlTypeSpecifier& backing_type,
1076 const ConstantValueDecorator& decorator) const {
Will McVickerd7d18df2019-09-12 13:40:50 -07001077 return GetValue()->ValueString(backing_type, decorator);
Daniel Norman85aed542019-08-21 12:01:14 -07001078}
1079
1080AidlEnumDeclaration::AidlEnumDeclaration(const AidlLocation& location, const std::string& name,
1081 std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
Jiyong Park18132182020-06-08 20:24:40 +09001082 const std::string& package, const std::string& comments)
Daniel Norman2e4112d2019-10-03 10:22:35 -07001083 : AidlDefinedType(location, name, comments, package), enumerators_(std::move(*enumerators)) {}
Daniel Norman85aed542019-08-21 12:01:14 -07001084
1085void AidlEnumDeclaration::SetBackingType(std::unique_ptr<const AidlTypeSpecifier> type) {
1086 backing_type_ = std::move(type);
1087}
1088
Steven Moreland59e53e42019-11-26 20:38:08 -08001089bool AidlEnumDeclaration::Autofill() {
Daniel Normanb28684e2019-10-17 15:31:39 -07001090 const AidlEnumerator* previous = nullptr;
1091 for (const auto& enumerator : enumerators_) {
1092 if (enumerator->GetValue() == nullptr) {
1093 if (previous == nullptr) {
Devin Mooredf93ebb2020-03-25 14:03:35 -07001094 enumerator->SetValue(
1095 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "0")));
Daniel Normanb28684e2019-10-17 15:31:39 -07001096 } else {
Steven Moreland59e53e42019-11-26 20:38:08 -08001097 auto prev_value = std::unique_ptr<AidlConstantValue>(
1098 AidlConstantValue::ShallowIntegralCopy(*previous->GetValue()));
1099 if (prev_value == nullptr) {
1100 return false;
1101 }
Daniel Normanb28684e2019-10-17 15:31:39 -07001102 enumerator->SetValue(std::make_unique<AidlBinaryConstExpression>(
Devin Mooredf93ebb2020-03-25 14:03:35 -07001103 GetLocation(), std::move(prev_value), "+",
1104 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "1"))));
Daniel Normanb28684e2019-10-17 15:31:39 -07001105 }
1106 }
1107 previous = enumerator.get();
1108 }
Steven Moreland59e53e42019-11-26 20:38:08 -08001109 return true;
Daniel Normanb28684e2019-10-17 15:31:39 -07001110}
1111
Steven Moreland0cea4aa2020-04-20 21:06:02 -07001112std::set<AidlAnnotation::Type> AidlEnumDeclaration::GetSupportedAnnotations() const {
1113 return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::BACKING,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09001114 AidlAnnotation::Type::HIDE, AidlAnnotation::Type::JAVA_PASSTHROUGH};
Devin Moore24f68572020-02-26 13:20:59 -08001115}
1116
1117bool AidlEnumDeclaration::CheckValid(const AidlTypenames& typenames) const {
1118 if (!AidlDefinedType::CheckValid(typenames)) {
1119 return false;
1120 }
Daniel Norman85aed542019-08-21 12:01:14 -07001121 if (backing_type_ == nullptr) {
1122 AIDL_ERROR(this) << "Enum declaration missing backing type.";
1123 return false;
1124 }
1125 bool success = true;
1126 for (const auto& enumerator : enumerators_) {
1127 success = success && enumerator->CheckValid(GetBackingType());
1128 }
1129 return success;
1130}
1131
Jeongik Cha997281d2020-01-16 15:23:59 +09001132void AidlEnumDeclaration::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -08001133 DumpHeader(writer);
Daniel Norman37d43dd2019-09-09 17:22:34 -07001134 writer->Write("enum %s {\n", GetName().c_str());
Daniel Norman85aed542019-08-21 12:01:14 -07001135 writer->Indent();
1136 for (const auto& enumerator : GetEnumerators()) {
Daniel Norman85aed542019-08-21 12:01:14 -07001137 writer->Write("%s = %s,\n", enumerator->GetName().c_str(),
1138 enumerator->ValueString(GetBackingType(), AidlConstantValueDecorator).c_str());
1139 }
1140 writer->Dedent();
1141 writer->Write("}\n");
1142}
1143
Jooyung Han2946afc2020-10-05 20:29:16 +09001144AidlUnionDecl::AidlUnionDecl(const AidlLocation& location, const std::string& name,
1145 const std::string& package, const std::string& comments,
1146 std::vector<std::unique_ptr<AidlVariableDeclaration>>* variables,
1147 std::vector<std::string>* type_params)
1148 : AidlParcelable(location, name, package, comments, "" /*cpp_header*/, type_params),
1149 variables_(std::move(*variables)) {}
1150
1151std::set<AidlAnnotation::Type> AidlUnionDecl::GetSupportedAnnotations() const {
1152 return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::HIDE,
1153 AidlAnnotation::Type::JAVA_PASSTHROUGH};
1154}
1155
1156void AidlUnionDecl::Dump(CodeWriter* writer) const {
1157 DumpHeader(writer);
1158 writer->Write("union %s {\n", GetName().c_str());
1159 writer->Indent();
1160 for (const auto& field : GetFields()) {
1161 if (field->GetType().IsHidden()) {
1162 AddHideComment(writer);
1163 }
1164 writer->Write("%s;\n", field->ToString().c_str());
1165 }
1166 writer->Dedent();
1167 writer->Write("}\n");
1168}
1169
Jooyung Hanfe89f122020-10-14 03:49:18 +09001170bool AidlUnionDecl::CheckValid(const AidlTypenames& typenames) const {
1171 // visit parent
1172 if (!AidlParcelable::CheckValid(typenames)) {
1173 return false;
1174 }
1175 // visit members
1176 for (const auto& v : GetFields()) {
1177 if (!v->CheckValid(typenames)) {
1178 return false;
1179 }
1180 }
1181
1182 // now, visit self!
1183 bool success = true;
1184
1185 // TODO(b/170807936) do we need to allow ParcelableHolder in union?
1186 for (const auto& v : GetFields()) {
1187 if (v->GetType().GetName() == "ParcelableHolder") {
1188 AIDL_ERROR(*v) << "A union can't have a member of ParcelableHolder '" << v->GetName() << "'";
1189 success = false;
1190 }
1191 }
1192
1193 // first member should have default value (implicit or explicit)
1194 if (GetFields().empty()) {
1195 AIDL_ERROR(*this) << "The union '" << this->GetName() << "' has no fields.";
1196 return false;
1197 }
1198
1199 return success;
1200}
1201
1202// TODO: we should treat every backend all the same in future.
1203bool AidlUnionDecl::LanguageSpecificCheckValid(const AidlTypenames& typenames,
1204 Options::Language lang) const {
1205 if (!AidlParcelable::LanguageSpecificCheckValid(typenames, lang)) {
1206 return false;
1207 }
1208 for (const auto& v : this->GetFields()) {
1209 if (!v->GetType().LanguageSpecificCheckValid(typenames, lang)) {
1210 return false;
1211 }
1212 }
1213 return true;
1214}
1215
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001216// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -07001217bool AidlInterface::LanguageSpecificCheckValid(const AidlTypenames& typenames,
1218 Options::Language lang) const {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001219 for (const auto& m : this->GetMethods()) {
Steven Morelandd59e3172020-05-11 16:42:09 -07001220 if (!m->GetType().LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001221 return false;
1222 }
1223 for (const auto& arg : m->GetArguments()) {
Steven Morelandd59e3172020-05-11 16:42:09 -07001224 if (!arg->GetType().LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001225 return false;
1226 }
1227 }
1228 }
1229 return true;
1230}
1231
Steven Moreland46e9da82018-07-27 15:45:29 -07001232AidlInterface::AidlInterface(const AidlLocation& location, const std::string& name,
Casey Dahlinfb7da2e2015-10-08 17:26:09 -07001233 const std::string& comments, bool oneway,
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001234 std::vector<std::unique_ptr<AidlMember>>* members,
Jiyong Park18132182020-06-08 20:24:40 +09001235 const std::string& package)
Steven Morelandacd53472018-12-14 10:17:26 -08001236 : AidlDefinedType(location, name, comments, package) {
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001237 for (auto& member : *members) {
1238 AidlMember* local = member.release();
1239 AidlMethod* method = local->AsMethod();
Steven Moreland693640b2018-07-19 13:46:27 -07001240 AidlConstantDeclaration* constant = local->AsConstantDeclaration();
1241
Steven Moreland21780812020-09-11 01:29:45 +00001242 AIDL_FATAL_IF(method != nullptr && constant != nullptr, member);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001243
1244 if (method) {
Steven Moreland8c70ba92018-12-17 10:20:31 -08001245 method->ApplyInterfaceOneway(oneway);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001246 methods_.emplace_back(method);
Steven Moreland693640b2018-07-19 13:46:27 -07001247 } else if (constant) {
1248 constants_.emplace_back(constant);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001249 } else {
Steven Moreland46e9da82018-07-27 15:45:29 -07001250 AIDL_FATAL(this) << "Member is neither method nor constant!";
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001251 }
1252 }
1253
1254 delete members;
Casey Dahlinfb7da2e2015-10-08 17:26:09 -07001255}
1256
Jeongik Cha997281d2020-01-16 15:23:59 +09001257void AidlInterface::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -08001258 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +09001259 writer->Write("interface %s {\n", GetName().c_str());
1260 writer->Indent();
1261 for (const auto& method : GetMethods()) {
Jeongik Cha997281d2020-01-16 15:23:59 +09001262 if (method->IsHidden()) {
1263 AddHideComment(writer);
1264 }
Jiyong Park309668e2018-07-28 16:55:44 +09001265 writer->Write("%s;\n", method->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +09001266 }
Jiyong Parka428d212018-08-29 22:26:30 +09001267 for (const auto& constdecl : GetConstantDeclarations()) {
Jeongik Cha997281d2020-01-16 15:23:59 +09001268 if (constdecl->GetType().IsHidden()) {
1269 AddHideComment(writer);
1270 }
Jiyong Parka428d212018-08-29 22:26:30 +09001271 writer->Write("%s;\n", constdecl->ToString().c_str());
1272 }
Jiyong Park02da7422018-07-16 16:00:26 +09001273 writer->Dedent();
1274 writer->Write("}\n");
1275}
1276
Steven Moreland0cea4aa2020-04-20 21:06:02 -07001277std::set<AidlAnnotation::Type> AidlInterface::GetSupportedAnnotations() const {
1278 return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
Jiyong Park27fd7fd2020-08-27 16:25:09 +09001279 AidlAnnotation::Type::HIDE, AidlAnnotation::Type::JAVA_PASSTHROUGH,
1280 AidlAnnotation::Type::DESCRIPTOR};
Devin Moore24f68572020-02-26 13:20:59 -08001281}
1282
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001283bool AidlInterface::CheckValid(const AidlTypenames& typenames) const {
Devin Moore24f68572020-02-26 13:20:59 -08001284 if (!AidlDefinedType::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +01001285 return false;
1286 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001287 // Has to be a pointer due to deleting copy constructor. No idea why.
1288 map<string, const AidlMethod*> method_names;
1289 for (const auto& m : GetMethods()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001290 if (!m->GetType().CheckValid(typenames)) {
1291 return false;
1292 }
1293
Jeongik Cha649e8a72020-03-27 17:47:40 +09001294 // TODO(b/156872582): Support it when ParcelableHolder supports every backend.
1295 if (m->GetType().GetName() == "ParcelableHolder") {
1296 AIDL_ERROR(m) << "ParcelableHolder cannot be a return type";
1297 return false;
1298 }
Steven Morelandacd53472018-12-14 10:17:26 -08001299 if (m->IsOneway() && m->GetType().GetName() != "void") {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001300 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot return a value";
1301 return false;
1302 }
1303
1304 set<string> argument_names;
1305 for (const auto& arg : m->GetArguments()) {
1306 auto it = argument_names.find(arg->GetName());
1307 if (it != argument_names.end()) {
1308 AIDL_ERROR(m) << "method '" << m->GetName() << "' has duplicate argument name '"
1309 << arg->GetName() << "'";
1310 return false;
1311 }
1312 argument_names.insert(arg->GetName());
1313
1314 if (!arg->GetType().CheckValid(typenames)) {
1315 return false;
1316 }
1317
Jeongik Cha649e8a72020-03-27 17:47:40 +09001318 // TODO(b/156872582): Support it when ParcelableHolder supports every backend.
1319 if (arg->GetType().GetName() == "ParcelableHolder") {
1320 AIDL_ERROR(arg) << "ParcelableHolder cannot be an argument type";
1321 return false;
1322 }
Steven Morelandacd53472018-12-14 10:17:26 -08001323 if (m->IsOneway() && arg->IsOut()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001324 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot have out parameters";
1325 return false;
1326 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001327 const bool can_be_out = typenames.CanBeOutParameter(arg->GetType());
1328 if (!arg->DirectionWasSpecified() && can_be_out) {
1329 AIDL_ERROR(arg) << "'" << arg->GetType().ToString()
1330 << "' can be an out type, so you must declare it as in, out, or inout.";
1331 return false;
1332 }
1333
1334 if (arg->GetDirection() != AidlArgument::IN_DIR && !can_be_out) {
1335 AIDL_ERROR(arg) << "'" << arg->ToString() << "' can only be an in parameter.";
1336 return false;
1337 }
1338
1339 // check that the name doesn't match a keyword
Jeongik Cha997281d2020-01-16 15:23:59 +09001340 if (IsJavaKeyword(arg->GetName().c_str())) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001341 AIDL_ERROR(arg) << "Argument name is a Java or aidl keyword";
1342 return false;
1343 }
1344
1345 // Reserve a namespace for internal use
1346 if (android::base::StartsWith(arg->GetName(), "_aidl")) {
1347 AIDL_ERROR(arg) << "Argument name cannot begin with '_aidl'";
1348 return false;
1349 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001350 }
1351
1352 auto it = method_names.find(m->GetName());
1353 // prevent duplicate methods
1354 if (it == method_names.end()) {
1355 method_names[m->GetName()] = m.get();
1356 } else {
1357 AIDL_ERROR(m) << "attempt to redefine method " << m->GetName() << ":";
1358 AIDL_ERROR(it->second) << "previously defined here.";
1359 return false;
1360 }
1361
Paul Trautrimb77048c2020-01-21 16:39:32 +09001362 static set<string> reserved_methods{"asBinder()", "getInterfaceHash()", "getInterfaceVersion()",
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001363 "getTransactionName(int)"};
1364
1365 if (reserved_methods.find(m->Signature()) != reserved_methods.end()) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001366 AIDL_ERROR(m) << " method " << m->Signature() << " is reserved for internal use.";
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001367 return false;
1368 }
1369 }
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001370
1371 bool success = true;
1372 set<string> constant_names;
1373 for (const std::unique_ptr<AidlConstantDeclaration>& constant : GetConstantDeclarations()) {
1374 if (constant_names.count(constant->GetName()) > 0) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001375 AIDL_ERROR(constant) << "Found duplicate constant name '" << constant->GetName() << "'";
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001376 success = false;
1377 }
1378 constant_names.insert(constant->GetName());
1379 success = success && constant->CheckValid(typenames);
1380 }
1381
1382 return success;
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001383}
1384
Jiyong Park27fd7fd2020-08-27 16:25:09 +09001385std::string AidlInterface::GetDescriptor() const {
1386 std::string annotatedDescriptor = AidlAnnotatable::GetDescriptor();
1387 if (annotatedDescriptor != "") {
1388 return annotatedDescriptor;
1389 }
1390 return GetCanonicalName();
1391}
1392
Steven Moreland46e9da82018-07-27 15:45:29 -07001393AidlImport::AidlImport(const AidlLocation& location, const std::string& needed_class)
1394 : AidlNode(location), needed_class_(needed_class) {}