blob: b76cf3a62fe50442ccdce7c0cb937171a04e341b [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
Roshan Pius9d7810a2016-07-28 08:57:50 -070015#include <android-base/parseint.h>
Elliott Hughes0a620672015-12-04 13:53:18 -080016#include <android-base/strings.h>
Christopher Wileyd76067c2015-10-19 17:00:13 -070017
Ying Wang3000e752016-01-11 18:05:59 -080018#include "aidl_language_y.h"
Christopher Wiley4a2884b2015-10-07 11:27:45 -070019#include "logging.h"
Jiyong Park02da7422018-07-16 16:00:26 +090020#include "type_java.h"
21#include "type_namespace.h"
Adam Lesinskiffa16862014-01-23 18:17:42 -080022
Casey Dahlin07b9dde2015-09-10 19:13:49 -070023#ifdef _WIN32
24int isatty(int fd)
25{
26 return (fd == 0);
27}
28#endif
29
Christopher Wiley4a2884b2015-10-07 11:27:45 -070030using android::aidl::IoDelegate;
Christopher Wileyd76067c2015-10-19 17:00:13 -070031using android::base::Join;
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -080032using android::base::Split;
Casey Dahlindd691812015-09-09 17:59:06 -070033using std::cerr;
34using std::endl;
Jiyong Park1deecc32018-07-17 01:14:41 +090035using std::pair;
Jiyong Park68bc77a2018-07-19 19:00:45 +090036using std::set;
Christopher Wiley4a2884b2015-10-07 11:27:45 -070037using std::string;
38using std::unique_ptr;
Jiyong Parkccf00f82018-07-17 01:39:23 +090039using std::vector;
Adam Lesinskiffa16862014-01-23 18:17:42 -080040
Casey Dahlindd691812015-09-09 17:59:06 -070041void yylex_init(void **);
42void yylex_destroy(void *);
43void yyset_in(FILE *f, void *);
Casey Dahline2507492015-09-14 17:11:20 -070044int yyparse(Parser*);
Christopher Wiley4a2884b2015-10-07 11:27:45 -070045YY_BUFFER_STATE yy_scan_buffer(char *, size_t, void *);
Casey Dahlin89d44842015-09-24 18:45:54 -070046void yy_delete_buffer(YY_BUFFER_STATE, void *);
Casey Dahlindd691812015-09-09 17:59:06 -070047
Casey Dahlincdbbc8c2015-10-14 15:31:04 -070048AidlToken::AidlToken(const std::string& text, const std::string& comments)
49 : text_(text),
50 comments_(comments) {}
Casey Dahlin98a544b2015-10-14 14:22:55 -070051
Steven Moreland46e9da82018-07-27 15:45:29 -070052AidlLocation::AidlLocation(const std::string& file, Point begin, Point end)
53 : file_(file), begin_(begin), end_(end) {}
54
55std::ostream& operator<<(std::ostream& os, const AidlLocation& l) {
56 os << l.file_ << ":" << l.begin_.line << "." << l.begin_.column << "-";
57 if (l.begin_.line != l.end_.line) {
58 os << l.end_.line << ".";
59 }
60 os << l.end_.column;
61 return os;
62}
63
64AidlNode::AidlNode(const AidlLocation& location) : location_(location) {}
65
Steven Moreland92c55f12018-07-31 14:08:37 -070066AidlError::AidlError(bool fatal) : os_(std::cerr), fatal_(fatal) {
67 os_ << "ERROR: ";
68}
69
Jiyong Park68bc77a2018-07-19 19:00:45 +090070static const string kNullable("nullable");
71static const string kUtf8("utf8");
72static const string kUtf8InCpp("utf8InCpp");
73
74static const set<string> kAnnotationNames{kNullable, kUtf8, kUtf8InCpp};
75
Steven Moreland46e9da82018-07-27 15:45:29 -070076AidlAnnotation* AidlAnnotation::Parse(const AidlLocation& location, const string& name) {
77 if (kAnnotationNames.find(name) == kAnnotationNames.end()) {
Jiyong Park68bc77a2018-07-19 19:00:45 +090078 std::ostringstream stream;
Steven Moreland46e9da82018-07-27 15:45:29 -070079 stream << "'" << name << "' is not a recognized annotation. ";
Jiyong Park68bc77a2018-07-19 19:00:45 +090080 stream << "It must be one of:";
81 for (const string& kv : kAnnotationNames) {
82 stream << " " << kv;
83 }
84 stream << ".";
Steven Moreland46e9da82018-07-27 15:45:29 -070085 AIDL_ERROR(location) << stream.str();
86 return nullptr;
Jiyong Park68bc77a2018-07-19 19:00:45 +090087 }
Steven Moreland46e9da82018-07-27 15:45:29 -070088 return new AidlAnnotation(location, name);
Jiyong Park68bc77a2018-07-19 19:00:45 +090089}
90
Steven Moreland46e9da82018-07-27 15:45:29 -070091AidlAnnotation::AidlAnnotation(const AidlLocation& location, const string& name)
92 : AidlNode(location), name_(name) {}
93
Jiyong Park68bc77a2018-07-19 19:00:45 +090094static bool HasAnnotation(const set<unique_ptr<AidlAnnotation>>& annotations, const string& name) {
95 for (const auto& a : annotations) {
96 if (a->GetName() == name) {
97 return true;
98 }
99 }
100 return false;
101}
102
Steven Moreland46e9da82018-07-27 15:45:29 -0700103AidlAnnotatable::AidlAnnotatable(const AidlLocation& location) : AidlNode(location) {}
104
Jiyong Park68bc77a2018-07-19 19:00:45 +0900105bool AidlAnnotatable::IsNullable() const {
106 return HasAnnotation(annotations_, kNullable);
107}
108
109bool AidlAnnotatable::IsUtf8() const {
110 return HasAnnotation(annotations_, kUtf8);
111}
112
113bool AidlAnnotatable::IsUtf8InCpp() const {
114 return HasAnnotation(annotations_, kUtf8InCpp);
115}
116
117string AidlAnnotatable::ToString() const {
118 vector<string> ret;
119 for (const auto& a : annotations_) {
120 ret.emplace_back(a->ToString());
121 }
122 std::sort(ret.begin(), ret.end());
123 return Join(ret, " ");
124}
125
Steven Moreland46e9da82018-07-27 15:45:29 -0700126AidlTypeSpecifier::AidlTypeSpecifier(const AidlLocation& location, const string& unresolved_name,
127 bool is_array,
Jiyong Park1deecc32018-07-17 01:14:41 +0900128 vector<unique_ptr<AidlTypeSpecifier>>* type_params,
Steven Moreland46e9da82018-07-27 15:45:29 -0700129 const string& comments)
130 : AidlAnnotatable(location),
131 unresolved_name_(unresolved_name),
Casey Dahlinf7a421c2015-10-05 17:24:28 -0700132 is_array_(is_array),
Jiyong Park1deecc32018-07-17 01:14:41 +0900133 type_params_(type_params),
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700134 comments_(comments) {}
135
Jiyong Park1deecc32018-07-17 01:14:41 +0900136string AidlTypeSpecifier::ToString() const {
137 string ret = GetName();
138 if (IsGeneric()) {
139 vector<string> arg_names;
140 for (const auto& ta : GetTypeParameters()) {
Jiyong Parkccf00f82018-07-17 01:39:23 +0900141 arg_names.emplace_back(ta->ToString());
142 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900143 ret += "<" + Join(arg_names, ",") + ">";
Jiyong Parkccf00f82018-07-17 01:39:23 +0900144 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900145 if (IsArray()) {
146 ret += "[]";
147 }
148 return ret;
Jiyong Parkccf00f82018-07-17 01:39:23 +0900149}
150
Jiyong Park02da7422018-07-16 16:00:26 +0900151string AidlTypeSpecifier::Signature() const {
152 string ret = ToString();
153 string annotations = AidlAnnotatable::ToString();
154 if (annotations != "") {
155 ret = annotations + " " + ret;
156 }
157 return ret;
158}
159
Jiyong Park1deecc32018-07-17 01:14:41 +0900160bool AidlTypeSpecifier::Resolve(android::aidl::AidlTypenames& typenames) {
161 assert(!IsResolved());
162 pair<string, bool> result = typenames.ResolveTypename(unresolved_name_);
163 if (result.second) {
164 fully_qualified_name_ = result.first;
Jiyong Parkccf00f82018-07-17 01:39:23 +0900165 }
Jiyong Park1deecc32018-07-17 01:14:41 +0900166 return result.second;
Casey Dahlin70078e62015-09-30 17:01:30 -0700167}
168
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900169bool AidlTypeSpecifier::CheckValid() const {
170 if (IsGeneric()) {
171 const string& type_name = GetName();
172 const int num = GetTypeParameters().size();
173 if (type_name == "List") {
174 if (num > 1) {
175 cerr << " List cannot have type parameters more than one, but got "
176 << "'" << ToString() << "'" << endl;
177 return false;
178 }
179 } else if (type_name == "Map") {
180 if (num != 0 && num != 2) {
181 cerr << "Map must have 0 or 2 type parameters, but got "
182 << "'" << ToString() << "'" << endl;
183 return false;
184 }
185 }
186 }
187 return true;
188}
189
Steven Moreland46e9da82018-07-27 15:45:29 -0700190AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
191 AidlTypeSpecifier* type, const std::string& name)
192 : AidlVariableDeclaration(location, type, name, nullptr /*default_value*/) {}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700193
Steven Moreland46e9da82018-07-27 15:45:29 -0700194AidlVariableDeclaration::AidlVariableDeclaration(const AidlLocation& location,
195 AidlTypeSpecifier* type, const std::string& name,
196 AidlConstantValue* default_value)
197 : AidlNode(location), type_(type), name_(name), default_value_(default_value) {}
Steven Moreland9ea10e32018-07-19 15:26:09 -0700198
199bool AidlVariableDeclaration::CheckValid() const {
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900200 if (!type_->CheckValid()) {
201 return false;
202 }
203
Steven Moreland9ea10e32018-07-19 15:26:09 -0700204 if (default_value_ == nullptr) return true;
205
206 const string given_type = type_->GetName();
207 const string value_type = AidlConstantValue::ToString(default_value_->GetType());
208
209 if (given_type != value_type) {
Steven Moreland46e9da82018-07-27 15:45:29 -0700210 AIDL_ERROR(*this) << "Declaration " << name_ << " is of type " << given_type
211 << " but value is of type " << value_type << endl;
Steven Moreland9ea10e32018-07-19 15:26:09 -0700212 return false;
213 }
214 return true;
215}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700216
217string AidlVariableDeclaration::ToString() const {
Steven Moreland9ea10e32018-07-19 15:26:09 -0700218 string ret = type_->ToString() + " " + name_;
219 if (default_value_ != nullptr) {
220 ret += " = " + default_value_->ToString();
221 }
222 return ret;
Steven Moreland5557f1c2018-07-02 13:50:23 -0700223}
224
Jiyong Park02da7422018-07-16 16:00:26 +0900225string AidlVariableDeclaration::Signature() const {
226 return type_->Signature() + " " + name_;
227}
228
Steven Moreland46e9da82018-07-27 15:45:29 -0700229AidlArgument::AidlArgument(const AidlLocation& location, AidlArgument::Direction direction,
230 AidlTypeSpecifier* type, const std::string& name)
231 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700232 direction_(direction),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700233 direction_specified_(true) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700234
Steven Moreland46e9da82018-07-27 15:45:29 -0700235AidlArgument::AidlArgument(const AidlLocation& location, AidlTypeSpecifier* type,
236 const std::string& name)
237 : AidlVariableDeclaration(location, type, name),
Casey Dahlinfd6fb482015-09-30 14:48:18 -0700238 direction_(AidlArgument::IN_DIR),
Steven Moreland5557f1c2018-07-02 13:50:23 -0700239 direction_specified_(false) {}
Casey Dahlinc378c992015-09-29 16:50:40 -0700240
Jiyong Park02da7422018-07-16 16:00:26 +0900241string AidlArgument::GetDirectionSpecifier() const {
Casey Dahlinc378c992015-09-29 16:50:40 -0700242 string ret;
Casey Dahlinc378c992015-09-29 16:50:40 -0700243 if (direction_specified_) {
244 switch(direction_) {
245 case AidlArgument::IN_DIR:
246 ret += "in ";
247 break;
248 case AidlArgument::OUT_DIR:
249 ret += "out ";
250 break;
251 case AidlArgument::INOUT_DIR:
252 ret += "inout ";
253 break;
254 }
255 }
Casey Dahlinc378c992015-09-29 16:50:40 -0700256 return ret;
257}
Casey Dahlinbc7a50a2015-09-28 19:20:50 -0700258
Jiyong Park02da7422018-07-16 16:00:26 +0900259string AidlArgument::ToString() const {
260 return GetDirectionSpecifier() + AidlVariableDeclaration::ToString();
261}
262
263std::string AidlArgument::Signature() const {
Steven Moreland46e9da82018-07-27 15:45:29 -0700264 class AidlInterface;
265 class AidlInterface;
266 class AidlParcelable;
267 class AidlStructuredParcelable;
268 class AidlParcelable;
269 class AidlStructuredParcelable;
Jiyong Park02da7422018-07-16 16:00:26 +0900270 return GetDirectionSpecifier() + AidlVariableDeclaration::Signature();
271}
272
Steven Moreland46e9da82018-07-27 15:45:29 -0700273AidlMember::AidlMember(const AidlLocation& location) : AidlNode(location) {}
274
Steven Moreland693640b2018-07-19 13:46:27 -0700275string AidlConstantValue::ToString(Type type) {
276 switch (type) {
277 case Type::INTEGER:
278 return "int";
279 case Type::STRING:
280 return "String";
281 case Type::ERROR:
282 LOG(FATAL) << "aidl internal error: error type failed to halt program";
283 default:
284 LOG(FATAL) << "aidl internal error: unknown constant type: " << static_cast<int>(type);
285 return ""; // not reached
Roshan Pius3b2203d2016-07-22 16:13:20 -0700286 }
287}
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800288
Steven Moreland46e9da82018-07-27 15:45:29 -0700289AidlConstantValue::AidlConstantValue(const AidlLocation& location, Type type,
290 const std::string& checked_value)
291 : AidlNode(location), type_(type), value_(checked_value) {}
Steven Moreland693640b2018-07-19 13:46:27 -0700292
Steven Moreland46e9da82018-07-27 15:45:29 -0700293AidlConstantValue* AidlConstantValue::LiteralInt(const AidlLocation& location, int32_t value) {
294 return new AidlConstantValue(location, Type::INTEGER, std::to_string(value));
Steven Moreland693640b2018-07-19 13:46:27 -0700295}
296
Steven Moreland46e9da82018-07-27 15:45:29 -0700297AidlConstantValue* AidlConstantValue::ParseHex(const AidlLocation& location,
298 const std::string& value) {
Steven Moreland693640b2018-07-19 13:46:27 -0700299 uint32_t unsigned_value;
300 if (!android::base::ParseUint<uint32_t>(value.c_str(), &unsigned_value)) {
Steven Moreland46e9da82018-07-27 15:45:29 -0700301 AIDL_ERROR(location) << "Found invalid int value '" << value << "'";
302 return new AidlConstantValue(location, Type::ERROR, "");
Steven Moreland693640b2018-07-19 13:46:27 -0700303 }
304
Steven Moreland46e9da82018-07-27 15:45:29 -0700305 return LiteralInt(location, unsigned_value);
Steven Moreland693640b2018-07-19 13:46:27 -0700306}
307
Steven Moreland46e9da82018-07-27 15:45:29 -0700308AidlConstantValue* AidlConstantValue::ParseString(const AidlLocation& location,
309 const std::string& value) {
Steven Moreland693640b2018-07-19 13:46:27 -0700310 for (size_t i = 0; i < value.length(); ++i) {
311 const char& c = value[i];
Christopher Wileyd6bdd8d2016-05-03 11:23:13 -0700312 if (c <= 0x1f || // control characters are < 0x20
313 c >= 0x7f || // DEL is 0x7f
314 c == '\\') { // Disallow backslashes for future proofing.
Steven Moreland46e9da82018-07-27 15:45:29 -0700315 AIDL_ERROR(location) << "Found invalid character at index " << i << " in string constant '"
316 << value << "'";
317 return new AidlConstantValue(location, Type::ERROR, "");
Christopher Wileyd6bdd8d2016-05-03 11:23:13 -0700318 }
319 }
Steven Moreland693640b2018-07-19 13:46:27 -0700320
Steven Moreland46e9da82018-07-27 15:45:29 -0700321 return new AidlConstantValue(location, Type::STRING, value);
Steven Moreland693640b2018-07-19 13:46:27 -0700322}
323
324string AidlConstantValue::ToString() const {
325 CHECK(type_ != Type::ERROR) << "aidl internal error: error should be checked " << value_;
326 return value_;
327}
328
Steven Moreland46e9da82018-07-27 15:45:29 -0700329AidlConstantDeclaration::AidlConstantDeclaration(const AidlLocation& location,
330 AidlTypeSpecifier* type, const std::string& name,
331 AidlConstantValue* value)
332 : AidlMember(location), type_(type), name_(name), value_(value) {}
Steven Moreland693640b2018-07-19 13:46:27 -0700333
334bool AidlConstantDeclaration::CheckValid() const {
335 // Error message logged above
336 if (value_->GetType() == AidlConstantValue::Type::ERROR) return false;
337
338 if (type_->ToString() != AidlConstantValue::ToString(value_->GetType())) {
Steven Moreland46e9da82018-07-27 15:45:29 -0700339 AIDL_ERROR(this) << "Constant " << name_ << " is of type " << type_->ToString()
340 << " but value is of type " << AidlConstantValue::ToString(value_->GetType());
Steven Moreland693640b2018-07-19 13:46:27 -0700341 return false;
342 }
343
344 return true;
Christopher Wileyd6bdd8d2016-05-03 11:23:13 -0700345}
346
Steven Moreland46e9da82018-07-27 15:45:29 -0700347AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
348 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkb034bf02018-07-30 17:44:33 +0900349 const std::string& comments)
350 : AidlMethod(location, oneway, type, name, args, comments, 0, true) {
351 has_id_ = false;
352}
353
354AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
355 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkd59a10d2018-07-18 11:12:55 +0900356 const std::string& comments, int id)
Jiyong Parkb034bf02018-07-30 17:44:33 +0900357 : AidlMethod(location, oneway, type, name, args, comments, id, true) {}
358
359AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
360 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
361 const std::string& comments, int id, bool is_user_defined)
Steven Moreland46e9da82018-07-27 15:45:29 -0700362 : AidlMember(location),
363 oneway_(oneway),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700364 comments_(comments),
365 type_(type),
366 name_(name),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700367 arguments_(std::move(*args)),
Jiyong Parkb034bf02018-07-30 17:44:33 +0900368 id_(id),
369 is_user_defined_(is_user_defined) {
Casey Dahlinf4a93112015-10-05 16:58:09 -0700370 has_id_ = true;
371 delete args;
Christopher Wileyad339272015-10-05 19:11:58 -0700372 for (const unique_ptr<AidlArgument>& a : arguments_) {
373 if (a->IsIn()) { in_arguments_.push_back(a.get()); }
374 if (a->IsOut()) { out_arguments_.push_back(a.get()); }
375 }
Casey Dahlinf4a93112015-10-05 16:58:09 -0700376}
377
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700378
Jiyong Park02da7422018-07-16 16:00:26 +0900379string AidlMethod::Signature() const {
380 vector<string> arg_signatures;
381 for (const auto& arg : GetArguments()) {
Jiyong Park309668e2018-07-28 16:55:44 +0900382 arg_signatures.emplace_back(arg->GetType().ToString());
Jiyong Park02da7422018-07-16 16:00:26 +0900383 }
Jiyong Park309668e2018-07-28 16:55:44 +0900384 return GetName() + "(" + Join(arg_signatures, ", ") + ")";
385}
386
387string AidlMethod::ToString() const {
388 vector<string> arg_strings;
389 for (const auto& arg : GetArguments()) {
390 arg_strings.emplace_back(arg->Signature());
391 }
392 return GetType().Signature() + " " + GetName() + "(" + Join(arg_strings, ", ") + ")";
Jiyong Park02da7422018-07-16 16:00:26 +0900393}
394
Steven Moreland46e9da82018-07-27 15:45:29 -0700395AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
396 const std::string& comments,
Steven Moreland787b0432018-07-03 09:00:58 -0700397 const std::vector<std::string>& package)
Steven Moreland46e9da82018-07-27 15:45:29 -0700398 : AidlAnnotatable(location), name_(name), comments_(comments), package_(package) {}
Steven Moreland787b0432018-07-03 09:00:58 -0700399
400std::string AidlDefinedType::GetPackage() const {
401 return Join(package_, '.');
402}
403
404std::string AidlDefinedType::GetCanonicalName() const {
405 if (package_.empty()) {
406 return GetName();
407 }
408 return GetPackage() + "." + GetName();
409}
410
Steven Moreland46e9da82018-07-27 15:45:29 -0700411AidlParcelable::AidlParcelable(const AidlLocation& location, AidlQualifiedName* name,
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800412 const std::vector<std::string>& package,
413 const std::string& cpp_header)
Steven Moreland46e9da82018-07-27 15:45:29 -0700414 : AidlDefinedType(location, name->GetDotName(), "" /*comments*/, package),
Steven Moreland787b0432018-07-03 09:00:58 -0700415 name_(name),
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800416 cpp_header_(cpp_header) {
417 // Strip off quotation marks if we actually have a cpp header.
418 if (cpp_header_.length() >= 2) {
419 cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
420 }
Casey Dahlin59401da2015-10-09 18:16:45 -0700421}
422
Jiyong Park02da7422018-07-16 16:00:26 +0900423void AidlParcelable::Write(CodeWriter* writer) const {
424 writer->Write("parcelable %s ;\n", GetName().c_str());
425}
426
Steven Moreland5557f1c2018-07-02 13:50:23 -0700427AidlStructuredParcelable::AidlStructuredParcelable(
Steven Moreland46e9da82018-07-27 15:45:29 -0700428 const AidlLocation& location, AidlQualifiedName* name, const std::vector<std::string>& package,
Steven Moreland5557f1c2018-07-02 13:50:23 -0700429 std::vector<std::unique_ptr<AidlVariableDeclaration>>* variables)
Steven Moreland46e9da82018-07-27 15:45:29 -0700430 : AidlParcelable(location, name, package, "" /*cpp_header*/),
431 variables_(std::move(*variables)) {}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700432
Jiyong Park02da7422018-07-16 16:00:26 +0900433void AidlStructuredParcelable::Write(CodeWriter* writer) const {
434 writer->Write("parcelable %s {\n", GetName().c_str());
435 writer->Indent();
436 for (const auto& field : GetFields()) {
437 writer->Write("%s;\n", field->Signature().c_str());
438 }
439 writer->Dedent();
440 writer->Write("}\n");
441}
442
Steven Moreland46e9da82018-07-27 15:45:29 -0700443AidlInterface::AidlInterface(const AidlLocation& location, const std::string& name,
Casey Dahlinfb7da2e2015-10-08 17:26:09 -0700444 const std::string& comments, bool oneway,
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800445 std::vector<std::unique_ptr<AidlMember>>* members,
Christopher Wileyd76067c2015-10-19 17:00:13 -0700446 const std::vector<std::string>& package)
Steven Moreland46e9da82018-07-27 15:45:29 -0700447 : AidlDefinedType(location, name, comments, package), oneway_(oneway) {
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800448 for (auto& member : *members) {
449 AidlMember* local = member.release();
450 AidlMethod* method = local->AsMethod();
Steven Moreland693640b2018-07-19 13:46:27 -0700451 AidlConstantDeclaration* constant = local->AsConstantDeclaration();
452
453 CHECK(method == nullptr || constant == nullptr);
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800454
455 if (method) {
456 methods_.emplace_back(method);
Steven Moreland693640b2018-07-19 13:46:27 -0700457 } else if (constant) {
458 constants_.emplace_back(constant);
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800459 } else {
Steven Moreland46e9da82018-07-27 15:45:29 -0700460 AIDL_FATAL(this) << "Member is neither method nor constant!";
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800461 }
462 }
463
464 delete members;
Casey Dahlinfb7da2e2015-10-08 17:26:09 -0700465}
466
Jiyong Park02da7422018-07-16 16:00:26 +0900467void AidlInterface::Write(CodeWriter* writer) const {
468 writer->Write("interface %s {\n", GetName().c_str());
469 writer->Indent();
470 for (const auto& method : GetMethods()) {
Jiyong Park309668e2018-07-28 16:55:44 +0900471 writer->Write("%s;\n", method->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +0900472 }
473 writer->Dedent();
474 writer->Write("}\n");
475}
476
Steven Moreland46e9da82018-07-27 15:45:29 -0700477AidlQualifiedName::AidlQualifiedName(const AidlLocation& location, const std::string& term,
478 const std::string& comments)
479 : AidlNode(location), terms_({term}), comments_(comments) {
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800480 if (term.find('.') != string::npos) {
481 terms_ = Split(term, ".");
Steven Moreland46e9da82018-07-27 15:45:29 -0700482 for (const auto& subterm : terms_) {
483 if (subterm.empty()) {
484 AIDL_FATAL(this) << "Malformed qualified identifier: '" << term << "'";
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800485 }
486 }
487 }
Casey Dahlin2b2879b2015-10-13 16:59:44 -0700488}
489
Chih-Hung Hsiehf05cc262016-07-27 11:42:51 -0700490void AidlQualifiedName::AddTerm(const std::string& term) {
Casey Dahlin2b2879b2015-10-13 16:59:44 -0700491 terms_.push_back(term);
492}
493
Steven Moreland46e9da82018-07-27 15:45:29 -0700494AidlImport::AidlImport(const AidlLocation& location, const std::string& needed_class)
495 : AidlNode(location), needed_class_(needed_class) {}
Casey Dahlin0edf3422015-10-07 12:34:59 -0700496
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900497Parser::Parser(const IoDelegate& io_delegate, android::aidl::AidlTypenames& typenames)
498 : io_delegate_(io_delegate), typenames_(typenames) {
499 yylex_init(&scanner_);
500}
501
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700502Parser::~Parser() {
503 if (raw_buffer_) {
504 yy_delete_buffer(buffer_, scanner_);
505 raw_buffer_.reset();
506 }
507 yylex_destroy(scanner_);
508}
509
510bool Parser::ParseFile(const string& filename) {
511 // Make sure we can read the file first, before trashing previous state.
512 unique_ptr<string> new_buffer = io_delegate_.GetFileContents(filename);
513 if (!new_buffer) {
Steven Moreland46e9da82018-07-27 15:45:29 -0700514 AIDL_ERROR(filename) << "Error while opening file for parsing";
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700515 return false;
516 }
517
518 // Throw away old parsing state if we have any.
519 if (raw_buffer_) {
520 yy_delete_buffer(buffer_, scanner_);
521 raw_buffer_.reset();
522 }
523
524 raw_buffer_ = std::move(new_buffer);
525 // We're going to scan this buffer in place, and yacc demands we put two
526 // nulls at the end.
527 raw_buffer_->append(2u, '\0');
528 filename_ = filename;
Christopher Wileyd76067c2015-10-19 17:00:13 -0700529 package_.reset();
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700530 error_ = 0;
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700531
532 buffer_ = yy_scan_buffer(&(*raw_buffer_)[0], raw_buffer_->length(), scanner_);
533
Steven Moreland2ca4fcb2018-06-27 16:01:01 -0700534 if (yy::parser(this).parse() != 0 || error_ != 0)
535 return false;
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700536
Jiyong Park1deecc32018-07-17 01:14:41 +0900537 return true;
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700538}
539
Christopher Wiley90be4e32015-10-20 14:55:25 -0700540std::vector<std::string> Parser::Package() const {
541 if (!package_) {
542 return {};
543 }
544 return package_->GetTerms();
545}
546
Steven Moreland46e9da82018-07-27 15:45:29 -0700547void Parser::AddImport(AidlImport* import) {
548 imports_.emplace_back(import);
Casey Dahline2507492015-09-14 17:11:20 -0700549}
Jiyong Park1deecc32018-07-17 01:14:41 +0900550
551bool Parser::Resolve() {
552 bool success = true;
553 for (AidlTypeSpecifier* typespec : unresolved_typespecs_) {
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900554 if (!typespec->Resolve(typenames_)) {
Steven Moreland46e9da82018-07-27 15:45:29 -0700555 AIDL_ERROR(typespec) << "Failed to resolve '" << typespec->GetUnresolvedName() << "'";
Jiyong Park1deecc32018-07-17 01:14:41 +0900556 success = false;
557 // don't stop to show more errors if any
558 }
559 }
560 return success;
561}