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 < 0 || 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::SET || token.kind == TokenType::MAP ||
1023 token.kind == TokenType::ORDEREDMAP || token.kind == TokenType::SMQ ||
1024 token.kind == TokenType::SHAREDPTR || token.kind == TokenType::UNIQUEPTR || token.kind == TokenType::SPTR ||
1025 token.kind == TokenType::NULL_SHAREDPTR || token.kind == TokenType::NULL_UNIQUEPTR ||
1026 token.kind == TokenType::NULL_SPTR) {
1027 return ParseType();
1028 }
1029 return nullptr;
1030 }
1031
ParseMethodAttr()1032 AutoPtr<ASTAttr> Parser::ParseMethodAttr()
1033 {
1034 if (lexer_.PeekToken().kind != TokenType::BRACKETS_LEFT) {
1035 return new ASTAttr();
1036 }
1037
1038 AttrSet attrs = ParseAttributeInfo();
1039 AutoPtr<ASTAttr> methodAttr = new ASTAttr();
1040
1041 for (const auto &attr : attrs) {
1042 switch (attr.kind) {
1043 case TokenType::FULL:
1044 methodAttr->SetValue(ASTAttr::FULL);
1045 break;
1046 case TokenType::LITE:
1047 methodAttr->SetValue(ASTAttr::LITE);
1048 break;
1049 case TokenType::MINI:
1050 methodAttr->SetValue(ASTAttr::MINI);
1051 break;
1052 case TokenType::ONEWAY:
1053 methodAttr->SetValue(ASTAttr::ONEWAY);
1054 break;
1055 case TokenType::CACHEABLE:
1056 methodAttr->SetValue(ASTAttr::CACHEABLE);
1057 methodAttr->SetCacheableTimeString(attr.value);
1058 break;
1059 case TokenType::FREEZECONTROL:
1060 methodAttr->SetValue(ASTAttr::FREEZECONTROL);
1061 break;
1062 case TokenType::IPCCODE:
1063 methodAttr->SetValue(ASTAttr::IPCCODE);
1064 methodAttr->SetIpcCodeStr(attr.value);
1065 break;
1066 case TokenType::IPC_IN_CAPACITY:
1067 methodAttr->SetValue(ASTAttr::IPC_IN_CAPACITY);
1068 methodAttr->SetIpcInCapacity(attr.value);
1069 break;
1070 case TokenType::IPC_OUT_CAPACITY:
1071 methodAttr->SetValue(ASTAttr::IPC_OUT_CAPACITY);
1072 methodAttr->SetIpcOutCapacity(attr.value);
1073 break;
1074 case TokenType::CUSTOM_MSG_OPTION:
1075 methodAttr->SetValue(ASTAttr::CUSTOM_MSG_OPTION);
1076 break;
1077 case TokenType::MACRODEF:
1078 case TokenType::MACRONDEF:
1079 methodAttr->SetValue(ASTAttr::MACRO);
1080 break;
1081 default:
1082 LogError(__func__, __LINE__, attr, std::string("illegal attribute of interface"));
1083 break;
1084 }
1085 }
1086
1087 return methodAttr;
1088 }
1089
CreateGetVersionMethod()1090 AutoPtr<ASTMethod> Parser::CreateGetVersionMethod()
1091 {
1092 AutoPtr<ASTMethod> method = new ASTMethod();
1093 method->SetName("GetVersion");
1094
1095 AutoPtr<ASTType> type = ast_->FindType("unsigned int");
1096 if (type == nullptr) {
1097 type = new ASTUintType();
1098 }
1099
1100 method->AddParameter(new ASTParameter("majorVer", ASTParamAttr::PARAM_OUT, type));
1101 method->AddParameter(new ASTParameter("minorVer", ASTParamAttr::PARAM_OUT, type));
1102 return method;
1103 }
1104
CheckMethodAttr(const AutoPtr<ASTInterfaceType> & interface,const AutoPtr<ASTMethod> & method)1105 void Parser::CheckMethodAttr(const AutoPtr<ASTInterfaceType> &interface, const AutoPtr<ASTMethod> &method)
1106 {
1107 // if the attribute of method is empty, the default value is attribute of interface
1108 if (!method->IsMini() && !method->IsLite() && !method->IsFull()) {
1109 method->SetAttribute(interface->GetAttribute());
1110 }
1111
1112 if (!interface->IsMini() && method->IsMini()) {
1113 LogError(__func__, __LINE__, StringHelper::Format("the '%s' method can not have 'mini' attribute, because the "
1114 "'%s' interface has no 'mini' attribute", method->GetName().c_str(), interface->GetName().c_str()));
1115 }
1116
1117 if (!interface->IsLite() && method->IsLite()) {
1118 LogError(__func__, __LINE__, StringHelper::Format("the '%s' method can not have 'lite' attribute, because the "
1119 "'%s' interface has no 'lite' attribute", method->GetName().c_str(), interface->GetName().c_str()));
1120 }
1121
1122 if (!interface->IsFull() && method->IsFull()) {
1123 LogError(__func__, __LINE__, StringHelper::Format("the '%s' method can not have 'full' attribute, because the "
1124 "'%s' interface has no 'full' attribute", method->GetName().c_str(), interface->GetName().c_str()));
1125 }
1126
1127 // the method has 'oneway' attribute if interface or method has 'oneway' attribute
1128 if (interface->IsOneWay() || method->IsOneWay()) {
1129 method->GetAttribute()->SetValue(ASTAttr::ONEWAY);
1130 }
1131 }
1132
ParseMethodParamList(const AutoPtr<ASTMethod> & method)1133 void Parser::ParseMethodParamList(const AutoPtr<ASTMethod> &method)
1134 {
1135 // (
1136 Token token = lexer_.PeekToken();
1137 if (token.kind != TokenType::PARENTHESES_LEFT) {
1138 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '('"));
1139 } else {
1140 lexer_.GetToken();
1141 }
1142
1143 // ()
1144 token = lexer_.PeekToken();
1145 if (token.kind == TokenType::PARENTHESES_RIGHT) {
1146 lexer_.GetToken();
1147 return;
1148 }
1149
1150 // param
1151 while (token.kind != TokenType::PARENTHESES_RIGHT && token.kind != TokenType::END_OF_FILE) {
1152 AutoPtr<ASTParameter> param = ParseParam();
1153 if (method->IsOneWay() && (param->GetAttribute() & ASTParamAttr::PARAM_OUT)) {
1154 LogError(__func__, __LINE__, token, StringHelper::Format("the '%s' parameter of '%s' method "
1155 "can not be 'out'", param->GetName().c_str(), method->GetName().c_str()));
1156 }
1157 method->AddParameter(param);
1158
1159 // ,
1160 token = lexer_.PeekToken();
1161 if (token.kind == TokenType::COMMA) {
1162 lexer_.GetToken();
1163 token = lexer_.PeekToken();
1164 if (token.kind == TokenType::PARENTHESES_RIGHT) {
1165 LogError(__func__, __LINE__, token, std::string(""));
1166 }
1167 continue;
1168 }
1169
1170 // )
1171 if (token.kind == TokenType::PARENTHESES_RIGHT) {
1172 lexer_.GetToken();
1173 } else {
1174 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or ')'"));
1175 lexer_.SkipToken(TokenType::PARENTHESES_RIGHT);
1176 }
1177 break;
1178 }
1179 }
1180
ParseParam()1181 AutoPtr<ASTParameter> Parser::ParseParam()
1182 {
1183 AutoPtr<ASTParamAttr> paramAttr = ParseParamAttr();
1184 AutoPtr<ASTType> paramType = ParseType();
1185 std::string paramName;
1186
1187 // param name
1188 Token token = lexer_.PeekToken();
1189 if (token.kind != TokenType::ID) {
1190 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected param name"));
1191 } else {
1192 paramName = token.value;
1193 lexer_.GetToken();
1194 }
1195
1196 if (paramType != nullptr && paramType->IsInterfaceType()) {
1197 AutoPtr<ASTInterfaceType> ifaceType = static_cast<ASTInterfaceType *>(paramType.Get());
1198 if (!ifaceType->IsCallback()) {
1199 ifaceType->SetSerializable(true);
1200 }
1201 }
1202
1203 return new ASTParameter(paramName, paramAttr, paramType);
1204 }
1205
ParseParamAttr()1206 AutoPtr<ASTParamAttr> Parser::ParseParamAttr()
1207 {
1208 AutoPtr<ASTParamAttr> attr = new ASTParamAttr(ASTParamAttr::PARAM_NONE);
1209
1210 if (!CheckParamAttr()) {
1211 return attr;
1212 }
1213
1214 // [in], [out], [inout], [in, out]
1215 Token token = lexer_.PeekToken();
1216 while (token.kind != TokenType::BRACKETS_RIGHT && token.kind != TokenType::END_OF_FILE) {
1217 SetParamAttrVal(token, attr);
1218
1219 // ,
1220 token = lexer_.PeekToken();
1221 if (token.kind == TokenType::COMMA) {
1222 lexer_.GetToken();
1223 token = lexer_.PeekToken();
1224 continue;
1225 }
1226
1227 // ]
1228 if (token.kind != TokenType::BRACKETS_RIGHT) {
1229 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ']'"));
1230 while (token.kind != TokenType::COMMA && token.kind != TokenType::PARENTHESES_RIGHT &&
1231 token.kind != TokenType::END_OF_FILE) {
1232 lexer_.GetToken();
1233 token = lexer_.PeekToken();
1234 }
1235 return attr;
1236 }
1237 }
1238 if (attr->value_ == ASTParamAttr::PARAM_NONE) {
1239 attr->value_ |= ASTParamAttr::PARAM_IN;
1240 }
1241 lexer_.GetToken();
1242
1243 return attr;
1244 }
1245
CheckParamAttr()1246 bool Parser::CheckParamAttr()
1247 {
1248 Token token = lexer_.PeekToken();
1249 if (token.kind != TokenType::BRACKETS_LEFT) {
1250 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '['"));
1251 while (token.kind != TokenType::COMMA && token.kind != TokenType::PARENTHESES_RIGHT &&
1252 token.kind != TokenType::END_OF_FILE) {
1253 lexer_.GetToken();
1254 token = lexer_.PeekToken();
1255 }
1256 return false;
1257 }
1258 lexer_.GetToken();
1259 return true;
1260 }
1261
SetParamAttrVal(Token token,AutoPtr<ASTParamAttr> attr)1262 void Parser::SetParamAttrVal(Token token, AutoPtr<ASTParamAttr> attr)
1263 {
1264 switch (token.kind) {
1265 case TokenType::IN:
1266 attr->value_ |= ASTParamAttr::PARAM_IN;
1267 break;
1268 case TokenType::OUT:
1269 attr->value_ |= ASTParamAttr::PARAM_OUT;
1270 break;
1271 case TokenType::INOUT:
1272 attr->value_ |= ASTParamAttr::PARAM_INOUT;
1273 break;
1274 default:
1275 LogErrorBeforeToken(__func__, __LINE__, token,
1276 StringHelper::Format("expected 'in', 'out' or 'inout' attribute"));
1277 return;
1278 }
1279 lexer_.GetToken();
1280 }
1281
ParseType()1282 AutoPtr<ASTType> Parser::ParseType()
1283 {
1284 AutoPtr<ASTType> type = nullptr;
1285 Token token = lexer_.PeekToken();
1286 if (IntfTypeChecker::CheckBasicType(token)) {
1287 type = ParseBasicType();
1288 } else if (IntfTypeChecker::CheckUserDefType(token)) {
1289 type = ParseUserDefType();
1290 } else {
1291 switch (token.kind) {
1292 case TokenType::LIST:
1293 type = ParseListType();
1294 break;
1295 case TokenType::SET:
1296 type = ParseSetType();
1297 break;
1298 case TokenType::MAP:
1299 type = ParseMapType();
1300 break;
1301 case TokenType::ORDEREDMAP:
1302 type = ParseOrderedMapType();
1303 break;
1304 case TokenType::SMQ:
1305 type = ParseSmqType();
1306 break;
1307 case TokenType::SHAREDPTR:
1308 case TokenType::UNIQUEPTR:
1309 case TokenType::SPTR:
1310 case TokenType::NULL_SHAREDPTR:
1311 case TokenType::NULL_UNIQUEPTR:
1312 case TokenType::NULL_SPTR:
1313 type = ParsePtrType(token.kind);
1314 break;
1315 default:
1316 LogError(__func__, __LINE__, token, StringHelper::Format("'%s' of type is illegal",
1317 token.value.c_str()));
1318 return nullptr;
1319 }
1320 }
1321
1322 if (type == nullptr) {
1323 LogError(__func__, __LINE__, token, std::string("this type was not declared in this scope"));
1324 }
1325 if (!CheckType(token, type)) {
1326 return nullptr;
1327 }
1328
1329 while (lexer_.PeekToken().kind == TokenType::BRACKETS_LEFT) {
1330 type = ParseArrayType(type);
1331 }
1332 return type;
1333 }
1334
ParseBasicType()1335 AutoPtr<ASTType> Parser::ParseBasicType()
1336 {
1337 AutoPtr<ASTType> type = nullptr;
1338 Token token = lexer_.PeekToken();
1339 if (token.kind == TokenType::UNSIGNED) {
1340 type = ParseUnsignedType();
1341 } else {
1342 type = ast_->FindType(token.value);
1343 lexer_.GetToken();
1344 }
1345
1346 ast_->AddType(type);
1347 return type;
1348 }
1349
ParseUnsignedType()1350 AutoPtr<ASTType> Parser::ParseUnsignedType()
1351 {
1352 AutoPtr<ASTType> type = nullptr;
1353 std::string namePrefix = lexer_.GetToken().value;
1354 Token token = lexer_.PeekToken();
1355 switch (token.kind) {
1356 case TokenType::CHAR:
1357 case TokenType::SHORT:
1358 case TokenType::INT:
1359 case TokenType::LONG:
1360 type = ast_->FindType(namePrefix + " " + token.value);
1361 lexer_.GetToken();
1362 break;
1363 default:
1364 LogError(__func__, __LINE__, token,
1365 StringHelper::Format("'unsigned %s' was not declared in the idl file", token.value.c_str()));
1366 break;
1367 }
1368 return type;
1369 }
1370
ParseArrayType(const AutoPtr<ASTType> & elementType)1371 AutoPtr<ASTType> Parser::ParseArrayType(const AutoPtr<ASTType> &elementType)
1372 {
1373 lexer_.GetToken(); // '['
1374
1375 Token token = lexer_.PeekToken();
1376 if (token.kind != TokenType::BRACKETS_RIGHT) {
1377 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ']'"));
1378 return nullptr;
1379 }
1380 lexer_.GetToken(); // ']'
1381
1382 if (elementType == nullptr) {
1383 return nullptr;
1384 }
1385
1386 AutoPtr<ASTArrayType> arrayType = new ASTArrayType();
1387 arrayType->SetElementType(elementType);
1388 AutoPtr<ASTType> retType = ast_->FindType(arrayType->ToString(), false);
1389 if (retType == nullptr) {
1390 retType = arrayType.Get();
1391 ast_->AddType(retType);
1392 }
1393 return retType;
1394 }
1395
ParseListType()1396 AutoPtr<ASTType> Parser::ParseListType()
1397 {
1398 lexer_.GetToken(); // List
1399
1400 Token token = lexer_.PeekToken();
1401 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1402 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1403 } else {
1404 lexer_.GetToken(); // '<'
1405 }
1406
1407 AutoPtr<ASTType> type = ParseType(); // element type
1408 if (type == nullptr) {
1409 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1410 return nullptr;
1411 }
1412
1413 token = lexer_.PeekToken();
1414 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1415 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1416 } else {
1417 lexer_.GetToken(); // '>'
1418 }
1419
1420 AutoPtr<ASTListType> listType = new ASTListType();
1421 listType->SetElementType(type);
1422 AutoPtr<ASTType> retType = ast_->FindType(listType->ToString(), false);
1423 if (retType == nullptr) {
1424 retType = listType.Get();
1425 ast_->AddType(retType);
1426 }
1427 return retType;
1428 }
1429
ParseSetType()1430 AutoPtr<ASTType> Parser::ParseSetType()
1431 {
1432 lexer_.GetToken(); // Set
1433
1434 Token token = lexer_.PeekToken();
1435 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1436 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1437 } else {
1438 lexer_.GetToken(); // '<'
1439 }
1440
1441 AutoPtr<ASTType> type = ParseType(); // element type
1442 if (type == nullptr) {
1443 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1444 return nullptr;
1445 }
1446
1447 token = lexer_.PeekToken();
1448 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1449 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1450 } else {
1451 lexer_.GetToken(); // '>'
1452 }
1453
1454 AutoPtr<ASTSetType> setType = new ASTSetType();
1455 setType->SetElementType(type);
1456 AutoPtr<ASTType> retType = ast_->FindType(setType->ToString(), false);
1457 if (retType == nullptr) {
1458 retType = setType.Get();
1459 ast_->AddType(retType);
1460 }
1461 return retType;
1462 }
1463
ParsePtrType(TokenType ptrKind)1464 AutoPtr<ASTType> Parser::ParsePtrType(TokenType ptrKind)
1465 {
1466 lexer_.GetToken(); // shared_ptr unique_ptr sptr
1467
1468 Token token = lexer_.PeekToken();
1469 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1470 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1471 } else {
1472 lexer_.GetToken(); // '<'
1473 }
1474
1475 AutoPtr<ASTType> type = ParseType(); // element type
1476 if (type == nullptr || !IntfTypeChecker::CheckSAPtrType(type)) {
1477 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1478 return nullptr;
1479 }
1480
1481 token = lexer_.PeekToken();
1482 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1483 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1484 } else {
1485 lexer_.GetToken(); // '>'
1486 }
1487
1488 AutoPtr<ASTPtrType> ptrType = new ASTPtrType(ptrKind);
1489 ptrType->SetElementType(type);
1490 AutoPtr<ASTType> retType = ast_->FindType(ptrType->ToString(), false);
1491 if (retType == nullptr) {
1492 retType = ptrType.Get();
1493 ast_->AddType(retType);
1494 }
1495 return retType;
1496 }
1497
ParseMapType()1498 AutoPtr<ASTType> Parser::ParseMapType()
1499 {
1500 lexer_.GetToken(); // 'Map'
1501
1502 Token token = lexer_.PeekToken();
1503 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1504 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1505 } else {
1506 lexer_.GetToken(); // '<'
1507 }
1508
1509 AutoPtr<ASTType> keyType = ParseType(); // key type
1510 if (keyType == nullptr) {
1511 LogError(__func__, __LINE__, token, StringHelper::Format("key type '%s' is illegal", token.value.c_str()));
1512 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1513 return nullptr;
1514 }
1515
1516 token = lexer_.PeekToken();
1517 if (token.kind != TokenType::COMMA) {
1518 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ','"));
1519 } else {
1520 lexer_.GetToken(); // ','
1521 }
1522
1523 AutoPtr<ASTType> valueType = ParseType();
1524 if (valueType == nullptr) {
1525 LogError(__func__, __LINE__, token, StringHelper::Format("value type '%s' is illegal", token.value.c_str()));
1526 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1527 return nullptr;
1528 }
1529
1530 token = lexer_.PeekToken();
1531 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1532 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1533 } else {
1534 lexer_.GetToken();
1535 }
1536
1537 AutoPtr<ASTMapType> mapType = new ASTMapType();
1538 mapType->SetKeyType(keyType);
1539 mapType->SetValueType(valueType);
1540 AutoPtr<ASTType> retType = ast_->FindType(mapType->ToString(), false);
1541 if (retType == nullptr) {
1542 retType = mapType.Get();
1543 ast_->AddType(retType);
1544 }
1545 return retType;
1546 }
1547
ParseOrderedMapType()1548 AutoPtr<ASTType> Parser::ParseOrderedMapType()
1549 {
1550 lexer_.GetToken(); // 'OrderedMap'
1551
1552 Token token = lexer_.PeekToken();
1553 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1554 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1555 } else {
1556 lexer_.GetToken(); // '<'
1557 }
1558
1559 AutoPtr<ASTType> keyType = ParseType(); // key type
1560 if (keyType == nullptr) {
1561 LogError(__func__, __LINE__, token, StringHelper::Format("key type '%s' is illegal", token.value.c_str()));
1562 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1563 return nullptr;
1564 }
1565
1566 token = lexer_.PeekToken();
1567 if (token.kind != TokenType::COMMA) {
1568 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ','"));
1569 } else {
1570 lexer_.GetToken(); // ','
1571 }
1572
1573 AutoPtr<ASTType> valueType = ParseType();
1574 if (valueType == nullptr) {
1575 LogError(__func__, __LINE__, token, StringHelper::Format("value type '%s' is illegal", token.value.c_str()));
1576 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1577 return nullptr;
1578 }
1579
1580 token = lexer_.PeekToken();
1581 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1582 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1583 } else {
1584 lexer_.GetToken();
1585 }
1586
1587 AutoPtr<ASTOrderedMapType> orderedmapType = new ASTOrderedMapType();
1588 orderedmapType->SetKeyType(keyType);
1589 orderedmapType->SetValueType(valueType);
1590 AutoPtr<ASTType> retType = ast_->FindType(orderedmapType->ToString(), false);
1591 if (retType == nullptr) {
1592 retType = orderedmapType.Get();
1593 ast_->AddType(retType);
1594 }
1595 return retType;
1596 }
1597
ParseSmqType()1598 AutoPtr<ASTType> Parser::ParseSmqType()
1599 {
1600 lexer_.GetToken(); // 'SharedMemQueue'
1601
1602 Token token = lexer_.PeekToken();
1603 if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1604 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1605 } else {
1606 lexer_.GetToken(); // '<'
1607 }
1608
1609 AutoPtr<ASTType> innerType = ParseType();
1610 if (innerType == nullptr) {
1611 lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1612 return nullptr;
1613 }
1614
1615 token = lexer_.PeekToken();
1616 if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1617 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1618 } else {
1619 lexer_.GetToken(); // '>'
1620 }
1621
1622 AutoPtr<ASTSmqType> smqType = new ASTSmqType();
1623 smqType->SetInnerType(innerType);
1624 AutoPtr<ASTType> retType = smqType.Get();
1625 ast_->AddType(retType);
1626 return retType;
1627 }
1628
ParseUserDefType()1629 AutoPtr<ASTType> Parser::ParseUserDefType()
1630 {
1631 Token token = lexer_.GetToken();
1632 if (token.kind == TokenType::ID) {
1633 return ast_->FindType(token.value);
1634 }
1635
1636 token = lexer_.PeekToken();
1637 if (token.kind != TokenType::ID) {
1638 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected identifier"));
1639 return nullptr;
1640 }
1641 lexer_.GetToken();
1642 AutoPtr<ASTType> type = ast_->FindType(token.value);
1643 ast_->AddType(type);
1644 return type;
1645 }
1646
ParseEnumDeclaration(const AttrSet & attrs)1647 void Parser::ParseEnumDeclaration(const AttrSet &attrs)
1648 {
1649 AutoPtr<ASTEnumType> enumType = new ASTEnumType;
1650 currentEnum_ = enumType;
1651 enumType->SetAttribute(ParseUserDefTypeAttr(attrs));
1652
1653 lexer_.GetToken();
1654 Token token = lexer_.PeekToken();
1655 if (token.kind != TokenType::ID) {
1656 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected enum type name"));
1657 } else {
1658 lexer_.GetToken();
1659 enumType->SetName(token.value);
1660 }
1661
1662 token = lexer_.PeekToken();
1663 if (token.kind == TokenType::COLON || token.kind == TokenType::BRACES_LEFT) {
1664 enumType->SetBaseType(ParseEnumBaseType());
1665 } else {
1666 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ':' or '{'"));
1667 }
1668
1669 ParserEnumMember(enumType);
1670 token = lexer_.PeekToken();
1671 if (token.kind != TokenType::BRACES_RIGHT) {
1672 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'"));
1673 return;
1674 }
1675
1676 lexer_.GetToken();
1677
1678 token = lexer_.PeekToken();
1679 if (token.kind != TokenType::SEMICOLON) {
1680 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'"));
1681 } else {
1682 lexer_.GetToken();
1683 }
1684
1685 enumType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
1686 ast_->AddTypeDefinition(enumType.Get());
1687 currentEnum_ = nullptr;
1688 }
1689
ParseEnumBaseType()1690 AutoPtr<ASTType> Parser::ParseEnumBaseType()
1691 {
1692 Token token = lexer_.PeekToken();
1693 lexer_.GetToken();
1694 if (token.kind != TokenType::COLON) {
1695 return ast_->FindType("int");
1696 }
1697
1698 token = lexer_.PeekToken();
1699 AutoPtr<ASTType> baseType = ParseType();
1700 if (baseType != nullptr) {
1701 switch (baseType->GetTypeKind()) {
1702 case TypeKind::TYPE_BYTE:
1703 case TypeKind::TYPE_SHORT:
1704 case TypeKind::TYPE_INT:
1705 case TypeKind::TYPE_LONG:
1706 case TypeKind::TYPE_UCHAR:
1707 case TypeKind::TYPE_USHORT:
1708 case TypeKind::TYPE_UINT:
1709 case TypeKind::TYPE_ULONG:
1710 case TypeKind::TYPE_ENUM:
1711 break;
1712 default: {
1713 LogError(__func__, __LINE__, token, std::string("illegal base type of enum"));
1714 lexer_.SkipUntilToken(TokenType::BRACES_LEFT);
1715 break;
1716 }
1717 }
1718 }
1719
1720 token = lexer_.PeekToken();
1721 if (token.kind != TokenType::BRACES_LEFT) {
1722 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'"));
1723 }
1724 lexer_.GetToken();
1725 return baseType;
1726 }
1727
ParserEnumMember(const AutoPtr<ASTEnumType> & enumType)1728 void Parser::ParserEnumMember(const AutoPtr<ASTEnumType> &enumType)
1729 {
1730 while (lexer_.PeekToken().kind == TokenType::ID) {
1731 Token token = lexer_.GetToken();
1732 AutoPtr<ASTEnumValue> enumValue = new ASTEnumValue(token.value);
1733
1734 token = lexer_.PeekToken();
1735 if (token.kind == TokenType::ASSIGN) {
1736 lexer_.GetToken();
1737 enumValue->SetExprValue(ParseExpr());
1738 }
1739
1740 enumValue->SetType(enumType->GetBaseType());
1741 if (!enumType->AddMember(enumValue)) {
1742 LogError(__func__, __LINE__, StringHelper::Format("AddMemberException:member '%s' already exists !",
1743 enumValue->GetName().c_str()));
1744 }
1745 token = lexer_.PeekToken();
1746 if (token.kind == TokenType::COMMA) {
1747 lexer_.GetToken();
1748 continue;
1749 }
1750
1751 if (token.kind != TokenType::BRACES_RIGHT) {
1752 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or '}'"));
1753 }
1754 }
1755 }
1756
ParseStructDeclaration(const AttrSet & attrs)1757 void Parser::ParseStructDeclaration(const AttrSet &attrs)
1758 {
1759 AutoPtr<ASTStructType> structType = new ASTStructType;
1760 structType->SetAttribute(ParseUserDefTypeAttr(attrs));
1761
1762 lexer_.GetToken();
1763 Token token = lexer_.PeekToken();
1764 if (token.kind != TokenType::ID) {
1765 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected struct name"));
1766 } else {
1767 structType->SetName(token.value);
1768 lexer_.GetToken();
1769 }
1770
1771 token = lexer_.PeekToken();
1772 if (token.kind == TokenType::COLON) {
1773 AutoPtr<ASTStructType> parentType = ParseStructParentType();
1774 structType->SetParentType(parentType);
1775 } else if (token.kind != TokenType::BRACES_LEFT) {
1776 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'"));
1777 } else {
1778 lexer_.GetToken();
1779 }
1780
1781 ParseStructMember(structType);
1782
1783 token = lexer_.PeekToken();
1784 if (token.kind != TokenType::BRACES_RIGHT) {
1785 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'"));
1786 } else {
1787 lexer_.GetToken();
1788 }
1789
1790 token = lexer_.PeekToken();
1791 if (token.kind != TokenType::SEMICOLON) {
1792 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'"));
1793 } else {
1794 lexer_.GetToken();
1795 }
1796
1797 structType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
1798 ast_->AddTypeDefinition(structType.Get());
1799 }
1800
ParseStructParentType()1801 AutoPtr<ASTStructType> Parser::ParseStructParentType()
1802 {
1803 lexer_.GetToken();
1804 Token token = lexer_.PeekToken();
1805 AutoPtr<ASTType> baseType = ParseType();
1806 if (baseType == nullptr) {
1807 LogError(__func__, __LINE__, token, std::string("expected base type name before '{' token"));
1808 return nullptr;
1809 }
1810
1811 if (baseType->GetTypeKind() != TypeKind::TYPE_STRUCT) {
1812 LogError(__func__, __LINE__, token, StringHelper::Format("illegal base type of struct: '%s'",
1813 baseType->ToString().c_str()));
1814 lexer_.SkipUntilToken(TokenType::BRACES_LEFT);
1815 }
1816
1817 token = lexer_.PeekToken();
1818 if (token.kind != TokenType::BRACES_LEFT) {
1819 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'"));
1820 }
1821 lexer_.GetToken();
1822 return static_cast<ASTStructType *>(baseType.Get());
1823 }
1824
ParseStructMember(const AutoPtr<ASTStructType> & structType)1825 void Parser::ParseStructMember(const AutoPtr<ASTStructType> &structType)
1826 {
1827 Token token = lexer_.PeekToken();
1828 while (token.kind != TokenType::BRACES_RIGHT && token.kind != TokenType::END_OF_FILE) {
1829 AutoPtr<ASTType> memberType = ParseType();
1830 if (memberType == nullptr) {
1831 lexer_.SkipToken(TokenType::SEMICOLON);
1832 token = lexer_.PeekToken();
1833 continue;
1834 }
1835
1836 token = lexer_.PeekToken();
1837 if (token.kind != TokenType::ID) {
1838 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected member name"));
1839 lexer_.SkipToken(TokenType::SEMICOLON);
1840 token = lexer_.PeekToken();
1841 continue;
1842 }
1843
1844 lexer_.GetToken();
1845 std::string memberName = token.value;
1846 structType->AddMember(memberType, memberName);
1847
1848 token = lexer_.PeekToken();
1849 if (token.kind == TokenType::SEMICOLON) {
1850 lexer_.GetToken();
1851 token = lexer_.PeekToken();
1852 continue;
1853 }
1854
1855 if (token.kind != TokenType::BRACES_RIGHT) {
1856 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or '}'"));
1857 }
1858 }
1859 }
1860
ParseUnionDeclaration(const AttrSet & attrs)1861 void Parser::ParseUnionDeclaration(const AttrSet &attrs)
1862 {
1863 AutoPtr<ASTUnionType> unionType = new ASTUnionType;
1864 unionType->SetAttribute(ParseUserDefTypeAttr(attrs));
1865
1866 lexer_.GetToken();
1867 Token token = lexer_.PeekToken();
1868 if (token.kind != TokenType::ID) {
1869 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected struct name"));
1870 } else {
1871 unionType->SetName(token.value);
1872 lexer_.GetToken();
1873 }
1874
1875 token = lexer_.PeekToken();
1876 if (token.kind != TokenType::BRACES_LEFT) {
1877 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'"));
1878 } else {
1879 lexer_.GetToken();
1880 }
1881
1882 ParseUnionMember(unionType);
1883
1884 token = lexer_.PeekToken();
1885 if (token.kind != TokenType::BRACES_RIGHT) {
1886 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'"));
1887 } else {
1888 lexer_.GetToken();
1889 }
1890
1891 token = lexer_.PeekToken();
1892 if (token.kind != TokenType::SEMICOLON) {
1893 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'"));
1894 } else {
1895 lexer_.GetToken();
1896 }
1897
1898 unionType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
1899 ast_->AddTypeDefinition(unionType.Get());
1900 }
1901
ParseUnionMember(const AutoPtr<ASTUnionType> & unionType)1902 void Parser::ParseUnionMember(const AutoPtr<ASTUnionType> &unionType)
1903 {
1904 Token token = lexer_.PeekToken();
1905 while (token.kind != TokenType::BRACES_RIGHT && token.kind != TokenType::END_OF_FILE) {
1906 AutoPtr<ASTType> memberType = ParseType();
1907 if (memberType == nullptr) {
1908 lexer_.SkipToken(TokenType::SEMICOLON);
1909 token = lexer_.PeekToken();
1910 continue;
1911 }
1912
1913 token = lexer_.PeekToken();
1914 if (token.kind != TokenType::ID) {
1915 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected member name"));
1916 lexer_.SkipToken(TokenType::SEMICOLON);
1917 token = lexer_.PeekToken();
1918 continue;
1919 }
1920 lexer_.GetToken();
1921
1922 std::string memberName = token.value;
1923 if (!AddUnionMember(unionType, memberType, memberName)) {
1924 LogError(__func__, __LINE__, token, StringHelper::Format(
1925 "union not support this type or name of member duplicate '%s'", token.value.c_str()));
1926 }
1927
1928 token = lexer_.PeekToken();
1929 if (token.kind == TokenType::SEMICOLON) {
1930 lexer_.GetToken();
1931 token = lexer_.PeekToken();
1932 continue;
1933 }
1934
1935 if (token.kind != TokenType::BRACES_RIGHT) {
1936 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or '}'"));
1937 }
1938 }
1939 }
1940
AddUnionMember(const AutoPtr<ASTUnionType> & unionType,const AutoPtr<ASTType> & type,const std::string & name) const1941 bool Parser::AddUnionMember(
1942 const AutoPtr<ASTUnionType> &unionType, const AutoPtr<ASTType> &type, const std::string &name) const
1943 {
1944 for (size_t i = 0; i < unionType->GetMemberNumber(); i++) {
1945 if (name == unionType->GetMemberName(i)) {
1946 return false;
1947 }
1948 }
1949
1950 // Non pod type members are not allowed in the union
1951 if (!type->IsPod()) {
1952 return false;
1953 }
1954
1955 unionType->AddMember(type, name);
1956 return true;
1957 }
1958
ParseUserDefTypeAttr(const AttrSet & attrs)1959 AutoPtr<ASTAttr> Parser::ParseUserDefTypeAttr(const AttrSet &attrs)
1960 {
1961 AutoPtr<ASTAttr> attr = new ASTAttr();
1962 for (const auto &token : attrs) {
1963 switch (token.kind) {
1964 case TokenType::FULL:
1965 attr->SetValue(ASTAttr::FULL);
1966 break;
1967 case TokenType::LITE:
1968 attr->SetValue(ASTAttr::LITE);
1969 break;
1970 case TokenType::MINI:
1971 attr->SetValue(ASTAttr::MINI);
1972 break;
1973 default:
1974 LogError(__func__, __LINE__, token, StringHelper::Format("invalid attribute '%s' for type decl",
1975 token.value.c_str()));
1976 break;
1977 }
1978 }
1979
1980 if (attr->IsNone()) {
1981 attr->SetValue(ASTAttr::FULL | ASTAttr::LITE | ASTAttr::MINI);
1982 }
1983
1984 return attr;
1985 }
1986
ParseExpr()1987 AutoPtr<ASTExpr> Parser::ParseExpr()
1988 {
1989 lexer_.SetParseMode(Lexer::ParseMode::EXPR_MODE);
1990 AutoPtr<ASTExpr> value = ParseAndExpr();
1991 lexer_.SetParseMode(Lexer::ParseMode::DECL_MODE);
1992 return value;
1993 }
1994
ParseAndExpr()1995 AutoPtr<ASTExpr> Parser::ParseAndExpr()
1996 {
1997 AutoPtr<ASTExpr> left = ParseXorExpr();
1998 Token token = lexer_.PeekToken();
1999 while (token.kind == TokenType::AND) {
2000 lexer_.GetToken();
2001 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
2002 expr->op_ = BinaryOpKind::AND;
2003 expr->lExpr_ = left;
2004 expr->rExpr_ = ParseXorExpr();
2005
2006 left = expr.Get();
2007 token = lexer_.PeekToken();
2008 }
2009 return left;
2010 }
2011
ParseXorExpr()2012 AutoPtr<ASTExpr> Parser::ParseXorExpr()
2013 {
2014 AutoPtr<ASTExpr> left = ParseOrExpr();
2015 Token token = lexer_.PeekToken();
2016 while (token.kind == TokenType::XOR) {
2017 lexer_.GetToken();
2018 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
2019 expr->op_ = BinaryOpKind::XOR;
2020 expr->lExpr_ = left;
2021 expr->rExpr_ = ParseOrExpr();
2022
2023 left = expr.Get();
2024 token = lexer_.PeekToken();
2025 }
2026 return left;
2027 }
2028
ParseOrExpr()2029 AutoPtr<ASTExpr> Parser::ParseOrExpr()
2030 {
2031 AutoPtr<ASTExpr> left = ParseShiftExpr();
2032 Token token = lexer_.PeekToken();
2033 while (token.kind == TokenType::OR) {
2034 lexer_.GetToken();
2035 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
2036 expr->op_ = BinaryOpKind::OR;
2037 expr->lExpr_ = left;
2038 expr->rExpr_ = ParseShiftExpr();
2039
2040 left = expr.Get();
2041 token = lexer_.PeekToken();
2042 }
2043 return left;
2044 }
2045
ParseShiftExpr()2046 AutoPtr<ASTExpr> Parser::ParseShiftExpr()
2047 {
2048 AutoPtr<ASTExpr> left = ParseAddExpr();
2049 Token token = lexer_.PeekToken();
2050 while (token.kind == TokenType::LEFT_SHIFT || token.kind == TokenType::RIGHT_SHIFT) {
2051 lexer_.GetToken();
2052 BinaryOpKind op = (token.kind == TokenType::LEFT_SHIFT) ? BinaryOpKind::LSHIFT : BinaryOpKind::RSHIFT;
2053 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
2054 expr->op_ = op;
2055 expr->lExpr_ = left;
2056 expr->rExpr_ = ParseAddExpr();
2057
2058 left = expr.Get();
2059 token = lexer_.PeekToken();
2060 }
2061 return left;
2062 }
2063
ParseAddExpr()2064 AutoPtr<ASTExpr> Parser::ParseAddExpr()
2065 {
2066 AutoPtr<ASTExpr> left = ParseMulExpr();
2067 Token token = lexer_.PeekToken();
2068 while (token.kind == TokenType::ADD || token.kind == TokenType::SUB) {
2069 lexer_.GetToken();
2070 BinaryOpKind op = (token.kind == TokenType::ADD) ? BinaryOpKind::ADD : BinaryOpKind::SUB;
2071 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
2072 expr->op_ = op;
2073 expr->lExpr_ = left;
2074 expr->rExpr_ = ParseMulExpr();
2075
2076 left = expr.Get();
2077 token = lexer_.PeekToken();
2078 }
2079 return left;
2080 }
2081
ParseMulExpr()2082 AutoPtr<ASTExpr> Parser::ParseMulExpr()
2083 {
2084 AutoPtr<ASTExpr> left = ParseUnaryExpr();
2085 Token token = lexer_.PeekToken();
2086 while (
2087 token.kind == TokenType::STAR || token.kind == TokenType::SLASH || token.kind == TokenType::PERCENT_SIGN) {
2088 lexer_.GetToken();
2089 BinaryOpKind op = BinaryOpKind::MUL;
2090 if (token.kind == TokenType::SLASH) {
2091 op = BinaryOpKind::DIV;
2092 } else if (token.kind == TokenType::PERCENT_SIGN) {
2093 op = BinaryOpKind::MOD;
2094 }
2095 AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
2096 expr->op_ = op;
2097 expr->lExpr_ = left;
2098 expr->rExpr_ = ParseUnaryExpr();
2099
2100 left = expr.Get();
2101 token = lexer_.PeekToken();
2102 }
2103 return left;
2104 }
2105
ParseUnaryExpr()2106 AutoPtr<ASTExpr> Parser::ParseUnaryExpr()
2107 {
2108 Token token = lexer_.PeekToken();
2109 switch (token.kind) {
2110 case TokenType::ADD:
2111 case TokenType::SUB:
2112 case TokenType::TILDE: {
2113 lexer_.GetToken();
2114 AutoPtr<ASTUnaryExpr> expr = new ASTUnaryExpr;
2115 expr->op_ = UnaryOpKind::PLUS;
2116 if (token.kind == TokenType::SUB) {
2117 expr->op_ = UnaryOpKind::MINUS;
2118 } else if (token.kind == TokenType::TILDE) {
2119 expr->op_ = UnaryOpKind::TILDE;
2120 }
2121
2122 expr->expr_ = ParseUnaryExpr();
2123 return expr.Get();
2124 }
2125 default:
2126 return ParsePrimaryExpr();
2127 }
2128 }
2129
ParsePrimaryExpr()2130 AutoPtr<ASTExpr> Parser::ParsePrimaryExpr()
2131 {
2132 Token token = lexer_.PeekToken();
2133 switch (token.kind) {
2134 case TokenType::PARENTHESES_LEFT: {
2135 lexer_.GetToken();
2136 AutoPtr<ASTExpr> expr = ParseExpr();
2137 token = lexer_.PeekToken();
2138 if (token.kind != TokenType::PARENTHESES_RIGHT) {
2139 LogErrorBeforeToken(__func__, __LINE__, token, StringHelper::Format("expected ')'"));
2140 } else {
2141 lexer_.GetToken();
2142 expr->isParenExpr = true;
2143 }
2144 return expr;
2145 }
2146 case TokenType::NUM:
2147 return ParseNumExpr();
2148 case TokenType::ID:
2149 if (currentEnum_ == nullptr) {
2150 LogError(__func__, __LINE__, token, std::string("this expression is not supported"));
2151 lexer_.SkipUntilToken(TokenType::COMMA);
2152 return nullptr;
2153 }
2154 return ParseEnumExpr();
2155 default:
2156 LogError(__func__, __LINE__, token, std::string("this expression is not supported"));
2157 lexer_.SkipUntilToken(TokenType::COMMA);
2158 return nullptr;
2159 }
2160 }
2161
ParseNumExpr()2162 AutoPtr<ASTExpr> Parser::ParseNumExpr()
2163 {
2164 Token token = lexer_.GetToken();
2165 if (!CheckNumber(token.value)) {
2166 LogError(__func__, __LINE__, token, StringHelper::Format("unknown integer number: '%s'", token.value.c_str()));
2167 return nullptr;
2168 }
2169
2170 AutoPtr<ASTNumExpr> expr = new ASTNumExpr;
2171 expr->value_ = token.value;
2172 return expr.Get();
2173 }
2174
ParseEnumExpr()2175 AutoPtr<ASTExpr> Parser::ParseEnumExpr()
2176 {
2177 Token token = lexer_.GetToken();
2178 if (!currentEnum_->HasMember(token.value)) {
2179 LogError(__func__, __LINE__, token, StringHelper::Format("unknown enum member: '%s'", token.value.c_str()));
2180 return nullptr;
2181 }
2182
2183 AutoPtr<ASTEnumExpr> expr = new ASTEnumExpr;
2184 expr->value_ = token.value;
2185 return expr.Get();
2186 }
2187
CheckNumber(const std::string & integerVal) const2188 bool Parser::CheckNumber(const std::string& integerVal) const
2189 {
2190 try {
2191 return std::regex_match(integerVal, RE_BIN_NUM) || std::regex_match(integerVal, RE_OCT_NUM) ||
2192 std::regex_match(integerVal, RE_DEC_NUM) || std::regex_match(integerVal, RE_HEX_NUM);
2193 } catch (...) {
2194 return false;
2195 }
2196 }
2197
CheckType(const Token & token,const AutoPtr<ASTType> & type)2198 bool Parser::CheckType(const Token &token, const AutoPtr<ASTType> &type)
2199 {
2200 if ((type == nullptr) || !CheckTypeByMode(token, type)) {
2201 return false;
2202 }
2203
2204 if (Options::GetInstance().GetLanguage() == Language::C) {
2205 if (type->IsSequenceableType() || type->IsSmqType() || type->IsAshmemType() || type->IsRawDataType()) {
2206 LogError(__func__, __LINE__, token, StringHelper::Format("The %s type is not supported by c language.",
2207 type->ToString().c_str()));
2208 return false;
2209 }
2210 } else if (Options::GetInstance().GetLanguage() == Language::JAVA) {
2211 switch (type->GetTypeKind()) {
2212 case TypeKind::TYPE_UCHAR:
2213 case TypeKind::TYPE_USHORT:
2214 case TypeKind::TYPE_UINT:
2215 case TypeKind::TYPE_ULONG:
2216 case TypeKind::TYPE_ENUM:
2217 case TypeKind::TYPE_STRUCT:
2218 case TypeKind::TYPE_UNION:
2219 case TypeKind::TYPE_SMQ:
2220 case TypeKind::TYPE_UNKNOWN:
2221 LogError(__func__, __LINE__, token, StringHelper::Format("The '%s' type is not supported "
2222 "by java language.", type->ToString().c_str()));
2223 return false;
2224 default:
2225 break;
2226 }
2227 }
2228
2229 return true;
2230 }
2231
CheckTypeByMode(const Token & token,const AutoPtr<ASTType> & type)2232 bool Parser::CheckTypeByMode(const Token &token, const AutoPtr<ASTType> &type)
2233 {
2234 if (!Options::GetInstance().DoPassthrough() && type->IsPointerType()) {
2235 LogError(__func__, __LINE__, token, StringHelper::Format("The %s type is only supported by passthrough mode.",
2236 type->ToString().c_str()));
2237 return false;
2238 }
2239
2240 if (Options::GetInstance().DoGenerateKernelCode()) {
2241 switch (type->GetTypeKind()) {
2242 case TypeKind::TYPE_FLOAT:
2243 case TypeKind::TYPE_DOUBLE:
2244 case TypeKind::TYPE_FILEDESCRIPTOR:
2245 case TypeKind::TYPE_INTERFACE:
2246 case TypeKind::TYPE_SMQ:
2247 case TypeKind::TYPE_ASHMEM:
2248 case TypeKind::TYPE_NATIVE_BUFFER:
2249 case TypeKind::TYPE_POINTER:
2250 LogError(__func__, __LINE__, token,
2251 StringHelper::Format("The '%s' type is not supported by kernel mode.", type->ToString().c_str()));
2252 return false;
2253 default:
2254 break;
2255 }
2256 }
2257 return true;
2258 }
2259
SetAstFileType()2260 void Parser::SetAstFileType()
2261 {
2262 if (ast_->GetInterfaceDef() != nullptr) {
2263 if (ast_->GetInterfaceDef()->IsCallback()) {
2264 ast_->SetAStFileType(ASTFileType::AST_ICALLBACK);
2265 } else {
2266 ast_->SetAStFileType(ASTFileType::AST_IFACE);
2267 }
2268 } else {
2269 ast_->SetAStFileType(ASTFileType::AST_TYPES);
2270 }
2271 }
2272
2273 /*
2274 * filePath: ./ohos/interface/foo/v1_0/IFoo.idl
2275 * package OHOS.Hdi.foo.v1_0;
2276 */
CheckPackageName(const std::string & filePath,const std::string & packageName) const2277 bool Parser::CheckPackageName(const std::string &filePath, const std::string &packageName) const
2278 {
2279 std::string pkgToPath = Options::GetInstance().GetPackagePath(packageName);
2280
2281 size_t index = filePath.rfind(SEPARATOR);
2282 if (index == std::string::npos) {
2283 return false;
2284 }
2285
2286 std::string parentDir = filePath.substr(0, index);
2287 return parentDir == pkgToPath;
2288 }
2289
CheckImport(const Token & token)2290 bool Parser::CheckImport(const Token &token)
2291 {
2292 std::string importName = token.value;
2293 try {
2294 if (Options::GetInstance().GetInterfaceType() == InterfaceType::HDI) {
2295 if (!std::regex_match(importName.c_str(), RE_IMPORT)) {
2296 LogError(__func__, __LINE__, StringHelper::Format("invalid import name '%s'", importName.c_str()));
2297 return false;
2298 }
2299 } else if (Options::GetInstance().GetInterfaceType() == InterfaceType::SA) {
2300 if (!std::regex_match(importName.c_str(), RE_PACKAGE_OR_IMPORT_SA)) {
2301 LogError(__func__, __LINE__, StringHelper::Format("invalid import name '%s'", importName.c_str()));
2302 return false;
2303 }
2304 } else {
2305 if (!std::regex_match(importName.c_str(), RE_PACKAGE_OR_IMPORT_SM)) {
2306 LogError(__func__, __LINE__, StringHelper::Format("invalid import name '%s'", importName.c_str()));
2307 return false;
2308 }
2309 }
2310 } catch (...) {
2311 LogError(__func__, __LINE__, StringHelper::Format(
2312 "Unknown error when matching import name '%s'", importName.c_str()));
2313 return false;
2314 }
2315
2316 std::string idlFilePath = File::CanonicalPath(
2317 Options::GetInstance().GetImportFilePath(importName, token.location.filePath));
2318 if (!File::CheckValid(idlFilePath)) {
2319 LogError(__func__, __LINE__, StringHelper::Format("can not import '%s'", idlFilePath.c_str()));
2320 return false;
2321 }
2322 return true;
2323 }
2324
AddAst(const AutoPtr<AST> & ast)2325 bool Parser::AddAst(const AutoPtr<AST> &ast)
2326 {
2327 if (ast == nullptr) {
2328 LogError(__func__, __LINE__, std::string("ast is nullptr."));
2329 return false;
2330 }
2331
2332 allAsts_[ast->GetFullName()] = ast;
2333 return true;
2334 }
2335
ParseInterfaceExtends(AutoPtr<ASTInterfaceType> & interface)2336 void Parser::ParseInterfaceExtends(AutoPtr<ASTInterfaceType> &interface)
2337 {
2338 Token token = lexer_.PeekToken();
2339 if (token.kind != TokenType::EXTENDS) {
2340 return;
2341 }
2342 lexer_.GetToken();
2343 token = lexer_.PeekToken();
2344 if (token.kind != TokenType::ID) {
2345 LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected extends interface name"));
2346 lexer_.SkipToken(TokenType::BRACES_LEFT);
2347 return;
2348 }
2349 ParseExtendsInfo(interface);
2350 lexer_.GetToken();
2351 }
2352
ParseExtendsInfo(AutoPtr<ASTInterfaceType> & interfaceType)2353 void Parser::ParseExtendsInfo(AutoPtr<ASTInterfaceType> &interfaceType)
2354 {
2355 Token token = lexer_.PeekToken();
2356 std::string extendsInterfaceName = token.value;
2357 if (extendsInterfaceName.empty()) {
2358 LogError(__func__, __LINE__, token, std::string("extends interface name is empty"));
2359 return;
2360 }
2361 if (Options::GetInstance().GetInterfaceType() == InterfaceType::SA) {
2362 AutoPtr<ASTInterfaceType> extendsInterface = new ASTInterfaceType;
2363 extendsInterface->SetName(extendsInterfaceName);
2364 interfaceType->AddExtendsInterface(extendsInterface);
2365 return;
2366 }
2367 if (!CheckImport(token)) {
2368 LogError(__func__, __LINE__, token, std::string("extends interface name is illegal"));
2369 return;
2370 }
2371 auto iter = allAsts_.find(extendsInterfaceName);
2372 AutoPtr<AST> extendsAst = (iter != allAsts_.end()) ? iter->second : nullptr;
2373 if (extendsAst == nullptr) {
2374 LogError(__func__, __LINE__, token, StringHelper::Format("can not find idl file by extends interface "
2375 "name '%s', please check import info", extendsInterfaceName.c_str()));
2376 return;
2377 }
2378 if (!CheckExtendsName(interfaceType, extendsInterfaceName)) {
2379 LogError(__func__, __LINE__, token, StringHelper::Format(
2380 "extends interface name must same as current interface name '%s'", interfaceType->GetName().c_str()));
2381 return;
2382 }
2383 if (!CheckExtendsVersion(extendsAst)) {
2384 LogError(__func__, __LINE__, token,
2385 std::string("extends interface version must less than current interface version"));
2386 return;
2387 }
2388 if (!interfaceType->AddExtendsInterface(extendsAst->GetInterfaceDef())) {
2389 LogError(__func__, __LINE__, token, StringHelper::Format("multiple extends of '%s'",
2390 interfaceType->GetName().c_str()));
2391 }
2392 }
2393
CheckExtendsName(AutoPtr<ASTInterfaceType> & interfaceType,const std::string & extendsInterfaceName)2394 bool Parser::CheckExtendsName(AutoPtr<ASTInterfaceType> &interfaceType, const std::string &extendsInterfaceName)
2395 {
2396 return extendsInterfaceName.substr(extendsInterfaceName.rfind('.') + 1) == interfaceType->GetName();
2397 }
2398
CheckExtendsVersion(AutoPtr<AST> extendsAst)2399 bool Parser::CheckExtendsVersion(AutoPtr<AST> extendsAst)
2400 {
2401 return !(extendsAst->GetMajorVer() != ast_->GetMajorVer() || extendsAst->GetMinorVer() >= ast_->GetMinorVer());
2402 }
2403
CheckImportsVersion(AutoPtr<AST> extendsAst)2404 bool Parser::CheckImportsVersion(AutoPtr<AST> extendsAst)
2405 {
2406 return !(extendsAst->GetMajorVer() != ast_->GetMajorVer() || extendsAst->GetMinorVer() > ast_->GetMinorVer());
2407 }
2408
PostProcess()2409 bool Parser::PostProcess()
2410 {
2411 if ((Options::GetInstance().GetLanguage() != Language::C) || !CheckExistExtends()) {
2412 return true;
2413 }
2414 std::vector<size_t> genVersion = {0, 0};
2415 std::string genPackageName;
2416 AutoPtr<ASTNamespace> ns;
2417 if (!GetGenVersion(genVersion, genPackageName)) {
2418 return false;
2419 }
2420 GetGenNamespace(ns);
2421 AstMergeMap mergeMap;
2422 SortAstByName(mergeMap, allAsts_);
2423 allAsts_.clear();
2424 MergeAsts(mergeMap);
2425 ModifyImport(allAsts_, genPackageName);
2426 ModifyPackageNameAndVersion(allAsts_, genPackageName, genVersion);
2427 ModifyInterfaceNamespace(ns);
2428
2429 return true;
2430 }
2431
CheckExistExtends()2432 bool Parser::CheckExistExtends()
2433 {
2434 return std::any_of(allAsts_.begin(), allAsts_.end(), [](const std::pair<std::string, AutoPtr<AST>> &astPair) {
2435 return astPair.second->GetInterfaceDef() != nullptr &&
2436 astPair.second->GetInterfaceDef()->GetExtendsInterface() != nullptr;
2437 });
2438 }
2439
GetGenVersion(std::vector<size_t> & version,std::string & genPackageName)2440 bool Parser::GetGenVersion(std::vector<size_t> &version, std::string &genPackageName)
2441 {
2442 std::set<std::string> sourceFile = Options::GetInstance().GetSourceFiles();
2443 for (const auto &ast : allAsts_) {
2444 if (sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) {
2445 if (genPackageName.empty()) {
2446 genPackageName = ast.second->GetPackageName();
2447 version[0] = ast.second->GetMajorVer();
2448 version[1] = ast.second->GetMinorVer();
2449 continue;
2450 }
2451 if (genPackageName != ast.second->GetPackageName() || version[0] != ast.second->GetMajorVer() ||
2452 version[1] != ast.second->GetMinorVer()) {
2453 LogError(__func__, __LINE__,
2454 StringHelper::Format("merge ast failed, source files must have same package and version"));
2455 return false;
2456 }
2457 }
2458 }
2459 return true;
2460 }
2461
GetGenNamespace(AutoPtr<ASTNamespace> & ns)2462 void Parser::GetGenNamespace(AutoPtr<ASTNamespace> &ns)
2463 {
2464 std::set<std::string> sourceFile = Options::GetInstance().GetSourceFiles();
2465 for (const auto &ast : allAsts_) {
2466 if ((sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) &&
2467 (ast.second->GetInterfaceDef() != nullptr)) {
2468 ns = ast.second->GetInterfaceDef()->GetNamespace();
2469 return;
2470 }
2471 }
2472 }
2473
SortAstByName(AstMergeMap & mergeMap,StrAstMap & allAsts)2474 void Parser::SortAstByName(AstMergeMap &mergeMap, StrAstMap &allAsts)
2475 {
2476 for (const auto &astPair : allAsts) {
2477 AutoPtr<AST> ast = astPair.second;
2478 mergeMap[ast->GetName()].emplace(ast);
2479 }
2480 }
2481
MergeAsts(AstMergeMap & mergeMap)2482 void Parser::MergeAsts(AstMergeMap &mergeMap)
2483 {
2484 for (const auto &setPair : mergeMap) {
2485 AutoPtr<AST> targetAst = nullptr;
2486 for (const auto &ast : setPair.second) {
2487 MergeAst(targetAst, ast);
2488 }
2489 AddAst(targetAst);
2490 }
2491 }
2492
MergeAst(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2493 void Parser::MergeAst(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2494 {
2495 if (targetAst == nullptr) {
2496 targetAst = sourceAst;
2497 return;
2498 }
2499 MergeImport(targetAst, sourceAst);
2500 MergeInterfaceDef(targetAst, sourceAst);
2501 MergeTypeDefinitions(targetAst, sourceAst);
2502 MergeTypes(targetAst, sourceAst);
2503 MergeSequenceableDef(targetAst, sourceAst);
2504 MergeRawDataDef(targetAst, sourceAst);
2505 }
2506
MergeImport(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2507 void Parser::MergeImport(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2508 {
2509 for (const auto &importPair : sourceAst->GetImports()) {
2510 AutoPtr<AST> importAst = importPair.second;
2511 targetAst->AddImport(importAst);
2512 }
2513 }
2514
MergeInterfaceDef(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2515 void Parser::MergeInterfaceDef(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2516 {
2517 AutoPtr<ASTInterfaceType> sourceInterface = sourceAst->GetInterfaceDef();
2518 if (sourceInterface == nullptr) {
2519 return;
2520 }
2521 AutoPtr<ASTInterfaceType> targetInterface = targetAst->GetInterfaceDef();
2522 if (targetInterface == nullptr) {
2523 targetInterface = sourceInterface;
2524 return;
2525 }
2526
2527 for (size_t i = 0; i < sourceInterface->GetMethodNumber(); i++) {
2528 targetInterface->AddMethod(sourceInterface->GetMethod(i));
2529 }
2530 targetInterface->SetSerializable(sourceInterface->IsSerializable());
2531 }
2532
MergeTypeDefinitions(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2533 void Parser::MergeTypeDefinitions(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2534 {
2535 for (size_t i = 0; i < sourceAst->GetTypeDefinitionNumber(); i++) {
2536 targetAst->AddTypeDefinition(sourceAst->GetTypeDefintion(i));
2537 }
2538 }
2539
MergeSequenceableDef(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2540 void Parser::MergeSequenceableDef(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2541 {
2542 if (sourceAst->GetSequenceableDef() != nullptr) {
2543 targetAst->AddSequenceableDef(sourceAst->GetSequenceableDef());
2544 }
2545 }
2546
MergeRawDataDef(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2547 void Parser::MergeRawDataDef(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2548 {
2549 if (sourceAst->GetRawDataDef() != nullptr) {
2550 targetAst->AddRawDataDef(sourceAst->GetRawDataDef());
2551 }
2552 }
2553
MergeTypes(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2554 void Parser::MergeTypes(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2555 {
2556 for (const auto &typePair : sourceAst->GetTypes()) {
2557 targetAst->AddType(typePair.second);
2558 }
2559 }
2560
ModifyImport(StrAstMap & allAsts,std::string & genPackageName)2561 void Parser::ModifyImport(StrAstMap &allAsts, std::string &genPackageName)
2562 {
2563 for (const auto &astPair : allAsts) {
2564 StrAstMap modifiedImport;
2565 StrAstMap import = astPair.second->GetImports();
2566 for (const auto &importPair : import) {
2567 if (importPair.second->GetName() == astPair.second->GetName()) {
2568 continue;
2569 }
2570 modifiedImport[importPair.second->GetName()] = importPair.second;
2571 }
2572 astPair.second->ClearImport();
2573 for (const auto &importPair : modifiedImport) {
2574 importPair.second->SetPackageName(genPackageName);
2575 astPair.second->AddImport(importPair.second);
2576 }
2577 }
2578 }
2579
ModifyPackageNameAndVersion(StrAstMap & allAsts,std::string & genPackageName,std::vector<size_t> genVersion)2580 void Parser::ModifyPackageNameAndVersion(
2581 StrAstMap &allAsts, std::string &genPackageName, std::vector<size_t> genVersion)
2582 {
2583 for (const auto &astPair : allAsts) {
2584 astPair.second->SetPackageName(genPackageName);
2585 astPair.second->SetVersion(genVersion[0], genVersion[1]);
2586 }
2587 }
2588
ModifyInterfaceNamespace(AutoPtr<ASTNamespace> & ns)2589 void Parser::ModifyInterfaceNamespace(AutoPtr<ASTNamespace> &ns)
2590 {
2591 for (const auto &astPair : allAsts_) {
2592 AutoPtr<ASTInterfaceType> interface = astPair.second->GetInterfaceDef();
2593 if (interface != nullptr) {
2594 interface->SetNamespace(ns);
2595 }
2596 }
2597 }
2598 } // namespace Idl
2599 } // namespace OHOS
2600