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