blob: 453ec98dd00682a91f9c5778e75b4e1c1d8b338e [file] [log] [blame]
Adam Lesinskiffa16862014-01-23 18:17:42 -08001#include "aidl_language.h"
Christopher Wileyf690be52015-09-14 15:19:10 -07002
3#include <iostream>
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>
Casey Dahlindd691812015-09-09 17:59:06 -07007#include <string>
Christopher Wileyf690be52015-09-14 15:19:10 -07008
Elliott Hughes0a620672015-12-04 13:53:18 -08009#include <android-base/strings.h>
Christopher Wileyd76067c2015-10-19 17:00:13 -070010
Ying Wang3000e752016-01-11 18:05:59 -080011#include "aidl_language_y.h"
Christopher Wiley4a2884b2015-10-07 11:27:45 -070012#include "logging.h"
Adam Lesinskiffa16862014-01-23 18:17:42 -080013
Casey Dahlin07b9dde2015-09-10 19:13:49 -070014#ifdef _WIN32
15int isatty(int fd)
16{
17 return (fd == 0);
18}
19#endif
20
Christopher Wiley4a2884b2015-10-07 11:27:45 -070021using android::aidl::IoDelegate;
Christopher Wileyd76067c2015-10-19 17:00:13 -070022using android::base::Join;
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -080023using android::base::Split;
Casey Dahlindd691812015-09-09 17:59:06 -070024using std::cerr;
25using std::endl;
Christopher Wiley4a2884b2015-10-07 11:27:45 -070026using std::string;
27using std::unique_ptr;
Adam Lesinskiffa16862014-01-23 18:17:42 -080028
Casey Dahlindd691812015-09-09 17:59:06 -070029void yylex_init(void **);
30void yylex_destroy(void *);
31void yyset_in(FILE *f, void *);
Casey Dahline2507492015-09-14 17:11:20 -070032int yyparse(Parser*);
Christopher Wiley4a2884b2015-10-07 11:27:45 -070033YY_BUFFER_STATE yy_scan_buffer(char *, size_t, void *);
Casey Dahlin89d44842015-09-24 18:45:54 -070034void yy_delete_buffer(YY_BUFFER_STATE, void *);
Casey Dahlindd691812015-09-09 17:59:06 -070035
Casey Dahlincdbbc8c2015-10-14 15:31:04 -070036AidlToken::AidlToken(const std::string& text, const std::string& comments)
37 : text_(text),
38 comments_(comments) {}
Casey Dahlin98a544b2015-10-14 14:22:55 -070039
Casey Dahlinf2d23f72015-10-02 16:19:19 -070040AidlType::AidlType(const std::string& name, unsigned line,
Casey Dahlinf7a421c2015-10-05 17:24:28 -070041 const std::string& comments, bool is_array)
Casey Dahlinf2d23f72015-10-02 16:19:19 -070042 : name_(name),
43 line_(line),
Casey Dahlinf7a421c2015-10-05 17:24:28 -070044 is_array_(is_array),
Casey Dahlinf2d23f72015-10-02 16:19:19 -070045 comments_(comments) {}
46
Casey Dahlin98a544b2015-10-14 14:22:55 -070047string AidlType::ToString() const {
48 return name_ + (is_array_ ? "[]" : "");
Casey Dahlin70078e62015-09-30 17:01:30 -070049}
50
Casey Dahlin0ee37582015-09-30 16:31:55 -070051AidlArgument::AidlArgument(AidlArgument::Direction direction, AidlType* type,
Casey Dahlin308f9d42015-10-05 18:48:42 -070052 std::string name, unsigned line)
Casey Dahlin0ee37582015-09-30 16:31:55 -070053 : type_(type),
Casey Dahlinfd6fb482015-09-30 14:48:18 -070054 direction_(direction),
55 direction_specified_(true),
Casey Dahlin308f9d42015-10-05 18:48:42 -070056 name_(name),
57 line_(line) {}
Casey Dahlinc378c992015-09-29 16:50:40 -070058
Casey Dahlin308f9d42015-10-05 18:48:42 -070059AidlArgument::AidlArgument(AidlType* type, std::string name, unsigned line)
Casey Dahlin0ee37582015-09-30 16:31:55 -070060 : type_(type),
Casey Dahlinfd6fb482015-09-30 14:48:18 -070061 direction_(AidlArgument::IN_DIR),
62 direction_specified_(false),
Casey Dahlin308f9d42015-10-05 18:48:42 -070063 name_(name),
64 line_(line) {}
Casey Dahlinc378c992015-09-29 16:50:40 -070065
66string AidlArgument::ToString() const {
67 string ret;
68
69 if (direction_specified_) {
70 switch(direction_) {
71 case AidlArgument::IN_DIR:
72 ret += "in ";
73 break;
74 case AidlArgument::OUT_DIR:
75 ret += "out ";
76 break;
77 case AidlArgument::INOUT_DIR:
78 ret += "inout ";
79 break;
80 }
81 }
82
Casey Dahlin70078e62015-09-30 17:01:30 -070083 ret += type_->ToString();
Casey Dahlinc378c992015-09-29 16:50:40 -070084 ret += " ";
Casey Dahlind127b502015-09-30 12:51:08 -070085 ret += name_;
Casey Dahlinc378c992015-09-29 16:50:40 -070086
87 return ret;
88}
Casey Dahlinbc7a50a2015-09-28 19:20:50 -070089
Casey Dahlind40e2fe2015-11-24 14:06:52 -080090AidlConstant::AidlConstant(std::string name, int32_t value)
91 : name_(name),
92 value_(value) {}
93
Casey Dahlinf4a93112015-10-05 16:58:09 -070094AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
95 std::vector<std::unique_ptr<AidlArgument>>* args,
Casey Dahlinfb7da2e2015-10-08 17:26:09 -070096 unsigned line, const std::string& comments, int id)
Casey Dahlinf4a93112015-10-05 16:58:09 -070097 : oneway_(oneway),
98 comments_(comments),
99 type_(type),
100 name_(name),
101 line_(line),
102 arguments_(std::move(*args)),
103 id_(id) {
104 has_id_ = true;
105 delete args;
Christopher Wileyad339272015-10-05 19:11:58 -0700106 for (const unique_ptr<AidlArgument>& a : arguments_) {
107 if (a->IsIn()) { in_arguments_.push_back(a.get()); }
108 if (a->IsOut()) { out_arguments_.push_back(a.get()); }
109 }
Casey Dahlinf4a93112015-10-05 16:58:09 -0700110}
111
112AidlMethod::AidlMethod(bool oneway, AidlType* type, std::string name,
113 std::vector<std::unique_ptr<AidlArgument>>* args,
Casey Dahlinfb7da2e2015-10-08 17:26:09 -0700114 unsigned line, const std::string& comments)
Casey Dahlinf4a93112015-10-05 16:58:09 -0700115 : AidlMethod(oneway, type, name, args, line, comments, 0) {
116 has_id_ = false;
117}
Casey Dahlinf2d23f72015-10-02 16:19:19 -0700118
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700119Parser::Parser(const IoDelegate& io_delegate)
120 : io_delegate_(io_delegate) {
121 yylex_init(&scanner_);
122}
123
Casey Dahlin2b2879b2015-10-13 16:59:44 -0700124AidlParcelable::AidlParcelable(AidlQualifiedName* name, unsigned line,
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800125 const std::vector<std::string>& package,
126 const std::string& cpp_header)
Casey Dahlin59401da2015-10-09 18:16:45 -0700127 : name_(name),
128 line_(line),
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800129 package_(package),
130 cpp_header_(cpp_header) {
131 // Strip off quotation marks if we actually have a cpp header.
132 if (cpp_header_.length() >= 2) {
133 cpp_header_ = cpp_header_.substr(1, cpp_header_.length() - 2);
134 }
Casey Dahlin59401da2015-10-09 18:16:45 -0700135}
136
Christopher Wileyd76067c2015-10-19 17:00:13 -0700137std::string AidlParcelable::GetPackage() const {
138 return Join(package_, '.');
139}
140
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800141std::string AidlParcelable::GetCanonicalName() const {
142 if (package_.empty()) {
143 return GetName();
144 }
145 return GetPackage() + "." + GetName();
146}
147
Casey Dahlinfb7da2e2015-10-08 17:26:09 -0700148AidlInterface::AidlInterface(const std::string& name, unsigned line,
149 const std::string& comments, bool oneway,
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800150 std::vector<std::unique_ptr<AidlMember>>* members,
Christopher Wileyd76067c2015-10-19 17:00:13 -0700151 const std::vector<std::string>& package)
Casey Dahlinfb7da2e2015-10-08 17:26:09 -0700152 : name_(name),
153 comments_(comments),
154 line_(line),
155 oneway_(oneway),
Casey Dahlinfb7da2e2015-10-08 17:26:09 -0700156 package_(package) {
Casey Dahlind40e2fe2015-11-24 14:06:52 -0800157 for (auto& member : *members) {
158 AidlMember* local = member.release();
159 AidlMethod* method = local->AsMethod();
160 AidlConstant* constant = local->AsConstant();
161
162 if (method) {
163 methods_.emplace_back(method);
164 } else if (constant) {
165 constants_.emplace_back(constant);
166 } else {
167 LOG(FATAL) << "Member is neither method nor constant!";
168 }
169 }
170
171 delete members;
Casey Dahlinfb7da2e2015-10-08 17:26:09 -0700172}
173
Christopher Wileyd76067c2015-10-19 17:00:13 -0700174std::string AidlInterface::GetPackage() const {
175 return Join(package_, '.');
176}
177
178std::string AidlInterface::GetCanonicalName() const {
179 if (package_.empty()) {
180 return GetName();
181 }
182 return GetPackage() + "." + GetName();
183}
184
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800185AidlDocument::AidlDocument(AidlInterface* interface)
186 : interface_(interface) {}
187
Casey Dahlin2b2879b2015-10-13 16:59:44 -0700188AidlQualifiedName::AidlQualifiedName(std::string term,
189 std::string comments)
190 : terms_({term}),
191 comments_(comments) {
Christopher Wiley8aa4d9f2015-11-16 19:10:45 -0800192 if (term.find('.') != string::npos) {
193 terms_ = Split(term, ".");
194 for (const auto& term: terms_) {
195 if (term.empty()) {
196 LOG(FATAL) << "Malformed qualified identifier: '" << term << "'";
197 }
198 }
199 }
Casey Dahlin2b2879b2015-10-13 16:59:44 -0700200}
201
202void AidlQualifiedName::AddTerm(std::string term) {
203 terms_.push_back(term);
204}
205
Casey Dahlin0edf3422015-10-07 12:34:59 -0700206AidlImport::AidlImport(const std::string& from,
207 const std::string& needed_class, unsigned line)
208 : from_(from),
209 needed_class_(needed_class),
210 line_(line) {}
211
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700212Parser::~Parser() {
213 if (raw_buffer_) {
214 yy_delete_buffer(buffer_, scanner_);
215 raw_buffer_.reset();
216 }
217 yylex_destroy(scanner_);
218}
219
220bool Parser::ParseFile(const string& filename) {
221 // Make sure we can read the file first, before trashing previous state.
222 unique_ptr<string> new_buffer = io_delegate_.GetFileContents(filename);
223 if (!new_buffer) {
224 LOG(ERROR) << "Error while opening file for parsing: '" << filename << "'";
225 return false;
226 }
227
228 // Throw away old parsing state if we have any.
229 if (raw_buffer_) {
230 yy_delete_buffer(buffer_, scanner_);
231 raw_buffer_.reset();
232 }
233
234 raw_buffer_ = std::move(new_buffer);
235 // We're going to scan this buffer in place, and yacc demands we put two
236 // nulls at the end.
237 raw_buffer_->append(2u, '\0');
238 filename_ = filename;
Christopher Wileyd76067c2015-10-19 17:00:13 -0700239 package_.reset();
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700240 error_ = 0;
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800241 document_.reset();
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700242
243 buffer_ = yy_scan_buffer(&(*raw_buffer_)[0], raw_buffer_->length(), scanner_);
244
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800245 if (yy::parser(this).parse() != 0 || error_ != 0) {
246 return false;}
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700247
Casey Dahlinc1f39b42015-11-24 10:34:34 -0800248 if (document_.get() != nullptr)
249 return true;
250
251 LOG(ERROR) << "Parser succeeded but yielded no document!";
252 return false;
Christopher Wiley4a2884b2015-10-07 11:27:45 -0700253}
254
Casey Dahlin98a544b2015-10-14 14:22:55 -0700255void Parser::ReportError(const string& err, unsigned line) {
256 cerr << filename_ << ":" << line << ": " << err << endl;
Casey Dahlindd691812015-09-09 17:59:06 -0700257 error_ = 1;
258}
259
Christopher Wiley90be4e32015-10-20 14:55:25 -0700260std::vector<std::string> Parser::Package() const {
261 if (!package_) {
262 return {};
263 }
264 return package_->GetTerms();
265}
266
Casey Dahlin2b2879b2015-10-13 16:59:44 -0700267void Parser::AddImport(AidlQualifiedName* name, unsigned line) {
268 imports_.emplace_back(new AidlImport(this->FileName(),
269 name->GetDotName(), line));
270 delete name;
Casey Dahline2507492015-09-14 17:11:20 -0700271}