blob: da80c385536a0daad5751876504837b9ff2348f1 [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"
Christopher Wileyf690be52015-09-14 15:19:10 -070019
Adam Lesinskiffa16862014-01-23 18:17:42 -080020#include <stdio.h>
Adam Lesinskiffa16862014-01-23 18:17:42 -080021#include <stdlib.h>
Christopher Wiley4a2884b2015-10-07 11:27:45 -070022#include <string.h>
Jiyong Park68bc77a2018-07-19 19:00:45 +090023#include <algorithm>
Jiyong Park1deecc32018-07-17 01:14:41 +090024#include <iostream>
Jiyong Park68bc77a2018-07-19 19:00:45 +090025#include <set>
26#include <sstream>
Casey Dahlindd691812015-09-09 17:59:06 -070027#include <string>
Jiyong Park1deecc32018-07-17 01:14:41 +090028#include <utility>
Christopher Wileyf690be52015-09-14 15:19:10 -070029
Steven Moreland1c4ba202018-08-09 10:49:54 -070030#include <android-base/parsedouble.h>
Roshan Pius9d7810a2016-07-28 08:57:50 -070031#include <android-base/parseint.h>
Elliott Hughes0a620672015-12-04 13:53:18 -080032#include <android-base/strings.h>
Christopher Wileyd76067c2015-10-19 17:00:13 -070033
Dan Willemsen609ba6d2019-12-30 10:44:00 -080034#include "aidl_language_y-module.h"
Christopher Wiley4a2884b2015-10-07 11:27:45 -070035#include "logging.h"
Adam Lesinskiffa16862014-01-23 18:17:42 -080036
Will McVickerd7d18df2019-09-12 13:40:50 -070037#include "aidl.h"
38
Casey Dahlin07b9dde2015-09-10 19:13:49 -070039#ifdef _WIN32
40int isatty(int fd)
41{
42 return (fd == 0);
43}
44#endif
45
Christopher Wiley4a2884b2015-10-07 11:27:45 -070046using android::aidl::IoDelegate;
Christopher Wileyd76067c2015-10-19 17:00:13 -070047using android::base::Join;
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -080048using android::base::Split;
Casey Dahlindd691812015-09-09 17:59:06 -070049using std::cerr;
Jiyong Park1deecc32018-07-17 01:14:41 +090050using std::pair;
Jiyong Park68bc77a2018-07-19 19:00:45 +090051using std::set;
Christopher Wiley4a2884b2015-10-07 11:27:45 -070052using std::string;
53using std::unique_ptr;
Jiyong Parkccf00f82018-07-17 01:39:23 +090054using std::vector;
Adam Lesinskiffa16862014-01-23 18:17:42 -080055
Jeongik Cha047c5ee2019-08-07 23:16:49 +090056namespace {
Jeongik Cha997281d2020-01-16 15:23:59 +090057bool IsJavaKeyword(const char* str) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +090058 static const std::vector<std::string> kJavaKeywords{
59 "abstract", "assert", "boolean", "break", "byte", "case", "catch",
60 "char", "class", "const", "continue", "default", "do", "double",
61 "else", "enum", "extends", "final", "finally", "float", "for",
62 "goto", "if", "implements", "import", "instanceof", "int", "interface",
63 "long", "native", "new", "package", "private", "protected", "public",
64 "return", "short", "static", "strictfp", "super", "switch", "synchronized",
65 "this", "throw", "throws", "transient", "try", "void", "volatile",
66 "while", "true", "false", "null",
67 };
68 return std::find(kJavaKeywords.begin(), kJavaKeywords.end(), str) != kJavaKeywords.end();
69}
Jeongik Cha997281d2020-01-16 15:23:59 +090070
71void AddHideComment(CodeWriter* writer) {
72 writer->Write("/* @hide */\n");
73}
74
75inline bool HasHideComment(const std::string& comment) {
76 return std::regex_search(comment, std::regex("@hide\\b"));
77}
Jeongik Cha047c5ee2019-08-07 23:16:49 +090078} // namespace
79
Casey Dahlindd691812015-09-09 17:59:06 -070080void yylex_init(void **);
81void yylex_destroy(void *);
82void yyset_in(FILE *f, void *);
Casey Dahline2507492015-09-14 17:11:20 -070083int yyparse(Parser*);
Christopher Wiley4a2884b2015-10-07 11:27:45 -070084YY_BUFFER_STATE yy_scan_buffer(char *, size_t, void *);
Casey Dahlin89d44842015-09-24 18:45:54 -070085void yy_delete_buffer(YY_BUFFER_STATE, void *);
Casey Dahlindd691812015-09-09 17:59:06 -070086
Casey Dahlincdbbc8c2015-10-14 15:31:04 -070087AidlToken::AidlToken(const std::string& text, const std::string& comments)
88 : text_(text),
89 comments_(comments) {}
Casey Dahlin98a544b2015-10-14 14:22:55 -070090
Devin Mooredf93ebb2020-03-25 14:03:35 -070091AidlLocation::AidlLocation(const std::string& file, Point begin, Point end, Source source)
92 : file_(file), begin_(begin), end_(end), source_(source) {}
Steven Moreland46e9da82018-07-27 15:45:29 -070093
94std::ostream& operator<<(std::ostream& os, const AidlLocation& l) {
95 os << l.file_ << ":" << l.begin_.line << "." << l.begin_.column << "-";
96 if (l.begin_.line != l.end_.line) {
97 os << l.end_.line << ".";
98 }
99 os << l.end_.column;
100 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 Morelandb0d15a52020-03-31 14:03:47 -0700118AidlErrorLog::AidlErrorLog(bool fatal) : os_(std::cerr), fatal_(fatal) {
Steven Morelandfdb57cd2020-01-08 20:03:30 -0800119 sHadError = true;
120
Steven Moreland92c55f12018-07-31 14:08:37 -0700121 os_ << "ERROR: ";
122}
123
Steven Morelandb0d15a52020-03-31 14:03:47 -0700124AidlErrorLog::AidlErrorLog(bool fatal, const AidlLocation& location) : AidlErrorLog(fatal) {
Devin Mooredf93ebb2020-03-25 14:03:35 -0700125 CHECK(!location.IsInternal())
126 << "Logging an internal location should not happen. Offending location: " << location;
127 os_ << location << ": ";
128}
129
Steven Morelandb0d15a52020-03-31 14:03:47 -0700130bool AidlErrorLog::sHadError = false;
Steven Morelandfdb57cd2020-01-08 20:03:30 -0800131
Jiyong Park68bc77a2018-07-19 19:00:45 +0900132static const string kNullable("nullable");
Jiyong Park68bc77a2018-07-19 19:00:45 +0900133static const string kUtf8InCpp("utf8InCpp");
Steven Morelanda57d0a62019-07-30 09:41:14 -0700134static const string kVintfStability("VintfStability");
Jiyong Parka6605ab2018-11-11 14:30:21 +0900135static const string kUnsupportedAppUsage("UnsupportedAppUsage");
Jeongik Cha88f95a82020-01-15 13:02:16 +0900136static const string kJavaStableParcelable("JavaOnlyStableParcelable");
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800137static const string kHide("Hide");
Daniel Norman85aed542019-08-21 12:01:14 -0700138static const string kBacking("Backing");
Jiyong Park68bc77a2018-07-19 19:00:45 +0900139
Andrei Onea9445fc62019-06-27 18:11:59 +0100140static const std::map<string, std::map<std::string, std::string>> kAnnotationParameters{
141 {kNullable, {}},
142 {kUtf8InCpp, {}},
Steven Morelanda57d0a62019-07-30 09:41:14 -0700143 {kVintfStability, {}},
Andrei Onea9445fc62019-06-27 18:11:59 +0100144 {kUnsupportedAppUsage,
145 {{"expectedSignature", "String"},
146 {"implicitMember", "String"},
147 {"maxTargetSdk", "int"},
148 {"publicAlternatives", "String"},
149 {"trackingBug", "long"}}},
Jeongik Cha88f95a82020-01-15 13:02:16 +0900150 {kJavaStableParcelable, {}},
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800151 {kHide, {}},
Daniel Norman85aed542019-08-21 12:01:14 -0700152 {kBacking, {{"type", "String"}}}};
Andrei Onea9445fc62019-06-27 18:11:59 +0100153
154AidlAnnotation* AidlAnnotation::Parse(
155 const AidlLocation& location, const string& name,
156 std::map<std::string, std::shared_ptr<AidlConstantValue>>* parameter_list) {
Steven Moreland29db3022019-07-30 12:37:17 -0700157 if (kAnnotationParameters.find(name) == kAnnotationParameters.end()) {
Jiyong Park68bc77a2018-07-19 19:00:45 +0900158 std::ostringstream stream;
Steven Moreland46e9da82018-07-27 15:45:29 -0700159 stream << "'" << name << "' is not a recognized annotation. ";
Jiyong Park68bc77a2018-07-19 19:00:45 +0900160 stream << "It must be one of:";
Steven Moreland29db3022019-07-30 12:37:17 -0700161 for (const auto& kv : kAnnotationParameters) {
162 stream << " " << kv.first;
Jiyong Park68bc77a2018-07-19 19:00:45 +0900163 }
164 stream << ".";
Steven Moreland46e9da82018-07-27 15:45:29 -0700165 AIDL_ERROR(location) << stream.str();
166 return nullptr;
Jiyong Park68bc77a2018-07-19 19:00:45 +0900167 }
Andrei Onea9445fc62019-06-27 18:11:59 +0100168 if (parameter_list == nullptr) {
169 return new AidlAnnotation(location, name);
170 }
171
172 return new AidlAnnotation(location, name, std::move(*parameter_list));
Jiyong Park68bc77a2018-07-19 19:00:45 +0900173}
174
Steven Moreland46e9da82018-07-27 15:45:29 -0700175AidlAnnotation::AidlAnnotation(const AidlLocation& location, const string& name)
Andrei Onea9445fc62019-06-27 18:11:59 +0100176 : AidlAnnotation(location, name, {}) {}
177
178AidlAnnotation::AidlAnnotation(
179 const AidlLocation& location, const string& name,
180 std::map<std::string, std::shared_ptr<AidlConstantValue>>&& parameters)
181 : AidlNode(location), name_(name), parameters_(std::move(parameters)) {}
182
183bool AidlAnnotation::CheckValid() const {
184 auto supported_params_iterator = kAnnotationParameters.find(GetName());
185 if (supported_params_iterator == kAnnotationParameters.end()) {
186 AIDL_ERROR(this) << GetName() << " annotation does not have any supported parameters.";
187 return false;
188 }
189 const auto& supported_params = supported_params_iterator->second;
190 for (const auto& name_and_param : parameters_) {
191 const std::string& param_name = name_and_param.first;
192 const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
Will McVickerd7d18df2019-09-12 13:40:50 -0700193 if (!param->CheckValid()) {
194 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
195 << GetName() << ".";
196 return false;
197 }
Andrei Onea9445fc62019-06-27 18:11:59 +0100198 auto parameter_mapping_it = supported_params.find(param_name);
199 if (parameter_mapping_it == supported_params.end()) {
200 std::ostringstream stream;
201 stream << "Parameter " << param_name << " not supported ";
202 stream << "for annotation " << GetName() << ".";
203 stream << "It must be one of:";
204 for (const auto& kv : supported_params) {
205 stream << " " << kv.first;
206 }
207 AIDL_ERROR(this) << stream.str();
208 return false;
209 }
210 AidlTypeSpecifier type{AIDL_LOCATION_HERE, parameter_mapping_it->second, false, nullptr, ""};
Will McVickerd7d18df2019-09-12 13:40:50 -0700211 const std::string param_value = param->ValueString(type, AidlConstantValueDecorator);
Andrei Onea9445fc62019-06-27 18:11:59 +0100212 // Assume error on empty string.
213 if (param_value == "") {
214 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
215 << GetName() << ".";
216 return false;
217 }
218 }
219 return true;
220}
221
222std::map<std::string, std::string> AidlAnnotation::AnnotationParams(
223 const ConstantValueDecorator& decorator) const {
224 std::map<std::string, std::string> raw_params;
225 const auto& supported_params = kAnnotationParameters.at(GetName());
226 for (const auto& name_and_param : parameters_) {
227 const std::string& param_name = name_and_param.first;
228 const std::shared_ptr<AidlConstantValue>& param = name_and_param.second;
229 AidlTypeSpecifier type{AIDL_LOCATION_HERE, supported_params.at(param_name), false, nullptr, ""};
Will McVickerd7d18df2019-09-12 13:40:50 -0700230 if (!param->CheckValid()) {
231 AIDL_ERROR(this) << "Invalid value for parameter " << param_name << " on annotation "
232 << GetName() << ".";
233 raw_params.clear();
234 return raw_params;
235 }
236
237 raw_params.emplace(param_name, param->ValueString(type, decorator));
Andrei Onea9445fc62019-06-27 18:11:59 +0100238 }
239 return raw_params;
240}
Steven Moreland46e9da82018-07-27 15:45:29 -0700241
Daniel Norman37d43dd2019-09-09 17:22:34 -0700242std::string AidlAnnotation::ToString(const ConstantValueDecorator& decorator) const {
243 if (parameters_.empty()) {
244 return "@" + GetName();
245 } else {
246 vector<string> param_strings;
247 for (const auto& [name, value] : AnnotationParams(decorator)) {
248 param_strings.emplace_back(name + "=" + value);
249 }
250 return "@" + GetName() + "(" + Join(param_strings, ", ") + ")";
251 }
252}
253
Jiyong Parka6605ab2018-11-11 14:30:21 +0900254static bool HasAnnotation(const vector<AidlAnnotation>& annotations, const string& name) {
Jiyong Park68bc77a2018-07-19 19:00:45 +0900255 for (const auto& a : annotations) {
Steven Moreland3be75772018-08-20 13:27:43 -0700256 if (a.GetName() == name) {
Jiyong Park68bc77a2018-07-19 19:00:45 +0900257 return true;
258 }
259 }
260 return false;
261}
262
Andrei Onea9445fc62019-06-27 18:11:59 +0100263static const AidlAnnotation* GetAnnotation(const vector<AidlAnnotation>& annotations,
264 const string& name) {
265 for (const auto& a : annotations) {
266 if (a.GetName() == name) {
267 return &a;
268 }
269 }
270 return nullptr;
271}
272
Steven Moreland46e9da82018-07-27 15:45:29 -0700273AidlAnnotatable::AidlAnnotatable(const AidlLocation& location) : AidlNode(location) {}
274
Jiyong Park68bc77a2018-07-19 19:00:45 +0900275bool AidlAnnotatable::IsNullable() const {
276 return HasAnnotation(annotations_, kNullable);
277}
278
Jiyong Park68bc77a2018-07-19 19:00:45 +0900279bool AidlAnnotatable::IsUtf8InCpp() const {
280 return HasAnnotation(annotations_, kUtf8InCpp);
281}
282
Steven Morelanda57d0a62019-07-30 09:41:14 -0700283bool AidlAnnotatable::IsVintfStability() const {
284 return HasAnnotation(annotations_, kVintfStability);
285}
286
Andrei Onea9445fc62019-06-27 18:11:59 +0100287const AidlAnnotation* AidlAnnotatable::UnsupportedAppUsage() const {
288 return GetAnnotation(annotations_, kUnsupportedAppUsage);
Jiyong Parka6605ab2018-11-11 14:30:21 +0900289}
290
Daniel Norman716d3112019-09-10 13:11:56 -0700291const AidlTypeSpecifier* AidlAnnotatable::BackingType(const AidlTypenames& typenames) const {
Daniel Norman85aed542019-08-21 12:01:14 -0700292 auto annotation = GetAnnotation(annotations_, kBacking);
293 if (annotation != nullptr) {
294 auto annotation_params = annotation->AnnotationParams(AidlConstantValueDecorator);
295 if (auto it = annotation_params.find("type"); it != annotation_params.end()) {
296 const string& type = it->second;
Daniel Norman716d3112019-09-10 13:11:56 -0700297 AidlTypeSpecifier* type_specifier =
298 new AidlTypeSpecifier(AIDL_LOCATION_HERE,
299 // Strip the quotes off the type String.
300 type.substr(1, type.length() - 2), false, nullptr, "");
301 type_specifier->Resolve(typenames);
302 return type_specifier;
Daniel Norman85aed542019-08-21 12:01:14 -0700303 }
304 }
305 return nullptr;
306}
307
Jeongik Cha88f95a82020-01-15 13:02:16 +0900308bool AidlAnnotatable::IsStableApiParcelable(Options::Language lang) const {
309 return HasAnnotation(annotations_, kJavaStableParcelable) && lang == Options::Language::JAVA;
Jeongik Cha82317dd2019-02-27 20:26:11 +0900310}
311
Makoto Onuki78a1c1c2020-03-04 16:57:23 -0800312bool AidlAnnotatable::IsHide() const {
313 return HasAnnotation(annotations_, kHide);
314}
315
Steven Moreland7e4b9502020-02-20 18:10:42 -0800316void AidlAnnotatable::DumpAnnotations(CodeWriter* writer) const {
317 if (annotations_.empty()) return;
318
319 writer->Write("%s\n", AidlAnnotatable::ToString().c_str());
320}
321
Devin Moore24f68572020-02-26 13:20:59 -0800322bool AidlAnnotatable::CheckValid(const AidlTypenames&) const {
323 std::set<string> supported_annotations = GetSupportedAnnotations();
Andrei Onea9445fc62019-06-27 18:11:59 +0100324 for (const auto& annotation : GetAnnotations()) {
325 if (!annotation.CheckValid()) {
326 return false;
327 }
Devin Moore24f68572020-02-26 13:20:59 -0800328 if (supported_annotations.find(annotation.GetName()) == supported_annotations.end()) {
329 AIDL_ERROR(this) << "'" << annotation.GetName()
330 << "' is not a supported annotation for this node. "
331 << "It must be one of: " << android::base::Join(supported_annotations, ", ");
332 return false;
333 }
Andrei Onea9445fc62019-06-27 18:11:59 +0100334 }
Steven Morelanda57d0a62019-07-30 09:41:14 -0700335
Andrei Onea9445fc62019-06-27 18:11:59 +0100336 return true;
337}
338
Jiyong Park68bc77a2018-07-19 19:00:45 +0900339string AidlAnnotatable::ToString() const {
340 vector<string> ret;
341 for (const auto& a : annotations_) {
Daniel Norman37d43dd2019-09-09 17:22:34 -0700342 ret.emplace_back(a.ToString(AidlConstantValueDecorator));
Jiyong Park68bc77a2018-07-19 19:00:45 +0900343 }
344 std::sort(ret.begin(), ret.end());
345 return Join(ret, " ");
346}
347
Steven Moreland46e9da82018-07-27 15:45:29 -0700348AidlTypeSpecifier::AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name,
349 bool is_array,
Jiyong Park1deecc32018-07-17 01:14:41 +0900350 vector<unique_ptr<AidlTypeSpecifier>>* type_params,
Steven Moreland46e9da82018-07-27 15:45:29 -0700351 const string& comments)
352 : AidlAnnotatable(location),
Jeongik Chadf76dc72019-11-28 00:08:47 +0900353 AidlParameterizable<unique_ptr<AidlTypeSpecifier>>(type_params),
Steven Moreland46e9da82018-07-27 15:45:29 -0700354 unresolved_name_(unresolved_name),
Casey Dahlinf7a421c2015-10-05 17:24:28 -0700355 is_array_(is_array),
Jeongik Cha1a7ab642019-07-29 17:31:02 +0900356 comments_(comments),
357 split_name_(Split(unresolved_name, ".")) {}
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700358
Steven Moreland3f658cf2018-08-20 13:40:54 -0700359AidlTypeSpecifier AidlTypeSpecifier::ArrayBase() const {
360 AIDL_FATAL_IF(!is_array_, this);
Jeongik Chadf76dc72019-11-28 00:08:47 +0900361 // Declaring array of generic type cannot happen, it is grammar error.
362 AIDL_FATAL_IF(IsGeneric(), this);
Steven Moreland3f658cf2018-08-20 13:40:54 -0700363
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800364 AidlTypeSpecifier array_base = *this;
365 array_base.is_array_ = false;
366 return array_base;
Steven Moreland3f658cf2018-08-20 13:40:54 -0700367}
368
Jeongik Cha997281d2020-01-16 15:23:59 +0900369bool AidlTypeSpecifier::IsHidden() const {
370 return HasHideComment(GetComments());
371}
372
Jiyong Park1deecc32018-07-17 01:14:41 +0900373string AidlTypeSpecifier::ToString() const {
374 string ret = GetName();
375 if (IsGeneric()) {
376 vector<string> arg_names;
377 for (const auto& ta : GetTypeParameters()) {
Jiyong Parkccf00f82018-07-17 01:39:23 +0900378 arg_names.emplace_back(ta->ToString());
379 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900380 ret += "<" + Join(arg_names, ",") + ">";
Jiyong Parkccf00f82018-07-17 01:39:23 +0900381 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900382 if (IsArray()) {
383 ret += "[]";
384 }
385 return ret;
Jiyong Parkccf00f82018-07-17 01:39:23 +0900386}
387
Jiyong Park02da7422018-07-16 16:00:26 +0900388string AidlTypeSpecifier::Signature() const {
389 string ret = ToString();
390 string annotations = AidlAnnotatable::ToString();
391 if (annotations != "") {
392 ret = annotations + " " + ret;
393 }
394 return ret;
395}
396
Daniel Norman716d3112019-09-10 13:11:56 -0700397bool AidlTypeSpecifier::Resolve(const AidlTypenames& typenames) {
Steven Moreland9731c632019-08-13 10:21:08 -0700398 CHECK(!IsResolved());
Jiyong Park1deecc32018-07-17 01:14:41 +0900399 pair<string, bool> result = typenames.ResolveTypename(unresolved_name_);
400 if (result.second) {
401 fully_qualified_name_ = result.first;
Jeongik Cha1a7ab642019-07-29 17:31:02 +0900402 split_name_ = Split(fully_qualified_name_, ".");
Jiyong Parkccf00f82018-07-17 01:39:23 +0900403 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900404 return result.second;
Casey Dahlin70078e62015-09-30 17:01:30 -0700405}
406
Devin Moore24f68572020-02-26 13:20:59 -0800407std::set<string> AidlTypeSpecifier::GetSupportedAnnotations() const {
408 // kHide and kUnsupportedAppUsage are both method return annotations
409 // which we don't distinguish from other type specifiers.
410 return {kNullable, kUtf8InCpp, kUnsupportedAppUsage, kHide};
411}
412
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900413bool AidlTypeSpecifier::CheckValid(const AidlTypenames& typenames) const {
Devin Moore24f68572020-02-26 13:20:59 -0800414 if (!AidlAnnotatable::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100415 return false;
416 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900417 if (IsGeneric()) {
418 const string& type_name = GetName();
Jeongik Chae74c86d2019-12-12 16:54:03 +0900419
420 auto& types = GetTypeParameters();
421 // TODO(b/136048684) Disallow to use primitive types only if it is List or Map.
422 if (type_name == "List" || type_name == "Map") {
423 if (std::any_of(types.begin(), types.end(), [](auto& type_ptr) {
424 return AidlTypenames::IsPrimitiveTypename(type_ptr->GetName());
425 })) {
Devin Moore7b8d5c92020-03-17 14:14:08 -0700426 AIDL_ERROR(this) << "A generic type cannot have any primitive type parameters.";
Jeongik Chae74c86d2019-12-12 16:54:03 +0900427 return false;
428 }
429 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800430 const auto defined_type = typenames.TryGetDefinedType(type_name);
Jeongik Chadf76dc72019-11-28 00:08:47 +0900431 const auto parameterizable =
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800432 defined_type != nullptr ? defined_type->AsParameterizable() : nullptr;
433 const bool is_user_defined_generic_type =
Jeongik Chadf76dc72019-11-28 00:08:47 +0900434 parameterizable != nullptr && parameterizable->IsGeneric();
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800435 const size_t num_params = GetTypeParameters().size();
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900436 if (type_name == "List") {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800437 if (num_params > 1) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900438 AIDL_ERROR(this) << " List cannot have type parameters more than one, but got "
439 << "'" << ToString() << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900440 return false;
441 }
442 } else if (type_name == "Map") {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800443 if (num_params != 0 && num_params != 2) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900444 AIDL_ERROR(this) << "Map must have 0 or 2 type parameters, but got "
445 << "'" << ToString() << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900446 return false;
447 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800448 if (num_params == 2) {
Jeongik Chae48d9942020-01-02 17:39:00 +0900449 const string& key_type = GetTypeParameters()[0]->GetName();
450 if (key_type != "String") {
451 AIDL_ERROR(this) << "The type of key in map must be String, but it is "
452 << "'" << key_type << "'";
453 return false;
454 }
455 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800456 } else if (is_user_defined_generic_type) {
Jeongik Chadf76dc72019-11-28 00:08:47 +0900457 const size_t allowed = parameterizable->GetTypeParameters().size();
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800458 if (num_params != allowed) {
Jeongik Chadf76dc72019-11-28 00:08:47 +0900459 AIDL_ERROR(this) << type_name << " must have " << allowed << " type parameters, but got "
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800460 << num_params;
Jeongik Chadf76dc72019-11-28 00:08:47 +0900461 return false;
462 }
463 } else {
464 AIDL_ERROR(this) << type_name << " is not a generic type.";
465 return false;
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900466 }
467 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900468
Steven Moreland11cb9452020-01-21 16:56:58 -0800469 const bool is_generic_string_list = GetName() == "List" && IsGeneric() &&
470 GetTypeParameters().size() == 1 &&
471 GetTypeParameters()[0]->GetName() == "String";
472 if (IsUtf8InCpp() && (GetName() != "String" && !is_generic_string_list)) {
473 AIDL_ERROR(this) << "@utf8InCpp can only be used on String, String[], and List<String>.";
474 return false;
475 }
476
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900477 if (GetName() == "void") {
478 if (IsArray() || IsNullable() || IsUtf8InCpp()) {
479 AIDL_ERROR(this) << "void type cannot be an array or nullable or utf8 string";
480 return false;
481 }
482 }
483
484 if (IsArray()) {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800485 const auto defined_type = typenames.TryGetDefinedType(GetName());
486 if (defined_type != nullptr && defined_type->AsInterface() != nullptr) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900487 AIDL_ERROR(this) << "Binder type cannot be an array";
488 return false;
489 }
490 }
491
492 if (IsNullable()) {
493 if (AidlTypenames::IsPrimitiveTypename(GetName()) && !IsArray()) {
494 AIDL_ERROR(this) << "Primitive type cannot get nullable annotation";
495 return false;
496 }
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800497 const auto defined_type = typenames.TryGetDefinedType(GetName());
498 if (defined_type != nullptr && defined_type->AsEnumDeclaration() != nullptr && !IsArray()) {
Daniel Normanee8674f2019-09-20 16:07:00 -0700499 AIDL_ERROR(this) << "Enum type cannot get nullable annotation";
500 return false;
501 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900502 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900503 return true;
504}
505
Steven Moreland860b1942018-08-16 14:59:28 -0700506std::string AidlConstantValueDecorator(const AidlTypeSpecifier& /*type*/,
507 const std::string& raw_value) {
508 return raw_value;
509}
510
Steven Moreland46e9da82018-07-27 15:45:29 -0700511AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
512 AidlTypeSpecifier* type, const std::string& name)
513 : AidlVariableDeclaration(location, type, name, nullptr /*default_value*/) {}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700514
Steven Moreland46e9da82018-07-27 15:45:29 -0700515AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
516 AidlTypeSpecifier* type, const std::string& name,
517 AidlConstantValue* default_value)
518 : AidlNode(location), type_(type), name_(name), default_value_(default_value) {}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700519
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900520bool AidlVariableDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700521 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900522 valid &= type_->CheckValid(typenames);
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900523
Steven Moreland54be7bd2019-12-05 11:17:53 -0800524 if (type_->GetName() == "void") {
525 AIDL_ERROR(this) << "Declaration " << name_
526 << " is void, but declarations cannot be of void type.";
527 valid = false;
528 }
529
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900530 if (default_value_ == nullptr) return valid;
Steven Moreland25294322018-08-07 18:13:55 -0700531 valid &= default_value_->CheckValid();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700532
Steven Moreland25294322018-08-07 18:13:55 -0700533 if (!valid) return false;
Steven Moreland9ea10e32018-07-19 15:26:09 -0700534
Steven Moreland860b1942018-08-16 14:59:28 -0700535 return !ValueString(AidlConstantValueDecorator).empty();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700536}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700537
538string AidlVariableDeclaration::ToString() const {
Jeongik Cha3271ffa2018-12-04 15:19:20 +0900539 string ret = type_->Signature() + " " + name_;
Steven Moreland9ea10e32018-07-19 15:26:09 -0700540 if (default_value_ != nullptr) {
Steven Moreland860b1942018-08-16 14:59:28 -0700541 ret += " = " + ValueString(AidlConstantValueDecorator);
Steven Moreland9ea10e32018-07-19 15:26:09 -0700542 }
543 return ret;
Steven Moreland5557f1c2018-07-02 13:50:23 -0700544}
545
Jiyong Park02da7422018-07-16 16:00:26 +0900546string AidlVariableDeclaration::Signature() const {
547 return type_->Signature() + " " + name_;
548}
549
Steven Moreland860b1942018-08-16 14:59:28 -0700550std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
Jiyong Parka468e2a2018-08-29 21:25:18 +0900551 if (default_value_ != nullptr) {
Will McVickerd7d18df2019-09-12 13:40:50 -0700552 return default_value_->ValueString(GetType(), decorator);
Jiyong Parka468e2a2018-08-29 21:25:18 +0900553 } else {
554 return "";
555 }
Steven Moreland25294322018-08-07 18:13:55 -0700556}
557
Steven Moreland46e9da82018-07-27 15:45:29 -0700558AidlArgument::AidlArgument(const AidlLocation& location, AidlArgument::Direction direction,
559 AidlTypeSpecifier* type, const std::string& name)
560 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700561 direction_(direction),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700562 direction_specified_(true) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700563
Steven Moreland46e9da82018-07-27 15:45:29 -0700564AidlArgument::AidlArgument(const AidlLocation& location, AidlTypeSpecifier* type,
565 const std::string& name)
566 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700567 direction_(AidlArgument::IN_DIR),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700568 direction_specified_(false) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700569
Jiyong Park02da7422018-07-16 16:00:26 +0900570string AidlArgument::GetDirectionSpecifier() const {
Casey Dahlinc378c992015-09-29 16:50:40 -0700571 string ret;
Casey Dahlinc378c992015-09-29 16:50:40 -0700572 if (direction_specified_) {
573 switch(direction_) {
574 case AidlArgument::IN_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700575 ret += "in";
Casey Dahlinc378c992015-09-29 16:50:40 -0700576 break;
577 case AidlArgument::OUT_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700578 ret += "out";
Casey Dahlinc378c992015-09-29 16:50:40 -0700579 break;
580 case AidlArgument::INOUT_DIR:
Devin Mooreeccdb902020-03-24 16:22:40 -0700581 ret += "inout";
Casey Dahlinc378c992015-09-29 16:50:40 -0700582 break;
583 }
584 }
Casey Dahlinc378c992015-09-29 16:50:40 -0700585 return ret;
586}
Casey Dahlinbc7a50a2015-09-28 19:20:50 -0700587
Jiyong Park02da7422018-07-16 16:00:26 +0900588string AidlArgument::ToString() const {
Devin Mooreeccdb902020-03-24 16:22:40 -0700589 if (direction_specified_) {
590 return GetDirectionSpecifier() + " " + AidlVariableDeclaration::ToString();
591 } else {
592 return AidlVariableDeclaration::ToString();
593 }
Jiyong Park02da7422018-07-16 16:00:26 +0900594}
595
596std::string AidlArgument::Signature() const {
Steven Moreland46e9da82018-07-27 15:45:29 -0700597 class AidlInterface;
598 class AidlInterface;
599 class AidlParcelable;
600 class AidlStructuredParcelable;
601 class AidlParcelable;
602 class AidlStructuredParcelable;
Devin Mooreeccdb902020-03-24 16:22:40 -0700603 if (direction_specified_) {
604 return GetDirectionSpecifier() + " " + AidlVariableDeclaration::Signature();
605 } else {
606 return AidlVariableDeclaration::Signature();
607 }
Jiyong Park02da7422018-07-16 16:00:26 +0900608}
609
Steven Moreland46e9da82018-07-27 15:45:29 -0700610AidlMember::AidlMember(const AidlLocation& location) : AidlNode(location) {}
611
Steven Moreland46e9da82018-07-27 15:45:29 -0700612AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
613 AidlTypeSpecifier* type, const std::string& name,
614 AidlConstantValue* value)
615 : AidlMember(location), type_(type), name_(name), value_(value) {}
Steven Moreland693640b2018-07-19 13:46:27 -0700616
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900617bool AidlConstantDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700618 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900619 valid &= type_->CheckValid(typenames);
Steven Moreland25294322018-08-07 18:13:55 -0700620 valid &= value_->CheckValid();
621 if (!valid) return false;
Steven Moreland693640b2018-07-19 13:46:27 -0700622
Steven Moreland25294322018-08-07 18:13:55 -0700623 const static set<string> kSupportedConstTypes = {"String", "int"};
624 if (kSupportedConstTypes.find(type_->ToString()) == kSupportedConstTypes.end()) {
625 AIDL_ERROR(this) << "Constant of type " << type_->ToString() << " is not supported.";
Steven Moreland693640b2018-07-19 13:46:27 -0700626 return false;
627 }
628
Will McVickerd7d18df2019-09-12 13:40:50 -0700629 return true;
Christopher Wileyd6bdd8d2016-05-03 11:23:13 -0700630}
631
Jiyong Parka428d212018-08-29 22:26:30 +0900632string AidlConstantDeclaration::ToString() const {
633 return "const " + type_->ToString() + " " + name_ + " = " +
634 ValueString(AidlConstantValueDecorator);
635}
636
637string AidlConstantDeclaration::Signature() const {
638 return type_->Signature() + " " + name_;
639}
640
Steven Moreland46e9da82018-07-27 15:45:29 -0700641AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
642 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkb034bf02018-07-30 17:44:33 +0900643 const std::string& comments)
644 : AidlMethod(location, oneway, type, name, args, comments, 0, true) {
645 has_id_ = false;
646}
647
648AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
649 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkb034bf02018-07-30 17:44:33 +0900650 const std::string& comments, int id, bool is_user_defined)
Steven Moreland46e9da82018-07-27 15:45:29 -0700651 : AidlMember(location),
652 oneway_(oneway),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700653 comments_(comments),
654 type_(type),
655 name_(name),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700656 arguments_(std::move(*args)),
Jiyong Parkb034bf02018-07-30 17:44:33 +0900657 id_(id),
658 is_user_defined_(is_user_defined) {
Casey Dahlinf4a93112015-10-05 16:58:09 -0700659 has_id_ = true;
660 delete args;
Christopher Wileyad339272015-10-05 19:11:58 -0700661 for (const unique_ptr<AidlArgument>& a : arguments_) {
662 if (a->IsIn()) { in_arguments_.push_back(a.get()); }
663 if (a->IsOut()) { out_arguments_.push_back(a.get()); }
664 }
Casey Dahlinf4a93112015-10-05 16:58:09 -0700665}
666
Jeongik Cha997281d2020-01-16 15:23:59 +0900667bool AidlMethod::IsHidden() const {
668 return HasHideComment(GetComments());
669}
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700670
Jiyong Park02da7422018-07-16 16:00:26 +0900671string AidlMethod::Signature() const {
672 vector<string> arg_signatures;
673 for (const auto& arg : GetArguments()) {
Jiyong Park309668e2018-07-28 16:55:44 +0900674 arg_signatures.emplace_back(arg->GetType().ToString());
Jiyong Park02da7422018-07-16 16:00:26 +0900675 }
Jiyong Park309668e2018-07-28 16:55:44 +0900676 return GetName() + "(" + Join(arg_signatures, ", ") + ")";
677}
678
679string AidlMethod::ToString() const {
680 vector<string> arg_strings;
681 for (const auto& arg : GetArguments()) {
682 arg_strings.emplace_back(arg->Signature());
683 }
Steven Moreland4ee68632018-12-14 15:52:46 -0800684 string ret = (IsOneway() ? "oneway " : "") + GetType().Signature() + " " + GetName() + "(" +
685 Join(arg_strings, ", ") + ")";
Jiyong Parked65bf42018-08-28 15:43:27 +0900686 if (HasId()) {
687 ret += " = " + std::to_string(GetId());
688 }
689 return ret;
Jiyong Park02da7422018-07-16 16:00:26 +0900690}
691
Steven Moreland46e9da82018-07-27 15:45:29 -0700692AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
693 const std::string& comments,
Steven Moreland787b0432018-07-03 09:00:58 -0700694 const std::vector<std::string>& package)
Steven Moreland46e9da82018-07-27 15:45:29 -0700695 : AidlAnnotatable(location), name_(name), comments_(comments), package_(package) {}
Steven Moreland787b0432018-07-03 09:00:58 -0700696
697std::string AidlDefinedType::GetPackage() const {
698 return Join(package_, '.');
699}
700
Devin Moore24f68572020-02-26 13:20:59 -0800701bool AidlDefinedType::CheckValid(const AidlTypenames& typenames) const {
702 if (!AidlAnnotatable::CheckValid(typenames)) {
703 return false;
704 }
705
706 return true;
707}
708
Jeongik Cha997281d2020-01-16 15:23:59 +0900709bool AidlDefinedType::IsHidden() const {
710 return HasHideComment(GetComments());
711}
712
Steven Moreland787b0432018-07-03 09:00:58 -0700713std::string AidlDefinedType::GetCanonicalName() const {
714 if (package_.empty()) {
715 return GetName();
716 }
717 return GetPackage() + "." + GetName();
718}
719
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800720void AidlDefinedType::DumpHeader(CodeWriter* writer) const {
721 if (this->IsHidden()) {
722 AddHideComment(writer);
723 }
724 DumpAnnotations(writer);
725}
726
Steven Moreland46e9da82018-07-27 15:45:29 -0700727AidlParcelable::AidlParcelable(const AidlLocation& location, AidlQualifiedName* name,
Jiyong Parka6605ab2018-11-11 14:30:21 +0900728 const std::vector<std::string>& package, const std::string& comments,
Jeongik Chadf76dc72019-11-28 00:08:47 +0900729 const std::string& cpp_header, std::vector<std::string>* type_params)
Jiyong Parka6605ab2018-11-11 14:30:21 +0900730 : AidlDefinedType(location, name->GetDotName(), comments, package),
Jeongik Chadf76dc72019-11-28 00:08:47 +0900731 AidlParameterizable<std::string>(type_params),
Steven Moreland787b0432018-07-03 09:00:58 -0700732 name_(name),
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800733 cpp_header_(cpp_header) {
734 // Strip off quotation marks if we actually have a cpp header.
735 if (cpp_header_.length() >= 2) {
736 cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
737 }
Casey Dahlin59401da2015-10-09 18:16:45 -0700738}
Jeongik Chadf76dc72019-11-28 00:08:47 +0900739template <typename T>
740AidlParameterizable<T>::AidlParameterizable(const AidlParameterizable& other) {
741 // Copying is not supported if it has type parameters.
742 // It doesn't make a problem because only ArrayBase() makes a copy,
743 // and it can be called only if a type is not generic.
744 CHECK(!other.IsGeneric());
745}
746
747template <typename T>
748bool AidlParameterizable<T>::CheckValid() const {
749 return true;
750};
751
752template <>
753bool AidlParameterizable<std::string>::CheckValid() const {
754 if (!IsGeneric()) {
755 return true;
756 }
757 std::unordered_set<std::string> set(GetTypeParameters().begin(), GetTypeParameters().end());
758 if (set.size() != GetTypeParameters().size()) {
759 AIDL_ERROR(this->AsAidlNode()) << "Every type parameter should be unique.";
760 return false;
761 }
762 return true;
763}
Casey Dahlin59401da2015-10-09 18:16:45 -0700764
Devin Moore24f68572020-02-26 13:20:59 -0800765std::set<string> AidlParcelable::GetSupportedAnnotations() const {
766 return {kVintfStability, kUnsupportedAppUsage, kJavaStableParcelable, kHide};
767}
768
769bool AidlParcelable::CheckValid(const AidlTypenames& typenames) const {
770 if (!AidlDefinedType::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +0100771 return false;
772 }
Jeongik Chadf76dc72019-11-28 00:08:47 +0900773 if (!AidlParameterizable<std::string>::CheckValid()) {
774 return false;
775 }
Jeongik Cha82317dd2019-02-27 20:26:11 +0900776
777 return true;
778}
779
Jeongik Cha997281d2020-01-16 15:23:59 +0900780void AidlParcelable::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800781 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +0900782 writer->Write("parcelable %s ;\n", GetName().c_str());
783}
784
Steven Moreland5557f1c2018-07-02 13:50:23 -0700785AidlStructuredParcelable::AidlStructuredParcelable(
Steven Moreland46e9da82018-07-27 15:45:29 -0700786 const AidlLocation& location, AidlQualifiedName* name, const std::vector<std::string>& package,
Jiyong Parka6605ab2018-11-11 14:30:21 +0900787 const std::string& comments, std::vector<std::unique_ptr<AidlVariableDeclaration>>* variables)
788 : AidlParcelable(location, name, package, comments, "" /*cpp_header*/),
Steven Moreland46e9da82018-07-27 15:45:29 -0700789 variables_(std::move(*variables)) {}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700790
Jeongik Cha997281d2020-01-16 15:23:59 +0900791void AidlStructuredParcelable::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800792 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +0900793 writer->Write("parcelable %s {\n", GetName().c_str());
794 writer->Indent();
795 for (const auto& field : GetFields()) {
Jeongik Cha997281d2020-01-16 15:23:59 +0900796 if (field->GetType().IsHidden()) {
797 AddHideComment(writer);
798 }
Jiyong Parka468e2a2018-08-29 21:25:18 +0900799 writer->Write("%s;\n", field->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +0900800 }
801 writer->Dedent();
802 writer->Write("}\n");
803}
804
Devin Moore24f68572020-02-26 13:20:59 -0800805std::set<string> AidlStructuredParcelable::GetSupportedAnnotations() const {
806 return {kVintfStability, kUnsupportedAppUsage, kHide};
807}
808
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900809bool AidlStructuredParcelable::CheckValid(const AidlTypenames& typenames) const {
Daniel Norman85aed542019-08-21 12:01:14 -0700810 bool success = true;
Devin Moore24f68572020-02-26 13:20:59 -0800811 if (!AidlParcelable::CheckValid(typenames)) {
812 return false;
813 }
814
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900815 for (const auto& v : GetFields()) {
Daniel Norman85aed542019-08-21 12:01:14 -0700816 success = success && v->CheckValid(typenames);
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900817 }
Daniel Norman85aed542019-08-21 12:01:14 -0700818 return success;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900819}
820
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900821// TODO: we should treat every backend all the same in future.
822bool AidlTypeSpecifier::LanguageSpecificCheckValid(Options::Language lang) const {
Steven Moreland04b07e12020-01-21 18:11:07 -0800823 if (lang != Options::Language::JAVA) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900824 if (this->GetName() == "List" && !this->IsGeneric()) {
Steven Moreland04b07e12020-01-21 18:11:07 -0800825 AIDL_ERROR(this) << "Currently, only the Java backend supports non-generic List.";
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900826 return false;
827 }
828 }
Steven Morelandc8a4ca82020-01-21 17:50:08 -0800829 if (this->GetName() == "FileDescriptor" && lang == Options::Language::NDK) {
830 AIDL_ERROR(this) << "FileDescriptor isn't supported with the NDK.";
831 return false;
832 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900833 if (this->IsGeneric()) {
834 if (this->GetName() == "List") {
835 if (this->GetTypeParameters().size() != 1) {
836 AIDL_ERROR(this) << "List must have only one type parameter.";
837 return false;
838 }
839 if (lang == Options::Language::CPP) {
Devin Moore2ac52f92020-03-23 15:39:36 -0700840 const string& contained_type = this->GetTypeParameters()[0]->GetName();
841 if (!(contained_type == "String" || contained_type == "IBinder")) {
842 AIDL_ERROR(this) << "List<" << contained_type
843 << "> is not supported. List in cpp supports only String and IBinder.";
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900844 return false;
845 }
Jeongik Cha08ca2182019-11-21 14:01:13 +0900846 } else if (lang == Options::Language::JAVA) {
847 const string& contained_type = this->GetTypeParameters()[0]->GetName();
848 if (AidlTypenames::IsBuiltinTypename(contained_type)) {
849 if (contained_type != "String" && contained_type != "IBinder" &&
850 contained_type != "ParcelFileDescriptor") {
Devin Moore2ac52f92020-03-23 15:39:36 -0700851 AIDL_ERROR(this) << "List<" << contained_type
852 << "> is not supported. List in Java supports only String, IBinder, "
853 "and ParcelFileDescriptor.";
Jeongik Cha08ca2182019-11-21 14:01:13 +0900854 return false;
855 }
856 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900857 }
Jeongik Chabb55b5e2020-01-07 23:11:26 +0900858 }
859 }
Jeongik Chab75a4512020-01-10 13:37:04 +0900860 if (this->GetName() == "Map" || this->GetName() == "CharSequence") {
Jeongik Chabb55b5e2020-01-07 23:11:26 +0900861 if (lang != Options::Language::JAVA) {
Jeongik Chab75a4512020-01-10 13:37:04 +0900862 AIDL_ERROR(this) << "Currently, only Java backend supports " << this->GetName() << ".";
Jeongik Chabb55b5e2020-01-07 23:11:26 +0900863 return false;
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900864 }
865 }
Jeongik Cha08ca2182019-11-21 14:01:13 +0900866 if (lang == Options::Language::JAVA) {
867 const string name = this->GetName();
868 // List[], Map[], CharSequence[] are not supported.
869 if (AidlTypenames::IsBuiltinTypename(name) && this->IsArray()) {
870 if (name == "List" || name == "Map" || name == "CharSequence") {
871 AIDL_ERROR(this) << "List[], Map[], CharSequence[] are not supported.";
872 return false;
873 }
874 }
875 }
876
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900877 return true;
878}
879
880// TODO: we should treat every backend all the same in future.
881bool AidlParcelable::LanguageSpecificCheckValid(Options::Language lang) const {
882 if (lang != Options::Language::JAVA) {
Steven Moreland0d9c26e2020-01-22 08:52:08 -0800883 const AidlParcelable* unstructured_parcelable = this->AsUnstructuredParcelable();
884 if (unstructured_parcelable != nullptr) {
885 if (unstructured_parcelable->GetCppHeader().empty()) {
886 AIDL_ERROR(unstructured_parcelable)
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900887 << "Unstructured parcelable must have C++ header defined.";
888 return false;
889 }
890 }
891 }
892 return true;
893}
894
895// TODO: we should treat every backend all the same in future.
896bool AidlStructuredParcelable::LanguageSpecificCheckValid(Options::Language lang) const {
897 if (!AidlParcelable::LanguageSpecificCheckValid(lang)) {
898 return false;
899 }
900 for (const auto& v : this->GetFields()) {
901 if (!v->GetType().LanguageSpecificCheckValid(lang)) {
902 return false;
903 }
904 }
905 return true;
906}
907
Daniel Norman85aed542019-08-21 12:01:14 -0700908AidlEnumerator::AidlEnumerator(const AidlLocation& location, const std::string& name,
Daniel Norman2e4112d2019-10-03 10:22:35 -0700909 AidlConstantValue* value, const std::string& comments)
910 : AidlNode(location), name_(name), value_(value), comments_(comments) {}
Daniel Norman85aed542019-08-21 12:01:14 -0700911
912bool AidlEnumerator::CheckValid(const AidlTypeSpecifier& enum_backing_type) const {
913 if (GetValue() == nullptr) {
914 return false;
915 }
916 if (!GetValue()->CheckValid()) {
917 return false;
918 }
Will McVickerd7d18df2019-09-12 13:40:50 -0700919 if (GetValue()->ValueString(enum_backing_type, AidlConstantValueDecorator).empty()) {
Daniel Norman85aed542019-08-21 12:01:14 -0700920 AIDL_ERROR(this) << "Enumerator type differs from enum backing type.";
921 return false;
922 }
923 return true;
924}
925
926string AidlEnumerator::ValueString(const AidlTypeSpecifier& backing_type,
927 const ConstantValueDecorator& decorator) const {
Will McVickerd7d18df2019-09-12 13:40:50 -0700928 return GetValue()->ValueString(backing_type, decorator);
Daniel Norman85aed542019-08-21 12:01:14 -0700929}
930
931AidlEnumDeclaration::AidlEnumDeclaration(const AidlLocation& location, const std::string& name,
932 std::vector<std::unique_ptr<AidlEnumerator>>* enumerators,
Daniel Norman2e4112d2019-10-03 10:22:35 -0700933 const std::vector<std::string>& package,
934 const std::string& comments)
935 : AidlDefinedType(location, name, comments, package), enumerators_(std::move(*enumerators)) {}
Daniel Norman85aed542019-08-21 12:01:14 -0700936
937void AidlEnumDeclaration::SetBackingType(std::unique_ptr<const AidlTypeSpecifier> type) {
938 backing_type_ = std::move(type);
939}
940
Steven Moreland59e53e42019-11-26 20:38:08 -0800941bool AidlEnumDeclaration::Autofill() {
Daniel Normanb28684e2019-10-17 15:31:39 -0700942 const AidlEnumerator* previous = nullptr;
943 for (const auto& enumerator : enumerators_) {
944 if (enumerator->GetValue() == nullptr) {
945 if (previous == nullptr) {
Devin Mooredf93ebb2020-03-25 14:03:35 -0700946 enumerator->SetValue(
947 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "0")));
Daniel Normanb28684e2019-10-17 15:31:39 -0700948 } else {
Steven Moreland59e53e42019-11-26 20:38:08 -0800949 auto prev_value = std::unique_ptr<AidlConstantValue>(
950 AidlConstantValue::ShallowIntegralCopy(*previous->GetValue()));
951 if (prev_value == nullptr) {
952 return false;
953 }
Daniel Normanb28684e2019-10-17 15:31:39 -0700954 enumerator->SetValue(std::make_unique<AidlBinaryConstExpression>(
Devin Mooredf93ebb2020-03-25 14:03:35 -0700955 GetLocation(), std::move(prev_value), "+",
956 std::unique_ptr<AidlConstantValue>(AidlConstantValue::Integral(GetLocation(), "1"))));
Daniel Normanb28684e2019-10-17 15:31:39 -0700957 }
958 }
959 previous = enumerator.get();
960 }
Steven Moreland59e53e42019-11-26 20:38:08 -0800961 return true;
Daniel Normanb28684e2019-10-17 15:31:39 -0700962}
963
Devin Moore24f68572020-02-26 13:20:59 -0800964std::set<string> AidlEnumDeclaration::GetSupportedAnnotations() const {
965 return {kVintfStability, kBacking, kHide};
966}
967
968bool AidlEnumDeclaration::CheckValid(const AidlTypenames& typenames) const {
969 if (!AidlDefinedType::CheckValid(typenames)) {
970 return false;
971 }
Daniel Norman85aed542019-08-21 12:01:14 -0700972 if (backing_type_ == nullptr) {
973 AIDL_ERROR(this) << "Enum declaration missing backing type.";
974 return false;
975 }
976 bool success = true;
977 for (const auto& enumerator : enumerators_) {
978 success = success && enumerator->CheckValid(GetBackingType());
979 }
980 return success;
981}
982
Jeongik Cha997281d2020-01-16 15:23:59 +0900983void AidlEnumDeclaration::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -0800984 DumpHeader(writer);
Daniel Norman37d43dd2019-09-09 17:22:34 -0700985 writer->Write("enum %s {\n", GetName().c_str());
Daniel Norman85aed542019-08-21 12:01:14 -0700986 writer->Indent();
987 for (const auto& enumerator : GetEnumerators()) {
Daniel Norman85aed542019-08-21 12:01:14 -0700988 writer->Write("%s = %s,\n", enumerator->GetName().c_str(),
989 enumerator->ValueString(GetBackingType(), AidlConstantValueDecorator).c_str());
990 }
991 writer->Dedent();
992 writer->Write("}\n");
993}
994
Jeongik Cha047c5ee2019-08-07 23:16:49 +0900995// TODO: we should treat every backend all the same in future.
996bool AidlInterface::LanguageSpecificCheckValid(Options::Language lang) const {
997 for (const auto& m : this->GetMethods()) {
998 if (!m->GetType().LanguageSpecificCheckValid(lang)) {
999 return false;
1000 }
1001 for (const auto& arg : m->GetArguments()) {
1002 if (!arg->GetType().LanguageSpecificCheckValid(lang)) {
1003 return false;
1004 }
1005 }
1006 }
1007 return true;
1008}
1009
Steven Moreland46e9da82018-07-27 15:45:29 -07001010AidlInterface::AidlInterface(const AidlLocation& location, const std::string& name,
Casey Dahlinfb7da2e2015-10-08 17:26:09 -07001011 const std::string& comments, bool oneway,
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001012 std::vector<std::unique_ptr<AidlMember>>* members,
Christopher Wileyd76067c2015-10-19 17:00:13 -07001013 const std::vector<std::string>& package)
Steven Morelandacd53472018-12-14 10:17:26 -08001014 : AidlDefinedType(location, name, comments, package) {
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001015 for (auto& member : *members) {
1016 AidlMember* local = member.release();
1017 AidlMethod* method = local->AsMethod();
Steven Moreland693640b2018-07-19 13:46:27 -07001018 AidlConstantDeclaration* constant = local->AsConstantDeclaration();
1019
1020 CHECK(method == nullptr || constant == nullptr);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001021
1022 if (method) {
Steven Moreland8c70ba92018-12-17 10:20:31 -08001023 method->ApplyInterfaceOneway(oneway);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001024 methods_.emplace_back(method);
Steven Moreland693640b2018-07-19 13:46:27 -07001025 } else if (constant) {
1026 constants_.emplace_back(constant);
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001027 } else {
Steven Moreland46e9da82018-07-27 15:45:29 -07001028 AIDL_FATAL(this) << "Member is neither method nor constant!";
Casey Dahlind40e2fe2015-11-24 14:06:52 -08001029 }
1030 }
1031
1032 delete members;
Casey Dahlinfb7da2e2015-10-08 17:26:09 -07001033}
1034
Jeongik Cha997281d2020-01-16 15:23:59 +09001035void AidlInterface::Dump(CodeWriter* writer) const {
Steven Morelanda5d9c5c2020-02-21 16:01:09 -08001036 DumpHeader(writer);
Jiyong Park02da7422018-07-16 16:00:26 +09001037 writer->Write("interface %s {\n", GetName().c_str());
1038 writer->Indent();
1039 for (const auto& method : GetMethods()) {
Jeongik Cha997281d2020-01-16 15:23:59 +09001040 if (method->IsHidden()) {
1041 AddHideComment(writer);
1042 }
Jiyong Park309668e2018-07-28 16:55:44 +09001043 writer->Write("%s;\n", method->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +09001044 }
Jiyong Parka428d212018-08-29 22:26:30 +09001045 for (const auto& constdecl : GetConstantDeclarations()) {
Jeongik Cha997281d2020-01-16 15:23:59 +09001046 if (constdecl->GetType().IsHidden()) {
1047 AddHideComment(writer);
1048 }
Jiyong Parka428d212018-08-29 22:26:30 +09001049 writer->Write("%s;\n", constdecl->ToString().c_str());
1050 }
Jiyong Park02da7422018-07-16 16:00:26 +09001051 writer->Dedent();
1052 writer->Write("}\n");
1053}
1054
Devin Moore24f68572020-02-26 13:20:59 -08001055std::set<string> AidlInterface::GetSupportedAnnotations() const {
1056 return {kVintfStability, kUnsupportedAppUsage, kHide};
1057}
1058
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001059bool AidlInterface::CheckValid(const AidlTypenames& typenames) const {
Devin Moore24f68572020-02-26 13:20:59 -08001060 if (!AidlDefinedType::CheckValid(typenames)) {
Andrei Onea9445fc62019-06-27 18:11:59 +01001061 return false;
1062 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001063 // Has to be a pointer due to deleting copy constructor. No idea why.
1064 map<string, const AidlMethod*> method_names;
1065 for (const auto& m : GetMethods()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001066 if (!m->GetType().CheckValid(typenames)) {
1067 return false;
1068 }
1069
Steven Morelandacd53472018-12-14 10:17:26 -08001070 if (m->IsOneway() && m->GetType().GetName() != "void") {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001071 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot return a value";
1072 return false;
1073 }
1074
1075 set<string> argument_names;
1076 for (const auto& arg : m->GetArguments()) {
1077 auto it = argument_names.find(arg->GetName());
1078 if (it != argument_names.end()) {
1079 AIDL_ERROR(m) << "method '" << m->GetName() << "' has duplicate argument name '"
1080 << arg->GetName() << "'";
1081 return false;
1082 }
1083 argument_names.insert(arg->GetName());
1084
1085 if (!arg->GetType().CheckValid(typenames)) {
1086 return false;
1087 }
1088
Steven Morelandacd53472018-12-14 10:17:26 -08001089 if (m->IsOneway() && arg->IsOut()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001090 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot have out parameters";
1091 return false;
1092 }
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001093 const bool can_be_out = typenames.CanBeOutParameter(arg->GetType());
1094 if (!arg->DirectionWasSpecified() && can_be_out) {
1095 AIDL_ERROR(arg) << "'" << arg->GetType().ToString()
1096 << "' can be an out type, so you must declare it as in, out, or inout.";
1097 return false;
1098 }
1099
1100 if (arg->GetDirection() != AidlArgument::IN_DIR && !can_be_out) {
1101 AIDL_ERROR(arg) << "'" << arg->ToString() << "' can only be an in parameter.";
1102 return false;
1103 }
1104
1105 // check that the name doesn't match a keyword
Jeongik Cha997281d2020-01-16 15:23:59 +09001106 if (IsJavaKeyword(arg->GetName().c_str())) {
Jeongik Cha047c5ee2019-08-07 23:16:49 +09001107 AIDL_ERROR(arg) << "Argument name is a Java or aidl keyword";
1108 return false;
1109 }
1110
1111 // Reserve a namespace for internal use
1112 if (android::base::StartsWith(arg->GetName(), "_aidl")) {
1113 AIDL_ERROR(arg) << "Argument name cannot begin with '_aidl'";
1114 return false;
1115 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001116 }
1117
1118 auto it = method_names.find(m->GetName());
1119 // prevent duplicate methods
1120 if (it == method_names.end()) {
1121 method_names[m->GetName()] = m.get();
1122 } else {
1123 AIDL_ERROR(m) << "attempt to redefine method " << m->GetName() << ":";
1124 AIDL_ERROR(it->second) << "previously defined here.";
1125 return false;
1126 }
1127
Paul Trautrimb77048c2020-01-21 16:39:32 +09001128 static set<string> reserved_methods{"asBinder()", "getInterfaceHash()", "getInterfaceVersion()",
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001129 "getTransactionName(int)"};
1130
1131 if (reserved_methods.find(m->Signature()) != reserved_methods.end()) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001132 AIDL_ERROR(m) << " method " << m->Signature() << " is reserved for internal use.";
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001133 return false;
1134 }
1135 }
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001136
1137 bool success = true;
1138 set<string> constant_names;
1139 for (const std::unique_ptr<AidlConstantDeclaration>& constant : GetConstantDeclarations()) {
1140 if (constant_names.count(constant->GetName()) > 0) {
Devin Moore097a3ab2020-03-11 16:08:44 -07001141 AIDL_ERROR(constant) << "Found duplicate constant name '" << constant->GetName() << "'";
Steven Moreland4d12f9a2018-10-31 14:30:55 -07001142 success = false;
1143 }
1144 constant_names.insert(constant->GetName());
1145 success = success && constant->CheckValid(typenames);
1146 }
1147
1148 return success;
Jeongik Chadb0f59e2018-11-01 18:11:21 +09001149}
1150
Steven Moreland46e9da82018-07-27 15:45:29 -07001151AidlQualifiedName::AidlQualifiedName(const AidlLocation& location, const std::string& term,
1152 const std::string& comments)
1153 : AidlNode(location), terms_({term}), comments_(comments) {
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -08001154 if (term.find('.') != string::npos) {
1155 terms_ = Split(term, ".");
Steven Moreland46e9da82018-07-27 15:45:29 -07001156 for (const auto& subterm : terms_) {
1157 if (subterm.empty()) {
1158 AIDL_FATAL(this) << "Malformed qualified identifier: '" << term << "'";
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -08001159 }
1160 }
1161 }
Casey Dahlin2b2879b2015-10-13 16:59:44 -07001162}
1163
Chih-Hung Hsiehf05cc262016-07-27 11:42:51 -07001164void AidlQualifiedName::AddTerm(const std::string& term) {
Casey Dahlin2b2879b2015-10-13 16:59:44 -07001165 terms_.push_back(term);
1166}
1167
Steven Moreland46e9da82018-07-27 15:45:29 -07001168AidlImport::AidlImport(const AidlLocation& location, const std::string& needed_class)
1169 : AidlNode(location), needed_class_(needed_class) {}
Casey Dahlin0edf3422015-10-07 12:34:59 -07001170
Steven Moreland64e29be2018-08-08 18:52:19 -07001171std::unique_ptr<Parser> Parser::Parse(const std::string& filename,
1172 const android::aidl::IoDelegate& io_delegate,
1173 AidlTypenames& typenames) {
Christopher Wiley4a2884b2015-10-07 11:27:45 -07001174 // Make sure we can read the file first, before trashing previous state.
Steven Moreland64e29be2018-08-08 18:52:19 -07001175 unique_ptr<string> raw_buffer = io_delegate.GetFileContents(filename);
1176 if (raw_buffer == nullptr) {
Steven Moreland46e9da82018-07-27 15:45:29 -07001177 AIDL_ERROR(filename) << "Error while opening file for parsing";
Steven Moreland64e29be2018-08-08 18:52:19 -07001178 return nullptr;
Christopher Wiley4a2884b2015-10-07 11:27:45 -07001179 }
1180
Christopher Wiley4a2884b2015-10-07 11:27:45 -07001181 // We're going to scan this buffer in place, and yacc demands we put two
1182 // nulls at the end.
Steven Moreland64e29be2018-08-08 18:52:19 -07001183 raw_buffer->append(2u, '\0');
Christopher Wiley4a2884b2015-10-07 11:27:45 -07001184
Steven Moreland64e29be2018-08-08 18:52:19 -07001185 std::unique_ptr<Parser> parser(new Parser(filename, *raw_buffer, typenames));
Christopher Wiley4a2884b2015-10-07 11:27:45 -07001186
Steven Moreland64e29be2018-08-08 18:52:19 -07001187 if (yy::parser(parser.get()).parse() != 0 || parser->HasError()) return nullptr;
Christopher Wiley4a2884b2015-10-07 11:27:45 -07001188
Steven Moreland64e29be2018-08-08 18:52:19 -07001189 return parser;
Christopher Wiley4a2884b2015-10-07 11:27:45 -07001190}
1191
Christopher Wiley90be4e32015-10-20 14:55:25 -07001192std::vector<std::string> Parser::Package() const {
1193 if (!package_) {
1194 return {};
1195 }
1196 return package_->GetTerms();
1197}
1198
Steven Morelandd1039a92020-01-23 09:49:43 -08001199void Parser::AddImport(std::unique_ptr<AidlImport>&& import) {
Jiyong Park8f6ec462020-01-19 20:52:47 +09001200 for (const auto& i : imports_) {
1201 if (i->GetNeededClass() == import->GetNeededClass()) {
1202 return;
1203 }
1204 }
Steven Morelandd1039a92020-01-23 09:49:43 -08001205 imports_.emplace_back(std::move(import));
Casey Dahline2507492015-09-14 17:11:20 -07001206}
Jiyong Park1deecc32018-07-17 01:14:41 +09001207
1208bool Parser::Resolve() {
1209 bool success = true;
1210 for (AidlTypeSpecifier* typespec : unresolved_typespecs_) {
Jiyong Park1d2df7d2018-07-23 15:22:50 +09001211 if (!typespec->Resolve(typenames_)) {
Steven Moreland46e9da82018-07-27 15:45:29 -07001212 AIDL_ERROR(typespec) << "Failed to resolve '" << typespec->GetUnresolvedName() << "'";
Jiyong Park1deecc32018-07-17 01:14:41 +09001213 success = false;
1214 // don't stop to show more errors if any
1215 }
1216 }
1217 return success;
1218}
Steven Moreland64e29be2018-08-08 18:52:19 -07001219
1220Parser::Parser(const std::string& filename, std::string& raw_buffer,
1221 android::aidl::AidlTypenames& typenames)
1222 : filename_(filename), typenames_(typenames) {
1223 yylex_init(&scanner_);
1224 buffer_ = yy_scan_buffer(&raw_buffer[0], raw_buffer.length(), scanner_);
1225}
1226
1227Parser::~Parser() {
1228 yy_delete_buffer(buffer_, scanner_);
1229 yylex_destroy(scanner_);
1230}