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