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