blob: f356f32bcaa48f9b502a288377b59e6a6b84b5ca [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
Jeongik Cha91180252020-07-31 15:43:11 +090072inline std::string CapitalizeFirstLetter(const std::string& str) {
73 CHECK(str.size() > 0) << "Input cannot be empty.";
74 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{
120 {AidlAnnotation::Type::NULLABLE, "nullable", {}},
121 {AidlAnnotation::Type::UTF8_IN_CPP, "utf8InCpp", {}},
122 {AidlAnnotation::Type::VINTF_STABILITY, "VintfStability", {}},
123 {AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
124 "UnsupportedAppUsage",
125 {{"expectedSignature", "String"},
126 {"implicitMember", "String"},
127 {"maxTargetSdk", "int"},
128 {"publicAlternatives", "String"},
129 {"trackingBug", "long"}}},
130 {AidlAnnotation::Type::JAVA_STABLE_PARCELABLE, "JavaOnlyStableParcelable", {}},
131 {AidlAnnotation::Type::HIDE, "Hide", {}},
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900132 {AidlAnnotation::Type::BACKING, "Backing", {{"type", "String"}}},
133 {AidlAnnotation::Type::JAVA_PASSTHROUGH, "JavaPassthrough", {{"annotation", "String"}}},
Jiyong Park43113fb2020-07-20 16:26:19 +0900134 {AidlAnnotation::Type::JAVA_DEBUG, "JavaDebug", {}},
Jeongik Chad0a10272020-08-06 16:33:36 +0900135 {AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE, "JavaOnlyImmutable", {}},
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900136 };
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700137 return kSchemas;
138}
Jiyong Park68bc77a2018-07-19 19:00:45 +0900139
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700140std::string AidlAnnotation::TypeToString(Type type) {
141 for (const Schema& schema : AllSchemas()) {
142 if (type == schema.type) return schema.name;
143 }
144 AIDL_FATAL(AIDL_LOCATION_HERE) << "Unrecognized type: " << static_cast<size_t>(type);
145 __builtin_unreachable();
146}
Andrei Onea9445fc62019-06-27 18:11:59 +0100147
148AidlAnnotation* AidlAnnotation::Parse(
149 const AidlLocation& location, const string& name,
150 std::map<std::string, std::shared_ptr<AidlConstantValue>>* parameter_list) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700151 const Schema* schema = nullptr;
152 for (const Schema& a_schema : AllSchemas()) {
153 if (a_schema.name == name) {
154 schema = &a_schema;
155 }
156 }
157
158 if (schema == nullptr) {
Jiyong Park68bc77a2018-07-19 19:00:45 +0900159 std::ostringstream stream;
Steven Moreland46e9da82018-07-27 15:45:29 -0700160 stream << "'" << name << "' is not a recognized annotation. ";
Jiyong Park68bc77a2018-07-19 19:00:45 +0900161 stream << "It must be one of:";
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700162 for (const Schema& s : AllSchemas()) {
163 stream << " " << s.name;
Jiyong Park68bc77a2018-07-19 19:00:45 +0900164 }
165 stream << ".";
Steven Moreland46e9da82018-07-27 15:45:29 -0700166 AIDL_ERROR(location) << stream.str();
167 return nullptr;
Jiyong Park68bc77a2018-07-19 19:00:45 +0900168 }
Andrei Onea9445fc62019-06-27 18:11:59 +0100169 if (parameter_list == nullptr) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700170 return new AidlAnnotation(location, *schema, {});
Andrei Onea9445fc62019-06-27 18:11:59 +0100171 }
172
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700173 return new AidlAnnotation(location, *schema, std::move(*parameter_list));
Jiyong Park68bc77a2018-07-19 19:00:45 +0900174}
175
Andrei Onea9445fc62019-06-27 18:11:59 +0100176AidlAnnotation::AidlAnnotation(
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700177 const AidlLocation& location, const Schema& schema,
Andrei Onea9445fc62019-06-27 18:11:59 +0100178 std::map<std::string, std::shared_ptr<AidlConstantValue>>&& parameters)
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700179 : AidlNode(location), schema_(schema), parameters_(std::move(parameters)) {}
Andrei Onea9445fc62019-06-27 18:11:59 +0100180
181bool AidlAnnotation::CheckValid() const {
Andrei Onea9445fc62019-06-27 18:11:59 +0100182 for (const auto& name_and_param : parameters_) {
183 const std::string& param_name = name_and_param.first;
184 const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
Will McVickerd7d18df2019-09-12 13:40:50 -0700185 if (!param->CheckValid()) {
186 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
187 << GetName() << ".";
188 return false;
189 }
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700190 auto parameter_mapping_it = schema_.supported_parameters.find(param_name);
191 if (parameter_mapping_it == schema_.supported_parameters.end()) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100192 std::ostringstream stream;
193 stream << "Parameter " << param_name << " not supported ";
Devin Mooredecaf292020-04-30 09:16:40 -0700194 stream << "for annotation " << GetName() << ". ";
Andrei Onea9445fc62019-06-27 18:11:59 +0100195 stream << "It must be one of:";
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700196 for (const auto& kv : schema_.supported_parameters) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100197 stream << " " << kv.first;
198 }
199 AIDL_ERROR(this) << stream.str();
200 return false;
201 }
202 AidlTypeSpecifier type{AIDL_LOCATION_HERE, parameter_mapping_it->second, false, nullptr, ""};
Will McVickerd7d18df2019-09-12 13:40:50 -0700203 const std::string param_value = param->ValueString(type, AidlConstantValueDecorator);
Andrei Onea9445fc62019-06-27 18:11:59 +0100204 // Assume error on empty string.
205 if (param_value == "") {
206 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
207 << GetName() << ".";
208 return false;
209 }
210 }
211 return true;
212}
213
214std::map<std::string, std::string> AidlAnnotation::AnnotationParams(
215 const ConstantValueDecorator& decorator) const {
216 std::map<std::string, std::string> raw_params;
Andrei Onea9445fc62019-06-27 18:11:59 +0100217 for (const auto& name_and_param : parameters_) {
218 const std::string& param_name = name_and_param.first;
219 const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
Devin Mooredecaf292020-04-30 09:16:40 -0700220 if (schema_.supported_parameters.find(param_name) == schema_.supported_parameters.end()) {
221 std::ostringstream stream;
222 stream << "Parameter " << param_name << " not supported ";
223 stream << "for annotation " << GetName() << ". ";
224 stream << "It must be one of:";
225 for (const auto& kv : schema_.supported_parameters) {
226 stream << " " << kv.first;
227 }
228 AIDL_ERROR(this) << stream.str();
229 continue;
230 }
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700231 AidlTypeSpecifier type{AIDL_LOCATION_HERE, schema_.supported_parameters.at(param_name), false,
232 nullptr, ""};
Will McVickerd7d18df2019-09-12 13:40:50 -0700233 if (!param->CheckValid()) {
234 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
235 << GetName() << ".";
Devin Mooredecaf292020-04-30 09:16:40 -0700236 continue;
Will McVickerd7d18df2019-09-12 13:40:50 -0700237 }
238
239 raw_params.emplace(param_name, param->ValueString(type, decorator));
Andrei Onea9445fc62019-06-27 18:11:59 +0100240 }
241 return raw_params;
242}
Steven Moreland46e9da82018-07-27 15:45:29 -0700243
Daniel Norman37d43dd2019-09-09 17:22:34 -0700244std::string AidlAnnotation::ToString(const ConstantValueDecorator& decorator) const {
245 if (parameters_.empty()) {
246 return "@" + GetName();
247 } else {
248 vector<string> param_strings;
249 for (const auto& [name, value] : AnnotationParams(decorator)) {
250 param_strings.emplace_back(name + "=" + value);
251 }
252 return "@" + GetName() + "(" + Join(param_strings, ", ") + ")";
253 }
254}
255
Andrei Onea9445fc62019-06-27 18:11:59 +0100256static const AidlAnnotation* GetAnnotation(const vector<AidlAnnotation>& annotations,
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700257 AidlAnnotation::Type type) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100258 for (const auto& a : annotations) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700259 if (a.GetType() == type) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100260 return &a;
261 }
262 }
263 return nullptr;
264}
265
Steven Moreland46e9da82018-07-27 15:45:29 -0700266AidlAnnotatable::AidlAnnotatable(const AidlLocation& location) : AidlNode(location) {}
267
Jiyong Park68bc77a2018-07-19 19:00:45 +0900268bool AidlAnnotatable::IsNullable() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700269 return GetAnnotation(annotations_, AidlAnnotation::Type::NULLABLE);
Jiyong Park68bc77a2018-07-19 19:00:45 +0900270}
271
Jiyong Park68bc77a2018-07-19 19:00:45 +0900272bool AidlAnnotatable::IsUtf8InCpp() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700273 return GetAnnotation(annotations_, AidlAnnotation::Type::UTF8_IN_CPP);
Jiyong Park68bc77a2018-07-19 19:00:45 +0900274}
275
Steven Morelanda57d0a62019-07-30 09:41:14 -0700276bool AidlAnnotatable::IsVintfStability() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700277 return GetAnnotation(annotations_, AidlAnnotation::Type::VINTF_STABILITY);
Steven Morelanda57d0a62019-07-30 09:41:14 -0700278}
279
Jeongik Chad0a10272020-08-06 16:33:36 +0900280bool AidlAnnotatable::IsJavaOnlyImmutable() const {
281 return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE);
Jeongik Cha36f76c32020-07-28 00:25:52 +0900282}
283
Andrei Onea9445fc62019-06-27 18:11:59 +0100284const AidlAnnotation* AidlAnnotatable::UnsupportedAppUsage() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700285 return GetAnnotation(annotations_, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE);
Jiyong Parka6605ab2018-11-11 14:30:21 +0900286}
287
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900288const AidlAnnotation* AidlAnnotatable::JavaPassthrough() const {
289 return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_PASSTHROUGH);
290}
291
Daniel Norman716d3112019-09-10 13:11:56 -0700292const AidlTypeSpecifier* AidlAnnotatable::BackingType(const AidlTypenames& typenames) const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700293 auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::BACKING);
Daniel Norman85aed542019-08-21 12:01:14 -0700294 if (annotation != nullptr) {
295 auto annotation_params = annotation->AnnotationParams(AidlConstantValueDecorator);
296 if (auto it = annotation_params.find("type"); it != annotation_params.end()) {
297 const string& type = it->second;
Steven Morelande7d5d082020-05-21 20:29:02 +0000298
299 AIDL_FATAL_IF(type.size() < 2, this) << type;
300 AIDL_FATAL_IF(type[0] != '"', this) << type;
301 AIDL_FATAL_IF(type[type.length() - 1] != '"', this) << type;
302 string unquoted_type = type.substr(1, type.length() - 2);
303
Daniel Norman716d3112019-09-10 13:11:56 -0700304 AidlTypeSpecifier* type_specifier =
Steven Morelande7d5d082020-05-21 20:29:02 +0000305 new AidlTypeSpecifier(AIDL_LOCATION_HERE, unquoted_type, false, nullptr, "");
Daniel Norman716d3112019-09-10 13:11:56 -0700306 type_specifier->Resolve(typenames);
307 return type_specifier;
Daniel Norman85aed542019-08-21 12:01:14 -0700308 }
309 }
310 return nullptr;
311}
312
Jeongik Cha88f95a82020-01-15 13:02:16 +0900313bool AidlAnnotatable::IsStableApiParcelable(Options::Language lang) const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700314 return lang == Options::Language::JAVA &&
315 GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_STABLE_PARCELABLE);
Jeongik Cha82317dd2019-02-27 20:26:11 +0900316}
317
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800318bool AidlAnnotatable::IsHide() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700319 return GetAnnotation(annotations_, AidlAnnotation::Type::HIDE);
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800320}
321
Jiyong Park43113fb2020-07-20 16:26:19 +0900322bool AidlAnnotatable::IsJavaDebug() const {
323 return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_DEBUG);
324}
325
Steven Moreland7e4b9502020-02-20 18:10:42 -0800326void AidlAnnotatable::DumpAnnotations(CodeWriter* writer) const {
327 if (annotations_.empty()) return;
328
329 writer->Write("%s\n", AidlAnnotatable::ToString().c_str());
330}
331
Devin Moore24f68572020-02-26 13:20:59 -0800332bool AidlAnnotatable::CheckValid(const AidlTypenames&) const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700333 std::set<AidlAnnotation::Type> supported_annotations = GetSupportedAnnotations();
Andrei Onea9445fc62019-06-27 18:11:59 +0100334 for (const auto& annotation : GetAnnotations()) {
335 if (!annotation.CheckValid()) {
336 return false;
337 }
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700338
339 std::vector<std::string> supported_annot_strings;
340 for (AidlAnnotation::Type type : supported_annotations) {
341 supported_annot_strings.push_back(AidlAnnotation::TypeToString(type));
342 }
343
344 if (supported_annotations.find(annotation.GetType()) == supported_annotations.end()) {
Devin Moore24f68572020-02-26 13:20:59 -0800345 AIDL_ERROR(this) << "'" << annotation.GetName()
346 << "' is not a supported annotation for this node. "
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700347 << "It must be one of: "
348 << android::base::Join(supported_annot_strings, ", ");
Devin Moore24f68572020-02-26 13:20:59 -0800349 return false;
350 }
Andrei Onea9445fc62019-06-27 18:11:59 +0100351 }
Steven Morelanda57d0a62019-07-30 09:41:14 -0700352
Andrei Onea9445fc62019-06-27 18:11:59 +0100353 return true;
354}
355
Jiyong Park68bc77a2018-07-19 19:00:45 +0900356string AidlAnnotatable::ToString() const {
357 vector<string> ret;
358 for (const auto& a : annotations_) {
Daniel Norman37d43dd2019-09-09 17:22:34 -0700359 ret.emplace_back(a.ToString(AidlConstantValueDecorator));
Jiyong Park68bc77a2018-07-19 19:00:45 +0900360 }
361 std::sort(ret.begin(), ret.end());
362 return Join(ret, " ");
363}
364
Steven Moreland46e9da82018-07-27 15:45:29 -0700365AidlTypeSpecifier::AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name,
366 bool is_array,
Jiyong Park1deecc32018-07-17 01:14:41 +0900367 vector<unique_ptr<AidlTypeSpecifier>>* type_params,
Steven Moreland46e9da82018-07-27 15:45:29 -0700368 const string& comments)
369 : AidlAnnotatable(location),
Jeongik Chadf76dc72019-11-28 00:08:47 +0900370 AidlParameterizable<unique_ptr<AidlTypeSpecifier>>(type_params),
Steven Moreland46e9da82018-07-27 15:45:29 -0700371 unresolved_name_(unresolved_name),
Casey Dahlinf7a421c2015-10-05 17:24:28 -0700372 is_array_(is_array),
Jeongik Cha1a7ab642019-07-29 17:31:02 +0900373 comments_(comments),
374 split_name_(Split(unresolved_name, ".")) {}
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700375
Steven Moreland3f658cf2018-08-20 13:40:54 -0700376AidlTypeSpecifier AidlTypeSpecifier::ArrayBase() const {
377 AIDL_FATAL_IF(!is_array_, this);
Jeongik Chadf76dc72019-11-28 00:08:47 +0900378 // Declaring array of generic type cannot happen, it is grammar error.
379 AIDL_FATAL_IF(IsGeneric(), this);
Steven Moreland3f658cf2018-08-20 13:40:54 -0700380
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800381 AidlTypeSpecifier array_base = *this;
382 array_base.is_array_ = false;
383 return array_base;
Steven Moreland3f658cf2018-08-20 13:40:54 -0700384}
385
Jeongik Cha997281d2020-01-16 15:23:59 +0900386bool AidlTypeSpecifier::IsHidden() const {
387 return HasHideComment(GetComments());
388}
389
Jiyong Park1deecc32018-07-17 01:14:41 +0900390string AidlTypeSpecifier::ToString() const {
391 string ret = GetName();
392 if (IsGeneric()) {
393 vector<string> arg_names;
394 for (const auto& ta : GetTypeParameters()) {
Jiyong Parkccf00f82018-07-17 01:39:23 +0900395 arg_names.emplace_back(ta->ToString());
396 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900397 ret += "<" + Join(arg_names, ",") + ">";
Jiyong Parkccf00f82018-07-17 01:39:23 +0900398 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900399 if (IsArray()) {
400 ret += "[]";
401 }
402 return ret;
Jiyong Parkccf00f82018-07-17 01:39:23 +0900403}
404
Jiyong Park02da7422018-07-16 16:00:26 +0900405string AidlTypeSpecifier::Signature() const {
406 string ret = ToString();
407 string annotations = AidlAnnotatable::ToString();
408 if (annotations != "") {
409 ret = annotations + " " + ret;
410 }
411 return ret;
412}
413
Daniel Norman716d3112019-09-10 13:11:56 -0700414bool AidlTypeSpecifier::Resolve(const AidlTypenames& typenames) {
Steven Moreland9731c632019-08-13 10:21:08 -0700415 CHECK(!IsResolved());
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700416 AidlTypenames::ResolvedTypename result = typenames.ResolveTypename(unresolved_name_);
417 if (result.is_resolved) {
418 fully_qualified_name_ = result.canonical_name;
Jeongik Cha1a7ab642019-07-29 17:31:02 +0900419 split_name_ = Split(fully_qualified_name_, ".");
Jiyong Parkccf00f82018-07-17 01:39:23 +0900420 }
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700421 return result.is_resolved;
Casey Dahlin70078e62015-09-30 17:01:30 -0700422}
423
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700424std::set<AidlAnnotation::Type> AidlTypeSpecifier::GetSupportedAnnotations() const {
Devin Moore24f68572020-02-26 13:20:59 -0800425 // kHide and kUnsupportedAppUsage are both method return annotations
426 // which we don't distinguish from other type specifiers.
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700427 return {AidlAnnotation::Type::NULLABLE, AidlAnnotation::Type::UTF8_IN_CPP,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900428 AidlAnnotation::Type::UNSUPPORTED_APP_USAGE, AidlAnnotation::Type::HIDE,
429 AidlAnnotation::Type::JAVA_PASSTHROUGH};
Devin Moore24f68572020-02-26 13:20:59 -0800430}
431
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900432bool AidlTypeSpecifier::CheckValid(const AidlTypenames& typenames) const {
Devin Moore24f68572020-02-26 13:20:59 -0800433 if (!AidlAnnotatable::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100434 return false;
435 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900436 if (IsGeneric()) {
437 const string& type_name = GetName();
Jeongik Chae74c86d2019-12-12 16:54:03 +0900438
439 auto& types = GetTypeParameters();
440 // TODO(b/136048684) Disallow to use primitive types only if it is List or Map.
441 if (type_name == "List" || type_name == "Map") {
442 if (std::any_of(types.begin(), types.end(), [](auto& type_ptr) {
443 return AidlTypenames::IsPrimitiveTypename(type_ptr->GetName());
444 })) {
Devin Moore7b8d5c92020-03-17 14:14:08 -0700445 AIDL_ERROR(this) << "A generic type cannot have any primitive type parameters.";
Jeongik Chae74c86d2019-12-12 16:54:03 +0900446 return false;
447 }
448 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800449 const auto defined_type = typenames.TryGetDefinedType(type_name);
Jeongik Chadf76dc72019-11-28 00:08:47 +0900450 const auto parameterizable =
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800451 defined_type != nullptr ? defined_type->AsParameterizable() : nullptr;
452 const bool is_user_defined_generic_type =
Jeongik Chadf76dc72019-11-28 00:08:47 +0900453 parameterizable != nullptr && parameterizable->IsGeneric();
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800454 const size_t num_params = GetTypeParameters().size();
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900455 if (type_name == "List") {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800456 if (num_params > 1) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900457 AIDL_ERROR(this) << " List cannot have type parameters more than one, but got "
458 << "'" << ToString() << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900459 return false;
460 }
461 } else if (type_name == "Map") {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800462 if (num_params != 0 && num_params != 2) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900463 AIDL_ERROR(this) << "Map must have 0 or 2 type parameters, but got "
464 << "'" << ToString() << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900465 return false;
466 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800467 if (num_params == 2) {
Jeongik Chae48d9942020-01-02 17:39:00 +0900468 const string& key_type = GetTypeParameters()[0]->GetName();
469 if (key_type != "String") {
470 AIDL_ERROR(this) << "The type of key in map must be String, but it is "
471 << "'" << key_type << "'";
472 return false;
473 }
474 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800475 } else if (is_user_defined_generic_type) {
Jeongik Chadf76dc72019-11-28 00:08:47 +0900476 const size_t allowed = parameterizable->GetTypeParameters().size();
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800477 if (num_params != allowed) {
Jeongik Chadf76dc72019-11-28 00:08:47 +0900478 AIDL_ERROR(this) << type_name << " must have " << allowed << " type parameters, but got "
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800479 << num_params;
Jeongik Chadf76dc72019-11-28 00:08:47 +0900480 return false;
481 }
482 } else {
483 AIDL_ERROR(this) << type_name << " is not a generic type.";
484 return false;
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900485 }
486 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900487
Steven Moreland11cb9452020-01-21 16:56:58 -0800488 const bool is_generic_string_list = GetName() == "List" && IsGeneric() &&
489 GetTypeParameters().size() == 1 &&
490 GetTypeParameters()[0]->GetName() == "String";
491 if (IsUtf8InCpp() && (GetName() != "String" && !is_generic_string_list)) {
492 AIDL_ERROR(this) << "@utf8InCpp can only be used on String, String[], and List<String>.";
493 return false;
494 }
495
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900496 if (GetName() == "void") {
497 if (IsArray() || IsNullable() || IsUtf8InCpp()) {
498 AIDL_ERROR(this) << "void type cannot be an array or nullable or utf8 string";
499 return false;
500 }
501 }
502
503 if (IsArray()) {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800504 const auto defined_type = typenames.TryGetDefinedType(GetName());
505 if (defined_type != nullptr && defined_type->AsInterface() != nullptr) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900506 AIDL_ERROR(this) << "Binder type cannot be an array";
507 return false;
508 }
509 }
510
511 if (IsNullable()) {
512 if (AidlTypenames::IsPrimitiveTypename(GetName()) && !IsArray()) {
513 AIDL_ERROR(this) << "Primitive type cannot get nullable annotation";
514 return false;
515 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800516 const auto defined_type = typenames.TryGetDefinedType(GetName());
517 if (defined_type != nullptr && defined_type->AsEnumDeclaration() != nullptr && !IsArray()) {
Daniel Normanee8674f2019-09-20 16:07:00 -0700518 AIDL_ERROR(this) << "Enum type cannot get nullable annotation";
519 return false;
520 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900521 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900522 return true;
523}
524
Steven Moreland860b1942018-08-16 14:59:28 -0700525std::string AidlConstantValueDecorator(const AidlTypeSpecifier& /*type*/,
526 const std::string& raw_value) {
527 return raw_value;
528}
529
Steven Moreland46e9da82018-07-27 15:45:29 -0700530AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
531 AidlTypeSpecifier* type, const std::string& name)
Steven Moreland541788d2020-05-21 22:05:52 +0000532 : AidlVariableDeclaration(location, type, name, AidlConstantValue::Default(*type)) {
533 default_user_specified_ = false;
534}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700535
Steven Moreland46e9da82018-07-27 15:45:29 -0700536AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
537 AidlTypeSpecifier* type, const std::string& name,
538 AidlConstantValue* default_value)
Steven Moreland541788d2020-05-21 22:05:52 +0000539 : AidlNode(location),
540 type_(type),
541 name_(name),
542 default_user_specified_(true),
543 default_value_(default_value) {}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700544
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900545bool AidlVariableDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700546 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900547 valid &= type_->CheckValid(typenames);
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900548
Steven Moreland54be7bd2019-12-05 11:17:53 -0800549 if (type_->GetName() == "void") {
550 AIDL_ERROR(this) << "Declaration " << name_
551 << " is void, but declarations cannot be of void type.";
552 valid = false;
553 }
554
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900555 if (default_value_ == nullptr) return valid;
Steven Moreland25294322018-08-07 18:13:55 -0700556 valid &= default_value_->CheckValid();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700557
Steven Moreland25294322018-08-07 18:13:55 -0700558 if (!valid) return false;
Steven Moreland9ea10e32018-07-19 15:26:09 -0700559
Steven Moreland860b1942018-08-16 14:59:28 -0700560 return !ValueString(AidlConstantValueDecorator).empty();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700561}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700562
563string AidlVariableDeclaration::ToString() const {
Jeongik Cha3271ffa2018-12-04 15:19:20 +0900564 string ret = type_->Signature() + " " + name_;
Steven Moreland541788d2020-05-21 22:05:52 +0000565 if (default_value_ != nullptr && default_user_specified_) {
Steven Moreland860b1942018-08-16 14:59:28 -0700566 ret += " = " + ValueString(AidlConstantValueDecorator);
Steven Moreland9ea10e32018-07-19 15:26:09 -0700567 }
568 return ret;
Steven Moreland5557f1c2018-07-02 13:50:23 -0700569}
570
Jiyong Park02da7422018-07-16 16:00:26 +0900571string AidlVariableDeclaration::Signature() const {
572 return type_->Signature() + " " + name_;
573}
574
Steven Moreland860b1942018-08-16 14:59:28 -0700575std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
Jiyong Parka468e2a2018-08-29 21:25:18 +0900576 if (default_value_ != nullptr) {
Will McVickerd7d18df2019-09-12 13:40:50 -0700577 return default_value_->ValueString(GetType(), decorator);
Jiyong Parka468e2a2018-08-29 21:25:18 +0900578 } else {
579 return "";
580 }
Steven Moreland25294322018-08-07 18:13:55 -0700581}
582
Steven Moreland46e9da82018-07-27 15:45:29 -0700583AidlArgument::AidlArgument(const AidlLocation& location, AidlArgument::Direction direction,
584 AidlTypeSpecifier* type, const std::string& name)
585 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700586 direction_(direction),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700587 direction_specified_(true) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700588
Steven Moreland46e9da82018-07-27 15:45:29 -0700589AidlArgument::AidlArgument(const AidlLocation& location, AidlTypeSpecifier* type,
590 const std::string& name)
591 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700592 direction_(AidlArgument::IN_DIR),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700593 direction_specified_(false) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700594
Jiyong Park02da7422018-07-16 16:00:26 +0900595string AidlArgument::GetDirectionSpecifier() const {
Casey Dahlinc378c992015-09-29 16:50:40 -0700596 string ret;
Casey Dahlinc378c992015-09-29 16:50:40 -0700597 if (direction_specified_) {
598 switch(direction_) {
599 case AidlArgument::IN_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700600 ret += "in";
Casey Dahlinc378c992015-09-29 16:50:40 -0700601 break;
602 case AidlArgument::OUT_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700603 ret += "out";
Casey Dahlinc378c992015-09-29 16:50:40 -0700604 break;
605 case AidlArgument::INOUT_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700606 ret += "inout";
Casey Dahlinc378c992015-09-29 16:50:40 -0700607 break;
608 }
609 }
Casey Dahlinc378c992015-09-29 16:50:40 -0700610 return ret;
611}
Casey Dahlinbc7a50a2015-09-28 19:20:50 -0700612
Jiyong Park02da7422018-07-16 16:00:26 +0900613string AidlArgument::ToString() const {
Devin Mooreeccdb902020-03-24 16:22:40 -0700614 if (direction_specified_) {
615 return GetDirectionSpecifier() + " " + AidlVariableDeclaration::ToString();
616 } else {
617 return AidlVariableDeclaration::ToString();
618 }
Jiyong Park02da7422018-07-16 16:00:26 +0900619}
620
621std::string AidlArgument::Signature() const {
Steven Moreland46e9da82018-07-27 15:45:29 -0700622 class AidlInterface;
623 class AidlInterface;
624 class AidlParcelable;
625 class AidlStructuredParcelable;
626 class AidlParcelable;
627 class AidlStructuredParcelable;
Devin Mooreeccdb902020-03-24 16:22:40 -0700628 if (direction_specified_) {
629 return GetDirectionSpecifier() + " " + AidlVariableDeclaration::Signature();
630 } else {
631 return AidlVariableDeclaration::Signature();
632 }
Jiyong Park02da7422018-07-16 16:00:26 +0900633}
634
Steven Moreland46e9da82018-07-27 15:45:29 -0700635AidlMember::AidlMember(const AidlLocation& location) : AidlNode(location) {}
636
Steven Moreland46e9da82018-07-27 15:45:29 -0700637AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
638 AidlTypeSpecifier* type, const std::string& name,
639 AidlConstantValue* value)
640 : AidlMember(location), type_(type), name_(name), value_(value) {}
Steven Moreland693640b2018-07-19 13:46:27 -0700641
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900642bool AidlConstantDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700643 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900644 valid &= type_->CheckValid(typenames);
Steven Moreland25294322018-08-07 18:13:55 -0700645 valid &= value_->CheckValid();
646 if (!valid) return false;
Steven Moreland693640b2018-07-19 13:46:27 -0700647
Steven Moreland25294322018-08-07 18:13:55 -0700648 const static set<string> kSupportedConstTypes = {"String", "int"};
649 if (kSupportedConstTypes.find(type_->ToString()) == kSupportedConstTypes.end()) {
650 AIDL_ERROR(this) << "Constant of type " << type_->ToString() << " is not supported.";
Steven Moreland693640b2018-07-19 13:46:27 -0700651 return false;
652 }
653
Will McVickerd7d18df2019-09-12 13:40:50 -0700654 return true;
Christopher Wileyd6bdd8d2016-05-03 11:23:13 -0700655}
656
Jiyong Parka428d212018-08-29 22:26:30 +0900657string AidlConstantDeclaration::ToString() const {
658 return "const " + type_->ToString() + " " + name_ + " = " +
659 ValueString(AidlConstantValueDecorator);
660}
661
662string AidlConstantDeclaration::Signature() const {
663 return type_->Signature() + " " + name_;
664}
665
Steven Moreland46e9da82018-07-27 15:45:29 -0700666AidlMethod::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)
669 : AidlMethod(location, oneway, type, name, args, comments, 0, true) {
670 has_id_ = false;
671}
672
673AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
674 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkb034bf02018-07-30 17:44:33 +0900675 const std::string& comments, int id, bool is_user_defined)
Steven Moreland46e9da82018-07-27 15:45:29 -0700676 : AidlMember(location),
677 oneway_(oneway),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700678 comments_(comments),
679 type_(type),
680 name_(name),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700681 arguments_(std::move(*args)),
Jiyong Parkb034bf02018-07-30 17:44:33 +0900682 id_(id),
683 is_user_defined_(is_user_defined) {
Casey Dahlinf4a93112015-10-05 16:58:09 -0700684 has_id_ = true;
685 delete args;
Christopher Wileyad339272015-10-05 19:11:58 -0700686 for (const unique_ptr<AidlArgument>& a : arguments_) {
687 if (a->IsIn()) { in_arguments_.push_back(a.get()); }
688 if (a->IsOut()) { out_arguments_.push_back(a.get()); }
689 }
Casey Dahlinf4a93112015-10-05 16:58:09 -0700690}
691
Jeongik Cha997281d2020-01-16 15:23:59 +0900692bool AidlMethod::IsHidden() const {
693 return HasHideComment(GetComments());
694}
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700695
Jiyong Park02da7422018-07-16 16:00:26 +0900696string AidlMethod::Signature() const {
697 vector<string> arg_signatures;
698 for (const auto& arg : GetArguments()) {
Jiyong Park309668e2018-07-28 16:55:44 +0900699 arg_signatures.emplace_back(arg->GetType().ToString());
Jiyong Park02da7422018-07-16 16:00:26 +0900700 }
Jiyong Park309668e2018-07-28 16:55:44 +0900701 return GetName() + "(" + Join(arg_signatures, ", ") + ")";
702}
703
704string AidlMethod::ToString() const {
705 vector<string> arg_strings;
706 for (const auto& arg : GetArguments()) {
707 arg_strings.emplace_back(arg->Signature());
708 }
Steven Moreland4ee68632018-12-14 15:52:46 -0800709 string ret = (IsOneway() ? "oneway " : "") + GetType().Signature() + " " + GetName() + "(" +
710 Join(arg_strings, ", ") + ")";
Jiyong Parked65bf42018-08-28 15:43:27 +0900711 if (HasId()) {
712 ret += " = " + std::to_string(GetId());
713 }
714 return ret;
Jiyong Park02da7422018-07-16 16:00:26 +0900715}
716
Steven Moreland46e9da82018-07-27 15:45:29 -0700717AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
Jiyong Park18132182020-06-08 20:24:40 +0900718 const std::string& comments, const std::string& package)
719 : AidlAnnotatable(location),
720 name_(name),
721 comments_(comments),
722 package_(package),
723 split_package_(package.empty() ? std::vector<std::string>()
724 : android::base::Split(package, ".")) {}
Steven Moreland787b0432018-07-03 09:00:58 -0700725
Devin Moore24f68572020-02-26 13:20:59 -0800726bool AidlDefinedType::CheckValid(const AidlTypenames& typenames) const {
727 if (!AidlAnnotatable::CheckValid(typenames)) {
728 return false;
729 }
730
731 return true;
732}
733
Jeongik Cha997281d2020-01-16 15:23:59 +0900734bool AidlDefinedType::IsHidden() const {
735 return HasHideComment(GetComments());
736}
737
Steven Moreland787b0432018-07-03 09:00:58 -0700738std::string AidlDefinedType::GetCanonicalName() const {
739 if (package_.empty()) {
740 return GetName();
741 }
742 return GetPackage() + "." + GetName();
743}
744
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800745void AidlDefinedType::DumpHeader(CodeWriter* writer) const {
746 if (this->IsHidden()) {
747 AddHideComment(writer);
748 }
749 DumpAnnotations(writer);
750}
751
Jiyong Park18132182020-06-08 20:24:40 +0900752AidlParcelable::AidlParcelable(const AidlLocation& location, const std::string& name,
753 const std::string& package, const std::string& comments,
Jeongik Chadf76dc72019-11-28 00:08:47 +0900754 const std::string& cpp_header, std::vector<std::string>* type_params)
Jiyong Park18132182020-06-08 20:24:40 +0900755 : AidlDefinedType(location, name, comments, package),
Jeongik Chadf76dc72019-11-28 00:08:47 +0900756 AidlParameterizable<std::string>(type_params),
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800757 cpp_header_(cpp_header) {
758 // Strip off quotation marks if we actually have a cpp header.
759 if (cpp_header_.length() >= 2) {
760 cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
761 }
Casey Dahlin59401da2015-10-09 18:16:45 -0700762}
Jeongik Chadf76dc72019-11-28 00:08:47 +0900763template <typename T>
764AidlParameterizable<T>::AidlParameterizable(const AidlParameterizable& other) {
765 // Copying is not supported if it has type parameters.
766 // It doesn't make a problem because only ArrayBase() makes a copy,
767 // and it can be called only if a type is not generic.
768 CHECK(!other.IsGeneric());
769}
770
771template <typename T>
772bool AidlParameterizable<T>::CheckValid() const {
773 return true;
774};
775
776template <>
777bool AidlParameterizable<std::string>::CheckValid() const {
778 if (!IsGeneric()) {
779 return true;
780 }
781 std::unordered_set<std::string> set(GetTypeParameters().begin(), GetTypeParameters().end());
782 if (set.size() != GetTypeParameters().size()) {
783 AIDL_ERROR(this->AsAidlNode()) << "Every type parameter should be unique.";
784 return false;
785 }
786 return true;
787}
Casey Dahlin59401da2015-10-09 18:16:45 -0700788
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700789std::set<AidlAnnotation::Type> AidlParcelable::GetSupportedAnnotations() const {
Jeongik Cha36f76c32020-07-28 00:25:52 +0900790 return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900791 AidlAnnotation::Type::JAVA_STABLE_PARCELABLE, AidlAnnotation::Type::HIDE,
Jeongik Chad0a10272020-08-06 16:33:36 +0900792 AidlAnnotation::Type::JAVA_PASSTHROUGH, AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE};
Devin Moore24f68572020-02-26 13:20:59 -0800793}
794
795bool AidlParcelable::CheckValid(const AidlTypenames& typenames) const {
796 if (!AidlDefinedType::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100797 return false;
798 }
Jeongik Chadf76dc72019-11-28 00:08:47 +0900799 if (!AidlParameterizable<std::string>::CheckValid()) {
800 return false;
801 }
Jeongik Cha82317dd2019-02-27 20:26:11 +0900802
803 return true;
804}
805
Jeongik Cha997281d2020-01-16 15:23:59 +0900806void AidlParcelable::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800807 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +0900808 writer->Write("parcelable %s ;\n", GetName().c_str());
809}
810
Steven Moreland5557f1c2018-07-02 13:50:23 -0700811AidlStructuredParcelable::AidlStructuredParcelable(
Jiyong Park18132182020-06-08 20:24:40 +0900812 const AidlLocation& location, const std::string& name, const std::string& package,
Jiyong Parka6605ab2018-11-11 14:30:21 +0900813 const std::string& comments, std::vector<std::unique_ptr<AidlVariableDeclaration>>* variables)
814 : AidlParcelable(location, name, package, comments, "" /*cpp_header*/),
Steven Moreland46e9da82018-07-27 15:45:29 -0700815 variables_(std::move(*variables)) {}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700816
Jeongik Cha997281d2020-01-16 15:23:59 +0900817void AidlStructuredParcelable::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800818 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +0900819 writer->Write("parcelable %s {\n", GetName().c_str());
820 writer->Indent();
821 for (const auto& field : GetFields()) {
Jeongik Cha997281d2020-01-16 15:23:59 +0900822 if (field->GetType().IsHidden()) {
823 AddHideComment(writer);
824 }
Jiyong Parka468e2a2018-08-29 21:25:18 +0900825 writer->Write("%s;\n", field->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +0900826 }
827 writer->Dedent();
828 writer->Write("}\n");
829}
830
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700831std::set<AidlAnnotation::Type> AidlStructuredParcelable::GetSupportedAnnotations() const {
Jeongik Cha36f76c32020-07-28 00:25:52 +0900832 return {AidlAnnotation::Type::VINTF_STABILITY,
833 AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
834 AidlAnnotation::Type::HIDE,
835 AidlAnnotation::Type::JAVA_PASSTHROUGH,
836 AidlAnnotation::Type::JAVA_DEBUG,
Jeongik Chad0a10272020-08-06 16:33:36 +0900837 AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE};
Devin Moore24f68572020-02-26 13:20:59 -0800838}
839
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900840bool AidlStructuredParcelable::CheckValid(const AidlTypenames& typenames) const {
Daniel Norman85aed542019-08-21 12:01:14 -0700841 bool success = true;
Devin Moore24f68572020-02-26 13:20:59 -0800842 if (!AidlParcelable::CheckValid(typenames)) {
843 return false;
844 }
Jeongik Cha13066da2020-08-06 15:43:19 +0900845 std::set<std::string> fieldnames;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900846 for (const auto& v : GetFields()) {
Daniel Norman85aed542019-08-21 12:01:14 -0700847 success = success && v->CheckValid(typenames);
Jeongik Cha91180252020-07-31 15:43:11 +0900848 bool duplicated;
Jeongik Chad0a10272020-08-06 16:33:36 +0900849 if (IsJavaOnlyImmutable()) {
850 success = success && typenames.CanBeJavaOnlyImmutable(v->GetType());
Jeongik Cha91180252020-07-31 15:43:11 +0900851 duplicated = !fieldnames.emplace(CapitalizeFirstLetter(v->GetName())).second;
852 } else {
853 duplicated = !fieldnames.emplace(v->GetName()).second;
Jeongik Cha36f76c32020-07-28 00:25:52 +0900854 }
Jeongik Cha13066da2020-08-06 15:43:19 +0900855
Jeongik Cha91180252020-07-31 15:43:11 +0900856 if (duplicated) {
Jeongik Cha13066da2020-08-06 15:43:19 +0900857 AIDL_ERROR(this) << "The parcelable '" << this->GetName() << "' has duplicate field name '"
Jeongik Cha91180252020-07-31 15:43:11 +0900858 << v->GetName() << "'"
Jeongik Chad0a10272020-08-06 16:33:36 +0900859 << (IsJavaOnlyImmutable() ? " after capitalizing the first letter" : "");
Jeongik Cha13066da2020-08-06 15:43:19 +0900860 return false;
861 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900862 }
Jeongik Cha36f76c32020-07-28 00:25:52 +0900863
Daniel Norman85aed542019-08-21 12:01:14 -0700864 return success;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900865}
866
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900867// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -0700868bool AidlTypeSpecifier::LanguageSpecificCheckValid(const AidlTypenames& typenames,
869 Options::Language lang) const {
Steven Moreland0185d9b2020-05-15 23:21:22 +0000870 if (lang == Options::Language::NDK && IsArray() && GetName() == "IBinder") {
871 AIDL_ERROR(this) << "The NDK backend does not support array of IBinder";
872 return false;
873 }
Steven Morelandd59e3172020-05-11 16:42:09 -0700874 if (lang == Options::Language::NDK && IsArray() && IsNullable()) {
Steven Moreland0185d9b2020-05-15 23:21:22 +0000875 if (GetName() == "ParcelFileDescriptor") {
876 AIDL_ERROR(this) << "The NDK backend does not support nullable array of ParcelFileDescriptor";
877 return false;
878 }
879
Steven Morelandd59e3172020-05-11 16:42:09 -0700880 const auto defined_type = typenames.TryGetDefinedType(GetName());
881 if (defined_type != nullptr && defined_type->AsParcelable() != nullptr) {
882 AIDL_ERROR(this) << "The NDK backend does not support nullable array of parcelable";
883 return false;
884 }
885 }
Steven Moreland04b07e12020-01-21 18:11:07 -0800886 if (lang != Options::Language::JAVA) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900887 if (this->GetName() == "List" && !this->IsGeneric()) {
Steven Moreland04b07e12020-01-21 18:11:07 -0800888 AIDL_ERROR(this) << "Currently, only the Java backend supports non-generic List.";
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900889 return false;
890 }
891 }
Steven Morelandc8a4ca82020-01-21 17:50:08 -0800892 if (this->GetName() == "FileDescriptor" && lang == Options::Language::NDK) {
893 AIDL_ERROR(this) << "FileDescriptor isn't supported with the NDK.";
894 return false;
895 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900896 if (this->IsGeneric()) {
897 if (this->GetName() == "List") {
898 if (this->GetTypeParameters().size() != 1) {
899 AIDL_ERROR(this) << "List must have only one type parameter.";
900 return false;
901 }
902 if (lang == Options::Language::CPP) {
Devin Moore2ac52f92020-03-23 15:39:36 -0700903 const string& contained_type = this->GetTypeParameters()[0]->GetName();
904 if (!(contained_type == "String" || contained_type == "IBinder")) {
905 AIDL_ERROR(this) << "List<" << contained_type
906 << "> is not supported. List in cpp supports only String and IBinder.";
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900907 return false;
908 }
Jeongik Cha08ca2182019-11-21 14:01:13 +0900909 } else if (lang == Options::Language::JAVA) {
910 const string& contained_type = this->GetTypeParameters()[0]->GetName();
911 if (AidlTypenames::IsBuiltinTypename(contained_type)) {
912 if (contained_type != "String" && contained_type != "IBinder" &&
913 contained_type != "ParcelFileDescriptor") {
Devin Moore2ac52f92020-03-23 15:39:36 -0700914 AIDL_ERROR(this) << "List<" << contained_type
915 << "> is not supported. List in Java supports only String, IBinder, "
916 "and ParcelFileDescriptor.";
Jeongik Cha08ca2182019-11-21 14:01:13 +0900917 return false;
918 }
919 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900920 }
Jeongik Chabb55b5e2020-01-07 23:11:26 +0900921 }
922 }
Jeongik Chab75a4512020-01-10 13:37:04 +0900923 if (this->GetName() == "Map" || this->GetName() == "CharSequence") {
Jeongik Chabb55b5e2020-01-07 23:11:26 +0900924 if (lang != Options::Language::JAVA) {
Jeongik Chab75a4512020-01-10 13:37:04 +0900925 AIDL_ERROR(this) << "Currently, only Java backend supports " << this->GetName() << ".";
Jeongik Chabb55b5e2020-01-07 23:11:26 +0900926 return false;
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900927 }
928 }
Jeongik Cha08ca2182019-11-21 14:01:13 +0900929 if (lang == Options::Language::JAVA) {
930 const string name = this->GetName();
931 // List[], Map[], CharSequence[] are not supported.
932 if (AidlTypenames::IsBuiltinTypename(name) && this->IsArray()) {
933 if (name == "List" || name == "Map" || name == "CharSequence") {
934 AIDL_ERROR(this) << "List[], Map[], CharSequence[] are not supported.";
935 return false;
936 }
937 }
938 }
939
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900940 return true;
941}
942
943// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -0700944bool AidlParcelable::LanguageSpecificCheckValid(const AidlTypenames& /*typenames*/,
945 Options::Language lang) const {
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900946 if (lang != Options::Language::JAVA) {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800947 const AidlParcelable* unstructured_parcelable = this->AsUnstructuredParcelable();
948 if (unstructured_parcelable != nullptr) {
949 if (unstructured_parcelable->GetCppHeader().empty()) {
950 AIDL_ERROR(unstructured_parcelable)
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900951 << "Unstructured parcelable must have C++ header defined.";
952 return false;
953 }
954 }
955 }
956 return true;
957}
958
959// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -0700960bool AidlStructuredParcelable::LanguageSpecificCheckValid(const AidlTypenames& typenames,
961 Options::Language lang) const {
962 if (!AidlParcelable::LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900963 return false;
964 }
965 for (const auto& v : this->GetFields()) {
Steven Morelandd59e3172020-05-11 16:42:09 -0700966 if (!v->GetType().LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900967 return false;
968 }
969 }
970 return true;
971}
972
Daniel Norman85aed542019-08-21 12:01:14 -0700973AidlEnumerator::AidlEnumerator(const AidlLocation& location, const std::string& name,
Daniel Norman2e4112d2019-10-03 10:22:35 -0700974 AidlConstantValue* value, const std::string& comments)
975 : AidlNode(location), name_(name), value_(value), comments_(comments) {}
Daniel Norman85aed542019-08-21 12:01:14 -0700976
977bool AidlEnumerator::CheckValid(const AidlTypeSpecifier& enum_backing_type) const {
978 if (GetValue() == nullptr) {
979 return false;
980 }
981 if (!GetValue()->CheckValid()) {
982 return false;
983 }
Will McVickerd7d18df2019-09-12 13:40:50 -0700984 if (GetValue()->ValueString(enum_backing_type, AidlConstantValueDecorator).empty()) {
Daniel Norman85aed542019-08-21 12:01:14 -0700985 AIDL_ERROR(this) << "Enumerator type differs from enum backing type.";
986 return false;
987 }
988 return true;
989}
990
991string AidlEnumerator::ValueString(const AidlTypeSpecifier& backing_type,
992 const ConstantValueDecorator& decorator) const {
Will McVickerd7d18df2019-09-12 13:40:50 -0700993 return GetValue()->ValueString(backing_type, decorator);
Daniel Norman85aed542019-08-21 12:01:14 -0700994}
995
996AidlEnumDeclaration::AidlEnumDeclaration(const AidlLocation& location, const std::string& name,
997 std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
Jiyong Park18132182020-06-08 20:24:40 +0900998 const std::string& package, const std::string& comments)
Daniel Norman2e4112d2019-10-03 10:22:35 -0700999 : AidlDefinedType(location, name, comments, package), enumerators_(std::move(*enumerators)) {}
Daniel Norman85aed542019-08-21 12:01:14 -07001000
1001void AidlEnumDeclaration::SetBackingType(std::unique_ptr<const AidlTypeSpecifier> type) {
1002 backing_type_ = std::move(type);
1003}
1004
Steven Moreland59e53e42019-11-26 20:38:08 -08001005bool AidlEnumDeclaration::Autofill() {
Daniel Normanb28684e2019-10-17 15:31:39 -07001006 const AidlEnumerator* previous = nullptr;
1007 for (const auto& enumerator : enumerators_) {
1008 if (enumerator->GetValue() == nullptr) {
1009 if (previous == nullptr) {
Devin Mooredf93ebb2020-03-25 14:03:35 -07001010 enumerator->SetValue(
1011 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "0")));
Daniel Normanb28684e2019-10-17 15:31:39 -07001012 } else {
Steven Moreland59e53e42019-11-26 20:38:08 -08001013 auto prev_value = std::unique_ptr<AidlConstantValue>(
1014 AidlConstantValue::ShallowIntegralCopy(*previous->GetValue()));
1015 if (prev_value == nullptr) {
1016 return false;
1017 }
Daniel Normanb28684e2019-10-17 15:31:39 -07001018 enumerator->SetValue(std::make_unique<AidlBinaryConstExpression>(
Devin Mooredf93ebb2020-03-25 14:03:35 -07001019 GetLocation(), std::move(prev_value), "+",
1020 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "1"))));
Daniel Normanb28684e2019-10-17 15:31:39 -07001021 }
1022 }
1023 previous = enumerator.get();
1024 }
Steven Moreland59e53e42019-11-26 20:38:08 -08001025 return true;
Daniel Normanb28684e2019-10-17 15:31:39 -07001026}
1027
Steven Moreland0cea4aa2020-04-20 21:06:02 -07001028std::set<AidlAnnotation::Type> AidlEnumDeclaration::GetSupportedAnnotations() const {
1029 return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::BACKING,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09001030 AidlAnnotation::Type::HIDE, AidlAnnotation::Type::JAVA_PASSTHROUGH};
Devin Moore24f68572020-02-26 13:20:59 -08001031}
1032
1033bool AidlEnumDeclaration::CheckValid(const AidlTypenames& typenames) const {
1034 if (!AidlDefinedType::CheckValid(typenames)) {
1035 return false;
1036 }
Daniel Norman85aed542019-08-21 12:01:14 -07001037 if (backing_type_ == nullptr) {
1038 AIDL_ERROR(this) << "Enum declaration missing backing type.";
1039 return false;
1040 }
1041 bool success = true;
1042 for (const auto& enumerator : enumerators_) {
1043 success = success && enumerator->CheckValid(GetBackingType());
1044 }
1045 return success;
1046}
1047
Jeongik Cha997281d2020-01-16 15:23:59 +09001048void AidlEnumDeclaration::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -08001049 DumpHeader(writer);
Daniel Norman37d43dd2019-09-09 17:22:34 -07001050 writer->Write("enum %s {\n", GetName().c_str());
Daniel Norman85aed542019-08-21 12:01:14 -07001051 writer->Indent();
1052 for (const auto& enumerator : GetEnumerators()) {
Daniel Norman85aed542019-08-21 12:01:14 -07001053 writer->Write("%s = %s,\n", enumerator->GetName().c_str(),
1054 enumerator->ValueString(GetBackingType(), AidlConstantValueDecorator).c_str());
1055 }
1056 writer->Dedent();
1057 writer->Write("}\n");
1058}
1059
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001060// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -07001061bool AidlInterface::LanguageSpecificCheckValid(const AidlTypenames& typenames,
1062 Options::Language lang) const {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001063 for (const auto& m : this->GetMethods()) {
Steven Morelandd59e3172020-05-11 16:42:09 -07001064 if (!m->GetType().LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001065 return false;
1066 }
1067 for (const auto& arg : m->GetArguments()) {
Steven Morelandd59e3172020-05-11 16:42:09 -07001068 if (!arg->GetType().LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001069 return false;
1070 }
1071 }
1072 }
1073 return true;
1074}
1075
Steven Moreland46e9da82018-07-27 15:45:29 -07001076AidlInterface::AidlInterface(const AidlLocation& location, const std::string& name,
Casey Dahlinfb7da2e2015-10-08 17:26:09 -07001077 const std::string& comments, bool oneway,
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001078 std::vector<std::unique_ptr<AidlMember>>* members,
Jiyong Park18132182020-06-08 20:24:40 +09001079 const std::string& package)
Steven Morelandacd53472018-12-14 10:17:26 -08001080 : AidlDefinedType(location, name, comments, package) {
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001081 for (auto& member : *members) {
1082 AidlMember* local = member.release();
1083 AidlMethod* method = local->AsMethod();
Steven Moreland693640b2018-07-19 13:46:27 -07001084 AidlConstantDeclaration* constant = local->AsConstantDeclaration();
1085
1086 CHECK(method == nullptr || constant == nullptr);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001087
1088 if (method) {
Steven Moreland8c70ba92018-12-17 10:20:31 -08001089 method->ApplyInterfaceOneway(oneway);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001090 methods_.emplace_back(method);
Steven Moreland693640b2018-07-19 13:46:27 -07001091 } else if (constant) {
1092 constants_.emplace_back(constant);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001093 } else {
Steven Moreland46e9da82018-07-27 15:45:29 -07001094 AIDL_FATAL(this) << "Member is neither method nor constant!";
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001095 }
1096 }
1097
1098 delete members;
Casey Dahlinfb7da2e2015-10-08 17:26:09 -07001099}
1100
Jeongik Cha997281d2020-01-16 15:23:59 +09001101void AidlInterface::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -08001102 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +09001103 writer->Write("interface %s {\n", GetName().c_str());
1104 writer->Indent();
1105 for (const auto& method : GetMethods()) {
Jeongik Cha997281d2020-01-16 15:23:59 +09001106 if (method->IsHidden()) {
1107 AddHideComment(writer);
1108 }
Jiyong Park309668e2018-07-28 16:55:44 +09001109 writer->Write("%s;\n", method->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +09001110 }
Jiyong Parka428d212018-08-29 22:26:30 +09001111 for (const auto& constdecl : GetConstantDeclarations()) {
Jeongik Cha997281d2020-01-16 15:23:59 +09001112 if (constdecl->GetType().IsHidden()) {
1113 AddHideComment(writer);
1114 }
Jiyong Parka428d212018-08-29 22:26:30 +09001115 writer->Write("%s;\n", constdecl->ToString().c_str());
1116 }
Jiyong Park02da7422018-07-16 16:00:26 +09001117 writer->Dedent();
1118 writer->Write("}\n");
1119}
1120
Steven Moreland0cea4aa2020-04-20 21:06:02 -07001121std::set<AidlAnnotation::Type> AidlInterface::GetSupportedAnnotations() const {
1122 return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09001123 AidlAnnotation::Type::HIDE, AidlAnnotation::Type::JAVA_PASSTHROUGH};
Devin Moore24f68572020-02-26 13:20:59 -08001124}
1125
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001126bool AidlInterface::CheckValid(const AidlTypenames& typenames) const {
Devin Moore24f68572020-02-26 13:20:59 -08001127 if (!AidlDefinedType::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +01001128 return false;
1129 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001130 // Has to be a pointer due to deleting copy constructor. No idea why.
1131 map<string, const AidlMethod*> method_names;
1132 for (const auto& m : GetMethods()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001133 if (!m->GetType().CheckValid(typenames)) {
1134 return false;
1135 }
1136
Jeongik Cha649e8a72020-03-27 17:47:40 +09001137 // TODO(b/156872582): Support it when ParcelableHolder supports every backend.
1138 if (m->GetType().GetName() == "ParcelableHolder") {
1139 AIDL_ERROR(m) << "ParcelableHolder cannot be a return type";
1140 return false;
1141 }
Steven Morelandacd53472018-12-14 10:17:26 -08001142 if (m->IsOneway() && m->GetType().GetName() != "void") {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001143 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot return a value";
1144 return false;
1145 }
1146
1147 set<string> argument_names;
1148 for (const auto& arg : m->GetArguments()) {
1149 auto it = argument_names.find(arg->GetName());
1150 if (it != argument_names.end()) {
1151 AIDL_ERROR(m) << "method '" << m->GetName() << "' has duplicate argument name '"
1152 << arg->GetName() << "'";
1153 return false;
1154 }
1155 argument_names.insert(arg->GetName());
1156
1157 if (!arg->GetType().CheckValid(typenames)) {
1158 return false;
1159 }
1160
Jeongik Cha649e8a72020-03-27 17:47:40 +09001161 // TODO(b/156872582): Support it when ParcelableHolder supports every backend.
1162 if (arg->GetType().GetName() == "ParcelableHolder") {
1163 AIDL_ERROR(arg) << "ParcelableHolder cannot be an argument type";
1164 return false;
1165 }
Steven Morelandacd53472018-12-14 10:17:26 -08001166 if (m->IsOneway() && arg->IsOut()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001167 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot have out parameters";
1168 return false;
1169 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001170 const bool can_be_out = typenames.CanBeOutParameter(arg->GetType());
1171 if (!arg->DirectionWasSpecified() && can_be_out) {
1172 AIDL_ERROR(arg) << "'" << arg->GetType().ToString()
1173 << "' can be an out type, so you must declare it as in, out, or inout.";
1174 return false;
1175 }
1176
1177 if (arg->GetDirection() != AidlArgument::IN_DIR && !can_be_out) {
1178 AIDL_ERROR(arg) << "'" << arg->ToString() << "' can only be an in parameter.";
1179 return false;
1180 }
1181
1182 // check that the name doesn't match a keyword
Jeongik Cha997281d2020-01-16 15:23:59 +09001183 if (IsJavaKeyword(arg->GetName().c_str())) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001184 AIDL_ERROR(arg) << "Argument name is a Java or aidl keyword";
1185 return false;
1186 }
1187
1188 // Reserve a namespace for internal use
1189 if (android::base::StartsWith(arg->GetName(), "_aidl")) {
1190 AIDL_ERROR(arg) << "Argument name cannot begin with '_aidl'";
1191 return false;
1192 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001193 }
1194
1195 auto it = method_names.find(m->GetName());
1196 // prevent duplicate methods
1197 if (it == method_names.end()) {
1198 method_names[m->GetName()] = m.get();
1199 } else {
1200 AIDL_ERROR(m) << "attempt to redefine method " << m->GetName() << ":";
1201 AIDL_ERROR(it->second) << "previously defined here.";
1202 return false;
1203 }
1204
Paul Trautrimb77048c2020-01-21 16:39:32 +09001205 static set<string> reserved_methods{"asBinder()", "getInterfaceHash()", "getInterfaceVersion()",
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001206 "getTransactionName(int)"};
1207
1208 if (reserved_methods.find(m->Signature()) != reserved_methods.end()) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001209 AIDL_ERROR(m) << " method " << m->Signature() << " is reserved for internal use.";
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001210 return false;
1211 }
1212 }
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001213
1214 bool success = true;
1215 set<string> constant_names;
1216 for (const std::unique_ptr<AidlConstantDeclaration>& constant : GetConstantDeclarations()) {
1217 if (constant_names.count(constant->GetName()) > 0) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001218 AIDL_ERROR(constant) << "Found duplicate constant name '" << constant->GetName() << "'";
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001219 success = false;
1220 }
1221 constant_names.insert(constant->GetName());
1222 success = success && constant->CheckValid(typenames);
1223 }
1224
1225 return success;
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001226}
1227
Steven Moreland46e9da82018-07-27 15:45:29 -07001228AidlImport::AidlImport(const AidlLocation& location, const std::string& needed_class)
1229 : AidlNode(location), needed_class_(needed_class) {}