1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "parser/parser.h"
17
18 #include <regex>
19
20 #include "ast/ast_array_type.h"
21 #include "ast/ast_enum_type.h"
22 #include "ast/ast_map_type.h"
23 #include "ast/ast_parameter.h"
24 #include "ast/ast_sequenceable_type.h"
25 #include "ast/ast_smq_type.h"
26 #include "ast/ast_struct_type.h"
27 #include "ast/ast_union_type.h"
28 #include "util/logger.h"
29 #include "util/string_builder.h"
30
31 namespace OHOS {
32 namespace Idl {
33 static constexpr const char *RE_BIN_DIGIT = "0[b][0|1]+"; // binary digit
34 static constexpr const char *RE_OCT_DIGIT = "0[0-7]+"; // octal digit
35 static constexpr const char *RE_DEC_DIGIT = "[0-9]+"; // decimal digit
36 static constexpr const char *RE_HEX_DIFIT = "0[xX][0-9a-fA-F]+"; // hexadecimal digit
37 static constexpr const char *RE_DIGIT_SUFFIX = "(u|l|ll|ul|ull|)$";
38 static constexpr const char *RE_IDENTIFIER = "[a-zA-Z_][a-zA-Z0-9_]*";
39
40 static constexpr unsigned int RE_PACKAGE_NUM = 3;
41 static constexpr unsigned int RE_PACKAGE_INDEX = 0;
42 static constexpr unsigned int RE_PACKAGE_MAJOR_VER_INDEX = 1;
43 static constexpr unsigned int RE_PACKAGE_MINOR_VER_INDEX = 2;
44
45 static const std::regex RE_PACKAGE(std::string(RE_IDENTIFIER) + "(?:\\." + std::string(RE_IDENTIFIER) + ")*\\.[V|v]" +
46 "(" + std::string(RE_DEC_DIGIT) + ")_(" + std::string(RE_DEC_DIGIT) + ")");
47 static const std::regex RE_PACKAGE_OR_IMPORT_SM(std::string(RE_IDENTIFIER) +
48 "(?:\\." + std::string(RE_IDENTIFIER) + ")*");
49 static const std::regex RE_IMPORT(std::string(RE_IDENTIFIER) + "(?:\\." + std::string(RE_IDENTIFIER) + ")*\\.[V|v]" +
50 std::string(RE_DEC_DIGIT) + "_" + std::string(RE_DEC_DIGIT) + "." + std::string(RE_IDENTIFIER));
51 static const std::regex RE_BIN_NUM(std::string(RE_BIN_DIGIT) + std::string(RE_DIGIT_SUFFIX),
52 std::regex_constants::icase);
53 static const std::regex RE_OCT_NUM(std::string(RE_OCT_DIGIT) + std::string(RE_DIGIT_SUFFIX),
54 std::regex_constants::icase);
55 static const std::regex RE_DEC_NUM(std::string(RE_DEC_DIGIT) + std::string(RE_DIGIT_SUFFIX),
56 std::regex_constants::icase);
57 static const std::regex RE_HEX_NUM(std::string(RE_HEX_DIFIT) + std::string(RE_DIGIT_SUFFIX),
58 std::regex_constants::icase);
59 AutoPtr<ASTEnumType> g_currentEnum = nullptr;
60
Parse(const std::vector<FileDetail> & fileDetails)61 bool Parser::Parse(const std::vector<FileDetail> &fileDetails)
62 {
63 for (const auto &fileDetail : fileDetails) {
64 if (!ParseOne(fileDetail.filePath_)) {
65 return false;
66 }
67 }
68
69 return PostProcess();
70 }
71
ParseOne(const std::string & sourceFile)72 bool Parser::ParseOne(const std::string &sourceFile)
73 {
74 if (!Reset(sourceFile)) {
75 return false;
76 }
77
78 bool ret = ParseFile();
79 IntfTypeChecker checker(ast_);
80 ret = checker.CheckIntegrity() && ret;
81 ret = AddAst(ast_) && ret;
82 if (!ret || !errors_.empty()) {
83 ShowError();
84 return false;
85 }
86
87 return true;
88 }
89
Reset(const std::string & sourceFile)90 bool Parser::Reset(const std::string &sourceFile)
91 {
92 if (!lexer_.Reset(sourceFile)) {
93 Logger::E(TAG, "Fail to open file '%s'.", sourceFile.c_str());
94 return false;
95 }
96
97 errors_.clear();
98 ast_ = nullptr;
99 return true;
100 }
101
ParseFile()102 bool Parser::ParseFile()
103 {
104 ast_ = new AST();
105 ast_->SetIdlFile(lexer_.GetFilePath());
106 ast_->SetLicense(ParseLicense());
107
108 TokenType tokenKind;
109 bool ret = true;
110 while (((tokenKind = lexer_.PeekToken().kind) != TokenType::END_OF_FILE) && ret) {
111 switch (tokenKind) {
112 case TokenType::PACKAGE:
113 ret = ParsePackage() && ret;
114 continue;
115 case TokenType::INTERFACE_TOKEN:
116 ret = ParseInterfaceToken() && ret;
117 continue;
118 case TokenType::SUPPORT_DELEGATOR:
119 ret = ParseSupportDelegator() && ret;
120 continue;
121 case TokenType::IMPORT:
122 case TokenType::SEQ:
123 ret = ParseImports() && ret;
124 continue;
125 default:
126 ret = ParseTypeDecls() && ret;
127 continue;
128 }
129 }
130
131 SetAstFileType();
132 return ret;
133 }
134
ParseLicense()135 std::string Parser::ParseLicense()
136 {
137 Token token = lexer_.PeekToken(false);
138 if (token.kind == TokenType::COMMENT_BLOCK) {
139 lexer_.GetToken(false);
140 return token.value;
141 }
142
143 return std::string("");
144 }
145
ParsePackage()146 bool Parser::ParsePackage()
147 {
148 // package
149 Token token = lexer_.PeekToken();
150 if (token.kind != TokenType::PACKAGE) {
151 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected 'package'"));
152 return false;
153 }
154 lexer_.GetToken();
155
156 // package name
157 token = lexer_.PeekToken();
158 if (token.kind != TokenType::ID) {
159 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected name of package"));
160 lexer_.SkipToken(TokenType::SEMICOLON);
161 return false;
162 }
163 std::string packageName = token.value;
164 lexer_.GetToken();
165
166 // expect symbol ";"
167 token = lexer_.PeekToken();
168 if (token.kind != TokenType::SEMICOLON) {
169 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'"));
170 return false;
171 }
172 lexer_.GetToken();
173
174 if (packageName.empty()) {
175 LogError(__func__, __LINE__, std::string("package name is not expected."));
176 return false;
177 } else if (!CheckPackageName(lexer_.GetFilePath(), packageName)) {
178 LogError(__func__, __LINE__, StringHelper::Format(
179 "package name '%s' does not match file apth '%s'.", packageName.c_str(), lexer_.GetFilePath().c_str()));
180 return false;
181 }
182
183 if (!ParserPackageInfo(packageName)) {
184 LogError(__func__, __LINE__, StringHelper::Format("parse package '%s' infomation failed.",
185 packageName.c_str()));
186 return false;
187 }
188
189 return true;
190 }
191
ParserPackageInfo(const std::string & packageName)192 bool Parser::ParserPackageInfo(const std::string &packageName)
193 {
194 std::cmatch result;
195 if (Options::GetInstance().GetInterfaceType() == InterfaceType::HDI) {
196 if (!std::regex_match(packageName.c_str(), result, RE_PACKAGE) || (result.size() < RE_PACKAGE_NUM)) {
197 return false;
198 }
199
200 ast_->SetPackageName(result.str(RE_PACKAGE_INDEX).c_str());
201 size_t majorVersion = std::stoul(result.str(RE_PACKAGE_MAJOR_VER_INDEX));
202 size_t minorVersion = std::stoul(result.str(RE_PACKAGE_MINOR_VER_INDEX));
203 ast_->SetVersion(majorVersion, minorVersion);
204 } else {
205 if (!std::regex_match(packageName.c_str(), result, RE_PACKAGE_OR_IMPORT_SM)) {
206 return false;
207 }
208 ast_->SetPackageName(result.str(RE_PACKAGE_INDEX).c_str());
209 }
210 return true;
211 }
212
ParseInterfaceToken()213 bool Parser::ParseInterfaceToken()
214 {
215 Token token = lexer_.PeekToken();
216 if (token.kind != TokenType::INTERFACE_TOKEN) {
217 LogError(__func__, __LINE__, token, StringHelper::Format("expected 'interface token'"));
218 return false;
219 }
220 lexer_.GetToken();
221
222 token = lexer_.PeekToken();
223 if (token.kind != TokenType::ID) {
224 LogError(__func__, __LINE__, token, StringHelper::Format("expected name of interface_token before '%s' token",
225 token.value.c_str()));
226 lexer_.SkipToken(TokenType::SEMICOLON);
227 return false;
228 }
229 std::string interfaceToken = token.value;
230 lexer_.GetToken();
231
232 token = lexer_.PeekToken();
233 if (token.kind != TokenType::SEMICOLON) {
234 LogError(__func__, __LINE__, token, StringHelper::Format("expected ';' before '%s' token",
235 token.value.c_str()));
236 return false;
237 }
238 lexer_.GetToken();
239
240 if (interfaceToken.empty()) {
241 LogError(__func__, __LINE__, token, StringHelper::Format("interface_token name is not expected."));
242 return false;
243 }
244
245 ast_->SetInterfaceToken(interfaceToken);
246 return true;
247 }
248
ParseSupportDelegator()249 bool Parser::ParseSupportDelegator()
250 {
251 Token token = lexer_.PeekToken();
252 if (token.kind != TokenType::SUPPORT_DELEGATOR) {
253 LogError(__func__, __LINE__, token, StringHelper::Format("expected 'support_delegator'"));
254 return false;
255 }
256 lexer_.GetToken();
257
258 token = lexer_.PeekToken();
259 if (token.kind != TokenType::ID) {
260 LogError(__func__, __LINE__, token, StringHelper::Format("expected name of suport_delegator before '%s' token",
261 token.value.c_str()));
262 lexer_.SkipToken(TokenType::SEMICOLON);
263 return false;
264 }
265 std::string supportDelegator = token.value;
266 lexer_.GetToken();
267
268 token = lexer_.PeekToken();
269 if (token.kind != TokenType::SEMICOLON) {
270 LogError(__func__, __LINE__, token, StringHelper::Format("expected ';' before '%s' token",
271 token.value.c_str()));
272 return false;
273 }
274 lexer_.GetToken();
275
276 if (supportDelegator.empty()) {
277 LogError(__func__, __LINE__, token, StringHelper::Format("support_delegator name is not expected."));
278 return false;
279 }
280
281 ast_->SetSupportDelegator(supportDelegator);
282 return true;
283 }
284
ParseImports()285 bool Parser::ParseImports()
286 {
287 Token token = lexer_.PeekToken();
288 TokenType kind = token.kind;
289 lexer_.GetToken();
290
291 // name
292 token = lexer_.PeekToken();
293 if (token.kind != TokenType::ID) {
294 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected identifier"));
295 lexer_.SkipToken(TokenType::SEMICOLON);
296 token = lexer_.PeekToken();
297 return false;
298 }
299
300 if (kind == TokenType::IMPORT) {
301 ParseImportInfo();
302 } else {
303 ParseSequenceableInfo();
304 }
305 lexer_.GetToken();
306
307 // expect symbol ";"
308 token = lexer_.PeekToken();
309 if (token.kind != TokenType::SEMICOLON) {
310 LogError(__func__, __LINE__, token, StringHelper::Format("expected ';' before '%s'.", token.value.c_str()));
311 return false;
312 }
313 lexer_.GetToken();
314
315 return true;
316 }
317
ParseImportInfo()318 void Parser::ParseImportInfo()
319 {
320 Token token = lexer_.PeekToken();
321 std::string importName = token.value;
322 if (importName.empty()) {
323 LogError(__func__, __LINE__, token, std::string("import name is empty"));
324 return;
325 }
326
327 if (!CheckImport(importName)) {
328 LogError(__func__, __LINE__, token, std::string("import name is illegal"));
329 return;
330 }
331
332 auto iter = allAsts_.find(importName);
333 AutoPtr<AST> importAst = (iter != allAsts_.end()) ? iter->second : nullptr;
334 if (importAst == nullptr) {
335 LogError(__func__, __LINE__, token,
336 StringHelper::Format("can not find idl file from import name '%s'", importName.c_str()));
337 return;
338 }
339
340 if (!CheckImportsVersion(importAst)) {
341 LogError(__func__, __LINE__, token,
342 std::string("extends import version must less than current import version"));
343 return;
344 }
345
346 if (!ast_->AddImport(importAst)) {
347 LogError(__func__, __LINE__, token, StringHelper::Format("multiple import of '%s'", importName.c_str()));
348 }
349 }
350
ParseSequenceableInfo()351 void Parser::ParseSequenceableInfo()
352 {
353 Token token = lexer_.PeekToken();
354 std::string seqName = token.value;
355 if (seqName.empty()) {
356 LogError(__func__, __LINE__, token, std::string("sequenceable name is empty"));
357 return;
358 }
359
360 AutoPtr<ASTSequenceableType> seqType = new ASTSequenceableType();
361 size_t index = seqName.rfind('.');
362 if (index != std::string::npos) {
363 seqType->SetName(seqName.substr(index + 1));
364 seqType->SetNamespace(ast_->ParseNamespace(seqName));
365 } else {
366 seqType->SetName(seqName);
367 seqType->SetNamespace(ast_->ParseNamespace(""));
368 }
369
370 AutoPtr<AST> seqAst = new AST();
371 seqAst->SetFullName(seqName);
372 seqAst->AddSequenceableDef(seqType);
373 seqAst->SetAStFileType(ASTFileType::AST_SEQUENCEABLE);
374 ast_->AddImport(seqAst);
375 ast_->AddSequenceableDef(seqType);
376 AddAst(seqAst);
377 }
378
ParseTypeDecls()379 bool Parser::ParseTypeDecls()
380 {
381 Token token = lexer_.PeekToken();
382 switch (token.kind) {
383 case TokenType::BRACKETS_LEFT:
384 ParseAttribute();
385 break;
386 case TokenType::INTERFACE:
387 ParseInterface();
388 break;
389 case TokenType::ENUM:
390 ParseEnumDeclaration();
391 break;
392 case TokenType::STRUCT:
393 ParseStructDeclaration();
394 break;
395 case TokenType::UNION:
396 ParseUnionDeclaration();
397 break;
398 default:
399 LogError(__func__, __LINE__, token, StringHelper::Format("'%s' is not expected", token.value.c_str()));
400 lexer_.SkipToken(TokenType::SEMICOLON);
401 return false;
402 }
403
404 return true;
405 }
406
ParseAttribute()407 void Parser::ParseAttribute()
408 {
409 AttrSet attrs = ParseAttributeInfo();
410 Token token = lexer_.PeekToken();
411 switch (token.kind) {
412 case TokenType::INTERFACE:
413 ParseInterface(attrs);
414 break;
415 case TokenType::ENUM:
416 ParseEnumDeclaration(attrs);
417 break;
418 case TokenType::STRUCT:
419 ParseStructDeclaration(attrs);
420 break;
421 case TokenType::UNION:
422 ParseUnionDeclaration(attrs);
423 break;
424 default:
425 LogError(__func__, __LINE__, token, StringHelper::Format("'%s' is not expected", token.value.c_str()));
426 lexer_.SkipToken(token.kind);
427 break;
428 }
429 }
430
ParseAttributeInfo()431 AttrSet Parser::ParseAttributeInfo()
432 {
433 AttrSet attrs;
434 // [
435 Token token = lexer_.PeekToken();
436 if (token.kind != TokenType::BRACKETS_LEFT) {
437 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '['"));
438 lexer_.SkipToken(token.kind);
439 return attrs;
440 }
441 lexer_.GetToken();
442
443 // attrunit
444 token = lexer_.PeekToken();
445 while (token.kind != TokenType::BRACKETS_RIGHT && token.kind != TokenType::END_OF_FILE) {
446 if (!ParseAttrUnit(attrs)) {
447 return attrs;
448 }
449 // expect symbol ","
450 token = lexer_.PeekToken();
451 if (token.kind == TokenType::COMMA) {
452 lexer_.GetToken();
453 token = lexer_.PeekToken();
454 continue;
455 }
456 // ]
457 if (token.kind == TokenType::BRACKETS_RIGHT) {
458 lexer_.GetToken();
459 } else {
460 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or ']'"));
461 lexer_.SkipToken(TokenType::BRACKETS_RIGHT);
462 }
463 break;
464 }
465
466 return attrs;
467 }
468
ParseAttrUnit(AttrSet & attrs)469 bool Parser::ParseAttrUnit(AttrSet &attrs)
470 {
471 Token token = lexer_.PeekToken();
472 switch (token.kind) {
473 case TokenType::FULL:
474 case TokenType::LITE:
475 case TokenType::MINI:
476 case TokenType::CALLBACK:
477 case TokenType::ONEWAY: {
478 if (attrs.find(token) != attrs.end()) {
479 LogError(__func__, __LINE__, token, StringHelper::Format("Duplicate declared attributes '%s'",
480 token.value.c_str()));
481 } else {
482 attrs.insert(token);
483 }
484 lexer_.GetToken();
485 return true;
486 }
487 case TokenType::CACHEABLE: {
488 if (attrs.find(token) != attrs.end()) {
489 LogError(__func__, __LINE__, token, StringHelper::Format("Duplicate declared attributes cacheable"));
490 } else {
491 if (!lexer_.ReadCacheableTime(token)) {
492 LogError(__func__, __LINE__, token, StringHelper::Format("Cacheable time parse failed"));
493 }
494 attrs.insert(token);
495 }
496 lexer_.GetToken();
497 return true;
498 }
499 case TokenType::FREEZECONTROL: {
500 ParseAttrUnitFreezecontrol(attrs, token);
501 return true;
502 }
503 default:
504 LogError(__func__, __LINE__, token, StringHelper::Format("'%s' is a illegal attribute",
505 token.value.c_str()));
506 lexer_.SkipToken(TokenType::BRACKETS_RIGHT);
507 return false;
508 }
509 }
510
ParseAttrUnitFreezecontrol(AttrSet & attrs,Token & token)511 void Parser::ParseAttrUnitFreezecontrol(AttrSet &attrs, Token &token)
512 {
513 if (attrs.find(token) != attrs.end()) {
514 LogError(__func__, __LINE__, token, StringHelper::Format("Duplicate declared attr freezecontrol"));
515 } else {
516 attrs.insert(token);
517 lexer_.GetToken();
518 token = lexer_.PeekToken();
519 if (token.value == "]") {
520 LogError(__func__, __LINE__, token, StringHelper::Format("freezecontrol attr cannot be empty"));
521 } else if (token.kind == TokenType::ID) {
522 freezecontrolAttr_ = token.value;
523 }
524 }
525 lexer_.GetToken();
526 }
527
ParseInterface(const AttrSet & attrs)528 void Parser::ParseInterface(const AttrSet &attrs)
529 {
530 AutoPtr<ASTInterfaceType> interfaceType = new ASTInterfaceType;
531 AutoPtr<ASTAttr> astAttr = ParseInfAttrInfo(attrs);
532 interfaceType->SetAttribute(astAttr);
533
534 lexer_.GetToken();
535 Token token = lexer_.PeekToken();
536 if (token.kind != TokenType::ID) {
537 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected interface name"));
538 } else {
539 size_t index = token.value.rfind('.');
540 if (index != std::string::npos) {
541 interfaceType->SetName(StringHelper::SubStr(token.value, index + 1));
542 interfaceType->SetNamespace(ast_->ParseNamespace(token.value));
543 } else {
544 interfaceType->SetName(token.value);
545 interfaceType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
546 }
547 interfaceType->SetLicense(ast_->GetLicense());
548 lexer_.GetToken();
549 }
550
551 CheckInterfaceAttr(interfaceType, token);
552 ParseInterfaceExtends(interfaceType);
553 token = lexer_.PeekToken();
554 if (token.kind == TokenType::SEMICOLON) {
555 ParseInterfaceExternal(interfaceType);
556 } else {
557 if (interfaceType->GetName() != ast_->GetName()) {
558 LogError(__func__, __LINE__, token, StringHelper::Format(
559 "interface name '%s' is not equal idl file name", interfaceType->GetName().c_str()));
560 }
561 ParseInterfaceBody(interfaceType);
562 }
563 interfaceType->SetVersion(ast_->GetMajorVer(), ast_->GetMinorVer());
564 ast_->AddInterfaceDef(interfaceType);
565 }
566
ParseInfAttrInfo(const AttrSet & attrs)567 AutoPtr<ASTAttr> Parser::ParseInfAttrInfo(const AttrSet &attrs)
568 {
569 AutoPtr<ASTAttr> infAttr = new ASTAttr();
570 InterfaceType interfaceType = Options::GetInstance().GetInterfaceType();
571 for (const auto &attr : attrs) {
572 switch (attr.kind) {
573 case TokenType::FULL:
574 infAttr->SetValue(ASTAttr::FULL);
575 break;
576 case TokenType::LITE:
577 infAttr->SetValue(ASTAttr::LITE);
578 break;
579 case TokenType::MINI:
580 infAttr->SetValue(ASTAttr::MINI);
581 break;
582 case TokenType::CALLBACK:
583 infAttr->SetValue(ASTAttr::CALLBACK);
584 break;
585 case TokenType::ONEWAY:
586 infAttr->SetValue(ASTAttr::ONEWAY);
587 break;
588 default:
589 LogError(__func__, __LINE__, attr, std::string("illegal attribute of interface"));
590 break;
591 }
592 }
593
594 if ((interfaceType == InterfaceType::HDI) &&
595 (!infAttr->HasValue(ASTAttr::FULL) && !infAttr->HasValue(ASTAttr::LITE) &&
596 !infAttr->HasValue(ASTAttr::MINI))) {
597 infAttr->SetValue(ASTAttr::FULL | ASTAttr::LITE | ASTAttr::MINI);
598 }
599
600 return infAttr;
601 }
602
CheckInterfaceAttr(const AutoPtr<ASTInterfaceType> & interface,Token token)603 void Parser::CheckInterfaceAttr(const AutoPtr<ASTInterfaceType> &interface, Token token)
604 {
605 bool ret = true;
606 std::string systemName;
607 switch (Options::GetInstance().GetSystemLevel()) {
608 case SystemLevel::FULL:
609 systemName = "full";
610 ret = interface->IsFull();
611 break;
612 case SystemLevel::LITE:
613 systemName = "lite";
614 ret = interface->IsLite();
615 break;
616 case SystemLevel::MINI:
617 systemName = "mini";
618 ret = interface->IsMini();
619 break;
620 default:
621 break;
622 }
623
624 if (!ret) {
625 LogError(__func__, __LINE__, token, StringHelper::Format("the system option is '%s', but the '%s' interface "
626 "has no '%s' attribute", systemName.c_str(), interface->GetName().c_str(), systemName.c_str()));
627 }
628 }
629
ParseInterfaceExternal(const AutoPtr<ASTInterfaceType> & interface)630 void Parser::ParseInterfaceExternal(const AutoPtr<ASTInterfaceType> &interface)
631 {
632 Token token = lexer_.PeekToken();
633 lexer_.GetToken();
634 if (interface->IsAttributeNone()) {
635 interface->SetExternal(true);
636 } else {
637 LogError(__func__, __LINE__, token, std::string("interface forward declaration should not have attribute."));
638 }
639 }
640
ParseInterfaceBody(const AutoPtr<ASTInterfaceType> & interface)641 void Parser::ParseInterfaceBody(const AutoPtr<ASTInterfaceType> &interface)
642 {
643 Token token = lexer_.PeekToken();
644 // expect symbol "{" or ";"
645 if (token.kind != TokenType::BRACES_LEFT) {
646 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'"));
647 } else {
648 lexer_.GetToken();
649 }
650
651 // parse method
652 token = lexer_.PeekToken();
653 while (token.kind != TokenType::BRACES_RIGHT && token.kind != TokenType::END_OF_FILE) {
654 AutoPtr<ASTMethod> method = ParseMethod(interface);
655 interface->AddMethod(method);
656 token = lexer_.PeekToken();
657 }
658
659 // expect symbol "}"
660 token = lexer_.PeekToken();
661 if (token.kind != TokenType::BRACES_RIGHT) {
662 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'"));
663 } else {
664 lexer_.GetToken();
665 }
666
667 // expect symbol ";"
668 token = lexer_.PeekToken();
669 if (token.kind == TokenType::SEMICOLON) {
670 lexer_.GetToken();
671 }
672
673 interface->AddVersionMethod(CreateGetVersionMethod());
674 }
675
ParseMethod(const AutoPtr<ASTInterfaceType> & interface)676 AutoPtr<ASTMethod> Parser::ParseMethod(const AutoPtr<ASTInterfaceType> &interface)
677 {
678 freezecontrolAttr_ = "";
679 AutoPtr<ASTMethod> method = new ASTMethod();
680 AutoPtr<ASTAttr> methodAttr = ParseMethodAttr();
681 method->SetAttribute(methodAttr);
682 method->SetCacheable(methodAttr);
683 method->SetReturnType(ParseMethodReturnType());
684
685 // parser method name
686 Token token = lexer_.PeekToken();
687 if (token.kind != TokenType::ID) {
688 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected method name"));
689 } else {
690 method->SetName(token.value);
691 lexer_.GetToken();
692 }
693
694 CheckMethodAttr(interface, method);
695 // (param1, param2, ...)
696 ParseMethodParamList(method);
697
698 // parse symbol ";"
699 token = lexer_.PeekToken();
700 if (token.kind != TokenType::SEMICOLON) {
701 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'"));
702 } else {
703 lexer_.GetToken();
704 }
705
706 size_t methodsCount = interface->GetMethodNumber() + 1;
707 AutoPtr<ASTInterfaceType> extInterface = interface->GetExtendsInterface();
708 while (extInterface != nullptr) {
709 methodsCount += extInterface->GetMethodNumber();
710 extInterface = extInterface->GetExtendsInterface();
711 }
712 method->SetCmdId(methodsCount);
713 method->CheckOverload(interface);
714
715 if (!freezecontrolAttr_.empty()) {
716 method->SetFreezeControlReason(freezecontrolAttr_);
717 }
718
719 return method;
720 }
721
ParseMethodReturnType()722 AutoPtr<ASTType> Parser::ParseMethodReturnType()
723 {
724 if (Options::GetInstance().GetInterfaceType() == InterfaceType::HDI) {
725 return nullptr;
726 }
727 Token token = lexer_.PeekToken();
728 if (token.kind == TokenType::ID && ast_->FindType(token.value) == nullptr) {
729 return nullptr;
730 }
731 // parse method return type, maybe not exist
732 if (CheckBasicType(token) || CheckUserDefType(token) || token.kind == TokenType::LIST ||
733 token.kind == TokenType::MAP || token.kind == TokenType::SMQ) {
734 return ParseType();
735 }
736 return nullptr;
737 }
738
ParseMethodAttr()739 AutoPtr<ASTAttr> Parser::ParseMethodAttr()
740 {
741 if (lexer_.PeekToken().kind != TokenType::BRACKETS_LEFT) {
742 return new ASTAttr();
743 }
744
745 AttrSet attrs = ParseAttributeInfo();
746 AutoPtr<ASTAttr> methodAttr = new ASTAttr();
747
748 for (const auto &attr : attrs) {
749 switch (attr.kind) {
750 case TokenType::FULL:
751 methodAttr->SetValue(ASTAttr::FULL);
752 break;
753 case TokenType::LITE:
754 methodAttr->SetValue(ASTAttr::LITE);
755 break;
756 case TokenType::MINI:
757 methodAttr->SetValue(ASTAttr::MINI);
758 break;
759 case TokenType::ONEWAY:
760 methodAttr->SetValue(ASTAttr::ONEWAY);
761 break;
762 case TokenType::CACHEABLE:
763 methodAttr->SetValue(ASTAttr::CACHEABLE);
764 methodAttr->SetCacheableTimeString(attr.value);
765 break;
766 case TokenType::FREEZECONTROL:
767 methodAttr->SetValue(ASTAttr::FREEZECONTROL);
768 break;
769 default:
770 LogError(__func__, __LINE__, attr, std::string("illegal attribute of interface"));
771 break;
772 }
773 }
774
775 return methodAttr;
776 }
777
CreateGetVersionMethod()778 AutoPtr<ASTMethod> Parser::CreateGetVersionMethod()
779 {
780 AutoPtr<ASTMethod> method = new ASTMethod();
781 method->SetName("GetVersion");
782
783 AutoPtr<ASTType> type = ast_->FindType("unsigned int");
784 if (type == nullptr) {
785 type = new ASTUintType();
786 }
787
788 method->AddParameter(new ASTParameter("majorVer", ASTParamAttr::PARAM_OUT, type));
789 method->AddParameter(new ASTParameter("minorVer", ASTParamAttr::PARAM_OUT, type));
790 return method;
791 }
792
CheckMethodAttr(const AutoPtr<ASTInterfaceType> & interface,const AutoPtr<ASTMethod> & method)793 void Parser::CheckMethodAttr(const AutoPtr<ASTInterfaceType> &interface, const AutoPtr<ASTMethod> &method)
794 {
795 // if the attribute of method is empty, the default value is attribute of interface
796 if (!method->IsMini() && !method->IsLite() && !method->IsFull()) {
797 method->SetAttribute(interface->GetAttribute());
798 }
799
800 if (!interface->IsMini() && method->IsMini()) {
801 LogError(__func__, __LINE__, StringHelper::Format("the '%s' method can not have 'mini' attribute, because the "
802 "'%s' interface has no 'mini' attribute", method->GetName().c_str(), interface->GetName().c_str()));
803 }
804
805 if (!interface->IsLite() && method->IsLite()) {
806 LogError(__func__, __LINE__, StringHelper::Format("the '%s' method can not have 'lite' attribute, because the "
807 "'%s' interface has no 'lite' attribute", method->GetName().c_str(), interface->GetName().c_str()));
808 }
809
810 if (!interface->IsFull() && method->IsFull()) {
811 LogError(__func__, __LINE__, StringHelper::Format("the '%s' method can not have 'full' attribute, because the "
812 "'%s' interface has no 'full' attribute", method->GetName().c_str(), interface->GetName().c_str()));
813 }
814
815 // the method has 'oneway' attribute if interface or method has 'oneway' attribute
816 if (interface->IsOneWay() || method->IsOneWay()) {
817 method->GetAttribute()->SetValue(ASTAttr::ONEWAY);
818 }
819 }
820
ParseMethodParamList(const AutoPtr<ASTMethod> & method)821 void Parser::ParseMethodParamList(const AutoPtr<ASTMethod> &method)
822 {
823 // (
824 Token token = lexer_.PeekToken();
825 if (token.kind != TokenType::PARENTHESES_LEFT) {
826 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '('"));
827 } else {
828 lexer_.GetToken();
829 }
830
831 // ()
832 token = lexer_.PeekToken();
833 if (token.kind == TokenType::PARENTHESES_RIGHT) {
834 lexer_.GetToken();
835 return;
836 }
837
838 // param
839 while (token.kind != TokenType::PARENTHESES_RIGHT && token.kind != TokenType::END_OF_FILE) {
840 AutoPtr<ASTParameter> param = ParseParam();
841 if (method->IsOneWay() && (param->GetAttribute() & ASTParamAttr::PARAM_OUT)) {
842 LogError(__func__, __LINE__, token, StringHelper::Format("the '%s' parameter of '%s' method "
843 "can not be 'out'", param->GetName().c_str(), method->GetName().c_str()));
844 }
845 method->AddParameter(param);
846
847 // ,
848 token = lexer_.PeekToken();
849 if (token.kind == TokenType::COMMA) {
850 lexer_.GetToken();
851 token = lexer_.PeekToken();
852 if (token.kind == TokenType::PARENTHESES_RIGHT) {
853 LogError(__func__, __LINE__, token, std::string(""));
854 }
855 continue;
856 }
857
858 // )
859 if (token.kind == TokenType::PARENTHESES_RIGHT) {
860 lexer_.GetToken();
861 } else {
862 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or ')'"));
863 lexer_.SkipToken(TokenType::PARENTHESES_RIGHT);
864 }
865 break;
866 }
867 }
868
ParseParam()869 AutoPtr<ASTParameter> Parser::ParseParam()
870 {
871 AutoPtr<ASTParamAttr> paramAttr = ParseParamAttr();
872 AutoPtr<ASTType> paramType = ParseType();
873 std::string paramName = "";
874
875 // param name
876 Token token = lexer_.PeekToken();
877 if (token.kind != TokenType::ID) {
878 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected param name"));
879 } else {
880 paramName = token.value;
881 lexer_.GetToken();
882 }
883
884 if (paramType != nullptr && paramType->IsInterfaceType()) {
885 AutoPtr<ASTInterfaceType> ifaceType = dynamic_cast<ASTInterfaceType *>(paramType.Get());
886 if (!ifaceType->IsCallback()) {
887 ifaceType->SetSerializable(true);
888 }
889 }
890
891 return new ASTParameter(paramName, paramAttr, paramType);
892 }
893
ParseParamAttr()894 AutoPtr<ASTParamAttr> Parser::ParseParamAttr()
895 {
896 AutoPtr<ASTParamAttr> attr = new ASTParamAttr(ASTParamAttr::PARAM_NONE);
897
898 if (!CheckParamAttr()) {
899 return attr;
900 }
901
902 // [in], [out], [inout], [in, out]
903 Token token = lexer_.PeekToken();
904 while (token.kind != TokenType::BRACKETS_RIGHT && token.kind != TokenType::END_OF_FILE) {
905 SetParamAttrVal(token, attr);
906
907 // ,
908 token = lexer_.PeekToken();
909 if (token.kind == TokenType::COMMA) {
910 lexer_.GetToken();
911 token = lexer_.PeekToken();
912 continue;
913 }
914
915 // ]
916 if (token.kind != TokenType::BRACKETS_RIGHT) {
917 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ']'"));
918 while (token.kind != TokenType::COMMA && token.kind != TokenType::PARENTHESES_RIGHT &&
919 token.kind != TokenType::END_OF_FILE) {
920 lexer_.GetToken();
921 token = lexer_.PeekToken();
922 }
923 return attr;
924 }
925 }
926 if (attr->value_ == ASTParamAttr::PARAM_NONE) {
927 attr->value_ |= ASTParamAttr::PARAM_IN;
928 }
929 lexer_.GetToken();
930
931 return attr;
932 }
933
CheckParamAttr()934 bool Parser::CheckParamAttr()
935 {
936 Token token = lexer_.PeekToken();
937 if (token.kind != TokenType::BRACKETS_LEFT) {
938 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '['"));
939 while (token.kind != TokenType::COMMA && token.kind != TokenType::PARENTHESES_RIGHT &&
940 token.kind != TokenType::END_OF_FILE) {
941 lexer_.GetToken();
942 token = lexer_.PeekToken();
943 }
944 return false;
945 }
946 lexer_.GetToken();
947 return true;
948 }
949
SetParamAttrVal(Token token,AutoPtr<ASTParamAttr> attr)950 void Parser::SetParamAttrVal(Token token, AutoPtr<ASTParamAttr> attr)
951 {
952 switch (token.kind) {
953 case TokenType::IN:
954 attr->value_ |= ASTParamAttr::PARAM_IN;
955 break;
956 case TokenType::OUT:
957 attr->value_ |= ASTParamAttr::PARAM_OUT;
958 break;
959 case TokenType::INOUT:
960 attr->value_ |= ASTParamAttr::PARAM_INOUT;
961 break;
962 default:
963 LogErrorBeforeToken(__func__, __LINE__, token,
964 StringHelper::Format("expected 'in', 'out' or 'inout' attribute"));
965 return;
966 }
967 lexer_.GetToken();
968 }
969
ParseType()970 AutoPtr<ASTType> Parser::ParseType()
971 {
972 AutoPtr<ASTType> type = nullptr;
973 Token token = lexer_.PeekToken();
974 if (CheckBasicType(token)) {
975 type = ParseBasicType();
976 } else if (CheckUserDefType(token)) {
977 type = ParseUserDefType();
978 } else {
979 switch (token.kind) {
980 case TokenType::LIST:
981 type = ParseListType();
982 break;
983 case TokenType::MAP:
984 type = ParseMapType();
985 break;
986 case TokenType::SMQ:
987 type = ParseSmqType();
988 break;
989 default:
990 LogError(__func__, __LINE__, token, StringHelper::Format("'%s' of type is illegal",
991 token.value.c_str()));
992 return nullptr;
993 }
994 }
995
996 if (type == nullptr) {
997 LogError(__func__, __LINE__, token, std::string("this type was not declared in this scope"));
998 }
999 if (!CheckType(token, type)) {
1000 return nullptr;
1001 }
1002
1003 while (lexer_.PeekToken().kind == TokenType::BRACKETS_LEFT) {
1004 type = ParseArrayType(type);
1005 }
1006 return type;
1007 }
1008
CheckBasicType(Token token)1009 bool Parser::CheckBasicType(Token token)
1010 {
1011 switch (token.kind) {
1012 case TokenType::VOID:
1013 case TokenType::BOOLEAN:
1014 case TokenType::BYTE:
1015 case TokenType::SHORT:
1016 case TokenType::INT:
1017 case TokenType::LONG:
1018 case TokenType::STRING:
1019 case TokenType::STRING16:
1020 case TokenType::FLOAT:
1021 case TokenType::DOUBLE:
1022 case TokenType::FD:
1023 case TokenType::ASHMEM:
1024 case TokenType::NATIVE_BUFFER:
1025 case TokenType::POINTER:
1026 case TokenType::UNSIGNED:
1027 case TokenType::CHAR:
1028 return true;
1029 default:
1030 return false;
1031 }
1032 }
1033
ParseBasicType()1034 AutoPtr<ASTType> Parser::ParseBasicType()
1035 {
1036 AutoPtr<ASTType> type = nullptr;
1037 Token token = lexer_.PeekToken();
1038 if (token.kind == TokenType::UNSIGNED) {
1039 type = ParseUnsignedType();
1040 } else {
1041 type = ast_->FindType(token.value);
1042 lexer_.GetToken();
1043 }
1044
1045 ast_->AddType(type);
1046 return type;
1047 }
1048
ParseUnsignedType()1049 AutoPtr<ASTType> Parser::ParseUnsignedType()
1050 {
1051 AutoPtr<ASTType> type = nullptr;
1052 std::string namePrefix = lexer_.GetToken().value;
1053 Token token = lexer_.PeekToken();
1054 switch (token.kind) {
1055 case TokenType::CHAR:
1056 case TokenType::SHORT:
1057 case TokenType::INT:
1058 case TokenType::LONG:
1059 type = ast_->FindType(namePrefix + " " + token.value);
1060 lexer_.GetToken();
1061 break;
1062 default:
1063 LogError(__func__, __LINE__, token,
1064 StringHelper::Format("'unsigned %s' was not declared in the idl file", token.value.c_str()));
1065 break;
1066 }
1067 return type;
1068 }
1069
ParseArrayType(const AutoPtr<ASTType> & elementType)1070 AutoPtr<ASTType> Parser::ParseArrayType(const AutoPtr<ASTType> &elementType)
1071 {
1072 lexer_.GetToken(); // '['
1073
1074 Token token = lexer_.PeekToken();
1075 if (token.kind != TokenType::BRACKETS_RIGHT) {
1076 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ']'"));
1077 return nullptr;
1078 }
1079 lexer_.GetToken(); // ']'
1080
1081 if (elementType == nullptr) {
1082 return nullptr;
1083 }
1084
1085 AutoPtr<ASTArrayType> arrayType = new ASTArrayType();
1086 arrayType->SetElementType(elementType);
1087 AutoPtr<ASTType> retType = ast_->FindType(arrayType->ToString(), false);
1088 if (retType == nullptr) {
1089 retType = arrayType.Get();
1090 ast_->AddType(retType);
1091 }
1092 return retType;
1093 }
1094
ParseListType()1095 AutoPtr<ASTType> Parser::ParseListType()
1096 {
1097 lexer_.GetToken(); // List
1098
1099 Token token = lexer_.PeekToken();
1100 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1101 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1102 } else {
1103 lexer_.GetToken(); // '<'
1104 }
1105
1106 AutoPtr<ASTType> type = ParseType(); // element type
1107 if (type == nullptr) {
1108 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1109 return nullptr;
1110 }
1111
1112 token = lexer_.PeekToken();
1113 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1114 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1115 } else {
1116 lexer_.GetToken(); // '>'
1117 }
1118
1119 AutoPtr<ASTListType> listType = new ASTListType();
1120 listType->SetElementType(type);
1121 AutoPtr<ASTType> retType = ast_->FindType(listType->ToString(), false);
1122 if (retType == nullptr) {
1123 retType = listType.Get();
1124 ast_->AddType(retType);
1125 }
1126 return retType;
1127 }
1128
ParseMapType()1129 AutoPtr<ASTType> Parser::ParseMapType()
1130 {
1131 lexer_.GetToken(); // 'Map'
1132
1133 Token token = lexer_.PeekToken();
1134 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1135 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1136 } else {
1137 lexer_.GetToken(); // '<'
1138 }
1139
1140 AutoPtr<ASTType> keyType = ParseType(); // key type
1141 if (keyType == nullptr) {
1142 LogError(__func__, __LINE__, token, StringHelper::Format("key type '%s' is illegal", token.value.c_str()));
1143 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1144 return nullptr;
1145 }
1146
1147 token = lexer_.PeekToken();
1148 if (token.kind != TokenType::COMMA) {
1149 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ','"));
1150 } else {
1151 lexer_.GetToken(); // ','
1152 }
1153
1154 AutoPtr<ASTType> valueType = ParseType();
1155 if (valueType == nullptr) {
1156 LogError(__func__, __LINE__, token, StringHelper::Format("value type '%s' is illegal", token.value.c_str()));
1157 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1158 return nullptr;
1159 }
1160
1161 token = lexer_.PeekToken();
1162 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1163 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1164 } else {
1165 lexer_.GetToken();
1166 }
1167
1168 AutoPtr<ASTMapType> mapType = new ASTMapType();
1169 mapType->SetKeyType(keyType);
1170 mapType->SetValueType(valueType);
1171 AutoPtr<ASTType> retType = ast_->FindType(mapType->ToString(), false);
1172 if (retType == nullptr) {
1173 retType = mapType.Get();
1174 ast_->AddType(retType);
1175 }
1176 return retType;
1177 }
1178
ParseSmqType()1179 AutoPtr<ASTType> Parser::ParseSmqType()
1180 {
1181 lexer_.GetToken(); // 'SharedMemQueue'
1182
1183 Token token = lexer_.PeekToken();
1184 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1185 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1186 } else {
1187 lexer_.GetToken(); // '<'
1188 }
1189
1190 AutoPtr<ASTType> innerType = ParseType();
1191 if (innerType == nullptr) {
1192 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1193 return nullptr;
1194 }
1195
1196 token = lexer_.PeekToken();
1197 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1198 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1199 } else {
1200 lexer_.GetToken(); // '>'
1201 }
1202
1203 AutoPtr<ASTSmqType> smqType = new ASTSmqType();
1204 smqType->SetInnerType(innerType);
1205 AutoPtr<ASTType> retType = smqType.Get();
1206 ast_->AddType(retType);
1207 return retType;
1208 }
1209
CheckUserDefType(Token token)1210 bool Parser::CheckUserDefType(Token token)
1211 {
1212 switch (token.kind) {
1213 case TokenType::ENUM:
1214 case TokenType::STRUCT:
1215 case TokenType::UNION:
1216 case TokenType::ID:
1217 case TokenType::SEQ:
1218 return true;
1219 default:
1220 return false;
1221 }
1222 }
1223
ParseUserDefType()1224 AutoPtr<ASTType> Parser::ParseUserDefType()
1225 {
1226 Token token = lexer_.GetToken();
1227 if (token.kind == TokenType::ID) {
1228 return ast_->FindType(token.value);
1229 }
1230
1231 token = lexer_.PeekToken();
1232 if (token.kind != TokenType::ID) {
1233 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected identifier"));
1234 return nullptr;
1235 }
1236 lexer_.GetToken();
1237 AutoPtr<ASTType> type = ast_->FindType(token.value);
1238 ast_->AddType(type);
1239 return type;
1240 }
1241
ParseEnumDeclaration(const AttrSet & attrs)1242 void Parser::ParseEnumDeclaration(const AttrSet &attrs)
1243 {
1244 AutoPtr<ASTEnumType> enumType = new ASTEnumType;
1245 g_currentEnum = enumType;
1246 enumType->SetAttribute(ParseUserDefTypeAttr(attrs));
1247
1248 lexer_.GetToken();
1249 Token token = lexer_.PeekToken();
1250 if (token.kind != TokenType::ID) {
1251 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected enum type name"));
1252 } else {
1253 lexer_.GetToken();
1254 enumType->SetName(token.value);
1255 }
1256
1257 token = lexer_.PeekToken();
1258 if (token.kind == TokenType::COLON || token.kind == TokenType::BRACES_LEFT) {
1259 enumType->SetBaseType(ParseEnumBaseType());
1260 } else {
1261 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ':' or '{'"));
1262 }
1263
1264 ParserEnumMember(enumType);
1265 token = lexer_.PeekToken();
1266 if (token.kind != TokenType::BRACES_RIGHT) {
1267 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'"));
1268 return;
1269 } else {
1270 lexer_.GetToken();
1271 }
1272
1273 token = lexer_.PeekToken();
1274 if (token.kind != TokenType::SEMICOLON) {
1275 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'"));
1276 } else {
1277 lexer_.GetToken();
1278 }
1279
1280 enumType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
1281 ast_->AddTypeDefinition(enumType.Get());
1282 g_currentEnum = nullptr;
1283 }
1284
ParseEnumBaseType()1285 AutoPtr<ASTType> Parser::ParseEnumBaseType()
1286 {
1287 Token token = lexer_.PeekToken();
1288 lexer_.GetToken();
1289 if (token.kind != TokenType::COLON) {
1290 return ast_->FindType("int");
1291 }
1292
1293 token = lexer_.PeekToken();
1294 AutoPtr<ASTType> baseType = ParseType();
1295 if (baseType != nullptr) {
1296 switch (baseType->GetTypeKind()) {
1297 case TypeKind::TYPE_BYTE:
1298 case TypeKind::TYPE_SHORT:
1299 case TypeKind::TYPE_INT:
1300 case TypeKind::TYPE_LONG:
1301 case TypeKind::TYPE_UCHAR:
1302 case TypeKind::TYPE_USHORT:
1303 case TypeKind::TYPE_UINT:
1304 case TypeKind::TYPE_ULONG:
1305 case TypeKind::TYPE_ENUM:
1306 break;
1307 default: {
1308 LogError(__func__, __LINE__, token, std::string("illegal base type of enum"));
1309 lexer_.SkipUntilToken(TokenType::BRACES_LEFT);
1310 break;
1311 }
1312 }
1313 }
1314
1315 token = lexer_.PeekToken();
1316 if (token.kind != TokenType::BRACES_LEFT) {
1317 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'"));
1318 }
1319 lexer_.GetToken();
1320 return baseType;
1321 }
1322
ParserEnumMember(const AutoPtr<ASTEnumType> & enumType)1323 void Parser::ParserEnumMember(const AutoPtr<ASTEnumType> &enumType)
1324 {
1325 while (lexer_.PeekToken().kind == TokenType::ID) {
1326 Token token = lexer_.GetToken();
1327 AutoPtr<ASTEnumValue> enumValue = new ASTEnumValue(token.value);
1328
1329 token = lexer_.PeekToken();
1330 if (token.kind == TokenType::ASSIGN) {
1331 lexer_.GetToken();
1332 enumValue->SetExprValue(ParseExpr());
1333 }
1334
1335 enumValue->SetType(enumType->GetBaseType());
1336 if (!enumType->AddMember(enumValue)) {
1337 LogError(__func__, __LINE__, StringHelper::Format("AddMemberException:member '%s' already exists !",
1338 enumValue->GetName().c_str()));
1339 }
1340 token = lexer_.PeekToken();
1341 if (token.kind == TokenType::COMMA) {
1342 lexer_.GetToken();
1343 continue;
1344 }
1345
1346 if (token.kind != TokenType::BRACES_RIGHT) {
1347 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or '}'"));
1348 }
1349 }
1350 }
1351
ParseStructDeclaration(const AttrSet & attrs)1352 void Parser::ParseStructDeclaration(const AttrSet &attrs)
1353 {
1354 AutoPtr<ASTStructType> structType = new ASTStructType;
1355 structType->SetAttribute(ParseUserDefTypeAttr(attrs));
1356
1357 lexer_.GetToken();
1358 Token token = lexer_.PeekToken();
1359 if (token.kind != TokenType::ID) {
1360 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected struct name"));
1361 } else {
1362 structType->SetName(token.value);
1363 lexer_.GetToken();
1364 }
1365
1366 token = lexer_.PeekToken();
1367 if (token.kind == TokenType::COLON) {
1368 AutoPtr<ASTStructType> parentType = ParseStructParentType();
1369 structType->SetParentType(parentType);
1370 } else if (token.kind != TokenType::BRACES_LEFT) {
1371 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'"));
1372 } else {
1373 lexer_.GetToken();
1374 }
1375
1376 ParseStructMember(structType);
1377
1378 token = lexer_.PeekToken();
1379 if (token.kind != TokenType::BRACES_RIGHT) {
1380 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'"));
1381 } else {
1382 lexer_.GetToken();
1383 }
1384
1385 token = lexer_.PeekToken();
1386 if (token.kind != TokenType::SEMICOLON) {
1387 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'"));
1388 } else {
1389 lexer_.GetToken();
1390 }
1391
1392 structType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
1393 ast_->AddTypeDefinition(structType.Get());
1394 }
1395
ParseStructParentType()1396 AutoPtr<ASTStructType> Parser::ParseStructParentType()
1397 {
1398 lexer_.GetToken();
1399 Token token = lexer_.PeekToken();
1400 AutoPtr<ASTType> baseType = ParseType();
1401 if (baseType == nullptr) {
1402 LogError(__func__, __LINE__, token, std::string("expected base type name before '{' token"));
1403 return nullptr;
1404 }
1405
1406 if (baseType->GetTypeKind() != TypeKind::TYPE_STRUCT) {
1407 LogError(__func__, __LINE__, token, StringHelper::Format("illegal base type of struct: '%s'",
1408 baseType->ToString().c_str()));
1409 lexer_.SkipUntilToken(TokenType::BRACES_LEFT);
1410 }
1411
1412 token = lexer_.PeekToken();
1413 if (token.kind != TokenType::BRACES_LEFT) {
1414 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'"));
1415 }
1416 lexer_.GetToken();
1417 return dynamic_cast<ASTStructType *>(baseType.Get());
1418 }
1419
ParseStructMember(const AutoPtr<ASTStructType> & structType)1420 void Parser::ParseStructMember(const AutoPtr<ASTStructType> &structType)
1421 {
1422 Token token = lexer_.PeekToken();
1423 while (token.kind != TokenType::BRACES_RIGHT && token.kind != TokenType::END_OF_FILE) {
1424 AutoPtr<ASTType> memberType = ParseType();
1425 if (memberType == nullptr) {
1426 lexer_.SkipToken(TokenType::SEMICOLON);
1427 token = lexer_.PeekToken();
1428 continue;
1429 }
1430
1431 token = lexer_.PeekToken();
1432 if (token.kind != TokenType::ID) {
1433 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected member name"));
1434 lexer_.SkipToken(TokenType::SEMICOLON);
1435 token = lexer_.PeekToken();
1436 continue;
1437 }
1438
1439 lexer_.GetToken();
1440 std::string memberName = token.value;
1441 structType->AddMember(memberType, memberName);
1442
1443 token = lexer_.PeekToken();
1444 if (token.kind == TokenType::SEMICOLON) {
1445 lexer_.GetToken();
1446 token = lexer_.PeekToken();
1447 continue;
1448 }
1449
1450 if (token.kind != TokenType::BRACES_RIGHT) {
1451 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or '}'"));
1452 }
1453 }
1454 }
1455
ParseUnionDeclaration(const AttrSet & attrs)1456 void Parser::ParseUnionDeclaration(const AttrSet &attrs)
1457 {
1458 AutoPtr<ASTUnionType> unionType = new ASTUnionType;
1459 unionType->SetAttribute(ParseUserDefTypeAttr(attrs));
1460
1461 lexer_.GetToken();
1462 Token token = lexer_.PeekToken();
1463 if (token.kind != TokenType::ID) {
1464 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected struct name"));
1465 } else {
1466 unionType->SetName(token.value);
1467 lexer_.GetToken();
1468 }
1469
1470 token = lexer_.PeekToken();
1471 if (token.kind != TokenType::BRACES_LEFT) {
1472 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'"));
1473 } else {
1474 lexer_.GetToken();
1475 }
1476
1477 ParseUnionMember(unionType);
1478
1479 token = lexer_.PeekToken();
1480 if (token.kind != TokenType::BRACES_RIGHT) {
1481 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'"));
1482 } else {
1483 lexer_.GetToken();
1484 }
1485
1486 token = lexer_.PeekToken();
1487 if (token.kind != TokenType::SEMICOLON) {
1488 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'"));
1489 } else {
1490 lexer_.GetToken();
1491 }
1492
1493 unionType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
1494 ast_->AddTypeDefinition(unionType.Get());
1495 }
1496
ParseUnionMember(const AutoPtr<ASTUnionType> & unionType)1497 void Parser::ParseUnionMember(const AutoPtr<ASTUnionType> &unionType)
1498 {
1499 Token token = lexer_.PeekToken();
1500 while (token.kind != TokenType::BRACES_RIGHT && token.kind != TokenType::END_OF_FILE) {
1501 AutoPtr<ASTType> memberType = ParseType();
1502 if (memberType == nullptr) {
1503 lexer_.SkipToken(TokenType::SEMICOLON);
1504 token = lexer_.PeekToken();
1505 continue;
1506 }
1507
1508 token = lexer_.PeekToken();
1509 if (token.kind != TokenType::ID) {
1510 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected member name"));
1511 lexer_.SkipToken(TokenType::SEMICOLON);
1512 token = lexer_.PeekToken();
1513 continue;
1514 }
1515 lexer_.GetToken();
1516
1517 std::string memberName = token.value;
1518 if (!AddUnionMember(unionType, memberType, memberName)) {
1519 LogError(__func__, __LINE__, token, StringHelper::Format(
1520 "union not support this type or name of member duplicate '%s'", token.value.c_str()));
1521 }
1522
1523 token = lexer_.PeekToken();
1524 if (token.kind == TokenType::SEMICOLON) {
1525 lexer_.GetToken();
1526 token = lexer_.PeekToken();
1527 continue;
1528 }
1529
1530 if (token.kind != TokenType::BRACES_RIGHT) {
1531 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or '}'"));
1532 }
1533 }
1534 }
1535
AddUnionMember(const AutoPtr<ASTUnionType> & unionType,const AutoPtr<ASTType> & type,const std::string & name) const1536 bool Parser::AddUnionMember(
1537 const AutoPtr<ASTUnionType> &unionType, const AutoPtr<ASTType> &type, const std::string &name) const
1538 {
1539 for (size_t i = 0; i < unionType->GetMemberNumber(); i++) {
1540 if (name == unionType->GetMemberName(i)) {
1541 return false;
1542 }
1543 }
1544
1545 // Non pod type members are not allowed in the union
1546 if (!type->IsPod()) {
1547 return false;
1548 }
1549
1550 unionType->AddMember(type, name);
1551 return true;
1552 }
1553
ParseUserDefTypeAttr(const AttrSet & attrs)1554 AutoPtr<ASTAttr> Parser::ParseUserDefTypeAttr(const AttrSet &attrs)
1555 {
1556 AutoPtr<ASTAttr> attr = new ASTAttr();
1557 for (const auto &token : attrs) {
1558 switch (token.kind) {
1559 case TokenType::FULL:
1560 attr->SetValue(ASTAttr::FULL);
1561 break;
1562 case TokenType::LITE:
1563 attr->SetValue(ASTAttr::LITE);
1564 break;
1565 case TokenType::MINI:
1566 attr->SetValue(ASTAttr::MINI);
1567 break;
1568 default:
1569 LogError(__func__, __LINE__, token, StringHelper::Format("invalid attribute '%s' for type decl",
1570 token.value.c_str()));
1571 break;
1572 }
1573 }
1574
1575 if (attr->IsNone()) {
1576 attr->SetValue(ASTAttr::FULL | ASTAttr::LITE | ASTAttr::MINI);
1577 }
1578
1579 return attr;
1580 }
1581
ParseExpr()1582 AutoPtr<ASTExpr> Parser::ParseExpr()
1583 {
1584 lexer_.SetParseMode(Lexer::ParseMode::EXPR_MODE);
1585 AutoPtr<ASTExpr> value = ParseAndExpr();
1586 lexer_.SetParseMode(Lexer::ParseMode::DECL_MODE);
1587 return value;
1588 }
1589
ParseAndExpr()1590 AutoPtr<ASTExpr> Parser::ParseAndExpr()
1591 {
1592 AutoPtr<ASTExpr> left = ParseXorExpr();
1593 Token token = lexer_.PeekToken();
1594 while (token.kind == TokenType::AND) {
1595 lexer_.GetToken();
1596 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
1597 expr->op_ = BinaryOpKind::AND;
1598 expr->lExpr_ = left;
1599 expr->rExpr_ = ParseXorExpr();
1600
1601 left = expr.Get();
1602 token = lexer_.PeekToken();
1603 }
1604 return left;
1605 }
1606
ParseXorExpr()1607 AutoPtr<ASTExpr> Parser::ParseXorExpr()
1608 {
1609 AutoPtr<ASTExpr> left = ParseOrExpr();
1610 Token token = lexer_.PeekToken();
1611 while (token.kind == TokenType::XOR) {
1612 lexer_.GetToken();
1613 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
1614 expr->op_ = BinaryOpKind::XOR;
1615 expr->lExpr_ = left;
1616 expr->rExpr_ = ParseOrExpr();
1617
1618 left = expr.Get();
1619 token = lexer_.PeekToken();
1620 }
1621 return left;
1622 }
1623
ParseOrExpr()1624 AutoPtr<ASTExpr> Parser::ParseOrExpr()
1625 {
1626 AutoPtr<ASTExpr> left = ParseShiftExpr();
1627 Token token = lexer_.PeekToken();
1628 while (token.kind == TokenType::OR) {
1629 lexer_.GetToken();
1630 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
1631 expr->op_ = BinaryOpKind::OR;
1632 expr->lExpr_ = left;
1633 expr->rExpr_ = ParseShiftExpr();
1634
1635 left = expr.Get();
1636 token = lexer_.PeekToken();
1637 }
1638 return left;
1639 }
1640
ParseShiftExpr()1641 AutoPtr<ASTExpr> Parser::ParseShiftExpr()
1642 {
1643 AutoPtr<ASTExpr> left = ParseAddExpr();
1644 Token token = lexer_.PeekToken();
1645 while (token.kind == TokenType::LEFT_SHIFT || token.kind == TokenType::RIGHT_SHIFT) {
1646 lexer_.GetToken();
1647 BinaryOpKind op = (token.kind == TokenType::LEFT_SHIFT) ? BinaryOpKind::LSHIFT : BinaryOpKind::RSHIFT;
1648 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
1649 expr->op_ = op;
1650 expr->lExpr_ = left;
1651 expr->rExpr_ = ParseAddExpr();
1652
1653 left = expr.Get();
1654 token = lexer_.PeekToken();
1655 }
1656 return left;
1657 }
1658
ParseAddExpr()1659 AutoPtr<ASTExpr> Parser::ParseAddExpr()
1660 {
1661 AutoPtr<ASTExpr> left = ParseMulExpr();
1662 Token token = lexer_.PeekToken();
1663 while (token.kind == TokenType::ADD || token.kind == TokenType::SUB) {
1664 lexer_.GetToken();
1665 BinaryOpKind op = (token.kind == TokenType::ADD) ? BinaryOpKind::ADD : BinaryOpKind::SUB;
1666 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
1667 expr->op_ = op;
1668 expr->lExpr_ = left;
1669 expr->rExpr_ = ParseMulExpr();
1670
1671 left = expr.Get();
1672 token = lexer_.PeekToken();
1673 }
1674 return left;
1675 }
1676
ParseMulExpr()1677 AutoPtr<ASTExpr> Parser::ParseMulExpr()
1678 {
1679 AutoPtr<ASTExpr> left = ParseUnaryExpr();
1680 Token token = lexer_.PeekToken();
1681 while (
1682 token.kind == TokenType::STAR || token.kind == TokenType::SLASH || token.kind == TokenType::PERCENT_SIGN) {
1683 lexer_.GetToken();
1684 BinaryOpKind op = BinaryOpKind::MUL;
1685 if (token.kind == TokenType::SLASH) {
1686 op = BinaryOpKind::DIV;
1687 } else if (token.kind == TokenType::PERCENT_SIGN) {
1688 op = BinaryOpKind::MOD;
1689 }
1690 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
1691 expr->op_ = op;
1692 expr->lExpr_ = left;
1693 expr->rExpr_ = ParseUnaryExpr();
1694
1695 left = expr.Get();
1696 token = lexer_.PeekToken();
1697 }
1698 return left;
1699 }
1700
ParseUnaryExpr()1701 AutoPtr<ASTExpr> Parser::ParseUnaryExpr()
1702 {
1703 Token token = lexer_.PeekToken();
1704 switch (token.kind) {
1705 case TokenType::ADD:
1706 case TokenType::SUB:
1707 case TokenType::TILDE: {
1708 lexer_.GetToken();
1709 AutoPtr<ASTUnaryExpr> expr = new ASTUnaryExpr;
1710 expr->op_ = UnaryOpKind::PLUS;
1711 if (token.kind == TokenType::SUB) {
1712 expr->op_ = UnaryOpKind::MINUS;
1713 } else if (token.kind == TokenType::TILDE) {
1714 expr->op_ = UnaryOpKind::TILDE;
1715 }
1716
1717 expr->expr_ = ParseUnaryExpr();
1718 return expr.Get();
1719 }
1720 default:
1721 return ParsePrimaryExpr();
1722 }
1723 }
1724
ParsePrimaryExpr()1725 AutoPtr<ASTExpr> Parser::ParsePrimaryExpr()
1726 {
1727 Token token = lexer_.PeekToken();
1728 switch (token.kind) {
1729 case TokenType::PARENTHESES_LEFT: {
1730 lexer_.GetToken();
1731 AutoPtr<ASTExpr> expr = ParseExpr();
1732 token = lexer_.PeekToken();
1733 if (token.kind != TokenType::PARENTHESES_RIGHT) {
1734 LogErrorBeforeToken(__func__, __LINE__, token, StringHelper::Format("expected ')'"));
1735 } else {
1736 lexer_.GetToken();
1737 expr->isParenExpr = true;
1738 }
1739 return expr;
1740 }
1741 case TokenType::NUM:
1742 return ParseNumExpr();
1743 case TokenType::ID:
1744 if (g_currentEnum == nullptr) {
1745 LogError(__func__, __LINE__, token, std::string("this expression is not supported"));
1746 lexer_.SkipUntilToken(TokenType::COMMA);
1747 return nullptr;
1748 }
1749 return ParseEnumExpr();
1750 default:
1751 LogError(__func__, __LINE__, token, std::string("this expression is not supported"));
1752 lexer_.SkipUntilToken(TokenType::COMMA);
1753 return nullptr;
1754 }
1755 }
1756
ParseNumExpr()1757 AutoPtr<ASTExpr> Parser::ParseNumExpr()
1758 {
1759 Token token = lexer_.GetToken();
1760 if (!CheckNumber(token.value)) {
1761 LogError(__func__, __LINE__, token, StringHelper::Format("unknown integer number: '%s'", token.value.c_str()));
1762 return nullptr;
1763 }
1764
1765 AutoPtr<ASTNumExpr> expr = new ASTNumExpr;
1766 expr->value_ = token.value;
1767 return expr.Get();
1768 }
1769
ParseEnumExpr()1770 AutoPtr<ASTExpr> Parser::ParseEnumExpr()
1771 {
1772 Token token = lexer_.GetToken();
1773 if (!g_currentEnum->HasMember(token.value)) {
1774 LogError(__func__, __LINE__, token, StringHelper::Format("unknown enum member: '%s'", token.value.c_str()));
1775 return nullptr;
1776 }
1777
1778 AutoPtr<ASTEnumExpr> expr = new ASTEnumExpr;
1779 expr->value_ = token.value;
1780 return expr.Get();
1781 }
1782
CheckNumber(const std::string & integerVal) const1783 bool Parser::CheckNumber(const std::string& integerVal) const
1784 {
1785 if (std::regex_match(integerVal, RE_BIN_NUM) || std::regex_match(integerVal, RE_OCT_NUM)||
1786 std::regex_match(integerVal, RE_DEC_NUM) || std::regex_match(integerVal, RE_HEX_NUM)) {
1787 return true;
1788 }
1789 return false;
1790 }
1791
CheckType(const Token & token,const AutoPtr<ASTType> & type)1792 bool Parser::CheckType(const Token &token, const AutoPtr<ASTType> &type)
1793 {
1794 if ((type == nullptr) || !CheckTypeByMode(token, type)) {
1795 return false;
1796 }
1797
1798 if (Options::GetInstance().GetLanguage() == Language::C) {
1799 if (type->IsSequenceableType() || type->IsSmqType() || type->IsAshmemType()) {
1800 LogError(__func__, __LINE__, token, StringHelper::Format("The %s type is not supported by c language.",
1801 type->ToString().c_str()));
1802 return false;
1803 }
1804 } else if (Options::GetInstance().GetLanguage() == Language::JAVA) {
1805 switch (type->GetTypeKind()) {
1806 case TypeKind::TYPE_UCHAR:
1807 case TypeKind::TYPE_USHORT:
1808 case TypeKind::TYPE_UINT:
1809 case TypeKind::TYPE_ULONG:
1810 case TypeKind::TYPE_ENUM:
1811 case TypeKind::TYPE_STRUCT:
1812 case TypeKind::TYPE_UNION:
1813 case TypeKind::TYPE_SMQ:
1814 case TypeKind::TYPE_UNKNOWN:
1815 LogError(__func__, __LINE__, token, StringHelper::Format("The '%s' type is not supported "
1816 "by java language.", type->ToString().c_str()));
1817 return false;
1818 default:
1819 break;
1820 }
1821 }
1822
1823 return true;
1824 }
1825
CheckTypeByMode(const Token & token,const AutoPtr<ASTType> & type)1826 bool Parser::CheckTypeByMode(const Token &token, const AutoPtr<ASTType> &type)
1827 {
1828 if (!Options::GetInstance().DoPassthrough() && type->IsPointerType()) {
1829 LogError(__func__, __LINE__, token, StringHelper::Format("The %s type is only supported by passthrough mode.",
1830 type->ToString().c_str()));
1831 return false;
1832 }
1833
1834 if (Options::GetInstance().DoGenerateKernelCode()) {
1835 switch (type->GetTypeKind()) {
1836 case TypeKind::TYPE_FLOAT:
1837 case TypeKind::TYPE_DOUBLE:
1838 case TypeKind::TYPE_FILEDESCRIPTOR:
1839 case TypeKind::TYPE_INTERFACE:
1840 case TypeKind::TYPE_SMQ:
1841 case TypeKind::TYPE_ASHMEM:
1842 case TypeKind::TYPE_NATIVE_BUFFER:
1843 case TypeKind::TYPE_POINTER:
1844 LogError(__func__, __LINE__, token,
1845 StringHelper::Format("The '%s' type is not supported by kernel mode.", type->ToString().c_str()));
1846 return false;
1847 default:
1848 break;
1849 }
1850 }
1851 return true;
1852 }
1853
SetAstFileType()1854 void Parser::SetAstFileType()
1855 {
1856 if (ast_->GetInterfaceDef() != nullptr) {
1857 if (ast_->GetInterfaceDef()->IsCallback()) {
1858 ast_->SetAStFileType(ASTFileType::AST_ICALLBACK);
1859 } else {
1860 ast_->SetAStFileType(ASTFileType::AST_IFACE);
1861 }
1862 } else {
1863 ast_->SetAStFileType(ASTFileType::AST_TYPES);
1864 }
1865 }
1866
1867 /*
1868 * filePath: ./ohos/interface/foo/v1_0/IFoo.idl
1869 * package OHOS.Hdi.foo.v1_0;
1870 */
CheckPackageName(const std::string & filePath,const std::string & packageName) const1871 bool Parser::CheckPackageName(const std::string &filePath, const std::string &packageName) const
1872 {
1873 std::string pkgToPath = Options::GetInstance().GetPackagePath(packageName);
1874
1875 size_t index = filePath.rfind(SEPARATOR);
1876 if (index == std::string::npos) {
1877 return false;
1878 }
1879
1880 std::string parentDir = filePath.substr(0, index);
1881 return parentDir == pkgToPath;
1882 }
1883
CheckImport(const std::string & importName)1884 bool Parser::CheckImport(const std::string &importName)
1885 {
1886 if (Options::GetInstance().GetInterfaceType() == InterfaceType::HDI) {
1887 if (!std::regex_match(importName.c_str(), RE_IMPORT)) {
1888 LogError(__func__, __LINE__, StringHelper::Format("invalid impirt name '%s'", importName.c_str()));
1889 return false;
1890 }
1891 } else {
1892 if (!std::regex_match(importName.c_str(), RE_PACKAGE_OR_IMPORT_SM)) {
1893 LogError(__func__, __LINE__, StringHelper::Format("invalid impirt name '%s'", importName.c_str()));
1894 return false;
1895 }
1896 }
1897 std::string idlFilePath = Options::GetInstance().GetImportFilePath(importName);
1898 if (!File::CheckValid(idlFilePath)) {
1899 LogError(__func__, __LINE__, StringHelper::Format("can not import '%s'", idlFilePath.c_str()));
1900 return false;
1901 }
1902 return true;
1903 }
1904
AddAst(const AutoPtr<AST> & ast)1905 bool Parser::AddAst(const AutoPtr<AST> &ast)
1906 {
1907 if (ast == nullptr) {
1908 LogError(__func__, __LINE__, std::string("ast is nullptr."));
1909 return false;
1910 }
1911
1912 allAsts_[ast->GetFullName()] = ast;
1913 return true;
1914 }
1915
ShowError()1916 void Parser::ShowError()
1917 {
1918 for (const auto &errMsg : errors_) {
1919 Logger::E(TAG, "%s", errMsg.c_str());
1920 }
1921 }
1922
ParseInterfaceExtends(AutoPtr<ASTInterfaceType> & interface)1923 void Parser::ParseInterfaceExtends(AutoPtr<ASTInterfaceType> &interface)
1924 {
1925 Token token = lexer_.PeekToken();
1926 if (token.kind != TokenType::EXTENDS) {
1927 return;
1928 }
1929 lexer_.GetToken();
1930 token = lexer_.PeekToken();
1931 if (token.kind != TokenType::ID) {
1932 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected extends interface name"));
1933 lexer_.SkipToken(TokenType::BRACES_LEFT);
1934 return;
1935 }
1936 ParseExtendsInfo(interface);
1937 lexer_.GetToken();
1938 }
1939
ParseExtendsInfo(AutoPtr<ASTInterfaceType> & interfaceType)1940 void Parser::ParseExtendsInfo(AutoPtr<ASTInterfaceType> &interfaceType)
1941 {
1942 Token token = lexer_.PeekToken();
1943 std::string extendsInterfaceName = token.value;
1944 if (extendsInterfaceName.empty()) {
1945 LogError(__func__, __LINE__, token, std::string("extends interface name is empty"));
1946 return;
1947 }
1948 if (!CheckImport(extendsInterfaceName)) {
1949 LogError(__func__, __LINE__, token, std::string("extends interface name is illegal"));
1950 return;
1951 }
1952 auto iter = allAsts_.find(extendsInterfaceName);
1953 AutoPtr<AST> extendsAst = (iter != allAsts_.end()) ? iter->second : nullptr;
1954 if (extendsAst == nullptr) {
1955 LogError(__func__, __LINE__, token, StringHelper::Format("can not find idl file by extends interface "
1956 "name '%s', please check import info", extendsInterfaceName.c_str()));
1957 return;
1958 }
1959 if (!CheckExtendsName(interfaceType, extendsInterfaceName)) {
1960 LogError(__func__, __LINE__, token, StringHelper::Format(
1961 "extends interface name must same as current interface name '%s'", interfaceType->GetName().c_str()));
1962 return;
1963 }
1964 if (!CheckExtendsVersion(interfaceType, extendsInterfaceName, extendsAst)) {
1965 LogError(__func__, __LINE__, token,
1966 std::string("extends interface version must less than current interface version"));
1967 return;
1968 }
1969 if (!interfaceType->AddExtendsInterface(extendsAst->GetInterfaceDef())) {
1970 LogError(__func__, __LINE__, token, StringHelper::Format("multiple extends of '%s'",
1971 interfaceType->GetName().c_str()));
1972 }
1973 }
1974
CheckExtendsName(AutoPtr<ASTInterfaceType> & interfaceType,const std::string & extendsInterfaceName)1975 bool Parser::CheckExtendsName(AutoPtr<ASTInterfaceType> &interfaceType, const std::string &extendsInterfaceName)
1976 {
1977 size_t index = extendsInterfaceName.rfind(".");
1978 return (extendsInterfaceName.substr(index + 1).compare(interfaceType->GetName()) == 0) ? true : false;
1979 }
1980
CheckExtendsVersion(AutoPtr<ASTInterfaceType> & interfaceType,const std::string & extendsName,AutoPtr<AST> extendsAst)1981 bool Parser::CheckExtendsVersion(
1982 AutoPtr<ASTInterfaceType> &interfaceType, const std::string &extendsName, AutoPtr<AST> extendsAst)
1983 {
1984 if (extendsAst->GetMajorVer() != ast_->GetMajorVer() || extendsAst->GetMinorVer() >= ast_->GetMinorVer()) {
1985 return false;
1986 }
1987 return true;
1988 }
1989
CheckImportsVersion(AutoPtr<AST> extendsAst)1990 bool Parser::CheckImportsVersion(AutoPtr<AST> extendsAst)
1991 {
1992 if (extendsAst->GetMajorVer() != ast_->GetMajorVer() || extendsAst->GetMinorVer() > ast_->GetMinorVer()) {
1993 return false;
1994 }
1995 return true;
1996 }
1997
PostProcess()1998 bool Parser::PostProcess()
1999 {
2000 if ((Options::GetInstance().GetLanguage() != Language::C) || !CheckExistExtends()) {
2001 return true;
2002 }
2003 std::vector<size_t> genVersion = {0, 0};
2004 std::string genPackageName;
2005 AutoPtr<ASTNamespace> ns;
2006 if (!GetGenVersion(genVersion, genPackageName)) {
2007 return false;
2008 }
2009 GetGenNamespace(ns);
2010 AstMergeMap mergeMap;
2011 SortAstByName(mergeMap, allAsts_);
2012 allAsts_.clear();
2013 MergeAsts(mergeMap);
2014 ModifyImport(allAsts_, genPackageName);
2015 ModifyPackageNameAndVersion(allAsts_, genPackageName, genVersion);
2016 ModifyInterfaceNamespace(ns);
2017
2018 return true;
2019 }
2020
CheckExistExtends()2021 bool Parser::CheckExistExtends()
2022 {
2023 return std::any_of(allAsts_.begin(), allAsts_.end(), [](const std::pair<std::string, AutoPtr<AST>> &astPair) {
2024 return astPair.second->GetInterfaceDef() != nullptr &&
2025 astPair.second->GetInterfaceDef()->GetExtendsInterface() != nullptr;
2026 });
2027 }
2028
GetGenVersion(std::vector<size_t> & version,std::string & genPackageName)2029 bool Parser::GetGenVersion(std::vector<size_t> &version, std::string &genPackageName)
2030 {
2031 std::set<std::string> sourceFile = Options::GetInstance().GetSourceFiles();
2032 for (const auto &ast : allAsts_) {
2033 if (sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) {
2034 if (genPackageName.empty()) {
2035 genPackageName = ast.second->GetPackageName();
2036 version[0] = ast.second->GetMajorVer();
2037 version[1] = ast.second->GetMinorVer();
2038 continue;
2039 }
2040 if (genPackageName != ast.second->GetPackageName() || version[0] != ast.second->GetMajorVer() ||
2041 version[1] != ast.second->GetMinorVer()) {
2042 LogError(__func__, __LINE__,
2043 StringHelper::Format("merge ast failed, source files must have same package and version"));
2044 return false;
2045 }
2046 }
2047 }
2048 return true;
2049 }
2050
GetGenNamespace(AutoPtr<ASTNamespace> & ns)2051 void Parser::GetGenNamespace(AutoPtr<ASTNamespace> &ns)
2052 {
2053 std::set<std::string> sourceFile = Options::GetInstance().GetSourceFiles();
2054 for (const auto &ast : allAsts_) {
2055 if ((sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) &&
2056 (ast.second->GetInterfaceDef() != nullptr)) {
2057 ns = ast.second->GetInterfaceDef()->GetNamespace();
2058 return;
2059 }
2060 }
2061 }
2062
SortAstByName(AstMergeMap & mergeMap,StrAstMap & allAsts)2063 void Parser::SortAstByName(AstMergeMap &mergeMap, StrAstMap &allAsts)
2064 {
2065 for (const auto &astPair : allAsts) {
2066 AutoPtr<AST> ast = astPair.second;
2067 mergeMap[ast->GetName()].emplace(ast);
2068 }
2069 }
2070
MergeAsts(AstMergeMap & mergeMap)2071 void Parser::MergeAsts(AstMergeMap &mergeMap)
2072 {
2073 for (const auto &setPair : mergeMap) {
2074 AutoPtr<AST> targetAst = nullptr;
2075 for (const auto &ast : setPair.second) {
2076 MergeAst(targetAst, ast);
2077 }
2078 AddAst(targetAst);
2079 }
2080 }
2081
MergeAst(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2082 void Parser::MergeAst(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2083 {
2084 if (targetAst == nullptr) {
2085 targetAst = sourceAst;
2086 return;
2087 }
2088 MergeImport(targetAst, sourceAst);
2089 MergeInterfaceDef(targetAst, sourceAst);
2090 MergeTypeDefinitions(targetAst, sourceAst);
2091 MergeTypes(targetAst, sourceAst);
2092 MergeSequenceableDef(targetAst, sourceAst);
2093 }
2094
MergeImport(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2095 void Parser::MergeImport(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2096 {
2097 for (const auto &importPair : sourceAst->GetImports()) {
2098 AutoPtr<AST> importAst = importPair.second;
2099 targetAst->AddImport(importAst);
2100 }
2101 }
2102
MergeInterfaceDef(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2103 void Parser::MergeInterfaceDef(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2104 {
2105 AutoPtr<ASTInterfaceType> sourceInterface = sourceAst->GetInterfaceDef();
2106 if (sourceInterface == nullptr) {
2107 return;
2108 }
2109 AutoPtr<ASTInterfaceType> targetInterface = targetAst->GetInterfaceDef();
2110 if (targetInterface == nullptr) {
2111 targetInterface = sourceInterface;
2112 return;
2113 }
2114
2115 for (size_t i = 0; i < sourceInterface->GetMethodNumber(); i++) {
2116 targetInterface->AddMethod(sourceInterface->GetMethod(i));
2117 }
2118 targetInterface->SetSerializable(sourceInterface->IsSerializable());
2119 }
2120
MergeTypeDefinitions(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2121 void Parser::MergeTypeDefinitions(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2122 {
2123 for (size_t i = 0; i < sourceAst->GetTypeDefinitionNumber(); i++) {
2124 targetAst->AddTypeDefinition(sourceAst->GetTypeDefintion(i));
2125 }
2126 }
2127
MergeSequenceableDef(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2128 void Parser::MergeSequenceableDef(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2129 {
2130 if (sourceAst->GetSequenceableDef() != nullptr) {
2131 targetAst->AddSequenceableDef(sourceAst->GetSequenceableDef());
2132 }
2133 }
2134
MergeTypes(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2135 void Parser::MergeTypes(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2136 {
2137 for (const auto &typePair : sourceAst->GetTypes()) {
2138 targetAst->AddType(typePair.second);
2139 }
2140 }
2141
ModifyImport(StrAstMap & allAsts,std::string & genPackageName)2142 void Parser::ModifyImport(StrAstMap &allAsts, std::string &genPackageName)
2143 {
2144 for (const auto &astPair : allAsts) {
2145 StrAstMap modifiedImport;
2146 StrAstMap import = astPair.second->GetImports();
2147 for (const auto &importPair : import) {
2148 if (importPair.second->GetName() == astPair.second->GetName()) {
2149 continue;
2150 }
2151 modifiedImport[importPair.second->GetName()] = importPair.second;
2152 }
2153 astPair.second->ClearImport();
2154 for (const auto &importPair : modifiedImport) {
2155 importPair.second->SetPackageName(genPackageName);
2156 astPair.second->AddImport(importPair.second);
2157 }
2158 }
2159 }
2160
ModifyPackageNameAndVersion(StrAstMap & allAsts,std::string & genPackageName,std::vector<size_t> genVersion)2161 void Parser::ModifyPackageNameAndVersion(
2162 StrAstMap &allAsts, std::string &genPackageName, std::vector<size_t> genVersion)
2163 {
2164 for (const auto &astPair : allAsts) {
2165 astPair.second->SetPackageName(genPackageName);
2166 astPair.second->SetVersion(genVersion[0], genVersion[1]);
2167 }
2168 }
2169
ModifyInterfaceNamespace(AutoPtr<ASTNamespace> & ns)2170 void Parser::ModifyInterfaceNamespace(AutoPtr<ASTNamespace> &ns)
2171 {
2172 for (const auto &astPair : allAsts_) {
2173 AutoPtr<ASTInterfaceType> interface = astPair.second->GetInterfaceDef();
2174 if (interface != nullptr) {
2175 interface->SetNamespace(ns);
2176 }
2177 }
2178 }
2179 } // namespace Idl
2180 } // namespace OHOS
2181