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