blob: 1dc5a46ce9d2de7ca69f0e890e16fcbe441f9077 [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 Parkd59a10d2018-07-18 11:12:55 +0900349 const std::string& comments, int id)
Steven Moreland46e9da82018-07-27 15:45:29 -0700350 : AidlMember(location),
351 oneway_(oneway),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700352 comments_(comments),
353 type_(type),
354 name_(name),
Casey Dahlinf4a93112015-10-05 16:58:09 -0700355 arguments_(std::move(*args)),
356 id_(id) {
357 has_id_ = true;
358 delete args;
Christopher Wileyad339272015-10-05 19:11:58 -0700359 for (const unique_ptr<AidlArgument>& a : arguments_) {
360 if (a->IsIn()) { in_arguments_.push_back(a.get()); }
361 if (a->IsOut()) { out_arguments_.push_back(a.get()); }
362 }
Casey Dahlinf4a93112015-10-05 16:58:09 -0700363}
364
Steven Moreland46e9da82018-07-27 15:45:29 -0700365AidlMethod::AidlMethod(const AidlLocation& location, bool oneway, AidlTypeSpecifier* type,
366 const std::string& name, std::vector<std::unique_ptr<AidlArgument>>* args,
Jiyong Parkd59a10d2018-07-18 11:12:55 +0900367 const std::string& comments)
Steven Moreland46e9da82018-07-27 15:45:29 -0700368 : AidlMethod(location, oneway, type, name, args, comments, 0) {
Casey Dahlinf4a93112015-10-05 16:58:09 -0700369 has_id_ = false;
370}
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700371
Jiyong Park02da7422018-07-16 16:00:26 +0900372string AidlMethod::Signature() const {
373 vector<string> arg_signatures;
374 for (const auto& arg : GetArguments()) {
Jiyong Park309668e2018-07-28 16:55:44 +0900375 arg_signatures.emplace_back(arg->GetType().ToString());
Jiyong Park02da7422018-07-16 16:00:26 +0900376 }
Jiyong Park309668e2018-07-28 16:55:44 +0900377 return GetName() + "(" + Join(arg_signatures, ", ") + ")";
378}
379
380string AidlMethod::ToString() const {
381 vector<string> arg_strings;
382 for (const auto& arg : GetArguments()) {
383 arg_strings.emplace_back(arg->Signature());
384 }
385 return GetType().Signature() + " " + GetName() + "(" + Join(arg_strings, ", ") + ")";
Jiyong Park02da7422018-07-16 16:00:26 +0900386}
387
Steven Moreland46e9da82018-07-27 15:45:29 -0700388AidlDefinedType::AidlDefinedType(const AidlLocation& location, const std::string& name,
389 const std::string& comments,
Steven Moreland787b0432018-07-03 09:00:58 -0700390 const std::vector<std::string>& package)
Steven Moreland46e9da82018-07-27 15:45:29 -0700391 : AidlAnnotatable(location), name_(name), comments_(comments), package_(package) {}
Steven Moreland787b0432018-07-03 09:00:58 -0700392
393std::string AidlDefinedType::GetPackage() const {
394 return Join(package_, '.');
395}
396
397std::string AidlDefinedType::GetCanonicalName() const {
398 if (package_.empty()) {
399 return GetName();
400 }
401 return GetPackage() + "." + GetName();
402}
403
Steven Moreland46e9da82018-07-27 15:45:29 -0700404AidlParcelable::AidlParcelable(const AidlLocation& location, AidlQualifiedName* name,
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800405 const std::vector<std::string>& package,
406 const std::string& cpp_header)
Steven Moreland46e9da82018-07-27 15:45:29 -0700407 : AidlDefinedType(location, name->GetDotName(), "" /*comments*/, package),
Steven Moreland787b0432018-07-03 09:00:58 -0700408 name_(name),
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800409 cpp_header_(cpp_header) {
410 // Strip off quotation marks if we actually have a cpp header.
411 if (cpp_header_.length() >= 2) {
412 cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
413 }
Casey Dahlin59401da2015-10-09 18:16:45 -0700414}
415
Jiyong Park02da7422018-07-16 16:00:26 +0900416void AidlParcelable::Write(CodeWriter* writer) const {
417 writer->Write("parcelable %s ;\n", GetName().c_str());
418}
419
Steven Moreland5557f1c2018-07-02 13:50:23 -0700420AidlStructuredParcelable::AidlStructuredParcelable(
Steven Moreland46e9da82018-07-27 15:45:29 -0700421 const AidlLocation& location, AidlQualifiedName* name, const std::vector<std::string>& package,
Steven Moreland5557f1c2018-07-02 13:50:23 -0700422 std::vector<std::unique_ptr<AidlVariableDeclaration>>* variables)
Steven Moreland46e9da82018-07-27 15:45:29 -0700423 : AidlParcelable(location, name, package, "" /*cpp_header*/),
424 variables_(std::move(*variables)) {}
Steven Moreland5557f1c2018-07-02 13:50:23 -0700425
Jiyong Park02da7422018-07-16 16:00:26 +0900426void AidlStructuredParcelable::Write(CodeWriter* writer) const {
427 writer->Write("parcelable %s {\n", GetName().c_str());
428 writer->Indent();
429 for (const auto& field : GetFields()) {
430 writer->Write("%s;\n", field->Signature().c_str());
431 }
432 writer->Dedent();
433 writer->Write("}\n");
434}
435
Steven Moreland46e9da82018-07-27 15:45:29 -0700436AidlInterface::AidlInterface(const AidlLocation& location, const std::string& name,
Casey Dahlinfb7da2e2015-10-08 17:26:09 -0700437 const std::string& comments, bool oneway,
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800438 std::vector<std::unique_ptr<AidlMember>>* members,
Christopher Wileyd76067c2015-10-19 17:00:13 -0700439 const std::vector<std::string>& package)
Steven Moreland46e9da82018-07-27 15:45:29 -0700440 : AidlDefinedType(location, name, comments, package), oneway_(oneway) {
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800441 for (auto& member : *members) {
442 AidlMember* local = member.release();
443 AidlMethod* method = local->AsMethod();
Steven Moreland693640b2018-07-19 13:46:27 -0700444 AidlConstantDeclaration* constant = local->AsConstantDeclaration();
445
446 CHECK(method == nullptr || constant == nullptr);
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800447
448 if (method) {
449 methods_.emplace_back(method);
Steven Moreland693640b2018-07-19 13:46:27 -0700450 } else if (constant) {
451 constants_.emplace_back(constant);
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800452 } else {
Steven Moreland46e9da82018-07-27 15:45:29 -0700453 AIDL_FATAL(this) << "Member is neither method nor constant!";
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800454 }
455 }
456
457 delete members;
Casey Dahlinfb7da2e2015-10-08 17:26:09 -0700458}
459
Jiyong Park02da7422018-07-16 16:00:26 +0900460void AidlInterface::Write(CodeWriter* writer) const {
461 writer->Write("interface %s {\n", GetName().c_str());
462 writer->Indent();
463 for (const auto& method : GetMethods()) {
Jiyong Park309668e2018-07-28 16:55:44 +0900464 writer->Write("%s;\n", method->ToString().c_str());
Jiyong Park02da7422018-07-16 16:00:26 +0900465 }
466 writer->Dedent();
467 writer->Write("}\n");
468}
469
Steven Morelandc258abc2018-07-10 14:03:38 -0700470AidlDefinedType* AidlDocument::ReleaseDefinedType() {
471 if (defined_types_.size() == 0) {
Steven Moreland5557f1c2018-07-02 13:50:23 -0700472 return nullptr;
473 }
474
Steven Morelandc258abc2018-07-10 14:03:38 -0700475 if (defined_types_.size() > 1) {
Steven Moreland46e9da82018-07-27 15:45:29 -0700476 AIDL_ERROR(*defined_types_[1]) << "AIDL only supports compiling one defined type per file.";
Steven Morelandc258abc2018-07-10 14:03:38 -0700477 return nullptr;
Steven Moreland5557f1c2018-07-02 13:50:23 -0700478 }
479
Steven Morelandc258abc2018-07-10 14:03:38 -0700480 return defined_types_[0].release();
Steven Moreland5557f1c2018-07-02 13:50:23 -0700481}
482
Steven Moreland46e9da82018-07-27 15:45:29 -0700483AidlQualifiedName::AidlQualifiedName(const AidlLocation& location, const std::string& term,
484 const std::string& comments)
485 : AidlNode(location), terms_({term}), comments_(comments) {
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800486 if (term.find('.') != string::npos) {
487 terms_ = Split(term, ".");
Steven Moreland46e9da82018-07-27 15:45:29 -0700488 for (const auto& subterm : terms_) {
489 if (subterm.empty()) {
490 AIDL_FATAL(this) << "Malformed qualified identifier: '" << term << "'";
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800491 }
492 }
493 }
Casey Dahlin2b2879b2015-10-13 16:59:44 -0700494}
495
Chih-Hung Hsiehf05cc262016-07-27 11:42:51 -0700496void AidlQualifiedName::AddTerm(const std::string& term) {
Casey Dahlin2b2879b2015-10-13 16:59:44 -0700497 terms_.push_back(term);
498}
499
Steven Moreland46e9da82018-07-27 15:45:29 -0700500AidlImport::AidlImport(const AidlLocation& location, const std::string& needed_class)
501 : AidlNode(location), needed_class_(needed_class) {}
Casey Dahlin0edf3422015-10-07 12:34:59 -0700502
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900503Parser::Parser(const IoDelegate& io_delegate, android::aidl::AidlTypenames& typenames)
504 : io_delegate_(io_delegate), typenames_(typenames) {
505 yylex_init(&scanner_);
506}
507
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700508Parser::~Parser() {
509 if (raw_buffer_) {
510 yy_delete_buffer(buffer_, scanner_);
511 raw_buffer_.reset();
512 }
513 yylex_destroy(scanner_);
514}
515
516bool Parser::ParseFile(const string& filename) {
517 // Make sure we can read the file first, before trashing previous state.
518 unique_ptr<string> new_buffer = io_delegate_.GetFileContents(filename);
519 if (!new_buffer) {
Steven Moreland46e9da82018-07-27 15:45:29 -0700520 AIDL_ERROR(filename) << "Error while opening file for parsing";
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700521 return false;
522 }
523
524 // Throw away old parsing state if we have any.
525 if (raw_buffer_) {
526 yy_delete_buffer(buffer_, scanner_);
527 raw_buffer_.reset();
528 }
529
530 raw_buffer_ = std::move(new_buffer);
531 // We're going to scan this buffer in place, and yacc demands we put two
532 // nulls at the end.
533 raw_buffer_->append(2u, '\0');
534 filename_ = filename;
Christopher Wileyd76067c2015-10-19 17:00:13 -0700535 package_.reset();
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700536 error_ = 0;
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800537 document_.reset();
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700538
539 buffer_ = yy_scan_buffer(&(*raw_buffer_)[0], raw_buffer_->length(), scanner_);
540
Steven Moreland2ca4fcb2018-06-27 16:01:01 -0700541 if (yy::parser(this).parse() != 0 || error_ != 0)
542 return false;
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700543
Jiyong Park1deecc32018-07-17 01:14:41 +0900544 if (document_.get() == nullptr) {
Steven Moreland46e9da82018-07-27 15:45:29 -0700545 AIDL_FATAL(filename) << "Parser succeeded but yielded no document!";
Jiyong Park1deecc32018-07-17 01:14:41 +0900546 }
547 return true;
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700548}
549
Christopher Wiley90be4e32015-10-20 14:55:25 -0700550std::vector<std::string> Parser::Package() const {
551 if (!package_) {
552 return {};
553 }
554 return package_->GetTerms();
555}
556
Steven Moreland46e9da82018-07-27 15:45:29 -0700557void Parser::AddImport(AidlImport* import) {
558 imports_.emplace_back(import);
Casey Dahline2507492015-09-14 17:11:20 -0700559}
Jiyong Park1deecc32018-07-17 01:14:41 +0900560
561bool Parser::Resolve() {
562 bool success = true;
563 for (AidlTypeSpecifier* typespec : unresolved_typespecs_) {
Jiyong Park1d2df7d2018-07-23 15:22:50 +0900564 if (!typespec->Resolve(typenames_)) {
Steven Moreland46e9da82018-07-27 15:45:29 -0700565 AIDL_ERROR(typespec) << "Failed to resolve '" << typespec->GetUnresolvedName() << "'";
Jiyong Park1deecc32018-07-17 01:14:41 +0900566 success = false;
567 // don't stop to show more errors if any
568 }
569 }
570 return success;
571}