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