blob: 547816aedf2ca89e478beb4157917990bdcb293f [file] [log] [blame]
Adam Lesinskiffa16862014-01-23 18:17:42 -08001#include "aidl_language.h"
Jiyong Park1deecc32018-07-17 01:14:41 +09002#include "aidl_typenames.h"
Christopher Wileyf690be52015-09-14 15:19:10 -07003
Adam Lesinskiffa16862014-01-23 18:17:42 -08004#include <stdio.h>
Adam Lesinskiffa16862014-01-23 18:17:42 -08005#include <stdlib.h>
Christopher Wiley4a2884b2015-10-07 11:27:45 -07006#include <string.h>
Jiyong Park68bc77a2018-07-19 19:00:45 +09007#include <algorithm>
Jiyong Park1deecc32018-07-17 01:14:41 +09008#include <cassert>
9#include <iostream>
Jiyong Park68bc77a2018-07-19 19:00:45 +090010#include <set>
11#include <sstream>
Casey Dahlindd691812015-09-09 17:59:06 -070012#include <string>
Jiyong Park1deecc32018-07-17 01:14:41 +090013#include <utility>
Christopher Wileyf690be52015-09-14 15:19:10 -070014
Steven Moreland1c4ba202018-08-09 10:49:54 -070015#include <android-base/parsedouble.h>
Roshan Pius9d7810a2016-07-28 08:57:50 -070016#include <android-base/parseint.h>
Elliott Hughes0a620672015-12-04 13:53:18 -080017#include <android-base/strings.h>
Christopher Wileyd76067c2015-10-19 17:00:13 -070018
Ying Wang3000e752016-01-11 18:05:59 -080019#include "aidl_language_y.h"
Christopher Wiley4a2884b2015-10-07 11:27:45 -070020#include "logging.h"
Jiyong Park02da7422018-07-16 16:00:26 +090021#include "type_java.h"
22#include "type_namespace.h"
Adam Lesinskiffa16862014-01-23 18:17:42 -080023
Casey Dahlin07b9dde2015-09-10 19:13:49 -070024#ifdef _WIN32
25int isatty(int fd)
26{
27 return (fd == 0);
28}
29#endif
30
Christopher Wiley4a2884b2015-10-07 11:27:45 -070031using android::aidl::IoDelegate;
Christopher Wileyd76067c2015-10-19 17:00:13 -070032using android::base::Join;
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -080033using android::base::Split;
Casey Dahlindd691812015-09-09 17:59:06 -070034using std::cerr;
35using std::endl;
Jiyong Park1deecc32018-07-17 01:14:41 +090036using std::pair;
Jiyong Park68bc77a2018-07-19 19:00:45 +090037using std::set;
Christopher Wiley4a2884b2015-10-07 11:27:45 -070038using std::string;
39using std::unique_ptr;
Jiyong Parkccf00f82018-07-17 01:39:23 +090040using std::vector;
Adam Lesinskiffa16862014-01-23 18:17:42 -080041
Casey Dahlindd691812015-09-09 17:59:06 -070042void yylex_init(void **);
43void yylex_destroy(void *);
44void yyset_in(FILE *f, void *);
Casey Dahline2507492015-09-14 17:11:20 -070045int yyparse(Parser*);
Christopher Wiley4a2884b2015-10-07 11:27:45 -070046YY_BUFFER_STATE yy_scan_buffer(char *, size_t, void *);
Casey Dahlin89d44842015-09-24 18:45:54 -070047void yy_delete_buffer(YY_BUFFER_STATE, void *);
Casey Dahlindd691812015-09-09 17:59:06 -070048
Casey Dahlincdbbc8c2015-10-14 15:31:04 -070049AidlToken::AidlToken(const std::string& text, const std::string& comments)
50 : text_(text),
51 comments_(comments) {}
Casey Dahlin98a544b2015-10-14 14:22:55 -070052
Steven Moreland46e9da82018-07-27 15:45:29 -070053AidlLocation::AidlLocation(const std::string& file, Point begin, Point end)
54 : file_(file), begin_(begin), end_(end) {}
55
56std::ostream& operator<<(std::ostream& os, const AidlLocation& l) {
57 os << l.file_ << ":" << l.begin_.line << "." << l.begin_.column << "-";
58 if (l.begin_.line != l.end_.line) {
59 os << l.end_.line << ".";
60 }
61 os << l.end_.column;
62 return os;
63}
64
65AidlNode::AidlNode(const AidlLocation& location) : location_(location) {}
66
Andrei Onea8714b022019-02-01 18:55:54 +000067std::string AidlNode::PrintLocation() const {
68 std::stringstream ss;
69 ss << location_.file_ << ":" << location_.begin_.line;
70 return ss.str();
71}
72
Steven Moreland92c55f12018-07-31 14:08:37 -070073AidlError::AidlError(bool fatal) : os_(std::cerr), fatal_(fatal) {
74 os_ << "ERROR: ";
75}
76
Jiyong Park68bc77a2018-07-19 19:00:45 +090077static const string kNullable("nullable");
Jiyong Park68bc77a2018-07-19 19:00:45 +090078static const string kUtf8InCpp("utf8InCpp");
Jiyong Parka6605ab2018-11-11 14:30:21 +090079static const string kUnsupportedAppUsage("UnsupportedAppUsage");
Jeongik Cha698e6af2018-12-12 14:39:55 +090080static const string kSystemApi("SystemApi");
Jeongik Cha82317dd2019-02-27 20:26:11 +090081static const string kStableParcelable("JavaOnlyStableParcelable");
Jiyong Park68bc77a2018-07-19 19:00:45 +090082
Jeongik Cha82317dd2019-02-27 20:26:11 +090083static const set<string> kAnnotationNames{kNullable, kUtf8InCpp, kUnsupportedAppUsage, kSystemApi,
84 kStableParcelable};
Jiyong Park68bc77a2018-07-19 19:00:45 +090085
Steven Moreland46e9da82018-07-27 15:45:29 -070086AidlAnnotation* AidlAnnotation::Parse(const AidlLocation& location, const string& name) {
87 if (kAnnotationNames.find(name) == kAnnotationNames.end()) {
Jiyong Park68bc77a2018-07-19 19:00:45 +090088 std::ostringstream stream;
Steven Moreland46e9da82018-07-27 15:45:29 -070089 stream << "'" << name << "' is not a recognized annotation. ";
Jiyong Park68bc77a2018-07-19 19:00:45 +090090 stream << "It must be one of:";
91 for (const string& kv : kAnnotationNames) {
92 stream << " " << kv;
93 }
94 stream << ".";
Steven Moreland46e9da82018-07-27 15:45:29 -070095 AIDL_ERROR(location) << stream.str();
96 return nullptr;
Jiyong Park68bc77a2018-07-19 19:00:45 +090097 }
Steven Moreland46e9da82018-07-27 15:45:29 -070098 return new AidlAnnotation(location, name);
Jiyong Park68bc77a2018-07-19 19:00:45 +090099}
100
Steven Moreland46e9da82018-07-27 15:45:29 -0700101AidlAnnotation::AidlAnnotation(const AidlLocation& location, const string& name)
102 : AidlNode(location), name_(name) {}
103
Jiyong Parka6605ab2018-11-11 14:30:21 +0900104static bool HasAnnotation(const vector<AidlAnnotation>& annotations, const string& name) {
Jiyong Park68bc77a2018-07-19 19:00:45 +0900105 for (const auto& a : annotations) {
Steven Moreland3be75772018-08-20 13:27:43 -0700106 if (a.GetName() == name) {
Jiyong Park68bc77a2018-07-19 19:00:45 +0900107 return true;
108 }
109 }
110 return false;
111}
112
Steven Moreland46e9da82018-07-27 15:45:29 -0700113AidlAnnotatable::AidlAnnotatable(const AidlLocation& location) : AidlNode(location) {}
114
Jiyong Park68bc77a2018-07-19 19:00:45 +0900115bool AidlAnnotatable::IsNullable() const {
116 return HasAnnotation(annotations_, kNullable);
117}
118
Jiyong Park68bc77a2018-07-19 19:00:45 +0900119bool AidlAnnotatable::IsUtf8InCpp() const {
120 return HasAnnotation(annotations_, kUtf8InCpp);
121}
122
Jiyong Parka6605ab2018-11-11 14:30:21 +0900123bool AidlAnnotatable::IsUnsupportedAppUsage() const {
124 return HasAnnotation(annotations_, kUnsupportedAppUsage);
125}
126
Jeongik Cha698e6af2018-12-12 14:39:55 +0900127bool AidlAnnotatable::IsSystemApi() const {
128 return HasAnnotation(annotations_, kSystemApi);
129}
130
Jeongik Cha82317dd2019-02-27 20:26:11 +0900131bool AidlAnnotatable::IsStableParcelable() const {
132 return HasAnnotation(annotations_, kStableParcelable);
133}
134
Jiyong Park68bc77a2018-07-19 19:00:45 +0900135string AidlAnnotatable::ToString() const {
136 vector<string> ret;
137 for (const auto& a : annotations_) {
Steven Moreland3be75772018-08-20 13:27:43 -0700138 ret.emplace_back(a.ToString());
Jiyong Park68bc77a2018-07-19 19:00:45 +0900139 }
140 std::sort(ret.begin(), ret.end());
141 return Join(ret, " ");
142}
143
Steven Moreland46e9da82018-07-27 15:45:29 -0700144AidlTypeSpecifier::AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name,
145 bool is_array,
Jiyong Park1deecc32018-07-17 01:14:41 +0900146 vector<unique_ptr<AidlTypeSpecifier>>* type_params,
Steven Moreland46e9da82018-07-27 15:45:29 -0700147 const string& comments)
148 : AidlAnnotatable(location),
149 unresolved_name_(unresolved_name),
Casey Dahlinf7a421c2015-10-05 17:24:28 -0700150 is_array_(is_array),
Jiyong Park1deecc32018-07-17 01:14:41 +0900151 type_params_(type_params),
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700152 comments_(comments) {}
153
Steven Moreland3f658cf2018-08-20 13:40:54 -0700154AidlTypeSpecifier AidlTypeSpecifier::ArrayBase() const {
155 AIDL_FATAL_IF(!is_array_, this);
156
157 AidlTypeSpecifier arrayBase = *this;
158 arrayBase.is_array_ = false;
159 return arrayBase;
160}
161
Jiyong Park1deecc32018-07-17 01:14:41 +0900162string AidlTypeSpecifier::ToString() const {
163 string ret = GetName();
164 if (IsGeneric()) {
165 vector<string> arg_names;
166 for (const auto& ta : GetTypeParameters()) {
Jiyong Parkccf00f82018-07-17 01:39:23 +0900167 arg_names.emplace_back(ta->ToString());
168 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900169 ret += "<" + Join(arg_names, ",") + ">";
Jiyong Parkccf00f82018-07-17 01:39:23 +0900170 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900171 if (IsArray()) {
172 ret += "[]";
173 }
174 return ret;
Jiyong Parkccf00f82018-07-17 01:39:23 +0900175}
176
Jiyong Park02da7422018-07-16 16:00:26 +0900177string AidlTypeSpecifier::Signature() const {
178 string ret = ToString();
179 string annotations = AidlAnnotatable::ToString();
180 if (annotations != "") {
181 ret = annotations + " " + ret;
182 }
183 return ret;
184}
185
Jiyong Park1deecc32018-07-17 01:14:41 +0900186bool AidlTypeSpecifier::Resolve(android::aidl::AidlTypenames& typenames) {
187 assert(!IsResolved());
188 pair<string, bool> result = typenames.ResolveTypename(unresolved_name_);
189 if (result.second) {
190 fully_qualified_name_ = result.first;
Jiyong Parkccf00f82018-07-17 01:39:23 +0900191 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900192 return result.second;
Casey Dahlin70078e62015-09-30 17:01:30 -0700193}
194
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900195bool AidlTypeSpecifier::CheckValid(const AidlTypenames& typenames) const {
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900196 if (IsGeneric()) {
197 const string& type_name = GetName();
198 const int num = GetTypeParameters().size();
199 if (type_name == "List") {
200 if (num > 1) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900201 AIDL_ERROR(this) << " List cannot have type parameters more than one, but got "
202 << "'" << ToString() << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900203 return false;
204 }
205 } else if (type_name == "Map") {
206 if (num != 0 && num != 2) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900207 AIDL_ERROR(this) << "Map must have 0 or 2 type parameters, but got "
208 << "'" << ToString() << "'";
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900209 return false;
210 }
211 }
212 }
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900213
214 if (GetName() == "void") {
215 if (IsArray() || IsNullable() || IsUtf8InCpp()) {
216 AIDL_ERROR(this) << "void type cannot be an array or nullable or utf8 string";
217 return false;
218 }
219 }
220
221 if (IsArray()) {
222 const auto definedType = typenames.TryGetDefinedType(GetName());
223 if (definedType != nullptr && definedType->AsInterface() != nullptr) {
224 AIDL_ERROR(this) << "Binder type cannot be an array";
225 return false;
226 }
227 }
228
229 if (IsNullable()) {
230 if (AidlTypenames::IsPrimitiveTypename(GetName()) && !IsArray()) {
231 AIDL_ERROR(this) << "Primitive type cannot get nullable annotation";
232 return false;
233 }
234 }
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900235 return true;
236}
237
Steven Moreland860b1942018-08-16 14:59:28 -0700238std::string AidlConstantValueDecorator(const AidlTypeSpecifier& /*type*/,
239 const std::string& raw_value) {
240 return raw_value;
241}
242
Steven Moreland46e9da82018-07-27 15:45:29 -0700243AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
244 AidlTypeSpecifier* type, const std::string& name)
245 : AidlVariableDeclaration(location, type, name, nullptr /*default_value*/) {}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700246
Steven Moreland46e9da82018-07-27 15:45:29 -0700247AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
248 AidlTypeSpecifier* type, const std::string& name,
249 AidlConstantValue* default_value)
250 : AidlNode(location), type_(type), name_(name), default_value_(default_value) {}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700251
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900252bool AidlVariableDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700253 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900254 valid &= type_->CheckValid(typenames);
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900255
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900256 if (default_value_ == nullptr) return valid;
Steven Moreland25294322018-08-07 18:13:55 -0700257 valid &= default_value_->CheckValid();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700258
Steven Moreland25294322018-08-07 18:13:55 -0700259 if (!valid) return false;
Steven Moreland9ea10e32018-07-19 15:26:09 -0700260
Steven Moreland860b1942018-08-16 14:59:28 -0700261 return !ValueString(AidlConstantValueDecorator).empty();
Steven Moreland9ea10e32018-07-19 15:26:09 -0700262}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700263
264string AidlVariableDeclaration::ToString() const {
Jeongik Cha3271ffa2018-12-04 15:19:20 +0900265 string ret = type_->Signature() + " " + name_;
Steven Moreland9ea10e32018-07-19 15:26:09 -0700266 if (default_value_ != nullptr) {
Steven Moreland860b1942018-08-16 14:59:28 -0700267 ret += " = " + ValueString(AidlConstantValueDecorator);
Steven Moreland9ea10e32018-07-19 15:26:09 -0700268 }
269 return ret;
Steven Moreland5557f1c2018-07-02 13:50:23 -0700270}
271
Jiyong Park02da7422018-07-16 16:00:26 +0900272string AidlVariableDeclaration::Signature() const {
273 return type_->Signature() + " " + name_;
274}
275
Steven Moreland860b1942018-08-16 14:59:28 -0700276std::string AidlVariableDeclaration::ValueString(const ConstantValueDecorator& decorator) const {
Jiyong Parka468e2a2018-08-29 21:25:18 +0900277 if (default_value_ != nullptr) {
278 return GetDefaultValue()->As(GetType(), decorator);
279 } else {
280 return "";
281 }
Steven Moreland25294322018-08-07 18:13:55 -0700282}
283
Steven Moreland46e9da82018-07-27 15:45:29 -0700284AidlArgument::AidlArgument(const AidlLocation& location, AidlArgument::Direction direction,
285 AidlTypeSpecifier* type, const std::string& name)
286 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700287 direction_(direction),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700288 direction_specified_(true) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700289
Steven Moreland46e9da82018-07-27 15:45:29 -0700290AidlArgument::AidlArgument(const AidlLocation& location, AidlTypeSpecifier* type,
291 const std::string& name)
292 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700293 direction_(AidlArgument::IN_DIR),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700294 direction_specified_(false) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700295
Jiyong Park02da7422018-07-16 16:00:26 +0900296string AidlArgument::GetDirectionSpecifier() const {
Casey Dahlinc378c992015-09-29 16:50:40 -0700297 string ret;
Casey Dahlinc378c992015-09-29 16:50:40 -0700298 if (direction_specified_) {
299 switch(direction_) {
300 case AidlArgument::IN_DIR:
301 ret += "in ";
302 break;
303 case AidlArgument::OUT_DIR:
304 ret += "out ";
305 break;
306 case AidlArgument::INOUT_DIR:
307 ret += "inout ";
308 break;
309 }
310 }
Casey Dahlinc378c992015-09-29 16:50:40 -0700311 return ret;
312}
Casey Dahlinbc7a50a2015-09-28 19:20:50 -0700313
Jiyong Park02da7422018-07-16 16:00:26 +0900314string AidlArgument::ToString() const {
315 return GetDirectionSpecifier() + AidlVariableDeclaration::ToString();
316}
317
318std::string AidlArgument::Signature() const {
Steven Moreland46e9da82018-07-27 15:45:29 -0700319 class AidlInterface;
320 class AidlInterface;
321 class AidlParcelable;
322 class AidlStructuredParcelable;
323 class AidlParcelable;
324 class AidlStructuredParcelable;
Jiyong Park02da7422018-07-16 16:00:26 +0900325 return GetDirectionSpecifier() + AidlVariableDeclaration::Signature();
326}
327
Steven Moreland46e9da82018-07-27 15:45:29 -0700328AidlMember::AidlMember(const AidlLocation& location) : AidlNode(location) {}
329
Steven Moreland46e9da82018-07-27 15:45:29 -0700330AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
331 const std::string& checked_value)
Steven Moreland1c4ba202018-08-09 10:49:54 -0700332 : AidlNode(location), type_(type), value_(checked_value) {
333 CHECK(!value_.empty() || type_ == Type::ERROR);
Steven Moreland860b1942018-08-16 14:59:28 -0700334 CHECK(type_ != Type::ARRAY);
Steven Moreland1c4ba202018-08-09 10:49:54 -0700335}
Steven Moreland693640b2018-07-19 13:46:27 -0700336
Steven Moreland860b1942018-08-16 14:59:28 -0700337AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
338 std::vector<std::unique_ptr<AidlConstantValue>>* values)
339 : AidlNode(location), type_(type), values_(std::move(*values)) {}
340
Steven Moreland25294322018-08-07 18:13:55 -0700341static bool isValidLiteralChar(char c) {
342 return !(c <= 0x1f || // control characters are < 0x20
343 c >= 0x7f || // DEL is 0x7f
344 c == '\\'); // Disallow backslashes for future proofing.
Steven Moreland693640b2018-07-19 13:46:27 -0700345}
346
Steven Moreland25294322018-08-07 18:13:55 -0700347AidlConstantValue* AidlConstantValue::Boolean(const AidlLocation& location, bool value) {
348 return new AidlConstantValue(location, Type::BOOLEAN, value ? "true" : "false");
349}
350
351AidlConstantValue* AidlConstantValue::Character(const AidlLocation& location, char value) {
352 if (!isValidLiteralChar(value)) {
353 AIDL_ERROR(location) << "Invalid character literal " << value;
Steven Moreland46e9da82018-07-27 15:45:29 -0700354 return new AidlConstantValue(location, Type::ERROR, "");
Steven Moreland693640b2018-07-19 13:46:27 -0700355 }
Steven Moreland25294322018-08-07 18:13:55 -0700356 return new AidlConstantValue(location, Type::CHARACTER, std::string("'") + value + "'");
Steven Moreland693640b2018-07-19 13:46:27 -0700357}
358
Steven Moreland1c4ba202018-08-09 10:49:54 -0700359AidlConstantValue* AidlConstantValue::Floating(const AidlLocation& location,
360 const std::string& value) {
361 return new AidlConstantValue(location, Type::FLOATING, value);
362}
363
Steven Moreland25294322018-08-07 18:13:55 -0700364AidlConstantValue* AidlConstantValue::Hex(const AidlLocation& location, const std::string& value) {
365 return new AidlConstantValue(location, Type::HEXIDECIMAL, value);
366}
367
368AidlConstantValue* AidlConstantValue::Integral(const AidlLocation& location,
369 const std::string& value) {
370 return new AidlConstantValue(location, Type::INTEGRAL, value);
371}
372
Steven Moreland860b1942018-08-16 14:59:28 -0700373AidlConstantValue* AidlConstantValue::Array(
374 const AidlLocation& location, std::vector<std::unique_ptr<AidlConstantValue>>* values) {
375 return new AidlConstantValue(location, Type::ARRAY, values);
376}
377
Steven Moreland25294322018-08-07 18:13:55 -0700378AidlConstantValue* AidlConstantValue::String(const AidlLocation& location,
379 const std::string& value) {
Steven Moreland693640b2018-07-19 13:46:27 -0700380 for (size_t i = 0; i < value.length(); ++i) {
Steven Moreland25294322018-08-07 18:13:55 -0700381 if (!isValidLiteralChar(value[i])) {
Steven Moreland46e9da82018-07-27 15:45:29 -0700382 AIDL_ERROR(location) << "Found invalid character at index " << i << " in string constant '"
383 << value << "'";
384 return new AidlConstantValue(location, Type::ERROR, "");
Christopher Wileyd6bdd8d2016-05-03 11:23:13 -0700385 }
386 }
Steven Moreland693640b2018-07-19 13:46:27 -0700387
Steven Moreland46e9da82018-07-27 15:45:29 -0700388 return new AidlConstantValue(location, Type::STRING, value);
Steven Moreland693640b2018-07-19 13:46:27 -0700389}
390
Steven Moreland25294322018-08-07 18:13:55 -0700391bool AidlConstantValue::CheckValid() const {
392 // error always logged during creation
393 return type_ != AidlConstantValue::Type::ERROR;
394}
395
Steven Moreland1c4ba202018-08-09 10:49:54 -0700396static string TrimIfSuffix(const string& str, const string& suffix) {
397 if (str.size() > suffix.size() &&
398 0 == str.compare(str.size() - suffix.size(), suffix.size(), suffix)) {
399 return str.substr(0, str.size() - suffix.size());
400 }
401 return str;
402}
403
Steven Moreland860b1942018-08-16 14:59:28 -0700404string AidlConstantValue::As(const AidlTypeSpecifier& type,
405 const ConstantValueDecorator& decorator) const {
406 if (type.IsGeneric()) {
407 AIDL_ERROR(type) << "Generic type cannot be specified with a constant literal.";
408 return "";
409 }
410
411 const std::string& type_string = type.GetName();
412
413 if ((type_ == Type::ARRAY) != type.IsArray()) {
414 goto mismatch_error;
415 }
Steven Moreland25294322018-08-07 18:13:55 -0700416
417 switch (type_) {
Steven Moreland860b1942018-08-16 14:59:28 -0700418 case AidlConstantValue::Type::ARRAY: {
419 vector<string> raw_values;
420 raw_values.reserve(values_.size());
421
422 bool success = true;
423 for (const auto& value : values_) {
424 const AidlTypeSpecifier& array_base = type.ArrayBase();
425 const std::string raw_value = value->As(array_base, decorator);
426
427 success &= !raw_value.empty();
428 raw_values.push_back(decorator(array_base, raw_value));
429 }
430 if (!success) {
431 AIDL_ERROR(this) << "Default value must be a literal array of " << type_string << ".";
432 return "";
433 }
434 return decorator(type, "{" + Join(raw_values, ", ") + "}");
435 }
Steven Moreland1c4ba202018-08-09 10:49:54 -0700436 case AidlConstantValue::Type::BOOLEAN:
Steven Moreland860b1942018-08-16 14:59:28 -0700437 if (type_string == "boolean") return decorator(type, value_);
Steven Moreland1c4ba202018-08-09 10:49:54 -0700438 goto mismatch_error;
439 case AidlConstantValue::Type::CHARACTER:
Steven Moreland860b1942018-08-16 14:59:28 -0700440 if (type_string == "char") return decorator(type, value_);
Steven Moreland1c4ba202018-08-09 10:49:54 -0700441 goto mismatch_error;
442 case AidlConstantValue::Type::FLOATING: {
443 bool is_float_literal = value_.back() == 'f';
444 const std::string raw_value = TrimIfSuffix(value_, "f");
445
446 if (type_string == "double") {
447 double parsed_value;
448 if (!android::base::ParseDouble(raw_value, &parsed_value)) goto parse_error;
Steven Moreland860b1942018-08-16 14:59:28 -0700449 return decorator(type, std::to_string(parsed_value));
Steven Moreland25294322018-08-07 18:13:55 -0700450 }
Steven Moreland1c4ba202018-08-09 10:49:54 -0700451 if (is_float_literal && type_string == "float") {
452 float parsed_value;
453 if (!android::base::ParseFloat(raw_value, &parsed_value)) goto parse_error;
Steven Moreland860b1942018-08-16 14:59:28 -0700454 return decorator(type, std::to_string(parsed_value) + "f");
Steven Moreland25294322018-08-07 18:13:55 -0700455 }
456 goto mismatch_error;
Steven Moreland1c4ba202018-08-09 10:49:54 -0700457 }
Steven Moreland25294322018-08-07 18:13:55 -0700458 case AidlConstantValue::Type::HEXIDECIMAL:
459 // For historical reasons, a hexidecimal int needs to have the specified bits interpreted
460 // as the signed type, so the other types are made consistent with it.
461 if (type_string == "byte") {
462 uint8_t unsigned_value;
463 if (!android::base::ParseUint<uint8_t>(value_, &unsigned_value)) goto parse_error;
Steven Moreland860b1942018-08-16 14:59:28 -0700464 return decorator(type, std::to_string((int8_t)unsigned_value));
Steven Moreland25294322018-08-07 18:13:55 -0700465 }
466 if (type_string == "int") {
467 uint32_t unsigned_value;
468 if (!android::base::ParseUint<uint32_t>(value_, &unsigned_value)) goto parse_error;
Steven Moreland860b1942018-08-16 14:59:28 -0700469 return decorator(type, std::to_string((int32_t)unsigned_value));
Steven Moreland25294322018-08-07 18:13:55 -0700470 }
471 if (type_string == "long") {
472 uint64_t unsigned_value;
473 if (!android::base::ParseUint<uint64_t>(value_, &unsigned_value)) goto parse_error;
Steven Moreland860b1942018-08-16 14:59:28 -0700474 return decorator(type, std::to_string((int64_t)unsigned_value));
Steven Moreland25294322018-08-07 18:13:55 -0700475 }
476 goto mismatch_error;
Steven Moreland1c4ba202018-08-09 10:49:54 -0700477 case AidlConstantValue::Type::INTEGRAL:
478 if (type_string == "byte") {
479 if (!android::base::ParseInt<int8_t>(value_, nullptr)) goto parse_error;
Steven Moreland860b1942018-08-16 14:59:28 -0700480 return decorator(type, value_);
Steven Moreland1c4ba202018-08-09 10:49:54 -0700481 }
482 if (type_string == "int") {
483 if (!android::base::ParseInt<int32_t>(value_, nullptr)) goto parse_error;
Steven Moreland860b1942018-08-16 14:59:28 -0700484 return decorator(type, value_);
Steven Moreland1c4ba202018-08-09 10:49:54 -0700485 }
486 if (type_string == "long") {
487 if (!android::base::ParseInt<int64_t>(value_, nullptr)) goto parse_error;
Steven Moreland860b1942018-08-16 14:59:28 -0700488 return decorator(type, value_);
Steven Moreland1c4ba202018-08-09 10:49:54 -0700489 }
Steven Moreland25294322018-08-07 18:13:55 -0700490 goto mismatch_error;
491 case AidlConstantValue::Type::STRING:
Steven Moreland860b1942018-08-16 14:59:28 -0700492 if (type_string == "String") return decorator(type, value_);
Steven Moreland25294322018-08-07 18:13:55 -0700493 goto mismatch_error;
494 default:
495 AIDL_FATAL(this) << "Unrecognized constant value type";
496 }
497
498mismatch_error:
Steven Moreland860b1942018-08-16 14:59:28 -0700499 AIDL_ERROR(this) << "Expecting type " << type_string << " but constant is " << ToString(type_);
Steven Moreland25294322018-08-07 18:13:55 -0700500 return "";
501parse_error:
502 AIDL_ERROR(this) << "Could not parse " << value_ << " as " << type_string;
503 return "";
504}
505
506string AidlConstantValue::ToString(Type type) {
507 switch (type) {
Steven Moreland860b1942018-08-16 14:59:28 -0700508 case Type::ARRAY:
509 return "a literal array";
Steven Moreland25294322018-08-07 18:13:55 -0700510 case Type::BOOLEAN:
511 return "a literal boolean";
512 case Type::CHARACTER:
513 return "a literal char";
Steven Moreland1c4ba202018-08-09 10:49:54 -0700514 case Type::FLOATING:
515 return "a floating-point literal";
516 case Type::HEXIDECIMAL:
517 return "a hexidecimal literal";
Steven Moreland25294322018-08-07 18:13:55 -0700518 case Type::INTEGRAL:
519 return "an integral literal";
520 case Type::STRING:
521 return "a literal string";
522 case Type::ERROR:
523 LOG(FATAL) << "aidl internal error: error type failed to halt program";
Wei Wang35b7bb62018-10-09 13:06:12 -0700524 return "";
Steven Moreland25294322018-08-07 18:13:55 -0700525 default:
526 LOG(FATAL) << "aidl internal error: unknown constant type: " << static_cast<int>(type);
527 return ""; // not reached
528 }
Steven Moreland693640b2018-07-19 13:46:27 -0700529}
530
Steven Moreland46e9da82018-07-27 15:45:29 -0700531AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
532 AidlTypeSpecifier* type, const std::string& name,
533 AidlConstantValue* value)
534 : AidlMember(location), type_(type), name_(name), value_(value) {}
Steven Moreland693640b2018-07-19 13:46:27 -0700535
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900536bool AidlConstantDeclaration::CheckValid(const AidlTypenames& typenames) const {
Steven Moreland25294322018-08-07 18:13:55 -0700537 bool valid = true;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900538 valid &= type_->CheckValid(typenames);
Steven Moreland25294322018-08-07 18:13:55 -0700539 valid &= value_->CheckValid();
540 if (!valid) return false;
Steven Moreland693640b2018-07-19 13:46:27 -0700541
Steven Moreland25294322018-08-07 18:13:55 -0700542 const static set<string> kSupportedConstTypes = {"String", "int"};
543 if (kSupportedConstTypes.find(type_->ToString()) == kSupportedConstTypes.end()) {
544 AIDL_ERROR(this) << "Constant of type " << type_->ToString() << " is not supported.";
Steven Moreland693640b2018-07-19 13:46:27 -0700545 return false;
546 }
547
Steven Moreland860b1942018-08-16 14:59:28 -0700548 return !ValueString(AidlConstantValueDecorator).empty();
Christopher Wileyd6bdd8d2016-05-03 11:23:13 -0700549}
550
Jiyong Parka428d212018-08-29 22:26:30 +0900551string AidlConstantDeclaration::ToString() const {
552 return "const " + type_->ToString() + " " + name_ + " = " +
553 ValueString(AidlConstantValueDecorator);
554}
555
556string AidlConstantDeclaration::Signature() const {
557 return type_->Signature() + " " + name_;
558}
559
Steven Moreland46e9da82018-07-27 15:45:29 -0700560AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
561 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkb034bf02018-07-30 17:44:33 +0900562 const std::string& comments)
563 : AidlMethod(location, oneway, type, name, args, comments, 0, true) {
564 has_id_ = false;
565}
566
567AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
568 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkb034bf02018-07-30 17:44:33 +0900569 const std::string& comments, int id, bool is_user_defined)
Steven Moreland46e9da82018-07-27 15:45:29 -0700570 : AidlMember(location),
571 oneway_(oneway),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700572 comments_(comments),
573 type_(type),
574 name_(name),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700575 arguments_(std::move(*args)),
Jiyong Parkb034bf02018-07-30 17:44:33 +0900576 id_(id),
577 is_user_defined_(is_user_defined) {
Casey Dahlinf4a93112015-10-05 16:58:09 -0700578 has_id_ = true;
579 delete args;
Christopher Wileyad339272015-10-05 19:11:58 -0700580 for (const unique_ptr<AidlArgument>& a : arguments_) {
581 if (a->IsIn()) { in_arguments_.push_back(a.get()); }
582 if (a->IsOut()) { out_arguments_.push_back(a.get()); }
583 }
Casey Dahlinf4a93112015-10-05 16:58:09 -0700584}
585
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700586
Jiyong Park02da7422018-07-16 16:00:26 +0900587string AidlMethod::Signature() const {
588 vector<string> arg_signatures;
589 for (const auto& arg : GetArguments()) {
Jiyong Park309668e2018-07-28 16:55:44 +0900590 arg_signatures.emplace_back(arg->GetType().ToString());
Jiyong Park02da7422018-07-16 16:00:26 +0900591 }
Jiyong Park309668e2018-07-28 16:55:44 +0900592 return GetName() + "(" + Join(arg_signatures, ", ") + ")";
593}
594
595string AidlMethod::ToString() const {
596 vector<string> arg_strings;
597 for (const auto& arg : GetArguments()) {
598 arg_strings.emplace_back(arg->Signature());
599 }
Steven Moreland4ee68632018-12-14 15:52:46 -0800600 string ret = (IsOneway() ? "oneway " : "") + GetType().Signature() + " " + GetName() + "(" +
601 Join(arg_strings, ", ") + ")";
Jiyong Parked65bf42018-08-28 15:43:27 +0900602 if (HasId()) {
603 ret += " = " + std::to_string(GetId());
604 }
605 return ret;
Jiyong Park02da7422018-07-16 16:00:26 +0900606}
607
Steven Moreland46e9da82018-07-27 15:45:29 -0700608AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
609 const std::string& comments,
Steven Moreland787b0432018-07-03 09:00:58 -0700610 const std::vector<std::string>& package)
Steven Moreland46e9da82018-07-27 15:45:29 -0700611 : AidlAnnotatable(location), name_(name), comments_(comments), package_(package) {}
Steven Moreland787b0432018-07-03 09:00:58 -0700612
613std::string AidlDefinedType::GetPackage() const {
614 return Join(package_, '.');
615}
616
617std::string AidlDefinedType::GetCanonicalName() const {
618 if (package_.empty()) {
619 return GetName();
620 }
621 return GetPackage() + "." + GetName();
622}
623
Steven Moreland46e9da82018-07-27 15:45:29 -0700624AidlParcelable::AidlParcelable(const AidlLocation& location, AidlQualifiedName* name,
Jiyong Parka6605ab2018-11-11 14:30:21 +0900625 const std::vector<std::string>& package, const std::string& comments,
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800626 const std::string& cpp_header)
Jiyong Parka6605ab2018-11-11 14:30:21 +0900627 : AidlDefinedType(location, name->GetDotName(), comments, package),
Steven Moreland787b0432018-07-03 09:00:58 -0700628 name_(name),
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800629 cpp_header_(cpp_header) {
630 // Strip off quotation marks if we actually have a cpp header.
631 if (cpp_header_.length() >= 2) {
632 cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
633 }
Casey Dahlin59401da2015-10-09 18:16:45 -0700634}
635
Jeongik Cha82317dd2019-02-27 20:26:11 +0900636bool AidlParcelable::CheckValid(const AidlTypenames&) const {
637 static const std::set<string> allowed{kStableParcelable};
638 for (const auto& v : GetAnnotations()) {
639 if (allowed.find(v.GetName()) == allowed.end()) {
640 std::ostringstream stream;
641 stream << "Unstructured parcelable can contain only";
642 for (const string& kv : allowed) {
643 stream << " " << kv;
644 }
645 stream << ".";
646 AIDL_ERROR(this) << stream.str();
647 return false;
648 }
649 }
650
651 return true;
652}
653
Jiyong Park02da7422018-07-16 16:00:26 +0900654void AidlParcelable::Write(CodeWriter* writer) const {
655 writer->Write("parcelable %s ;\n", GetName().c_str());
656}
657
Steven Moreland5557f1c2018-07-02 13:50:23 -0700658AidlStructuredParcelable::AidlStructuredParcelable(
Steven Moreland46e9da82018-07-27 15:45:29 -0700659 const AidlLocation& location, AidlQualifiedName* name, const std::vector<std::string>& package,
Jiyong Parka6605ab2018-11-11 14:30:21 +0900660 const std::string& comments, std::vector<std::unique_ptr<AidlVariableDeclaration>>* variables)
661 : AidlParcelable(location, name, package, comments, "" /*cpp_header*/),
Steven Moreland46e9da82018-07-27 15:45:29 -0700662 variables_(std::move(*variables)) {}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700663
Jiyong Park02da7422018-07-16 16:00:26 +0900664void AidlStructuredParcelable::Write(CodeWriter* writer) const {
665 writer->Write("parcelable %s {\n", GetName().c_str());
666 writer->Indent();
667 for (const auto& field : GetFields()) {
Jiyong Parka468e2a2018-08-29 21:25:18 +0900668 writer->Write("%s;\n", field->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +0900669 }
670 writer->Dedent();
671 writer->Write("}\n");
672}
673
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900674bool AidlStructuredParcelable::CheckValid(const AidlTypenames& typenames) const {
675 for (const auto& v : GetFields()) {
676 if (!(v->CheckValid(typenames))) {
677 return false;
678 }
679 }
680
681 return true;
682}
683
Steven Moreland46e9da82018-07-27 15:45:29 -0700684AidlInterface::AidlInterface(const AidlLocation& location, const std::string& name,
Casey Dahlinfb7da2e2015-10-08 17:26:09 -0700685 const std::string& comments, bool oneway,
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800686 std::vector<std::unique_ptr<AidlMember>>* members,
Christopher Wileyd76067c2015-10-19 17:00:13 -0700687 const std::vector<std::string>& package)
Steven Morelandacd53472018-12-14 10:17:26 -0800688 : AidlDefinedType(location, name, comments, package) {
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800689 for (auto& member : *members) {
690 AidlMember* local = member.release();
691 AidlMethod* method = local->AsMethod();
Steven Moreland693640b2018-07-19 13:46:27 -0700692 AidlConstantDeclaration* constant = local->AsConstantDeclaration();
693
694 CHECK(method == nullptr || constant == nullptr);
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800695
696 if (method) {
Steven Moreland8c70ba92018-12-17 10:20:31 -0800697 method->ApplyInterfaceOneway(oneway);
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800698 methods_.emplace_back(method);
Steven Moreland693640b2018-07-19 13:46:27 -0700699 } else if (constant) {
700 constants_.emplace_back(constant);
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800701 } else {
Steven Moreland46e9da82018-07-27 15:45:29 -0700702 AIDL_FATAL(this) << "Member is neither method nor constant!";
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800703 }
704 }
705
706 delete members;
Casey Dahlinfb7da2e2015-10-08 17:26:09 -0700707}
708
Jiyong Park02da7422018-07-16 16:00:26 +0900709void AidlInterface::Write(CodeWriter* writer) const {
710 writer->Write("interface %s {\n", GetName().c_str());
711 writer->Indent();
712 for (const auto& method : GetMethods()) {
Jiyong Park309668e2018-07-28 16:55:44 +0900713 writer->Write("%s;\n", method->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +0900714 }
Jiyong Parka428d212018-08-29 22:26:30 +0900715 for (const auto& constdecl : GetConstantDeclarations()) {
716 writer->Write("%s;\n", constdecl->ToString().c_str());
717 }
Jiyong Park02da7422018-07-16 16:00:26 +0900718 writer->Dedent();
719 writer->Write("}\n");
720}
721
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900722bool AidlInterface::CheckValid(const AidlTypenames& typenames) const {
723 // Has to be a pointer due to deleting copy constructor. No idea why.
724 map<string, const AidlMethod*> method_names;
725 for (const auto& m : GetMethods()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900726 if (!m->GetType().CheckValid(typenames)) {
727 return false;
728 }
729
Steven Morelandacd53472018-12-14 10:17:26 -0800730 if (m->IsOneway() && m->GetType().GetName() != "void") {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900731 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot return a value";
732 return false;
733 }
734
735 set<string> argument_names;
736 for (const auto& arg : m->GetArguments()) {
737 auto it = argument_names.find(arg->GetName());
738 if (it != argument_names.end()) {
739 AIDL_ERROR(m) << "method '" << m->GetName() << "' has duplicate argument name '"
740 << arg->GetName() << "'";
741 return false;
742 }
743 argument_names.insert(arg->GetName());
744
745 if (!arg->GetType().CheckValid(typenames)) {
746 return false;
747 }
748
Steven Morelandacd53472018-12-14 10:17:26 -0800749 if (m->IsOneway() && arg->IsOut()) {
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900750 AIDL_ERROR(m) << "oneway method '" << m->GetName() << "' cannot have out parameters";
751 return false;
752 }
753 }
754
755 auto it = method_names.find(m->GetName());
756 // prevent duplicate methods
757 if (it == method_names.end()) {
758 method_names[m->GetName()] = m.get();
759 } else {
760 AIDL_ERROR(m) << "attempt to redefine method " << m->GetName() << ":";
761 AIDL_ERROR(it->second) << "previously defined here.";
762 return false;
763 }
764
765 static set<string> reserved_methods{"asBinder()", "getInterfaceVersion()",
766 "getTransactionName(int)"};
767
768 if (reserved_methods.find(m->Signature()) != reserved_methods.end()) {
769 AIDL_ERROR(m) << " method " << m->Signature() << " is reserved for internal use." << endl;
770 return false;
771 }
772 }
Steven Moreland4d12f9a2018-10-31 14:30:55 -0700773
774 bool success = true;
775 set<string> constant_names;
776 for (const std::unique_ptr<AidlConstantDeclaration>& constant : GetConstantDeclarations()) {
777 if (constant_names.count(constant->GetName()) > 0) {
778 LOG(ERROR) << "Found duplicate constant name '" << constant->GetName() << "'";
779 success = false;
780 }
781 constant_names.insert(constant->GetName());
782 success = success && constant->CheckValid(typenames);
783 }
784
785 return success;
Jeongik Chadb0f59e2018-11-01 18:11:21 +0900786}
787
Steven Moreland46e9da82018-07-27 15:45:29 -0700788AidlQualifiedName::AidlQualifiedName(const AidlLocation& location, const std::string& term,
789 const std::string& comments)
790 : AidlNode(location), terms_({term}), comments_(comments) {
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800791 if (term.find('.') != string::npos) {
792 terms_ = Split(term, ".");
Steven Moreland46e9da82018-07-27 15:45:29 -0700793 for (const auto& subterm : terms_) {
794 if (subterm.empty()) {
795 AIDL_FATAL(this) << "Malformed qualified identifier: '" << term << "'";
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800796 }
797 }
798 }
Casey Dahlin2b2879b2015-10-13 16:59:44 -0700799}
800
Chih-Hung Hsiehf05cc262016-07-27 11:42:51 -0700801void AidlQualifiedName::AddTerm(const std::string& term) {
Casey Dahlin2b2879b2015-10-13 16:59:44 -0700802 terms_.push_back(term);
803}
804
Steven Moreland46e9da82018-07-27 15:45:29 -0700805AidlImport::AidlImport(const AidlLocation& location, const std::string& needed_class)
806 : AidlNode(location), needed_class_(needed_class) {}
Casey Dahlin0edf3422015-10-07 12:34:59 -0700807
Steven Moreland64e29be2018-08-08 18:52:19 -0700808std::unique_ptr<Parser> Parser::Parse(const std::string& filename,
809 const android::aidl::IoDelegate& io_delegate,
810 AidlTypenames& typenames) {
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700811 // Make sure we can read the file first, before trashing previous state.
Steven Moreland64e29be2018-08-08 18:52:19 -0700812 unique_ptr<string> raw_buffer = io_delegate.GetFileContents(filename);
813 if (raw_buffer == nullptr) {
Steven Moreland46e9da82018-07-27 15:45:29 -0700814 AIDL_ERROR(filename) << "Error while opening file for parsing";
Steven Moreland64e29be2018-08-08 18:52:19 -0700815 return nullptr;
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700816 }
817
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700818 // We're going to scan this buffer in place, and yacc demands we put two
819 // nulls at the end.
Steven Moreland64e29be2018-08-08 18:52:19 -0700820 raw_buffer->append(2u, '\0');
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700821
Steven Moreland64e29be2018-08-08 18:52:19 -0700822 std::unique_ptr<Parser> parser(new Parser(filename, *raw_buffer, typenames));
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700823
Steven Moreland64e29be2018-08-08 18:52:19 -0700824 if (yy::parser(parser.get()).parse() != 0 || parser->HasError()) return nullptr;
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700825
Steven Moreland64e29be2018-08-08 18:52:19 -0700826 return parser;
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700827}
828
Christopher Wiley90be4e32015-10-20 14:55:25 -0700829std::vector<std::string> Parser::Package() const {
830 if (!package_) {
831 return {};
832 }
833 return package_->GetTerms();
834}
835
Steven Moreland46e9da82018-07-27 15:45:29 -0700836void Parser::AddImport(AidlImport* import) {
837 imports_.emplace_back(import);
Casey Dahline2507492015-09-14 17:11:20 -0700838}
Jiyong Park1deecc32018-07-17 01:14:41 +0900839
840bool Parser::Resolve() {
841 bool success = true;
842 for (AidlTypeSpecifier* typespec : unresolved_typespecs_) {
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900843 if (!typespec->Resolve(typenames_)) {
Steven Moreland46e9da82018-07-27 15:45:29 -0700844 AIDL_ERROR(typespec) << "Failed to resolve '" << typespec->GetUnresolvedName() << "'";
Jiyong Park1deecc32018-07-17 01:14:41 +0900845 success = false;
846 // don't stop to show more errors if any
847 }
848 }
849 return success;
850}
Steven Moreland64e29be2018-08-08 18:52:19 -0700851
852Parser::Parser(const std::string& filename, std::string& raw_buffer,
853 android::aidl::AidlTypenames& typenames)
854 : filename_(filename), typenames_(typenames) {
855 yylex_init(&scanner_);
856 buffer_ = yy_scan_buffer(&raw_buffer[0], raw_buffer.length(), scanner_);
857}
858
859Parser::~Parser() {
860 yy_delete_buffer(buffer_, scanner_);
861 yylex_destroy(scanner_);
862}