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