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