blob: 9c0dcd041019b123085291f09e61aa4c1ae1d428 [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", {}},
Devin Moorec7e47a32020-08-07 10:55:25 -0700136 {AidlAnnotation::Type::FIXED_SIZE, "FixedSize", {}},
Jiyong Park27fd7fd2020-08-27 16:25:09 +0900137 {AidlAnnotation::Type::DESCRIPTOR, "Descriptor", {{"value", "String"}}},
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900138 };
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700139 return kSchemas;
140}
Jiyong Park68bc77a2018-07-19 19:00:45 +0900141
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700142std::string AidlAnnotation::TypeToString(Type type) {
143 for (const Schema& schema : AllSchemas()) {
144 if (type == schema.type) return schema.name;
145 }
146 AIDL_FATAL(AIDL_LOCATION_HERE) << "Unrecognized type: " << static_cast<size_t>(type);
147 __builtin_unreachable();
148}
Andrei Onea9445fc62019-06-27 18:11:59 +0100149
150AidlAnnotation* AidlAnnotation::Parse(
151 const AidlLocation& location, const string& name,
152 std::map<std::string, std::shared_ptr<AidlConstantValue>>* parameter_list) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700153 const Schema* schema = nullptr;
154 for (const Schema& a_schema : AllSchemas()) {
155 if (a_schema.name == name) {
156 schema = &a_schema;
157 }
158 }
159
160 if (schema == nullptr) {
Jiyong Park68bc77a2018-07-19 19:00:45 +0900161 std::ostringstream stream;
Steven Moreland46e9da82018-07-27 15:45:29 -0700162 stream << "'" << name << "' is not a recognized annotation. ";
Jiyong Park68bc77a2018-07-19 19:00:45 +0900163 stream << "It must be one of:";
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700164 for (const Schema& s : AllSchemas()) {
165 stream << " " << s.name;
Jiyong Park68bc77a2018-07-19 19:00:45 +0900166 }
167 stream << ".";
Steven Moreland46e9da82018-07-27 15:45:29 -0700168 AIDL_ERROR(location) << stream.str();
169 return nullptr;
Jiyong Park68bc77a2018-07-19 19:00:45 +0900170 }
Andrei Onea9445fc62019-06-27 18:11:59 +0100171 if (parameter_list == nullptr) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700172 return new AidlAnnotation(location, *schema, {});
Andrei Onea9445fc62019-06-27 18:11:59 +0100173 }
174
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700175 return new AidlAnnotation(location, *schema, std::move(*parameter_list));
Jiyong Park68bc77a2018-07-19 19:00:45 +0900176}
177
Andrei Onea9445fc62019-06-27 18:11:59 +0100178AidlAnnotation::AidlAnnotation(
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700179 const AidlLocation& location, const Schema& schema,
Andrei Onea9445fc62019-06-27 18:11:59 +0100180 std::map<std::string, std::shared_ptr<AidlConstantValue>>&& parameters)
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700181 : AidlNode(location), schema_(schema), parameters_(std::move(parameters)) {}
Andrei Onea9445fc62019-06-27 18:11:59 +0100182
183bool AidlAnnotation::CheckValid() const {
Andrei Onea9445fc62019-06-27 18:11:59 +0100184 for (const auto& name_and_param : parameters_) {
185 const std::string& param_name = name_and_param.first;
186 const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
Will McVickerd7d18df2019-09-12 13:40:50 -0700187 if (!param->CheckValid()) {
188 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
189 << GetName() << ".";
190 return false;
191 }
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700192 auto parameter_mapping_it = schema_.supported_parameters.find(param_name);
193 if (parameter_mapping_it == schema_.supported_parameters.end()) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100194 std::ostringstream stream;
195 stream << "Parameter " << param_name << " not supported ";
Devin Mooredecaf292020-04-30 09:16:40 -0700196 stream << "for annotation " << GetName() << ". ";
Andrei Onea9445fc62019-06-27 18:11:59 +0100197 stream << "It must be one of:";
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700198 for (const auto& kv : schema_.supported_parameters) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100199 stream << " " << kv.first;
200 }
201 AIDL_ERROR(this) << stream.str();
202 return false;
203 }
204 AidlTypeSpecifier type{AIDL_LOCATION_HERE, parameter_mapping_it->second, false, nullptr, ""};
Will McVickerd7d18df2019-09-12 13:40:50 -0700205 const std::string param_value = param->ValueString(type, AidlConstantValueDecorator);
Andrei Onea9445fc62019-06-27 18:11:59 +0100206 // Assume error on empty string.
207 if (param_value == "") {
208 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
209 << GetName() << ".";
210 return false;
211 }
212 }
213 return true;
214}
215
216std::map<std::string, std::string> AidlAnnotation::AnnotationParams(
217 const ConstantValueDecorator& decorator) const {
218 std::map<std::string, std::string> raw_params;
Andrei Onea9445fc62019-06-27 18:11:59 +0100219 for (const auto& name_and_param : parameters_) {
220 const std::string& param_name = name_and_param.first;
221 const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
Devin Mooredecaf292020-04-30 09:16:40 -0700222 if (schema_.supported_parameters.find(param_name) == schema_.supported_parameters.end()) {
223 std::ostringstream stream;
224 stream << "Parameter " << param_name << " not supported ";
225 stream << "for annotation " << GetName() << ". ";
226 stream << "It must be one of:";
227 for (const auto& kv : schema_.supported_parameters) {
228 stream << " " << kv.first;
229 }
230 AIDL_ERROR(this) << stream.str();
231 continue;
232 }
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700233 AidlTypeSpecifier type{AIDL_LOCATION_HERE, schema_.supported_parameters.at(param_name), false,
234 nullptr, ""};
Will McVickerd7d18df2019-09-12 13:40:50 -0700235 if (!param->CheckValid()) {
236 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
237 << GetName() << ".";
Devin Mooredecaf292020-04-30 09:16:40 -0700238 continue;
Will McVickerd7d18df2019-09-12 13:40:50 -0700239 }
240
241 raw_params.emplace(param_name, param->ValueString(type, decorator));
Andrei Onea9445fc62019-06-27 18:11:59 +0100242 }
243 return raw_params;
244}
Steven Moreland46e9da82018-07-27 15:45:29 -0700245
Daniel Norman37d43dd2019-09-09 17:22:34 -0700246std::string AidlAnnotation::ToString(const ConstantValueDecorator& decorator) const {
247 if (parameters_.empty()) {
248 return "@" + GetName();
249 } else {
250 vector<string> param_strings;
251 for (const auto& [name, value] : AnnotationParams(decorator)) {
252 param_strings.emplace_back(name + "=" + value);
253 }
254 return "@" + GetName() + "(" + Join(param_strings, ", ") + ")";
255 }
256}
257
Andrei Onea9445fc62019-06-27 18:11:59 +0100258static const AidlAnnotation* GetAnnotation(const vector<AidlAnnotation>& annotations,
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700259 AidlAnnotation::Type type) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100260 for (const auto& a : annotations) {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700261 if (a.GetType() == type) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100262 return &a;
263 }
264 }
265 return nullptr;
266}
267
Steven Moreland46e9da82018-07-27 15:45:29 -0700268AidlAnnotatable::AidlAnnotatable(const AidlLocation& location) : AidlNode(location) {}
269
Jiyong Park68bc77a2018-07-19 19:00:45 +0900270bool AidlAnnotatable::IsNullable() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700271 return GetAnnotation(annotations_, AidlAnnotation::Type::NULLABLE);
Jiyong Park68bc77a2018-07-19 19:00:45 +0900272}
273
Jiyong Park68bc77a2018-07-19 19:00:45 +0900274bool AidlAnnotatable::IsUtf8InCpp() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700275 return GetAnnotation(annotations_, AidlAnnotation::Type::UTF8_IN_CPP);
Jiyong Park68bc77a2018-07-19 19:00:45 +0900276}
277
Steven Morelanda57d0a62019-07-30 09:41:14 -0700278bool AidlAnnotatable::IsVintfStability() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700279 return GetAnnotation(annotations_, AidlAnnotation::Type::VINTF_STABILITY);
Steven Morelanda57d0a62019-07-30 09:41:14 -0700280}
281
Jeongik Chad0a10272020-08-06 16:33:36 +0900282bool AidlAnnotatable::IsJavaOnlyImmutable() const {
283 return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE);
Jeongik Cha36f76c32020-07-28 00:25:52 +0900284}
285
Devin Moorec7e47a32020-08-07 10:55:25 -0700286bool AidlAnnotatable::IsFixedSize() const {
287 return GetAnnotation(annotations_, AidlAnnotation::Type::FIXED_SIZE);
288}
289
Andrei Onea9445fc62019-06-27 18:11:59 +0100290const AidlAnnotation* AidlAnnotatable::UnsupportedAppUsage() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700291 return GetAnnotation(annotations_, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE);
Jiyong Parka6605ab2018-11-11 14:30:21 +0900292}
293
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900294const AidlAnnotation* AidlAnnotatable::JavaPassthrough() const {
295 return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_PASSTHROUGH);
296}
297
Daniel Norman716d3112019-09-10 13:11:56 -0700298const AidlTypeSpecifier* AidlAnnotatable::BackingType(const AidlTypenames& typenames) const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700299 auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::BACKING);
Daniel Norman85aed542019-08-21 12:01:14 -0700300 if (annotation != nullptr) {
301 auto annotation_params = annotation->AnnotationParams(AidlConstantValueDecorator);
302 if (auto it = annotation_params.find("type"); it != annotation_params.end()) {
303 const string& type = it->second;
Steven Morelande7d5d082020-05-21 20:29:02 +0000304
305 AIDL_FATAL_IF(type.size() < 2, this) << type;
306 AIDL_FATAL_IF(type[0] != '"', this) << type;
307 AIDL_FATAL_IF(type[type.length() - 1] != '"', this) << type;
308 string unquoted_type = type.substr(1, type.length() - 2);
309
Daniel Norman716d3112019-09-10 13:11:56 -0700310 AidlTypeSpecifier* type_specifier =
Steven Morelande7d5d082020-05-21 20:29:02 +0000311 new AidlTypeSpecifier(AIDL_LOCATION_HERE, unquoted_type, false, nullptr, "");
Daniel Norman716d3112019-09-10 13:11:56 -0700312 type_specifier->Resolve(typenames);
313 return type_specifier;
Daniel Norman85aed542019-08-21 12:01:14 -0700314 }
315 }
316 return nullptr;
317}
318
Jeongik Cha88f95a82020-01-15 13:02:16 +0900319bool AidlAnnotatable::IsStableApiParcelable(Options::Language lang) const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700320 return lang == Options::Language::JAVA &&
321 GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_STABLE_PARCELABLE);
Jeongik Cha82317dd2019-02-27 20:26:11 +0900322}
323
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800324bool AidlAnnotatable::IsHide() const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700325 return GetAnnotation(annotations_, AidlAnnotation::Type::HIDE);
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800326}
327
Jiyong Park43113fb2020-07-20 16:26:19 +0900328bool AidlAnnotatable::IsJavaDebug() const {
329 return GetAnnotation(annotations_, AidlAnnotation::Type::JAVA_DEBUG);
330}
331
Jiyong Park27fd7fd2020-08-27 16:25:09 +0900332std::string AidlAnnotatable::GetDescriptor() const {
333 auto annotation = GetAnnotation(annotations_, AidlAnnotation::Type::DESCRIPTOR);
334 if (annotation != nullptr) {
335 auto params = annotation->AnnotationParams(AidlConstantValueDecorator);
336 if (auto it = params.find("value"); it != params.end()) {
337 const string& value = it->second;
338
339 AIDL_FATAL_IF(value.size() < 2, this) << value;
340 AIDL_FATAL_IF(value[0] != '"', this) << value;
341 AIDL_FATAL_IF(value[value.length() - 1] != '"', this) << value;
342 std::string unquoted_value = value.substr(1, value.length() - 2);
343 return unquoted_value;
344 }
345 }
346 return "";
347}
348
Steven Moreland7e4b9502020-02-20 18:10:42 -0800349void AidlAnnotatable::DumpAnnotations(CodeWriter* writer) const {
350 if (annotations_.empty()) return;
351
352 writer->Write("%s\n", AidlAnnotatable::ToString().c_str());
353}
354
Devin Moore24f68572020-02-26 13:20:59 -0800355bool AidlAnnotatable::CheckValid(const AidlTypenames&) const {
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700356 std::set<AidlAnnotation::Type> supported_annotations = GetSupportedAnnotations();
Andrei Onea9445fc62019-06-27 18:11:59 +0100357 for (const auto& annotation : GetAnnotations()) {
358 if (!annotation.CheckValid()) {
359 return false;
360 }
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700361
362 std::vector<std::string> supported_annot_strings;
363 for (AidlAnnotation::Type type : supported_annotations) {
364 supported_annot_strings.push_back(AidlAnnotation::TypeToString(type));
365 }
366
367 if (supported_annotations.find(annotation.GetType()) == supported_annotations.end()) {
Devin Moore24f68572020-02-26 13:20:59 -0800368 AIDL_ERROR(this) << "'" << annotation.GetName()
369 << "' is not a supported annotation for this node. "
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700370 << "It must be one of: "
371 << android::base::Join(supported_annot_strings, ", ");
Devin Moore24f68572020-02-26 13:20:59 -0800372 return false;
373 }
Andrei Onea9445fc62019-06-27 18:11:59 +0100374 }
Steven Morelanda57d0a62019-07-30 09:41:14 -0700375
Andrei Onea9445fc62019-06-27 18:11:59 +0100376 return true;
377}
378
Jiyong Park68bc77a2018-07-19 19:00:45 +0900379string AidlAnnotatable::ToString() const {
380 vector<string> ret;
381 for (const auto& a : annotations_) {
Daniel Norman37d43dd2019-09-09 17:22:34 -0700382 ret.emplace_back(a.ToString(AidlConstantValueDecorator));
Jiyong Park68bc77a2018-07-19 19:00:45 +0900383 }
384 std::sort(ret.begin(), ret.end());
385 return Join(ret, " ");
386}
387
Steven Moreland46e9da82018-07-27 15:45:29 -0700388AidlTypeSpecifier::AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name,
389 bool is_array,
Jiyong Park1deecc32018-07-17 01:14:41 +0900390 vector<unique_ptr<AidlTypeSpecifier>>* type_params,
Steven Moreland46e9da82018-07-27 15:45:29 -0700391 const string& comments)
392 : AidlAnnotatable(location),
Jeongik Chadf76dc72019-11-28 00:08:47 +0900393 AidlParameterizable<unique_ptr<AidlTypeSpecifier>>(type_params),
Steven Moreland46e9da82018-07-27 15:45:29 -0700394 unresolved_name_(unresolved_name),
Casey Dahlinf7a421c2015-10-05 17:24:28 -0700395 is_array_(is_array),
Jeongik Cha1a7ab642019-07-29 17:31:02 +0900396 comments_(comments),
397 split_name_(Split(unresolved_name, ".")) {}
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700398
Steven Moreland3f658cf2018-08-20 13:40:54 -0700399AidlTypeSpecifier AidlTypeSpecifier::ArrayBase() const {
400 AIDL_FATAL_IF(!is_array_, this);
Jeongik Chadf76dc72019-11-28 00:08:47 +0900401 // Declaring array of generic type cannot happen, it is grammar error.
402 AIDL_FATAL_IF(IsGeneric(), this);
Steven Moreland3f658cf2018-08-20 13:40:54 -0700403
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800404 AidlTypeSpecifier array_base = *this;
405 array_base.is_array_ = false;
406 return array_base;
Steven Moreland3f658cf2018-08-20 13:40:54 -0700407}
408
Jeongik Cha997281d2020-01-16 15:23:59 +0900409bool AidlTypeSpecifier::IsHidden() const {
410 return HasHideComment(GetComments());
411}
412
Jiyong Park1deecc32018-07-17 01:14:41 +0900413string AidlTypeSpecifier::ToString() const {
414 string ret = GetName();
415 if (IsGeneric()) {
416 vector<string> arg_names;
417 for (const auto& ta : GetTypeParameters()) {
Jiyong Parkccf00f82018-07-17 01:39:23 +0900418 arg_names.emplace_back(ta->ToString());
419 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900420 ret += "<" + Join(arg_names, ",") + ">";
Jiyong Parkccf00f82018-07-17 01:39:23 +0900421 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900422 if (IsArray()) {
423 ret += "[]";
424 }
425 return ret;
Jiyong Parkccf00f82018-07-17 01:39:23 +0900426}
427
Jiyong Park02da7422018-07-16 16:00:26 +0900428string AidlTypeSpecifier::Signature() const {
429 string ret = ToString();
430 string annotations = AidlAnnotatable::ToString();
431 if (annotations != "") {
432 ret = annotations + " " + ret;
433 }
434 return ret;
435}
436
Daniel Norman716d3112019-09-10 13:11:56 -0700437bool AidlTypeSpecifier::Resolve(const AidlTypenames& typenames) {
Steven Moreland9731c632019-08-13 10:21:08 -0700438 CHECK(!IsResolved());
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700439 AidlTypenames::ResolvedTypename result = typenames.ResolveTypename(unresolved_name_);
440 if (result.is_resolved) {
441 fully_qualified_name_ = result.canonical_name;
Jeongik Cha1a7ab642019-07-29 17:31:02 +0900442 split_name_ = Split(fully_qualified_name_, ".");
Jiyong Parkccf00f82018-07-17 01:39:23 +0900443 }
Steven Morelandcb1bcd72020-04-29 16:30:35 -0700444 return result.is_resolved;
Casey Dahlin70078e62015-09-30 17:01:30 -0700445}
446
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700447std::set<AidlAnnotation::Type> AidlTypeSpecifier::GetSupportedAnnotations() const {
Devin Moore24f68572020-02-26 13:20:59 -0800448 // kHide and kUnsupportedAppUsage are both method return annotations
449 // which we don't distinguish from other type specifiers.
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700450 return {AidlAnnotation::Type::NULLABLE, AidlAnnotation::Type::UTF8_IN_CPP,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900451 AidlAnnotation::Type::UNSUPPORTED_APP_USAGE, AidlAnnotation::Type::HIDE,
452 AidlAnnotation::Type::JAVA_PASSTHROUGH};
Devin Moore24f68572020-02-26 13:20:59 -0800453}
454
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900455bool AidlTypeSpecifier::CheckValid(const AidlTypenames& typenames) const {
Devin Moore24f68572020-02-26 13:20:59 -0800456 if (!AidlAnnotatable::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100457 return false;
458 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900459 if (IsGeneric()) {
460 const string& type_name = GetName();
Jeongik Chae74c86d2019-12-12 16:54:03 +0900461
462 auto& types = GetTypeParameters();
463 // TODO(b/136048684) Disallow to use primitive types only if it is List or Map.
464 if (type_name == "List" || type_name == "Map") {
465 if (std::any_of(types.begin(), types.end(), [](auto& type_ptr) {
466 return AidlTypenames::IsPrimitiveTypename(type_ptr->GetName());
467 })) {
Devin Moore7b8d5c92020-03-17 14:14:08 -0700468 AIDL_ERROR(this) << "A generic type cannot have any primitive type parameters.";
Jeongik Chae74c86d2019-12-12 16:54:03 +0900469 return false;
470 }
471 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800472 const auto defined_type = typenames.TryGetDefinedType(type_name);
Jeongik Chadf76dc72019-11-28 00:08:47 +0900473 const auto parameterizable =
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800474 defined_type != nullptr ? defined_type->AsParameterizable() : nullptr;
475 const bool is_user_defined_generic_type =
Jeongik Chadf76dc72019-11-28 00:08:47 +0900476 parameterizable != nullptr && parameterizable->IsGeneric();
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800477 const size_t num_params = GetTypeParameters().size();
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900478 if (type_name == "List") {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800479 if (num_params > 1) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900480 AIDL_ERROR(this) << " List cannot have type parameters more than one, but got "
481 << "'" << ToString() << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900482 return false;
483 }
484 } else if (type_name == "Map") {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800485 if (num_params != 0 && num_params != 2) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900486 AIDL_ERROR(this) << "Map must have 0 or 2 type parameters, but got "
487 << "'" << ToString() << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900488 return false;
489 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800490 if (num_params == 2) {
Jeongik Chae48d9942020-01-02 17:39:00 +0900491 const string& key_type = GetTypeParameters()[0]->GetName();
492 if (key_type != "String") {
493 AIDL_ERROR(this) << "The type of key in map must be String, but it is "
494 << "'" << key_type << "'";
495 return false;
496 }
497 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800498 } else if (is_user_defined_generic_type) {
Jeongik Chadf76dc72019-11-28 00:08:47 +0900499 const size_t allowed = parameterizable->GetTypeParameters().size();
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800500 if (num_params != allowed) {
Jeongik Chadf76dc72019-11-28 00:08:47 +0900501 AIDL_ERROR(this) << type_name << " must have " << allowed << " type parameters, but got "
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800502 << num_params;
Jeongik Chadf76dc72019-11-28 00:08:47 +0900503 return false;
504 }
505 } else {
506 AIDL_ERROR(this) << type_name << " is not a generic type.";
507 return false;
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900508 }
509 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900510
Steven Moreland11cb9452020-01-21 16:56:58 -0800511 const bool is_generic_string_list = GetName() == "List" && IsGeneric() &&
512 GetTypeParameters().size() == 1 &&
513 GetTypeParameters()[0]->GetName() == "String";
514 if (IsUtf8InCpp() && (GetName() != "String" && !is_generic_string_list)) {
515 AIDL_ERROR(this) << "@utf8InCpp can only be used on String, String[], and List<String>.";
516 return false;
517 }
518
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900519 if (GetName() == "void") {
520 if (IsArray() || IsNullable() || IsUtf8InCpp()) {
521 AIDL_ERROR(this) << "void type cannot be an array or nullable or utf8 string";
522 return false;
523 }
524 }
525
526 if (IsArray()) {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800527 const auto defined_type = typenames.TryGetDefinedType(GetName());
528 if (defined_type != nullptr && defined_type->AsInterface() != nullptr) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900529 AIDL_ERROR(this) << "Binder type cannot be an array";
530 return false;
531 }
532 }
533
534 if (IsNullable()) {
535 if (AidlTypenames::IsPrimitiveTypename(GetName()) && !IsArray()) {
536 AIDL_ERROR(this) << "Primitive type cannot get nullable annotation";
537 return false;
538 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800539 const auto defined_type = typenames.TryGetDefinedType(GetName());
540 if (defined_type != nullptr && defined_type->AsEnumDeclaration() != nullptr && !IsArray()) {
Daniel Normanee8674f2019-09-20 16:07:00 -0700541 AIDL_ERROR(this) << "Enum type cannot get nullable annotation";
542 return false;
543 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900544 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900545 return true;
546}
547
Steven Moreland860b1942018-08-16 14:59:28 -0700548std::string AidlConstantValueDecorator(const AidlTypeSpecifier& /*type*/,
549 const std::string& raw_value) {
550 return raw_value;
551}
552
Steven Moreland46e9da82018-07-27 15:45:29 -0700553AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
554 AidlTypeSpecifier* type, const std::string& name)
Steven Moreland541788d2020-05-21 22:05:52 +0000555 : AidlVariableDeclaration(location, type, name, AidlConstantValue::Default(*type)) {
556 default_user_specified_ = false;
557}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700558
Steven Moreland46e9da82018-07-27 15:45:29 -0700559AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
560 AidlTypeSpecifier* type, const std::string& name,
561 AidlConstantValue* default_value)
Steven Moreland541788d2020-05-21 22:05:52 +0000562 : AidlNode(location),
563 type_(type),
564 name_(name),
565 default_user_specified_(true),
566 default_value_(default_value) {}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700567
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900568bool AidlVariableDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700569 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900570 valid &= type_->CheckValid(typenames);
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900571
Steven Moreland54be7bd2019-12-05 11:17:53 -0800572 if (type_->GetName() == "void") {
573 AIDL_ERROR(this) << "Declaration " << name_
574 << " is void, but declarations cannot be of void type.";
575 valid = false;
576 }
577
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900578 if (default_value_ == nullptr) return valid;
Steven Moreland25294322018-08-07 18:13:55 -0700579 valid &= default_value_->CheckValid();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700580
Steven Moreland25294322018-08-07 18:13:55 -0700581 if (!valid) return false;
Steven Moreland9ea10e32018-07-19 15:26:09 -0700582
Steven Moreland860b1942018-08-16 14:59:28 -0700583 return !ValueString(AidlConstantValueDecorator).empty();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700584}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700585
586string AidlVariableDeclaration::ToString() const {
Jeongik Cha3271ffa2018-12-04 15:19:20 +0900587 string ret = type_->Signature() + " " + name_;
Steven Moreland541788d2020-05-21 22:05:52 +0000588 if (default_value_ != nullptr && default_user_specified_) {
Steven Moreland860b1942018-08-16 14:59:28 -0700589 ret += " = " + ValueString(AidlConstantValueDecorator);
Steven Moreland9ea10e32018-07-19 15:26:09 -0700590 }
591 return ret;
Steven Moreland5557f1c2018-07-02 13:50:23 -0700592}
593
Jiyong Park02da7422018-07-16 16:00:26 +0900594string AidlVariableDeclaration::Signature() const {
595 return type_->Signature() + " " + name_;
596}
597
Steven Moreland860b1942018-08-16 14:59:28 -0700598std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
Jiyong Parka468e2a2018-08-29 21:25:18 +0900599 if (default_value_ != nullptr) {
Will McVickerd7d18df2019-09-12 13:40:50 -0700600 return default_value_->ValueString(GetType(), decorator);
Jiyong Parka468e2a2018-08-29 21:25:18 +0900601 } else {
602 return "";
603 }
Steven Moreland25294322018-08-07 18:13:55 -0700604}
605
Steven Moreland46e9da82018-07-27 15:45:29 -0700606AidlArgument::AidlArgument(const AidlLocation& location, AidlArgument::Direction direction,
607 AidlTypeSpecifier* type, const std::string& name)
608 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700609 direction_(direction),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700610 direction_specified_(true) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700611
Steven Moreland46e9da82018-07-27 15:45:29 -0700612AidlArgument::AidlArgument(const AidlLocation& location, AidlTypeSpecifier* type,
613 const std::string& name)
614 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700615 direction_(AidlArgument::IN_DIR),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700616 direction_specified_(false) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700617
Jiyong Park02da7422018-07-16 16:00:26 +0900618string AidlArgument::GetDirectionSpecifier() const {
Casey Dahlinc378c992015-09-29 16:50:40 -0700619 string ret;
Casey Dahlinc378c992015-09-29 16:50:40 -0700620 if (direction_specified_) {
621 switch(direction_) {
622 case AidlArgument::IN_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700623 ret += "in";
Casey Dahlinc378c992015-09-29 16:50:40 -0700624 break;
625 case AidlArgument::OUT_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700626 ret += "out";
Casey Dahlinc378c992015-09-29 16:50:40 -0700627 break;
628 case AidlArgument::INOUT_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700629 ret += "inout";
Casey Dahlinc378c992015-09-29 16:50:40 -0700630 break;
631 }
632 }
Casey Dahlinc378c992015-09-29 16:50:40 -0700633 return ret;
634}
Casey Dahlinbc7a50a2015-09-28 19:20:50 -0700635
Jiyong Park02da7422018-07-16 16:00:26 +0900636string AidlArgument::ToString() const {
Devin Mooreeccdb902020-03-24 16:22:40 -0700637 if (direction_specified_) {
638 return GetDirectionSpecifier() + " " + AidlVariableDeclaration::ToString();
639 } else {
640 return AidlVariableDeclaration::ToString();
641 }
Jiyong Park02da7422018-07-16 16:00:26 +0900642}
643
644std::string AidlArgument::Signature() const {
Steven Moreland46e9da82018-07-27 15:45:29 -0700645 class AidlInterface;
646 class AidlInterface;
647 class AidlParcelable;
648 class AidlStructuredParcelable;
649 class AidlParcelable;
650 class AidlStructuredParcelable;
Devin Mooreeccdb902020-03-24 16:22:40 -0700651 if (direction_specified_) {
652 return GetDirectionSpecifier() + " " + AidlVariableDeclaration::Signature();
653 } else {
654 return AidlVariableDeclaration::Signature();
655 }
Jiyong Park02da7422018-07-16 16:00:26 +0900656}
657
Steven Moreland46e9da82018-07-27 15:45:29 -0700658AidlMember::AidlMember(const AidlLocation& location) : AidlNode(location) {}
659
Steven Moreland46e9da82018-07-27 15:45:29 -0700660AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
661 AidlTypeSpecifier* type, const std::string& name,
662 AidlConstantValue* value)
663 : AidlMember(location), type_(type), name_(name), value_(value) {}
Steven Moreland693640b2018-07-19 13:46:27 -0700664
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900665bool AidlConstantDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700666 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900667 valid &= type_->CheckValid(typenames);
Steven Moreland25294322018-08-07 18:13:55 -0700668 valid &= value_->CheckValid();
669 if (!valid) return false;
Steven Moreland693640b2018-07-19 13:46:27 -0700670
Steven Moreland25294322018-08-07 18:13:55 -0700671 const static set<string> kSupportedConstTypes = {"String", "int"};
672 if (kSupportedConstTypes.find(type_->ToString()) == kSupportedConstTypes.end()) {
673 AIDL_ERROR(this) << "Constant of type " << type_->ToString() << " is not supported.";
Steven Moreland693640b2018-07-19 13:46:27 -0700674 return false;
675 }
676
Will McVickerd7d18df2019-09-12 13:40:50 -0700677 return true;
Christopher Wileyd6bdd8d2016-05-03 11:23:13 -0700678}
679
Jiyong Parka428d212018-08-29 22:26:30 +0900680string AidlConstantDeclaration::ToString() const {
681 return "const " + type_->ToString() + " " + name_ + " = " +
682 ValueString(AidlConstantValueDecorator);
683}
684
685string AidlConstantDeclaration::Signature() const {
686 return type_->Signature() + " " + name_;
687}
688
Steven Moreland46e9da82018-07-27 15:45:29 -0700689AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
690 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkb034bf02018-07-30 17:44:33 +0900691 const std::string& comments)
692 : AidlMethod(location, oneway, type, name, args, comments, 0, true) {
693 has_id_ = false;
694}
695
696AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
697 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkb034bf02018-07-30 17:44:33 +0900698 const std::string& comments, int id, bool is_user_defined)
Steven Moreland46e9da82018-07-27 15:45:29 -0700699 : AidlMember(location),
700 oneway_(oneway),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700701 comments_(comments),
702 type_(type),
703 name_(name),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700704 arguments_(std::move(*args)),
Jiyong Parkb034bf02018-07-30 17:44:33 +0900705 id_(id),
706 is_user_defined_(is_user_defined) {
Casey Dahlinf4a93112015-10-05 16:58:09 -0700707 has_id_ = true;
708 delete args;
Christopher Wileyad339272015-10-05 19:11:58 -0700709 for (const unique_ptr<AidlArgument>& a : arguments_) {
710 if (a->IsIn()) { in_arguments_.push_back(a.get()); }
711 if (a->IsOut()) { out_arguments_.push_back(a.get()); }
712 }
Casey Dahlinf4a93112015-10-05 16:58:09 -0700713}
714
Jeongik Cha997281d2020-01-16 15:23:59 +0900715bool AidlMethod::IsHidden() const {
716 return HasHideComment(GetComments());
717}
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700718
Jiyong Park02da7422018-07-16 16:00:26 +0900719string AidlMethod::Signature() const {
720 vector<string> arg_signatures;
721 for (const auto& arg : GetArguments()) {
Jiyong Park309668e2018-07-28 16:55:44 +0900722 arg_signatures.emplace_back(arg->GetType().ToString());
Jiyong Park02da7422018-07-16 16:00:26 +0900723 }
Jiyong Park309668e2018-07-28 16:55:44 +0900724 return GetName() + "(" + Join(arg_signatures, ", ") + ")";
725}
726
727string AidlMethod::ToString() const {
728 vector<string> arg_strings;
729 for (const auto& arg : GetArguments()) {
730 arg_strings.emplace_back(arg->Signature());
731 }
Steven Moreland4ee68632018-12-14 15:52:46 -0800732 string ret = (IsOneway() ? "oneway " : "") + GetType().Signature() + " " + GetName() + "(" +
733 Join(arg_strings, ", ") + ")";
Jiyong Parked65bf42018-08-28 15:43:27 +0900734 if (HasId()) {
735 ret += " = " + std::to_string(GetId());
736 }
737 return ret;
Jiyong Park02da7422018-07-16 16:00:26 +0900738}
739
Steven Moreland46e9da82018-07-27 15:45:29 -0700740AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
Jiyong Park18132182020-06-08 20:24:40 +0900741 const std::string& comments, const std::string& package)
742 : AidlAnnotatable(location),
743 name_(name),
744 comments_(comments),
745 package_(package),
746 split_package_(package.empty() ? std::vector<std::string>()
747 : android::base::Split(package, ".")) {}
Steven Moreland787b0432018-07-03 09:00:58 -0700748
Devin Moore24f68572020-02-26 13:20:59 -0800749bool AidlDefinedType::CheckValid(const AidlTypenames& typenames) const {
750 if (!AidlAnnotatable::CheckValid(typenames)) {
751 return false;
752 }
753
754 return true;
755}
756
Jeongik Cha997281d2020-01-16 15:23:59 +0900757bool AidlDefinedType::IsHidden() const {
758 return HasHideComment(GetComments());
759}
760
Steven Moreland787b0432018-07-03 09:00:58 -0700761std::string AidlDefinedType::GetCanonicalName() const {
762 if (package_.empty()) {
763 return GetName();
764 }
765 return GetPackage() + "." + GetName();
766}
767
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800768void AidlDefinedType::DumpHeader(CodeWriter* writer) const {
769 if (this->IsHidden()) {
770 AddHideComment(writer);
771 }
772 DumpAnnotations(writer);
773}
774
Jiyong Park18132182020-06-08 20:24:40 +0900775AidlParcelable::AidlParcelable(const AidlLocation& location, const std::string& name,
776 const std::string& package, const std::string& comments,
Jeongik Chadf76dc72019-11-28 00:08:47 +0900777 const std::string& cpp_header, std::vector<std::string>* type_params)
Jiyong Park18132182020-06-08 20:24:40 +0900778 : AidlDefinedType(location, name, comments, package),
Jeongik Chadf76dc72019-11-28 00:08:47 +0900779 AidlParameterizable<std::string>(type_params),
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800780 cpp_header_(cpp_header) {
781 // Strip off quotation marks if we actually have a cpp header.
782 if (cpp_header_.length() >= 2) {
783 cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
784 }
Casey Dahlin59401da2015-10-09 18:16:45 -0700785}
Jeongik Chadf76dc72019-11-28 00:08:47 +0900786template <typename T>
787AidlParameterizable<T>::AidlParameterizable(const AidlParameterizable& other) {
788 // Copying is not supported if it has type parameters.
789 // It doesn't make a problem because only ArrayBase() makes a copy,
790 // and it can be called only if a type is not generic.
791 CHECK(!other.IsGeneric());
792}
793
794template <typename T>
795bool AidlParameterizable<T>::CheckValid() const {
796 return true;
797};
798
799template <>
800bool AidlParameterizable<std::string>::CheckValid() const {
801 if (!IsGeneric()) {
802 return true;
803 }
804 std::unordered_set<std::string> set(GetTypeParameters().begin(), GetTypeParameters().end());
805 if (set.size() != GetTypeParameters().size()) {
806 AIDL_ERROR(this->AsAidlNode()) << "Every type parameter should be unique.";
807 return false;
808 }
809 return true;
810}
Casey Dahlin59401da2015-10-09 18:16:45 -0700811
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700812std::set<AidlAnnotation::Type> AidlParcelable::GetSupportedAnnotations() const {
Jeongik Cha36f76c32020-07-28 00:25:52 +0900813 return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +0900814 AidlAnnotation::Type::JAVA_STABLE_PARCELABLE, AidlAnnotation::Type::HIDE,
Jeongik Chad0a10272020-08-06 16:33:36 +0900815 AidlAnnotation::Type::JAVA_PASSTHROUGH, AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE};
Devin Moore24f68572020-02-26 13:20:59 -0800816}
817
818bool AidlParcelable::CheckValid(const AidlTypenames& typenames) const {
819 if (!AidlDefinedType::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100820 return false;
821 }
Jeongik Chadf76dc72019-11-28 00:08:47 +0900822 if (!AidlParameterizable<std::string>::CheckValid()) {
823 return false;
824 }
Jeongik Cha82317dd2019-02-27 20:26:11 +0900825
826 return true;
827}
828
Jeongik Cha997281d2020-01-16 15:23:59 +0900829void AidlParcelable::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800830 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +0900831 writer->Write("parcelable %s ;\n", GetName().c_str());
832}
833
Steven Moreland5557f1c2018-07-02 13:50:23 -0700834AidlStructuredParcelable::AidlStructuredParcelable(
Jiyong Park18132182020-06-08 20:24:40 +0900835 const AidlLocation& location, const std::string& name, const std::string& package,
Jiyong Parka6605ab2018-11-11 14:30:21 +0900836 const std::string& comments, std::vector<std::unique_ptr<AidlVariableDeclaration>>* variables)
837 : AidlParcelable(location, name, package, comments, "" /*cpp_header*/),
Steven Moreland46e9da82018-07-27 15:45:29 -0700838 variables_(std::move(*variables)) {}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700839
Jeongik Cha997281d2020-01-16 15:23:59 +0900840void AidlStructuredParcelable::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800841 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +0900842 writer->Write("parcelable %s {\n", GetName().c_str());
843 writer->Indent();
844 for (const auto& field : GetFields()) {
Jeongik Cha997281d2020-01-16 15:23:59 +0900845 if (field->GetType().IsHidden()) {
846 AddHideComment(writer);
847 }
Jiyong Parka468e2a2018-08-29 21:25:18 +0900848 writer->Write("%s;\n", field->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +0900849 }
850 writer->Dedent();
851 writer->Write("}\n");
852}
853
Steven Moreland0cea4aa2020-04-20 21:06:02 -0700854std::set<AidlAnnotation::Type> AidlStructuredParcelable::GetSupportedAnnotations() const {
Jeongik Cha36f76c32020-07-28 00:25:52 +0900855 return {AidlAnnotation::Type::VINTF_STABILITY,
856 AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
857 AidlAnnotation::Type::HIDE,
858 AidlAnnotation::Type::JAVA_PASSTHROUGH,
859 AidlAnnotation::Type::JAVA_DEBUG,
Devin Moorec7e47a32020-08-07 10:55:25 -0700860 AidlAnnotation::Type::JAVA_ONLY_IMMUTABLE,
861 AidlAnnotation::Type::FIXED_SIZE};
Devin Moore24f68572020-02-26 13:20:59 -0800862}
863
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900864bool AidlStructuredParcelable::CheckValid(const AidlTypenames& typenames) const {
Daniel Norman85aed542019-08-21 12:01:14 -0700865 bool success = true;
Devin Moore24f68572020-02-26 13:20:59 -0800866 if (!AidlParcelable::CheckValid(typenames)) {
867 return false;
868 }
Jeongik Cha13066da2020-08-06 15:43:19 +0900869 std::set<std::string> fieldnames;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900870 for (const auto& v : GetFields()) {
Daniel Norman85aed542019-08-21 12:01:14 -0700871 success = success && v->CheckValid(typenames);
Jeongik Cha91180252020-07-31 15:43:11 +0900872 bool duplicated;
Jeongik Chad0a10272020-08-06 16:33:36 +0900873 if (IsJavaOnlyImmutable()) {
874 success = success && typenames.CanBeJavaOnlyImmutable(v->GetType());
Jeongik Cha91180252020-07-31 15:43:11 +0900875 duplicated = !fieldnames.emplace(CapitalizeFirstLetter(v->GetName())).second;
876 } else {
Devin Moorec7e47a32020-08-07 10:55:25 -0700877 if (IsFixedSize()) {
878 success = success && typenames.CanBeFixedSize(v->GetType());
879 if (!success) {
880 AIDL_ERROR(v) << "The @FixedSize parcelable '" << this->GetName() << "' has a "
881 << "non-fixed size field named " << v->GetName() << ".";
882 }
883 }
Jeongik Cha91180252020-07-31 15:43:11 +0900884 duplicated = !fieldnames.emplace(v->GetName()).second;
Jeongik Cha36f76c32020-07-28 00:25:52 +0900885 }
Jeongik Cha13066da2020-08-06 15:43:19 +0900886
Jeongik Cha91180252020-07-31 15:43:11 +0900887 if (duplicated) {
Jeongik Cha13066da2020-08-06 15:43:19 +0900888 AIDL_ERROR(this) << "The parcelable '" << this->GetName() << "' has duplicate field name '"
Jeongik Cha91180252020-07-31 15:43:11 +0900889 << v->GetName() << "'"
Jeongik Chad0a10272020-08-06 16:33:36 +0900890 << (IsJavaOnlyImmutable() ? " after capitalizing the first letter" : "");
Jeongik Cha13066da2020-08-06 15:43:19 +0900891 return false;
892 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900893 }
Jeongik Cha36f76c32020-07-28 00:25:52 +0900894
Daniel Norman85aed542019-08-21 12:01:14 -0700895 return success;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900896}
897
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900898// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -0700899bool AidlTypeSpecifier::LanguageSpecificCheckValid(const AidlTypenames& typenames,
900 Options::Language lang) const {
Steven Moreland0185d9b2020-05-15 23:21:22 +0000901 if (lang == Options::Language::NDK && IsArray() && GetName() == "IBinder") {
902 AIDL_ERROR(this) << "The NDK backend does not support array of IBinder";
903 return false;
904 }
Steven Morelandd59e3172020-05-11 16:42:09 -0700905 if (lang == Options::Language::NDK && IsArray() && IsNullable()) {
Steven Moreland0185d9b2020-05-15 23:21:22 +0000906 if (GetName() == "ParcelFileDescriptor") {
907 AIDL_ERROR(this) << "The NDK backend does not support nullable array of ParcelFileDescriptor";
908 return false;
909 }
910
Steven Morelandd59e3172020-05-11 16:42:09 -0700911 const auto defined_type = typenames.TryGetDefinedType(GetName());
912 if (defined_type != nullptr && defined_type->AsParcelable() != nullptr) {
913 AIDL_ERROR(this) << "The NDK backend does not support nullable array of parcelable";
914 return false;
915 }
916 }
Steven Morelandc8a4ca82020-01-21 17:50:08 -0800917 if (this->GetName() == "FileDescriptor" && lang == Options::Language::NDK) {
918 AIDL_ERROR(this) << "FileDescriptor isn't supported with the NDK.";
919 return false;
920 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900921 if (this->IsGeneric()) {
922 if (this->GetName() == "List") {
923 if (this->GetTypeParameters().size() != 1) {
924 AIDL_ERROR(this) << "List must have only one type parameter.";
925 return false;
926 }
927 if (lang == Options::Language::CPP) {
Devin Moore2ac52f92020-03-23 15:39:36 -0700928 const string& contained_type = this->GetTypeParameters()[0]->GetName();
929 if (!(contained_type == "String" || contained_type == "IBinder")) {
930 AIDL_ERROR(this) << "List<" << contained_type
931 << "> is not supported. List in cpp supports only String and IBinder.";
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900932 return false;
933 }
Jeongik Cha08ca2182019-11-21 14:01:13 +0900934 } else if (lang == Options::Language::JAVA) {
935 const string& contained_type = this->GetTypeParameters()[0]->GetName();
936 if (AidlTypenames::IsBuiltinTypename(contained_type)) {
937 if (contained_type != "String" && contained_type != "IBinder" &&
938 contained_type != "ParcelFileDescriptor") {
Devin Moore2ac52f92020-03-23 15:39:36 -0700939 AIDL_ERROR(this) << "List<" << contained_type
940 << "> is not supported. List in Java supports only String, IBinder, "
941 "and ParcelFileDescriptor.";
Jeongik Cha08ca2182019-11-21 14:01:13 +0900942 return false;
943 }
944 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900945 }
Jeongik Chabb55b5e2020-01-07 23:11:26 +0900946 }
947 }
Devin Moore6a01ca12020-08-28 10:24:19 -0700948
949 if (this->IsArray()) {
950 if (this->GetName() == "List" || this->GetName() == "Map" ||
951 this->GetName() == "CharSequence") {
952 AIDL_ERROR(this) << this->GetName() << "[] is not supported.";
Jeongik Chabb55b5e2020-01-07 23:11:26 +0900953 return false;
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900954 }
955 }
Devin Moore6a01ca12020-08-28 10:24:19 -0700956
957 if (lang != Options::Language::JAVA) {
958 if (this->GetName() == "List" && !this->IsGeneric()) {
959 AIDL_ERROR(this) << "Currently, only the Java backend supports non-generic List.";
960 return false;
961 }
962 if (this->GetName() == "Map" || this->GetName() == "CharSequence") {
963 AIDL_ERROR(this) << "Currently, only Java backend supports " << this->GetName() << ".";
964 return false;
Jeongik Cha08ca2182019-11-21 14:01:13 +0900965 }
966 }
967
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900968 return true;
969}
970
971// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -0700972bool AidlParcelable::LanguageSpecificCheckValid(const AidlTypenames& /*typenames*/,
973 Options::Language lang) const {
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900974 if (lang != Options::Language::JAVA) {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800975 const AidlParcelable* unstructured_parcelable = this->AsUnstructuredParcelable();
976 if (unstructured_parcelable != nullptr) {
977 if (unstructured_parcelable->GetCppHeader().empty()) {
978 AIDL_ERROR(unstructured_parcelable)
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900979 << "Unstructured parcelable must have C++ header defined.";
980 return false;
981 }
982 }
983 }
984 return true;
985}
986
987// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -0700988bool AidlStructuredParcelable::LanguageSpecificCheckValid(const AidlTypenames& typenames,
989 Options::Language lang) const {
990 if (!AidlParcelable::LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900991 return false;
992 }
993 for (const auto& v : this->GetFields()) {
Steven Morelandd59e3172020-05-11 16:42:09 -0700994 if (!v->GetType().LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900995 return false;
996 }
997 }
998 return true;
999}
1000
Daniel Norman85aed542019-08-21 12:01:14 -07001001AidlEnumerator::AidlEnumerator(const AidlLocation& location, const std::string& name,
Daniel Norman2e4112d2019-10-03 10:22:35 -07001002 AidlConstantValue* value, const std::string& comments)
1003 : AidlNode(location), name_(name), value_(value), comments_(comments) {}
Daniel Norman85aed542019-08-21 12:01:14 -07001004
1005bool AidlEnumerator::CheckValid(const AidlTypeSpecifier& enum_backing_type) const {
1006 if (GetValue() == nullptr) {
1007 return false;
1008 }
1009 if (!GetValue()->CheckValid()) {
1010 return false;
1011 }
Will McVickerd7d18df2019-09-12 13:40:50 -07001012 if (GetValue()->ValueString(enum_backing_type, AidlConstantValueDecorator).empty()) {
Daniel Norman85aed542019-08-21 12:01:14 -07001013 AIDL_ERROR(this) << "Enumerator type differs from enum backing type.";
1014 return false;
1015 }
1016 return true;
1017}
1018
1019string AidlEnumerator::ValueString(const AidlTypeSpecifier& backing_type,
1020 const ConstantValueDecorator& decorator) const {
Will McVickerd7d18df2019-09-12 13:40:50 -07001021 return GetValue()->ValueString(backing_type, decorator);
Daniel Norman85aed542019-08-21 12:01:14 -07001022}
1023
1024AidlEnumDeclaration::AidlEnumDeclaration(const AidlLocation& location, const std::string& name,
1025 std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
Jiyong Park18132182020-06-08 20:24:40 +09001026 const std::string& package, const std::string& comments)
Daniel Norman2e4112d2019-10-03 10:22:35 -07001027 : AidlDefinedType(location, name, comments, package), enumerators_(std::move(*enumerators)) {}
Daniel Norman85aed542019-08-21 12:01:14 -07001028
1029void AidlEnumDeclaration::SetBackingType(std::unique_ptr<const AidlTypeSpecifier> type) {
1030 backing_type_ = std::move(type);
1031}
1032
Steven Moreland59e53e42019-11-26 20:38:08 -08001033bool AidlEnumDeclaration::Autofill() {
Daniel Normanb28684e2019-10-17 15:31:39 -07001034 const AidlEnumerator* previous = nullptr;
1035 for (const auto& enumerator : enumerators_) {
1036 if (enumerator->GetValue() == nullptr) {
1037 if (previous == nullptr) {
Devin Mooredf93ebb2020-03-25 14:03:35 -07001038 enumerator->SetValue(
1039 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "0")));
Daniel Normanb28684e2019-10-17 15:31:39 -07001040 } else {
Steven Moreland59e53e42019-11-26 20:38:08 -08001041 auto prev_value = std::unique_ptr<AidlConstantValue>(
1042 AidlConstantValue::ShallowIntegralCopy(*previous->GetValue()));
1043 if (prev_value == nullptr) {
1044 return false;
1045 }
Daniel Normanb28684e2019-10-17 15:31:39 -07001046 enumerator->SetValue(std::make_unique<AidlBinaryConstExpression>(
Devin Mooredf93ebb2020-03-25 14:03:35 -07001047 GetLocation(), std::move(prev_value), "+",
1048 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "1"))));
Daniel Normanb28684e2019-10-17 15:31:39 -07001049 }
1050 }
1051 previous = enumerator.get();
1052 }
Steven Moreland59e53e42019-11-26 20:38:08 -08001053 return true;
Daniel Normanb28684e2019-10-17 15:31:39 -07001054}
1055
Steven Moreland0cea4aa2020-04-20 21:06:02 -07001056std::set<AidlAnnotation::Type> AidlEnumDeclaration::GetSupportedAnnotations() const {
1057 return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::BACKING,
Jiyong Parkbf5fd5c2020-06-05 19:48:05 +09001058 AidlAnnotation::Type::HIDE, AidlAnnotation::Type::JAVA_PASSTHROUGH};
Devin Moore24f68572020-02-26 13:20:59 -08001059}
1060
1061bool AidlEnumDeclaration::CheckValid(const AidlTypenames& typenames) const {
1062 if (!AidlDefinedType::CheckValid(typenames)) {
1063 return false;
1064 }
Daniel Norman85aed542019-08-21 12:01:14 -07001065 if (backing_type_ == nullptr) {
1066 AIDL_ERROR(this) << "Enum declaration missing backing type.";
1067 return false;
1068 }
1069 bool success = true;
1070 for (const auto& enumerator : enumerators_) {
1071 success = success && enumerator->CheckValid(GetBackingType());
1072 }
1073 return success;
1074}
1075
Jeongik Cha997281d2020-01-16 15:23:59 +09001076void AidlEnumDeclaration::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -08001077 DumpHeader(writer);
Daniel Norman37d43dd2019-09-09 17:22:34 -07001078 writer->Write("enum %s {\n", GetName().c_str());
Daniel Norman85aed542019-08-21 12:01:14 -07001079 writer->Indent();
1080 for (const auto& enumerator : GetEnumerators()) {
Daniel Norman85aed542019-08-21 12:01:14 -07001081 writer->Write("%s = %s,\n", enumerator->GetName().c_str(),
1082 enumerator->ValueString(GetBackingType(), AidlConstantValueDecorator).c_str());
1083 }
1084 writer->Dedent();
1085 writer->Write("}\n");
1086}
1087
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001088// TODO: we should treat every backend all the same in future.
Steven Morelandd59e3172020-05-11 16:42:09 -07001089bool AidlInterface::LanguageSpecificCheckValid(const AidlTypenames& typenames,
1090 Options::Language lang) const {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001091 for (const auto& m : this->GetMethods()) {
Steven Morelandd59e3172020-05-11 16:42:09 -07001092 if (!m->GetType().LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001093 return false;
1094 }
1095 for (const auto& arg : m->GetArguments()) {
Steven Morelandd59e3172020-05-11 16:42:09 -07001096 if (!arg->GetType().LanguageSpecificCheckValid(typenames, lang)) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001097 return false;
1098 }
1099 }
1100 }
1101 return true;
1102}
1103
Steven Moreland46e9da82018-07-27 15:45:29 -07001104AidlInterface::AidlInterface(const AidlLocation& location, const std::string& name,
Casey Dahlinfb7da2e2015-10-08 17:26:09 -07001105 const std::string& comments, bool oneway,
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001106 std::vector<std::unique_ptr<AidlMember>>* members,
Jiyong Park18132182020-06-08 20:24:40 +09001107 const std::string& package)
Steven Morelandacd53472018-12-14 10:17:26 -08001108 : AidlDefinedType(location, name, comments, package) {
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001109 for (auto& member : *members) {
1110 AidlMember* local = member.release();
1111 AidlMethod* method = local->AsMethod();
Steven Moreland693640b2018-07-19 13:46:27 -07001112 AidlConstantDeclaration* constant = local->AsConstantDeclaration();
1113
1114 CHECK(method == nullptr || constant == nullptr);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001115
1116 if (method) {
Steven Moreland8c70ba92018-12-17 10:20:31 -08001117 method->ApplyInterfaceOneway(oneway);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001118 methods_.emplace_back(method);
Steven Moreland693640b2018-07-19 13:46:27 -07001119 } else if (constant) {
1120 constants_.emplace_back(constant);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001121 } else {
Steven Moreland46e9da82018-07-27 15:45:29 -07001122 AIDL_FATAL(this) << "Member is neither method nor constant!";
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001123 }
1124 }
1125
1126 delete members;
Casey Dahlinfb7da2e2015-10-08 17:26:09 -07001127}
1128
Jeongik Cha997281d2020-01-16 15:23:59 +09001129void AidlInterface::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -08001130 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +09001131 writer->Write("interface %s {\n", GetName().c_str());
1132 writer->Indent();
1133 for (const auto& method : GetMethods()) {
Jeongik Cha997281d2020-01-16 15:23:59 +09001134 if (method->IsHidden()) {
1135 AddHideComment(writer);
1136 }
Jiyong Park309668e2018-07-28 16:55:44 +09001137 writer->Write("%s;\n", method->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +09001138 }
Jiyong Parka428d212018-08-29 22:26:30 +09001139 for (const auto& constdecl : GetConstantDeclarations()) {
Jeongik Cha997281d2020-01-16 15:23:59 +09001140 if (constdecl->GetType().IsHidden()) {
1141 AddHideComment(writer);
1142 }
Jiyong Parka428d212018-08-29 22:26:30 +09001143 writer->Write("%s;\n", constdecl->ToString().c_str());
1144 }
Jiyong Park02da7422018-07-16 16:00:26 +09001145 writer->Dedent();
1146 writer->Write("}\n");
1147}
1148
Steven Moreland0cea4aa2020-04-20 21:06:02 -07001149std::set<AidlAnnotation::Type> AidlInterface::GetSupportedAnnotations() const {
1150 return {AidlAnnotation::Type::VINTF_STABILITY, AidlAnnotation::Type::UNSUPPORTED_APP_USAGE,
Jiyong Park27fd7fd2020-08-27 16:25:09 +09001151 AidlAnnotation::Type::HIDE, AidlAnnotation::Type::JAVA_PASSTHROUGH,
1152 AidlAnnotation::Type::DESCRIPTOR};
Devin Moore24f68572020-02-26 13:20:59 -08001153}
1154
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001155bool AidlInterface::CheckValid(const AidlTypenames& typenames) const {
Devin Moore24f68572020-02-26 13:20:59 -08001156 if (!AidlDefinedType::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +01001157 return false;
1158 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001159 // Has to be a pointer due to deleting copy constructor. No idea why.
1160 map<string, const AidlMethod*> method_names;
1161 for (const auto& m : GetMethods()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001162 if (!m->GetType().CheckValid(typenames)) {
1163 return false;
1164 }
1165
Jeongik Cha649e8a72020-03-27 17:47:40 +09001166 // TODO(b/156872582): Support it when ParcelableHolder supports every backend.
1167 if (m->GetType().GetName() == "ParcelableHolder") {
1168 AIDL_ERROR(m) << "ParcelableHolder cannot be a return type";
1169 return false;
1170 }
Steven Morelandacd53472018-12-14 10:17:26 -08001171 if (m->IsOneway() && m->GetType().GetName() != "void") {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001172 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot return a value";
1173 return false;
1174 }
1175
1176 set<string> argument_names;
1177 for (const auto& arg : m->GetArguments()) {
1178 auto it = argument_names.find(arg->GetName());
1179 if (it != argument_names.end()) {
1180 AIDL_ERROR(m) << "method '" << m->GetName() << "' has duplicate argument name '"
1181 << arg->GetName() << "'";
1182 return false;
1183 }
1184 argument_names.insert(arg->GetName());
1185
1186 if (!arg->GetType().CheckValid(typenames)) {
1187 return false;
1188 }
1189
Jeongik Cha649e8a72020-03-27 17:47:40 +09001190 // TODO(b/156872582): Support it when ParcelableHolder supports every backend.
1191 if (arg->GetType().GetName() == "ParcelableHolder") {
1192 AIDL_ERROR(arg) << "ParcelableHolder cannot be an argument type";
1193 return false;
1194 }
Steven Morelandacd53472018-12-14 10:17:26 -08001195 if (m->IsOneway() && arg->IsOut()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001196 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot have out parameters";
1197 return false;
1198 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001199 const bool can_be_out = typenames.CanBeOutParameter(arg->GetType());
1200 if (!arg->DirectionWasSpecified() && can_be_out) {
1201 AIDL_ERROR(arg) << "'" << arg->GetType().ToString()
1202 << "' can be an out type, so you must declare it as in, out, or inout.";
1203 return false;
1204 }
1205
1206 if (arg->GetDirection() != AidlArgument::IN_DIR && !can_be_out) {
1207 AIDL_ERROR(arg) << "'" << arg->ToString() << "' can only be an in parameter.";
1208 return false;
1209 }
1210
1211 // check that the name doesn't match a keyword
Jeongik Cha997281d2020-01-16 15:23:59 +09001212 if (IsJavaKeyword(arg->GetName().c_str())) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001213 AIDL_ERROR(arg) << "Argument name is a Java or aidl keyword";
1214 return false;
1215 }
1216
1217 // Reserve a namespace for internal use
1218 if (android::base::StartsWith(arg->GetName(), "_aidl")) {
1219 AIDL_ERROR(arg) << "Argument name cannot begin with '_aidl'";
1220 return false;
1221 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001222 }
1223
1224 auto it = method_names.find(m->GetName());
1225 // prevent duplicate methods
1226 if (it == method_names.end()) {
1227 method_names[m->GetName()] = m.get();
1228 } else {
1229 AIDL_ERROR(m) << "attempt to redefine method " << m->GetName() << ":";
1230 AIDL_ERROR(it->second) << "previously defined here.";
1231 return false;
1232 }
1233
Paul Trautrimb77048c2020-01-21 16:39:32 +09001234 static set<string> reserved_methods{"asBinder()", "getInterfaceHash()", "getInterfaceVersion()",
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001235 "getTransactionName(int)"};
1236
1237 if (reserved_methods.find(m->Signature()) != reserved_methods.end()) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001238 AIDL_ERROR(m) << " method " << m->Signature() << " is reserved for internal use.";
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001239 return false;
1240 }
1241 }
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001242
1243 bool success = true;
1244 set<string> constant_names;
1245 for (const std::unique_ptr<AidlConstantDeclaration>& constant : GetConstantDeclarations()) {
1246 if (constant_names.count(constant->GetName()) > 0) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001247 AIDL_ERROR(constant) << "Found duplicate constant name '" << constant->GetName() << "'";
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001248 success = false;
1249 }
1250 constant_names.insert(constant->GetName());
1251 success = success && constant->CheckValid(typenames);
1252 }
1253
1254 return success;
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001255}
1256
Jiyong Park27fd7fd2020-08-27 16:25:09 +09001257std::string AidlInterface::GetDescriptor() const {
1258 std::string annotatedDescriptor = AidlAnnotatable::GetDescriptor();
1259 if (annotatedDescriptor != "") {
1260 return annotatedDescriptor;
1261 }
1262 return GetCanonicalName();
1263}
1264
Steven Moreland46e9da82018-07-27 15:45:29 -07001265AidlImport::AidlImport(const AidlLocation& location, const std::string& needed_class)
1266 : AidlNode(location), needed_class_(needed_class) {}