• 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 < 0 || 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::SET || token.kind == TokenType::MAP ||
1023         token.kind == TokenType::ORDEREDMAP || token.kind == TokenType::SMQ ||
1024         token.kind == TokenType::SHAREDPTR || token.kind == TokenType::UNIQUEPTR || token.kind == TokenType::SPTR ||
1025         token.kind == TokenType::NULL_SHAREDPTR || token.kind == TokenType::NULL_UNIQUEPTR ||
1026         token.kind == TokenType::NULL_SPTR) {
1027         return ParseType();
1028     }
1029     return nullptr;
1030 }
1031 
ParseMethodAttr()1032 AutoPtr<ASTAttr> Parser::ParseMethodAttr()
1033 {
1034     if (lexer_.PeekToken().kind != TokenType::BRACKETS_LEFT) {
1035         return new ASTAttr();
1036     }
1037 
1038     AttrSet attrs = ParseAttributeInfo();
1039     AutoPtr<ASTAttr> methodAttr = new ASTAttr();
1040 
1041     for (const auto &attr : attrs) {
1042         switch (attr.kind) {
1043             case TokenType::FULL:
1044                 methodAttr->SetValue(ASTAttr::FULL);
1045                 break;
1046             case TokenType::LITE:
1047                 methodAttr->SetValue(ASTAttr::LITE);
1048                 break;
1049             case TokenType::MINI:
1050                 methodAttr->SetValue(ASTAttr::MINI);
1051                 break;
1052             case TokenType::ONEWAY:
1053                 methodAttr->SetValue(ASTAttr::ONEWAY);
1054                 break;
1055             case TokenType::CACHEABLE:
1056                 methodAttr->SetValue(ASTAttr::CACHEABLE);
1057                 methodAttr->SetCacheableTimeString(attr.value);
1058                 break;
1059             case TokenType::FREEZECONTROL:
1060                 methodAttr->SetValue(ASTAttr::FREEZECONTROL);
1061                 break;
1062             case TokenType::IPCCODE:
1063                 methodAttr->SetValue(ASTAttr::IPCCODE);
1064                 methodAttr->SetIpcCodeStr(attr.value);
1065                 break;
1066             case TokenType::IPC_IN_CAPACITY:
1067                 methodAttr->SetValue(ASTAttr::IPC_IN_CAPACITY);
1068                 methodAttr->SetIpcInCapacity(attr.value);
1069                 break;
1070             case TokenType::IPC_OUT_CAPACITY:
1071                 methodAttr->SetValue(ASTAttr::IPC_OUT_CAPACITY);
1072                 methodAttr->SetIpcOutCapacity(attr.value);
1073                 break;
1074             case TokenType::CUSTOM_MSG_OPTION:
1075                 methodAttr->SetValue(ASTAttr::CUSTOM_MSG_OPTION);
1076                 break;
1077             case TokenType::MACRODEF:
1078             case TokenType::MACRONDEF:
1079                 methodAttr->SetValue(ASTAttr::MACRO);
1080                 break;
1081             default:
1082                 LogError(__func__, __LINE__, attr, std::string("illegal attribute of interface"));
1083                 break;
1084         }
1085     }
1086 
1087     return methodAttr;
1088 }
1089 
CreateGetVersionMethod()1090 AutoPtr<ASTMethod> Parser::CreateGetVersionMethod()
1091 {
1092     AutoPtr<ASTMethod> method = new ASTMethod();
1093     method->SetName("GetVersion");
1094 
1095     AutoPtr<ASTType> type = ast_->FindType("unsigned int");
1096     if (type == nullptr) {
1097         type = new ASTUintType();
1098     }
1099 
1100     method->AddParameter(new ASTParameter("majorVer", ASTParamAttr::PARAM_OUT, type));
1101     method->AddParameter(new ASTParameter("minorVer", ASTParamAttr::PARAM_OUT, type));
1102     return method;
1103 }
1104 
CheckMethodAttr(const AutoPtr<ASTInterfaceType> & interface,const AutoPtr<ASTMethod> & method)1105 void Parser::CheckMethodAttr(const AutoPtr<ASTInterfaceType> &interface, const AutoPtr<ASTMethod> &method)
1106 {
1107     // if the attribute of method is empty, the default value is attribute of interface
1108     if (!method->IsMini() && !method->IsLite() && !method->IsFull()) {
1109         method->SetAttribute(interface->GetAttribute());
1110     }
1111 
1112     if (!interface->IsMini() && method->IsMini()) {
1113         LogError(__func__, __LINE__, StringHelper::Format("the '%s' method can not have 'mini' attribute, because the "
1114             "'%s' interface has no 'mini' attribute", method->GetName().c_str(), interface->GetName().c_str()));
1115     }
1116 
1117     if (!interface->IsLite() && method->IsLite()) {
1118         LogError(__func__, __LINE__, StringHelper::Format("the '%s' method can not have 'lite' attribute, because the "
1119             "'%s' interface has no 'lite' attribute", method->GetName().c_str(), interface->GetName().c_str()));
1120     }
1121 
1122     if (!interface->IsFull() && method->IsFull()) {
1123         LogError(__func__, __LINE__, StringHelper::Format("the '%s' method can not have 'full' attribute, because the "
1124             "'%s' interface has no 'full' attribute", method->GetName().c_str(), interface->GetName().c_str()));
1125     }
1126 
1127     // the method has 'oneway' attribute if interface or method has 'oneway' attribute
1128     if (interface->IsOneWay() || method->IsOneWay()) {
1129         method->GetAttribute()->SetValue(ASTAttr::ONEWAY);
1130     }
1131 }
1132 
ParseMethodParamList(const AutoPtr<ASTMethod> & method)1133 void Parser::ParseMethodParamList(const AutoPtr<ASTMethod> &method)
1134 {
1135     // (
1136     Token token = lexer_.PeekToken();
1137     if (token.kind != TokenType::PARENTHESES_LEFT) {
1138         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '('"));
1139     } else {
1140         lexer_.GetToken();
1141     }
1142 
1143     // ()
1144     token = lexer_.PeekToken();
1145     if (token.kind == TokenType::PARENTHESES_RIGHT) {
1146         lexer_.GetToken();
1147         return;
1148     }
1149 
1150     // param
1151     while (token.kind != TokenType::PARENTHESES_RIGHT && token.kind != TokenType::END_OF_FILE) {
1152         AutoPtr<ASTParameter> param = ParseParam();
1153         if (method->IsOneWay() && (param->GetAttribute() & ASTParamAttr::PARAM_OUT)) {
1154             LogError(__func__, __LINE__, token, StringHelper::Format("the '%s' parameter of '%s' method "
1155                 "can not be 'out'", param->GetName().c_str(), method->GetName().c_str()));
1156         }
1157         method->AddParameter(param);
1158 
1159         // ,
1160         token = lexer_.PeekToken();
1161         if (token.kind == TokenType::COMMA) {
1162             lexer_.GetToken();
1163             token = lexer_.PeekToken();
1164             if (token.kind == TokenType::PARENTHESES_RIGHT) {
1165                 LogError(__func__, __LINE__, token, std::string(""));
1166             }
1167             continue;
1168         }
1169 
1170         // )
1171         if (token.kind == TokenType::PARENTHESES_RIGHT) {
1172             lexer_.GetToken();
1173         } else {
1174             LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or ')'"));
1175             lexer_.SkipToken(TokenType::PARENTHESES_RIGHT);
1176         }
1177         break;
1178     }
1179 }
1180 
ParseParam()1181 AutoPtr<ASTParameter> Parser::ParseParam()
1182 {
1183     AutoPtr<ASTParamAttr> paramAttr = ParseParamAttr();
1184     AutoPtr<ASTType> paramType = ParseType();
1185     std::string paramName;
1186 
1187     // param name
1188     Token token = lexer_.PeekToken();
1189     if (token.kind != TokenType::ID) {
1190         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected param name"));
1191     } else {
1192         paramName = token.value;
1193         lexer_.GetToken();
1194     }
1195 
1196     if (paramType != nullptr && paramType->IsInterfaceType()) {
1197         AutoPtr<ASTInterfaceType> ifaceType = static_cast<ASTInterfaceType *>(paramType.Get());
1198         if (!ifaceType->IsCallback()) {
1199             ifaceType->SetSerializable(true);
1200         }
1201     }
1202 
1203     return new ASTParameter(paramName, paramAttr, paramType);
1204 }
1205 
ParseParamAttr()1206 AutoPtr<ASTParamAttr> Parser::ParseParamAttr()
1207 {
1208     AutoPtr<ASTParamAttr> attr = new ASTParamAttr(ASTParamAttr::PARAM_NONE);
1209 
1210     if (!CheckParamAttr()) {
1211         return attr;
1212     }
1213 
1214     // [in], [out], [inout], [in, out]
1215     Token token = lexer_.PeekToken();
1216     while (token.kind != TokenType::BRACKETS_RIGHT && token.kind != TokenType::END_OF_FILE) {
1217         SetParamAttrVal(token, attr);
1218 
1219         // ,
1220         token = lexer_.PeekToken();
1221         if (token.kind == TokenType::COMMA) {
1222             lexer_.GetToken();
1223             token = lexer_.PeekToken();
1224             continue;
1225         }
1226 
1227         // ]
1228         if (token.kind != TokenType::BRACKETS_RIGHT) {
1229             LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ']'"));
1230             while (token.kind != TokenType::COMMA && token.kind != TokenType::PARENTHESES_RIGHT &&
1231                 token.kind != TokenType::END_OF_FILE) {
1232                 lexer_.GetToken();
1233                 token = lexer_.PeekToken();
1234             }
1235             return attr;
1236         }
1237     }
1238     if (attr->value_ == ASTParamAttr::PARAM_NONE) {
1239         attr->value_ |= ASTParamAttr::PARAM_IN;
1240     }
1241     lexer_.GetToken();
1242 
1243     return attr;
1244 }
1245 
CheckParamAttr()1246 bool Parser::CheckParamAttr()
1247 {
1248     Token token = lexer_.PeekToken();
1249     if (token.kind != TokenType::BRACKETS_LEFT) {
1250         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '['"));
1251         while (token.kind != TokenType::COMMA && token.kind != TokenType::PARENTHESES_RIGHT &&
1252             token.kind != TokenType::END_OF_FILE) {
1253             lexer_.GetToken();
1254             token = lexer_.PeekToken();
1255         }
1256         return false;
1257     }
1258     lexer_.GetToken();
1259     return true;
1260 }
1261 
SetParamAttrVal(Token token,AutoPtr<ASTParamAttr> attr)1262 void Parser::SetParamAttrVal(Token token, AutoPtr<ASTParamAttr> attr)
1263 {
1264     switch (token.kind) {
1265         case TokenType::IN:
1266             attr->value_ |= ASTParamAttr::PARAM_IN;
1267             break;
1268         case TokenType::OUT:
1269             attr->value_ |= ASTParamAttr::PARAM_OUT;
1270             break;
1271         case TokenType::INOUT:
1272             attr->value_ |= ASTParamAttr::PARAM_INOUT;
1273             break;
1274         default:
1275             LogErrorBeforeToken(__func__, __LINE__, token,
1276                 StringHelper::Format("expected 'in', 'out' or 'inout' attribute"));
1277             return;
1278     }
1279     lexer_.GetToken();
1280 }
1281 
ParseType()1282 AutoPtr<ASTType> Parser::ParseType()
1283 {
1284     AutoPtr<ASTType> type = nullptr;
1285     Token token = lexer_.PeekToken();
1286     if (IntfTypeChecker::CheckBasicType(token)) {
1287         type = ParseBasicType();
1288     } else if (IntfTypeChecker::CheckUserDefType(token)) {
1289         type = ParseUserDefType();
1290     } else {
1291         switch (token.kind) {
1292             case TokenType::LIST:
1293                 type = ParseListType();
1294                 break;
1295             case TokenType::SET:
1296                 type = ParseSetType();
1297                 break;
1298             case TokenType::MAP:
1299                 type = ParseMapType();
1300                 break;
1301             case TokenType::ORDEREDMAP:
1302                 type = ParseOrderedMapType();
1303                 break;
1304             case TokenType::SMQ:
1305                 type = ParseSmqType();
1306                 break;
1307             case TokenType::SHAREDPTR:
1308             case TokenType::UNIQUEPTR:
1309             case TokenType::SPTR:
1310             case TokenType::NULL_SHAREDPTR:
1311             case TokenType::NULL_UNIQUEPTR:
1312             case TokenType::NULL_SPTR:
1313                 type = ParsePtrType(token.kind);
1314                 break;
1315             default:
1316                 LogError(__func__, __LINE__, token, StringHelper::Format("'%s' of type is illegal",
1317                     token.value.c_str()));
1318                 return nullptr;
1319         }
1320     }
1321 
1322     if (type == nullptr) {
1323         LogError(__func__, __LINE__, token, std::string("this type was not declared in this scope"));
1324     }
1325     if (!CheckType(token, type)) {
1326         return nullptr;
1327     }
1328 
1329     while (lexer_.PeekToken().kind == TokenType::BRACKETS_LEFT) {
1330         type = ParseArrayType(type);
1331     }
1332     return type;
1333 }
1334 
ParseBasicType()1335 AutoPtr<ASTType> Parser::ParseBasicType()
1336 {
1337     AutoPtr<ASTType> type = nullptr;
1338     Token token = lexer_.PeekToken();
1339     if (token.kind == TokenType::UNSIGNED) {
1340         type = ParseUnsignedType();
1341     } else {
1342         type = ast_->FindType(token.value);
1343         lexer_.GetToken();
1344     }
1345 
1346     ast_->AddType(type);
1347     return type;
1348 }
1349 
ParseUnsignedType()1350 AutoPtr<ASTType> Parser::ParseUnsignedType()
1351 {
1352     AutoPtr<ASTType> type = nullptr;
1353     std::string namePrefix = lexer_.GetToken().value;
1354     Token token = lexer_.PeekToken();
1355     switch (token.kind) {
1356         case TokenType::CHAR:
1357         case TokenType::SHORT:
1358         case TokenType::INT:
1359         case TokenType::LONG:
1360             type = ast_->FindType(namePrefix + " " + token.value);
1361             lexer_.GetToken();
1362             break;
1363         default:
1364             LogError(__func__, __LINE__, token,
1365                 StringHelper::Format("'unsigned %s' was not declared in the idl file", token.value.c_str()));
1366             break;
1367     }
1368     return type;
1369 }
1370 
ParseArrayType(const AutoPtr<ASTType> & elementType)1371 AutoPtr<ASTType> Parser::ParseArrayType(const AutoPtr<ASTType> &elementType)
1372 {
1373     lexer_.GetToken(); // '['
1374 
1375     Token token = lexer_.PeekToken();
1376     if (token.kind != TokenType::BRACKETS_RIGHT) {
1377         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ']'"));
1378         return nullptr;
1379     }
1380     lexer_.GetToken(); // ']'
1381 
1382     if (elementType == nullptr) {
1383         return nullptr;
1384     }
1385 
1386     AutoPtr<ASTArrayType> arrayType = new ASTArrayType();
1387     arrayType->SetElementType(elementType);
1388     AutoPtr<ASTType> retType = ast_->FindType(arrayType->ToString(), false);
1389     if (retType == nullptr) {
1390         retType = arrayType.Get();
1391         ast_->AddType(retType);
1392     }
1393     return retType;
1394 }
1395 
ParseListType()1396 AutoPtr<ASTType> Parser::ParseListType()
1397 {
1398     lexer_.GetToken(); // List
1399 
1400     Token token = lexer_.PeekToken();
1401     if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1402         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1403     } else {
1404         lexer_.GetToken(); // '<'
1405     }
1406 
1407     AutoPtr<ASTType> type = ParseType(); // element type
1408     if (type == nullptr) {
1409         lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1410         return nullptr;
1411     }
1412 
1413     token = lexer_.PeekToken();
1414     if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1415         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1416     } else {
1417         lexer_.GetToken(); // '>'
1418     }
1419 
1420     AutoPtr<ASTListType> listType = new ASTListType();
1421     listType->SetElementType(type);
1422     AutoPtr<ASTType> retType = ast_->FindType(listType->ToString(), false);
1423     if (retType == nullptr) {
1424         retType = listType.Get();
1425         ast_->AddType(retType);
1426     }
1427     return retType;
1428 }
1429 
ParseSetType()1430 AutoPtr<ASTType> Parser::ParseSetType()
1431 {
1432     lexer_.GetToken(); // Set
1433 
1434     Token token = lexer_.PeekToken();
1435     if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1436         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1437     } else {
1438         lexer_.GetToken(); // '<'
1439     }
1440 
1441     AutoPtr<ASTType> type = ParseType(); // element type
1442     if (type == nullptr) {
1443         lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1444         return nullptr;
1445     }
1446 
1447     token = lexer_.PeekToken();
1448     if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1449         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1450     } else {
1451         lexer_.GetToken(); // '>'
1452     }
1453 
1454     AutoPtr<ASTSetType> setType = new ASTSetType();
1455     setType->SetElementType(type);
1456     AutoPtr<ASTType> retType = ast_->FindType(setType->ToString(), false);
1457     if (retType == nullptr) {
1458         retType = setType.Get();
1459         ast_->AddType(retType);
1460     }
1461     return retType;
1462 }
1463 
ParsePtrType(TokenType ptrKind)1464 AutoPtr<ASTType> Parser::ParsePtrType(TokenType ptrKind)
1465 {
1466     lexer_.GetToken(); // shared_ptr unique_ptr sptr
1467 
1468     Token token = lexer_.PeekToken();
1469     if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1470         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1471     } else {
1472         lexer_.GetToken(); // '<'
1473     }
1474 
1475     AutoPtr<ASTType> type = ParseType(); // element type
1476     if (type == nullptr || !IntfTypeChecker::CheckSAPtrType(type)) {
1477         lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1478         return nullptr;
1479     }
1480 
1481     token = lexer_.PeekToken();
1482     if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1483         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1484     } else {
1485         lexer_.GetToken(); // '>'
1486     }
1487 
1488     AutoPtr<ASTPtrType> ptrType = new ASTPtrType(ptrKind);
1489     ptrType->SetElementType(type);
1490     AutoPtr<ASTType> retType = ast_->FindType(ptrType->ToString(), false);
1491     if (retType == nullptr) {
1492         retType = ptrType.Get();
1493         ast_->AddType(retType);
1494     }
1495     return retType;
1496 }
1497 
ParseMapType()1498 AutoPtr<ASTType> Parser::ParseMapType()
1499 {
1500     lexer_.GetToken(); // 'Map'
1501 
1502     Token token = lexer_.PeekToken();
1503     if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1504         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1505     } else {
1506         lexer_.GetToken(); // '<'
1507     }
1508 
1509     AutoPtr<ASTType> keyType = ParseType(); // key type
1510     if (keyType == nullptr) {
1511         LogError(__func__, __LINE__, token, StringHelper::Format("key type '%s' is illegal", token.value.c_str()));
1512         lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1513         return nullptr;
1514     }
1515 
1516     token = lexer_.PeekToken();
1517     if (token.kind != TokenType::COMMA) {
1518         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ','"));
1519     } else {
1520         lexer_.GetToken(); // ','
1521     }
1522 
1523     AutoPtr<ASTType> valueType = ParseType();
1524     if (valueType == nullptr) {
1525         LogError(__func__, __LINE__, token, StringHelper::Format("value type '%s' is illegal", token.value.c_str()));
1526         lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1527         return nullptr;
1528     }
1529 
1530     token = lexer_.PeekToken();
1531     if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1532         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1533     } else {
1534         lexer_.GetToken();
1535     }
1536 
1537     AutoPtr<ASTMapType> mapType = new ASTMapType();
1538     mapType->SetKeyType(keyType);
1539     mapType->SetValueType(valueType);
1540     AutoPtr<ASTType> retType = ast_->FindType(mapType->ToString(), false);
1541     if (retType == nullptr) {
1542         retType = mapType.Get();
1543         ast_->AddType(retType);
1544     }
1545     return retType;
1546 }
1547 
ParseOrderedMapType()1548 AutoPtr<ASTType> Parser::ParseOrderedMapType()
1549 {
1550     lexer_.GetToken(); // 'OrderedMap'
1551 
1552     Token token = lexer_.PeekToken();
1553     if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1554         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1555     } else {
1556         lexer_.GetToken(); // '<'
1557     }
1558 
1559     AutoPtr<ASTType> keyType = ParseType(); // key type
1560     if (keyType == nullptr) {
1561         LogError(__func__, __LINE__, token, StringHelper::Format("key type '%s' is illegal", token.value.c_str()));
1562         lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1563         return nullptr;
1564     }
1565 
1566     token = lexer_.PeekToken();
1567     if (token.kind != TokenType::COMMA) {
1568         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ','"));
1569     } else {
1570         lexer_.GetToken(); // ','
1571     }
1572 
1573     AutoPtr<ASTType> valueType = ParseType();
1574     if (valueType == nullptr) {
1575         LogError(__func__, __LINE__, token, StringHelper::Format("value type '%s' is illegal", token.value.c_str()));
1576         lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1577         return nullptr;
1578     }
1579 
1580     token = lexer_.PeekToken();
1581     if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1582         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1583     } else {
1584         lexer_.GetToken();
1585     }
1586 
1587     AutoPtr<ASTOrderedMapType> orderedmapType = new ASTOrderedMapType();
1588     orderedmapType->SetKeyType(keyType);
1589     orderedmapType->SetValueType(valueType);
1590     AutoPtr<ASTType> retType = ast_->FindType(orderedmapType->ToString(), false);
1591     if (retType == nullptr) {
1592         retType = orderedmapType.Get();
1593         ast_->AddType(retType);
1594     }
1595     return retType;
1596 }
1597 
ParseSmqType()1598 AutoPtr<ASTType> Parser::ParseSmqType()
1599 {
1600     lexer_.GetToken(); // 'SharedMemQueue'
1601 
1602     Token token = lexer_.PeekToken();
1603     if (token.kind != TokenType::ANGLE_BRACKETS_LEFT) {
1604         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '<'"));
1605     } else {
1606         lexer_.GetToken(); // '<'
1607     }
1608 
1609     AutoPtr<ASTType> innerType = ParseType();
1610     if (innerType == nullptr) {
1611         lexer_.SkipToken(TokenType::ANGLE_BRACKETS_RIGHT);
1612         return nullptr;
1613     }
1614 
1615     token = lexer_.PeekToken();
1616     if (token.kind != TokenType::ANGLE_BRACKETS_RIGHT) {
1617         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '>'"));
1618     } else {
1619         lexer_.GetToken(); // '>'
1620     }
1621 
1622     AutoPtr<ASTSmqType> smqType = new ASTSmqType();
1623     smqType->SetInnerType(innerType);
1624     AutoPtr<ASTType> retType = smqType.Get();
1625     ast_->AddType(retType);
1626     return retType;
1627 }
1628 
ParseUserDefType()1629 AutoPtr<ASTType> Parser::ParseUserDefType()
1630 {
1631     Token token = lexer_.GetToken();
1632     if (token.kind == TokenType::ID) {
1633         return ast_->FindType(token.value);
1634     }
1635 
1636     token = lexer_.PeekToken();
1637     if (token.kind != TokenType::ID) {
1638         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected identifier"));
1639         return nullptr;
1640     }
1641     lexer_.GetToken();
1642     AutoPtr<ASTType> type = ast_->FindType(token.value);
1643     ast_->AddType(type);
1644     return type;
1645 }
1646 
ParseEnumDeclaration(const AttrSet & attrs)1647 void Parser::ParseEnumDeclaration(const AttrSet &attrs)
1648 {
1649     AutoPtr<ASTEnumType> enumType = new ASTEnumType;
1650     currentEnum_ = enumType;
1651     enumType->SetAttribute(ParseUserDefTypeAttr(attrs));
1652 
1653     lexer_.GetToken();
1654     Token token = lexer_.PeekToken();
1655     if (token.kind != TokenType::ID) {
1656         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected enum type name"));
1657     } else {
1658         lexer_.GetToken();
1659         enumType->SetName(token.value);
1660     }
1661 
1662     token = lexer_.PeekToken();
1663     if (token.kind == TokenType::COLON || token.kind == TokenType::BRACES_LEFT) {
1664         enumType->SetBaseType(ParseEnumBaseType());
1665     } else {
1666         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ':' or '{'"));
1667     }
1668 
1669     ParserEnumMember(enumType);
1670     token = lexer_.PeekToken();
1671     if (token.kind != TokenType::BRACES_RIGHT) {
1672         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'"));
1673         return;
1674     }
1675 
1676     lexer_.GetToken();
1677 
1678     token = lexer_.PeekToken();
1679     if (token.kind != TokenType::SEMICOLON) {
1680         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'"));
1681     } else {
1682         lexer_.GetToken();
1683     }
1684 
1685     enumType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
1686     ast_->AddTypeDefinition(enumType.Get());
1687     currentEnum_ = nullptr;
1688 }
1689 
ParseEnumBaseType()1690 AutoPtr<ASTType> Parser::ParseEnumBaseType()
1691 {
1692     Token token = lexer_.PeekToken();
1693     lexer_.GetToken();
1694     if (token.kind != TokenType::COLON) {
1695         return ast_->FindType("int");
1696     }
1697 
1698     token = lexer_.PeekToken();
1699     AutoPtr<ASTType> baseType = ParseType();
1700     if (baseType != nullptr) {
1701         switch (baseType->GetTypeKind()) {
1702             case TypeKind::TYPE_BYTE:
1703             case TypeKind::TYPE_SHORT:
1704             case TypeKind::TYPE_INT:
1705             case TypeKind::TYPE_LONG:
1706             case TypeKind::TYPE_UCHAR:
1707             case TypeKind::TYPE_USHORT:
1708             case TypeKind::TYPE_UINT:
1709             case TypeKind::TYPE_ULONG:
1710             case TypeKind::TYPE_ENUM:
1711                 break;
1712             default: {
1713                 LogError(__func__, __LINE__, token, std::string("illegal base type of enum"));
1714                 lexer_.SkipUntilToken(TokenType::BRACES_LEFT);
1715                 break;
1716             }
1717         }
1718     }
1719 
1720     token = lexer_.PeekToken();
1721     if (token.kind != TokenType::BRACES_LEFT) {
1722         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'"));
1723     }
1724     lexer_.GetToken();
1725     return baseType;
1726 }
1727 
ParserEnumMember(const AutoPtr<ASTEnumType> & enumType)1728 void Parser::ParserEnumMember(const AutoPtr<ASTEnumType> &enumType)
1729 {
1730     while (lexer_.PeekToken().kind == TokenType::ID) {
1731         Token token = lexer_.GetToken();
1732         AutoPtr<ASTEnumValue> enumValue = new ASTEnumValue(token.value);
1733 
1734         token = lexer_.PeekToken();
1735         if (token.kind == TokenType::ASSIGN) {
1736             lexer_.GetToken();
1737             enumValue->SetExprValue(ParseExpr());
1738         }
1739 
1740         enumValue->SetType(enumType->GetBaseType());
1741         if (!enumType->AddMember(enumValue)) {
1742             LogError(__func__, __LINE__, StringHelper::Format("AddMemberException:member '%s' already exists !",
1743                 enumValue->GetName().c_str()));
1744         }
1745         token = lexer_.PeekToken();
1746         if (token.kind == TokenType::COMMA) {
1747             lexer_.GetToken();
1748             continue;
1749         }
1750 
1751         if (token.kind != TokenType::BRACES_RIGHT) {
1752             LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or '}'"));
1753         }
1754     }
1755 }
1756 
ParseStructDeclaration(const AttrSet & attrs)1757 void Parser::ParseStructDeclaration(const AttrSet &attrs)
1758 {
1759     AutoPtr<ASTStructType> structType = new ASTStructType;
1760     structType->SetAttribute(ParseUserDefTypeAttr(attrs));
1761 
1762     lexer_.GetToken();
1763     Token token = lexer_.PeekToken();
1764     if (token.kind != TokenType::ID) {
1765         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected struct name"));
1766     } else {
1767         structType->SetName(token.value);
1768         lexer_.GetToken();
1769     }
1770 
1771     token = lexer_.PeekToken();
1772     if (token.kind == TokenType::COLON) {
1773         AutoPtr<ASTStructType> parentType = ParseStructParentType();
1774         structType->SetParentType(parentType);
1775     } else if (token.kind != TokenType::BRACES_LEFT) {
1776         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'"));
1777     } else {
1778         lexer_.GetToken();
1779     }
1780 
1781     ParseStructMember(structType);
1782 
1783     token = lexer_.PeekToken();
1784     if (token.kind != TokenType::BRACES_RIGHT) {
1785         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'"));
1786     } else {
1787         lexer_.GetToken();
1788     }
1789 
1790     token = lexer_.PeekToken();
1791     if (token.kind != TokenType::SEMICOLON) {
1792         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'"));
1793     } else {
1794         lexer_.GetToken();
1795     }
1796 
1797     structType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
1798     ast_->AddTypeDefinition(structType.Get());
1799 }
1800 
ParseStructParentType()1801 AutoPtr<ASTStructType> Parser::ParseStructParentType()
1802 {
1803     lexer_.GetToken();
1804     Token token = lexer_.PeekToken();
1805     AutoPtr<ASTType> baseType = ParseType();
1806     if (baseType == nullptr) {
1807         LogError(__func__, __LINE__, token, std::string("expected base type name before '{' token"));
1808         return nullptr;
1809     }
1810 
1811     if (baseType->GetTypeKind() != TypeKind::TYPE_STRUCT) {
1812         LogError(__func__, __LINE__, token, StringHelper::Format("illegal base type of struct: '%s'",
1813             baseType->ToString().c_str()));
1814         lexer_.SkipUntilToken(TokenType::BRACES_LEFT);
1815     }
1816 
1817     token = lexer_.PeekToken();
1818     if (token.kind != TokenType::BRACES_LEFT) {
1819         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'"));
1820     }
1821     lexer_.GetToken();
1822     return static_cast<ASTStructType *>(baseType.Get());
1823 }
1824 
ParseStructMember(const AutoPtr<ASTStructType> & structType)1825 void Parser::ParseStructMember(const AutoPtr<ASTStructType> &structType)
1826 {
1827     Token token = lexer_.PeekToken();
1828     while (token.kind != TokenType::BRACES_RIGHT && token.kind != TokenType::END_OF_FILE) {
1829         AutoPtr<ASTType> memberType = ParseType();
1830         if (memberType == nullptr) {
1831             lexer_.SkipToken(TokenType::SEMICOLON);
1832             token = lexer_.PeekToken();
1833             continue;
1834         }
1835 
1836         token = lexer_.PeekToken();
1837         if (token.kind != TokenType::ID) {
1838             LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected member name"));
1839             lexer_.SkipToken(TokenType::SEMICOLON);
1840             token = lexer_.PeekToken();
1841             continue;
1842         }
1843 
1844         lexer_.GetToken();
1845         std::string memberName = token.value;
1846         structType->AddMember(memberType, memberName);
1847 
1848         token = lexer_.PeekToken();
1849         if (token.kind == TokenType::SEMICOLON) {
1850             lexer_.GetToken();
1851             token = lexer_.PeekToken();
1852             continue;
1853         }
1854 
1855         if (token.kind != TokenType::BRACES_RIGHT) {
1856             LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or '}'"));
1857         }
1858     }
1859 }
1860 
ParseUnionDeclaration(const AttrSet & attrs)1861 void Parser::ParseUnionDeclaration(const AttrSet &attrs)
1862 {
1863     AutoPtr<ASTUnionType> unionType = new ASTUnionType;
1864     unionType->SetAttribute(ParseUserDefTypeAttr(attrs));
1865 
1866     lexer_.GetToken();
1867     Token token = lexer_.PeekToken();
1868     if (token.kind != TokenType::ID) {
1869         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected struct name"));
1870     } else {
1871         unionType->SetName(token.value);
1872         lexer_.GetToken();
1873     }
1874 
1875     token = lexer_.PeekToken();
1876     if (token.kind != TokenType::BRACES_LEFT) {
1877         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '{'"));
1878     } else {
1879         lexer_.GetToken();
1880     }
1881 
1882     ParseUnionMember(unionType);
1883 
1884     token = lexer_.PeekToken();
1885     if (token.kind != TokenType::BRACES_RIGHT) {
1886         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected '}'"));
1887     } else {
1888         lexer_.GetToken();
1889     }
1890 
1891     token = lexer_.PeekToken();
1892     if (token.kind != TokenType::SEMICOLON) {
1893         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ';'"));
1894     } else {
1895         lexer_.GetToken();
1896     }
1897 
1898     unionType->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
1899     ast_->AddTypeDefinition(unionType.Get());
1900 }
1901 
ParseUnionMember(const AutoPtr<ASTUnionType> & unionType)1902 void Parser::ParseUnionMember(const AutoPtr<ASTUnionType> &unionType)
1903 {
1904     Token token = lexer_.PeekToken();
1905     while (token.kind != TokenType::BRACES_RIGHT && token.kind != TokenType::END_OF_FILE) {
1906         AutoPtr<ASTType> memberType = ParseType();
1907         if (memberType == nullptr) {
1908             lexer_.SkipToken(TokenType::SEMICOLON);
1909             token = lexer_.PeekToken();
1910             continue;
1911         }
1912 
1913         token = lexer_.PeekToken();
1914         if (token.kind != TokenType::ID) {
1915             LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected member name"));
1916             lexer_.SkipToken(TokenType::SEMICOLON);
1917             token = lexer_.PeekToken();
1918             continue;
1919         }
1920         lexer_.GetToken();
1921 
1922         std::string memberName = token.value;
1923         if (!AddUnionMember(unionType, memberType, memberName)) {
1924             LogError(__func__, __LINE__, token, StringHelper::Format(
1925                 "union not support this type or name of member duplicate '%s'", token.value.c_str()));
1926         }
1927 
1928         token = lexer_.PeekToken();
1929         if (token.kind == TokenType::SEMICOLON) {
1930             lexer_.GetToken();
1931             token = lexer_.PeekToken();
1932             continue;
1933         }
1934 
1935         if (token.kind != TokenType::BRACES_RIGHT) {
1936             LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected ',' or '}'"));
1937         }
1938     }
1939 }
1940 
AddUnionMember(const AutoPtr<ASTUnionType> & unionType,const AutoPtr<ASTType> & type,const std::string & name) const1941 bool Parser::AddUnionMember(
1942     const AutoPtr<ASTUnionType> &unionType, const AutoPtr<ASTType> &type, const std::string &name) const
1943 {
1944     for (size_t i = 0; i < unionType->GetMemberNumber(); i++) {
1945         if (name == unionType->GetMemberName(i)) {
1946             return false;
1947         }
1948     }
1949 
1950     // Non pod type members are not allowed in the union
1951     if (!type->IsPod()) {
1952         return false;
1953     }
1954 
1955     unionType->AddMember(type, name);
1956     return true;
1957 }
1958 
ParseUserDefTypeAttr(const AttrSet & attrs)1959 AutoPtr<ASTAttr> Parser::ParseUserDefTypeAttr(const AttrSet &attrs)
1960 {
1961     AutoPtr<ASTAttr> attr = new ASTAttr();
1962     for (const auto &token : attrs) {
1963         switch (token.kind) {
1964             case TokenType::FULL:
1965                 attr->SetValue(ASTAttr::FULL);
1966                 break;
1967             case TokenType::LITE:
1968                 attr->SetValue(ASTAttr::LITE);
1969                 break;
1970             case TokenType::MINI:
1971                 attr->SetValue(ASTAttr::MINI);
1972                 break;
1973             default:
1974                 LogError(__func__, __LINE__, token, StringHelper::Format("invalid attribute '%s' for type decl",
1975                     token.value.c_str()));
1976                 break;
1977         }
1978     }
1979 
1980     if (attr->IsNone()) {
1981         attr->SetValue(ASTAttr::FULL | ASTAttr::LITE | ASTAttr::MINI);
1982     }
1983 
1984     return attr;
1985 }
1986 
ParseExpr()1987 AutoPtr<ASTExpr> Parser::ParseExpr()
1988 {
1989     lexer_.SetParseMode(Lexer::ParseMode::EXPR_MODE);
1990     AutoPtr<ASTExpr> value = ParseAndExpr();
1991     lexer_.SetParseMode(Lexer::ParseMode::DECL_MODE);
1992     return value;
1993 }
1994 
ParseAndExpr()1995 AutoPtr<ASTExpr> Parser::ParseAndExpr()
1996 {
1997     AutoPtr<ASTExpr> left = ParseXorExpr();
1998     Token token = lexer_.PeekToken();
1999     while (token.kind == TokenType::AND) {
2000         lexer_.GetToken();
2001         AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
2002         expr->op_ = BinaryOpKind::AND;
2003         expr->lExpr_ = left;
2004         expr->rExpr_ = ParseXorExpr();
2005 
2006         left = expr.Get();
2007         token = lexer_.PeekToken();
2008     }
2009     return left;
2010 }
2011 
ParseXorExpr()2012 AutoPtr<ASTExpr> Parser::ParseXorExpr()
2013 {
2014     AutoPtr<ASTExpr> left = ParseOrExpr();
2015     Token token = lexer_.PeekToken();
2016     while (token.kind == TokenType::XOR) {
2017         lexer_.GetToken();
2018         AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
2019         expr->op_ = BinaryOpKind::XOR;
2020         expr->lExpr_ = left;
2021         expr->rExpr_ = ParseOrExpr();
2022 
2023         left = expr.Get();
2024         token = lexer_.PeekToken();
2025     }
2026     return left;
2027 }
2028 
ParseOrExpr()2029 AutoPtr<ASTExpr> Parser::ParseOrExpr()
2030 {
2031     AutoPtr<ASTExpr> left = ParseShiftExpr();
2032     Token token = lexer_.PeekToken();
2033     while (token.kind == TokenType::OR) {
2034         lexer_.GetToken();
2035         AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
2036         expr->op_ = BinaryOpKind::OR;
2037         expr->lExpr_ = left;
2038         expr->rExpr_ = ParseShiftExpr();
2039 
2040         left = expr.Get();
2041         token = lexer_.PeekToken();
2042     }
2043     return left;
2044 }
2045 
ParseShiftExpr()2046 AutoPtr<ASTExpr> Parser::ParseShiftExpr()
2047 {
2048     AutoPtr<ASTExpr> left = ParseAddExpr();
2049     Token token = lexer_.PeekToken();
2050     while (token.kind == TokenType::LEFT_SHIFT || token.kind == TokenType::RIGHT_SHIFT) {
2051         lexer_.GetToken();
2052         BinaryOpKind op = (token.kind == TokenType::LEFT_SHIFT) ? BinaryOpKind::LSHIFT : BinaryOpKind::RSHIFT;
2053         AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
2054         expr->op_ = op;
2055         expr->lExpr_ = left;
2056         expr->rExpr_ = ParseAddExpr();
2057 
2058         left = expr.Get();
2059         token = lexer_.PeekToken();
2060     }
2061     return left;
2062 }
2063 
ParseAddExpr()2064 AutoPtr<ASTExpr> Parser::ParseAddExpr()
2065 {
2066     AutoPtr<ASTExpr> left = ParseMulExpr();
2067     Token token = lexer_.PeekToken();
2068     while (token.kind == TokenType::ADD || token.kind == TokenType::SUB) {
2069         lexer_.GetToken();
2070         BinaryOpKind op = (token.kind == TokenType::ADD) ? BinaryOpKind::ADD : BinaryOpKind::SUB;
2071         AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
2072         expr->op_ = op;
2073         expr->lExpr_ = left;
2074         expr->rExpr_ = ParseMulExpr();
2075 
2076         left = expr.Get();
2077         token = lexer_.PeekToken();
2078     }
2079     return left;
2080 }
2081 
ParseMulExpr()2082 AutoPtr<ASTExpr> Parser::ParseMulExpr()
2083 {
2084     AutoPtr<ASTExpr> left = ParseUnaryExpr();
2085     Token token = lexer_.PeekToken();
2086     while (
2087         token.kind == TokenType::STAR || token.kind == TokenType::SLASH || token.kind == TokenType::PERCENT_SIGN) {
2088         lexer_.GetToken();
2089         BinaryOpKind op = BinaryOpKind::MUL;
2090         if (token.kind == TokenType::SLASH) {
2091             op = BinaryOpKind::DIV;
2092         } else if (token.kind == TokenType::PERCENT_SIGN) {
2093             op = BinaryOpKind::MOD;
2094         }
2095         AutoPtr<ASTBinaryExpr> expr = new ASTBinaryExpr;
2096         expr->op_ = op;
2097         expr->lExpr_ = left;
2098         expr->rExpr_ = ParseUnaryExpr();
2099 
2100         left = expr.Get();
2101         token = lexer_.PeekToken();
2102     }
2103     return left;
2104 }
2105 
ParseUnaryExpr()2106 AutoPtr<ASTExpr> Parser::ParseUnaryExpr()
2107 {
2108     Token token = lexer_.PeekToken();
2109     switch (token.kind) {
2110         case TokenType::ADD:
2111         case TokenType::SUB:
2112         case TokenType::TILDE: {
2113             lexer_.GetToken();
2114             AutoPtr<ASTUnaryExpr> expr = new ASTUnaryExpr;
2115             expr->op_ = UnaryOpKind::PLUS;
2116             if (token.kind == TokenType::SUB) {
2117                 expr->op_ = UnaryOpKind::MINUS;
2118             } else if (token.kind == TokenType::TILDE) {
2119                 expr->op_ = UnaryOpKind::TILDE;
2120             }
2121 
2122             expr->expr_ = ParseUnaryExpr();
2123             return expr.Get();
2124         }
2125         default:
2126             return ParsePrimaryExpr();
2127     }
2128 }
2129 
ParsePrimaryExpr()2130 AutoPtr<ASTExpr> Parser::ParsePrimaryExpr()
2131 {
2132     Token token = lexer_.PeekToken();
2133     switch (token.kind) {
2134         case TokenType::PARENTHESES_LEFT: {
2135             lexer_.GetToken();
2136             AutoPtr<ASTExpr> expr = ParseExpr();
2137             token = lexer_.PeekToken();
2138             if (token.kind != TokenType::PARENTHESES_RIGHT) {
2139                 LogErrorBeforeToken(__func__, __LINE__, token, StringHelper::Format("expected ')'"));
2140             } else {
2141                 lexer_.GetToken();
2142                 expr->isParenExpr = true;
2143             }
2144             return expr;
2145         }
2146         case TokenType::NUM:
2147             return ParseNumExpr();
2148         case TokenType::ID:
2149             if (currentEnum_ == nullptr) {
2150                 LogError(__func__, __LINE__, token, std::string("this expression is not supported"));
2151                 lexer_.SkipUntilToken(TokenType::COMMA);
2152                 return nullptr;
2153             }
2154             return ParseEnumExpr();
2155         default:
2156             LogError(__func__, __LINE__, token, std::string("this expression is not supported"));
2157             lexer_.SkipUntilToken(TokenType::COMMA);
2158             return nullptr;
2159     }
2160 }
2161 
ParseNumExpr()2162 AutoPtr<ASTExpr> Parser::ParseNumExpr()
2163 {
2164     Token token = lexer_.GetToken();
2165     if (!CheckNumber(token.value)) {
2166         LogError(__func__, __LINE__, token, StringHelper::Format("unknown integer number: '%s'", token.value.c_str()));
2167         return nullptr;
2168     }
2169 
2170     AutoPtr<ASTNumExpr> expr = new ASTNumExpr;
2171     expr->value_ = token.value;
2172     return expr.Get();
2173 }
2174 
ParseEnumExpr()2175 AutoPtr<ASTExpr> Parser::ParseEnumExpr()
2176 {
2177     Token token = lexer_.GetToken();
2178     if (!currentEnum_->HasMember(token.value)) {
2179         LogError(__func__, __LINE__, token, StringHelper::Format("unknown enum member: '%s'", token.value.c_str()));
2180         return nullptr;
2181     }
2182 
2183     AutoPtr<ASTEnumExpr> expr = new ASTEnumExpr;
2184     expr->value_ = token.value;
2185     return expr.Get();
2186 }
2187 
CheckNumber(const std::string & integerVal) const2188 bool Parser::CheckNumber(const std::string& integerVal) const
2189 {
2190     try {
2191         return std::regex_match(integerVal, RE_BIN_NUM) || std::regex_match(integerVal, RE_OCT_NUM) ||
2192                std::regex_match(integerVal, RE_DEC_NUM) || std::regex_match(integerVal, RE_HEX_NUM);
2193     } catch (...) {
2194         return false;
2195     }
2196 }
2197 
CheckType(const Token & token,const AutoPtr<ASTType> & type)2198 bool Parser::CheckType(const Token &token, const AutoPtr<ASTType> &type)
2199 {
2200     if ((type == nullptr) || !CheckTypeByMode(token, type)) {
2201         return false;
2202     }
2203 
2204     if (Options::GetInstance().GetLanguage() == Language::C) {
2205         if (type->IsSequenceableType() || type->IsSmqType() || type->IsAshmemType() || type->IsRawDataType()) {
2206             LogError(__func__, __LINE__, token, StringHelper::Format("The %s type is not supported by c language.",
2207                 type->ToString().c_str()));
2208             return false;
2209         }
2210     } else if (Options::GetInstance().GetLanguage() == Language::JAVA) {
2211         switch (type->GetTypeKind()) {
2212             case TypeKind::TYPE_UCHAR:
2213             case TypeKind::TYPE_USHORT:
2214             case TypeKind::TYPE_UINT:
2215             case TypeKind::TYPE_ULONG:
2216             case TypeKind::TYPE_ENUM:
2217             case TypeKind::TYPE_STRUCT:
2218             case TypeKind::TYPE_UNION:
2219             case TypeKind::TYPE_SMQ:
2220             case TypeKind::TYPE_UNKNOWN:
2221                 LogError(__func__, __LINE__, token, StringHelper::Format("The '%s' type is not supported "
2222                     "by java language.", type->ToString().c_str()));
2223                 return false;
2224             default:
2225                 break;
2226         }
2227     }
2228 
2229     return true;
2230 }
2231 
CheckTypeByMode(const Token & token,const AutoPtr<ASTType> & type)2232 bool Parser::CheckTypeByMode(const Token &token, const AutoPtr<ASTType> &type)
2233 {
2234     if (!Options::GetInstance().DoPassthrough() && type->IsPointerType()) {
2235         LogError(__func__, __LINE__, token, StringHelper::Format("The %s type is only supported by passthrough mode.",
2236             type->ToString().c_str()));
2237         return false;
2238     }
2239 
2240     if (Options::GetInstance().DoGenerateKernelCode()) {
2241         switch (type->GetTypeKind()) {
2242             case TypeKind::TYPE_FLOAT:
2243             case TypeKind::TYPE_DOUBLE:
2244             case TypeKind::TYPE_FILEDESCRIPTOR:
2245             case TypeKind::TYPE_INTERFACE:
2246             case TypeKind::TYPE_SMQ:
2247             case TypeKind::TYPE_ASHMEM:
2248             case TypeKind::TYPE_NATIVE_BUFFER:
2249             case TypeKind::TYPE_POINTER:
2250                 LogError(__func__, __LINE__, token,
2251                     StringHelper::Format("The '%s' type is not supported by kernel mode.", type->ToString().c_str()));
2252                 return false;
2253             default:
2254                 break;
2255         }
2256     }
2257     return true;
2258 }
2259 
SetAstFileType()2260 void Parser::SetAstFileType()
2261 {
2262     if (ast_->GetInterfaceDef() != nullptr) {
2263         if (ast_->GetInterfaceDef()->IsCallback()) {
2264             ast_->SetAStFileType(ASTFileType::AST_ICALLBACK);
2265         } else {
2266             ast_->SetAStFileType(ASTFileType::AST_IFACE);
2267         }
2268     } else {
2269         ast_->SetAStFileType(ASTFileType::AST_TYPES);
2270     }
2271 }
2272 
2273 /*
2274  * filePath: ./ohos/interface/foo/v1_0/IFoo.idl
2275  * package OHOS.Hdi.foo.v1_0;
2276  */
CheckPackageName(const std::string & filePath,const std::string & packageName) const2277 bool Parser::CheckPackageName(const std::string &filePath, const std::string &packageName) const
2278 {
2279     std::string pkgToPath = Options::GetInstance().GetPackagePath(packageName);
2280 
2281     size_t index = filePath.rfind(SEPARATOR);
2282     if (index == std::string::npos) {
2283         return false;
2284     }
2285 
2286     std::string parentDir = filePath.substr(0, index);
2287     return parentDir == pkgToPath;
2288 }
2289 
CheckImport(const Token & token)2290 bool Parser::CheckImport(const Token &token)
2291 {
2292     std::string importName = token.value;
2293     try {
2294         if (Options::GetInstance().GetInterfaceType() == InterfaceType::HDI) {
2295             if (!std::regex_match(importName.c_str(), RE_IMPORT)) {
2296                 LogError(__func__, __LINE__, StringHelper::Format("invalid import name '%s'", importName.c_str()));
2297                 return false;
2298             }
2299         } else if (Options::GetInstance().GetInterfaceType() == InterfaceType::SA) {
2300             if (!std::regex_match(importName.c_str(), RE_PACKAGE_OR_IMPORT_SA)) {
2301                 LogError(__func__, __LINE__, StringHelper::Format("invalid import name '%s'", importName.c_str()));
2302                 return false;
2303             }
2304         } else {
2305             if (!std::regex_match(importName.c_str(), RE_PACKAGE_OR_IMPORT_SM)) {
2306                 LogError(__func__, __LINE__, StringHelper::Format("invalid import name '%s'", importName.c_str()));
2307                 return false;
2308             }
2309         }
2310     } catch (...) {
2311         LogError(__func__, __LINE__, StringHelper::Format(
2312             "Unknown error when matching import name '%s'", importName.c_str()));
2313         return false;
2314     }
2315 
2316     std::string idlFilePath = File::CanonicalPath(
2317         Options::GetInstance().GetImportFilePath(importName, token.location.filePath));
2318     if (!File::CheckValid(idlFilePath)) {
2319         LogError(__func__, __LINE__, StringHelper::Format("can not import '%s'", idlFilePath.c_str()));
2320         return false;
2321     }
2322     return true;
2323 }
2324 
AddAst(const AutoPtr<AST> & ast)2325 bool Parser::AddAst(const AutoPtr<AST> &ast)
2326 {
2327     if (ast == nullptr) {
2328         LogError(__func__, __LINE__, std::string("ast is nullptr."));
2329         return false;
2330     }
2331 
2332     allAsts_[ast->GetFullName()] = ast;
2333     return true;
2334 }
2335 
ParseInterfaceExtends(AutoPtr<ASTInterfaceType> & interface)2336 void Parser::ParseInterfaceExtends(AutoPtr<ASTInterfaceType> &interface)
2337 {
2338     Token token = lexer_.PeekToken();
2339     if (token.kind != TokenType::EXTENDS) {
2340         return;
2341     }
2342     lexer_.GetToken();
2343     token = lexer_.PeekToken();
2344     if (token.kind != TokenType::ID) {
2345         LogErrorBeforeToken(__func__, __LINE__, token, std::string("expected  extends interface name"));
2346         lexer_.SkipToken(TokenType::BRACES_LEFT);
2347         return;
2348     }
2349     ParseExtendsInfo(interface);
2350     lexer_.GetToken();
2351 }
2352 
ParseExtendsInfo(AutoPtr<ASTInterfaceType> & interfaceType)2353 void Parser::ParseExtendsInfo(AutoPtr<ASTInterfaceType> &interfaceType)
2354 {
2355     Token token = lexer_.PeekToken();
2356     std::string extendsInterfaceName = token.value;
2357     if (extendsInterfaceName.empty()) {
2358         LogError(__func__, __LINE__, token, std::string("extends interface name is empty"));
2359         return;
2360     }
2361     if (Options::GetInstance().GetInterfaceType() == InterfaceType::SA) {
2362         AutoPtr<ASTInterfaceType> extendsInterface = new ASTInterfaceType;
2363         extendsInterface->SetName(extendsInterfaceName);
2364         interfaceType->AddExtendsInterface(extendsInterface);
2365         return;
2366     }
2367     if (!CheckImport(token)) {
2368         LogError(__func__, __LINE__, token, std::string("extends interface name is illegal"));
2369         return;
2370     }
2371     auto iter = allAsts_.find(extendsInterfaceName);
2372     AutoPtr<AST> extendsAst = (iter != allAsts_.end()) ? iter->second : nullptr;
2373     if (extendsAst == nullptr) {
2374         LogError(__func__, __LINE__, token, StringHelper::Format("can not find idl file by extends interface "
2375             "name '%s', please check import info", extendsInterfaceName.c_str()));
2376         return;
2377     }
2378     if (!CheckExtendsName(interfaceType, extendsInterfaceName)) {
2379         LogError(__func__, __LINE__, token, StringHelper::Format(
2380             "extends interface name must same as current interface name '%s'", interfaceType->GetName().c_str()));
2381         return;
2382     }
2383     if (!CheckExtendsVersion(extendsAst)) {
2384         LogError(__func__, __LINE__, token,
2385             std::string("extends interface version must less than current interface version"));
2386         return;
2387     }
2388     if (!interfaceType->AddExtendsInterface(extendsAst->GetInterfaceDef())) {
2389         LogError(__func__, __LINE__, token, StringHelper::Format("multiple extends of '%s'",
2390             interfaceType->GetName().c_str()));
2391     }
2392 }
2393 
CheckExtendsName(AutoPtr<ASTInterfaceType> & interfaceType,const std::string & extendsInterfaceName)2394 bool Parser::CheckExtendsName(AutoPtr<ASTInterfaceType> &interfaceType, const std::string &extendsInterfaceName)
2395 {
2396     return extendsInterfaceName.substr(extendsInterfaceName.rfind('.') + 1) == interfaceType->GetName();
2397 }
2398 
CheckExtendsVersion(AutoPtr<AST> extendsAst)2399 bool Parser::CheckExtendsVersion(AutoPtr<AST> extendsAst)
2400 {
2401     return !(extendsAst->GetMajorVer() != ast_->GetMajorVer() || extendsAst->GetMinorVer() >= ast_->GetMinorVer());
2402 }
2403 
CheckImportsVersion(AutoPtr<AST> extendsAst)2404 bool Parser::CheckImportsVersion(AutoPtr<AST> extendsAst)
2405 {
2406     return !(extendsAst->GetMajorVer() != ast_->GetMajorVer() || extendsAst->GetMinorVer() > ast_->GetMinorVer());
2407 }
2408 
PostProcess()2409 bool Parser::PostProcess()
2410 {
2411     if ((Options::GetInstance().GetLanguage() != Language::C) || !CheckExistExtends()) {
2412         return true;
2413     }
2414     std::vector<size_t> genVersion = {0, 0};
2415     std::string genPackageName;
2416     AutoPtr<ASTNamespace> ns;
2417     if (!GetGenVersion(genVersion, genPackageName)) {
2418         return false;
2419     }
2420     GetGenNamespace(ns);
2421     AstMergeMap mergeMap;
2422     SortAstByName(mergeMap, allAsts_);
2423     allAsts_.clear();
2424     MergeAsts(mergeMap);
2425     ModifyImport(allAsts_, genPackageName);
2426     ModifyPackageNameAndVersion(allAsts_, genPackageName, genVersion);
2427     ModifyInterfaceNamespace(ns);
2428 
2429     return true;
2430 }
2431 
CheckExistExtends()2432 bool Parser::CheckExistExtends()
2433 {
2434     return std::any_of(allAsts_.begin(), allAsts_.end(), [](const std::pair<std::string, AutoPtr<AST>> &astPair) {
2435         return astPair.second->GetInterfaceDef() != nullptr &&
2436             astPair.second->GetInterfaceDef()->GetExtendsInterface() != nullptr;
2437     });
2438 }
2439 
GetGenVersion(std::vector<size_t> & version,std::string & genPackageName)2440 bool Parser::GetGenVersion(std::vector<size_t> &version, std::string &genPackageName)
2441 {
2442     std::set<std::string> sourceFile = Options::GetInstance().GetSourceFiles();
2443     for (const auto &ast : allAsts_) {
2444         if (sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) {
2445             if (genPackageName.empty()) {
2446                 genPackageName = ast.second->GetPackageName();
2447                 version[0] = ast.second->GetMajorVer();
2448                 version[1] = ast.second->GetMinorVer();
2449                 continue;
2450             }
2451             if (genPackageName != ast.second->GetPackageName() || version[0] != ast.second->GetMajorVer() ||
2452                 version[1] != ast.second->GetMinorVer()) {
2453                 LogError(__func__, __LINE__,
2454                     StringHelper::Format("merge ast failed, source files must have same package and version"));
2455                 return false;
2456             }
2457         }
2458     }
2459     return true;
2460 }
2461 
GetGenNamespace(AutoPtr<ASTNamespace> & ns)2462 void Parser::GetGenNamespace(AutoPtr<ASTNamespace> &ns)
2463 {
2464     std::set<std::string> sourceFile = Options::GetInstance().GetSourceFiles();
2465     for (const auto &ast : allAsts_) {
2466         if ((sourceFile.find(ast.second->GetIdlFilePath()) != sourceFile.end()) &&
2467             (ast.second->GetInterfaceDef() != nullptr)) {
2468             ns = ast.second->GetInterfaceDef()->GetNamespace();
2469             return;
2470         }
2471     }
2472 }
2473 
SortAstByName(AstMergeMap & mergeMap,StrAstMap & allAsts)2474 void Parser::SortAstByName(AstMergeMap &mergeMap, StrAstMap &allAsts)
2475 {
2476     for (const auto &astPair : allAsts) {
2477         AutoPtr<AST> ast = astPair.second;
2478         mergeMap[ast->GetName()].emplace(ast);
2479     }
2480 }
2481 
MergeAsts(AstMergeMap & mergeMap)2482 void Parser::MergeAsts(AstMergeMap &mergeMap)
2483 {
2484     for (const auto &setPair : mergeMap) {
2485         AutoPtr<AST> targetAst = nullptr;
2486         for (const auto &ast : setPair.second) {
2487             MergeAst(targetAst, ast);
2488         }
2489         AddAst(targetAst);
2490     }
2491 }
2492 
MergeAst(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2493 void Parser::MergeAst(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2494 {
2495     if (targetAst == nullptr) {
2496         targetAst = sourceAst;
2497         return;
2498     }
2499     MergeImport(targetAst, sourceAst);
2500     MergeInterfaceDef(targetAst, sourceAst);
2501     MergeTypeDefinitions(targetAst, sourceAst);
2502     MergeTypes(targetAst, sourceAst);
2503     MergeSequenceableDef(targetAst, sourceAst);
2504     MergeRawDataDef(targetAst, sourceAst);
2505 }
2506 
MergeImport(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2507 void Parser::MergeImport(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2508 {
2509     for (const auto &importPair : sourceAst->GetImports()) {
2510         AutoPtr<AST> importAst = importPair.second;
2511         targetAst->AddImport(importAst);
2512     }
2513 }
2514 
MergeInterfaceDef(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2515 void Parser::MergeInterfaceDef(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2516 {
2517     AutoPtr<ASTInterfaceType> sourceInterface = sourceAst->GetInterfaceDef();
2518     if (sourceInterface == nullptr) {
2519         return;
2520     }
2521     AutoPtr<ASTInterfaceType> targetInterface = targetAst->GetInterfaceDef();
2522     if (targetInterface == nullptr) {
2523         targetInterface = sourceInterface;
2524         return;
2525     }
2526 
2527     for (size_t i = 0; i < sourceInterface->GetMethodNumber(); i++) {
2528         targetInterface->AddMethod(sourceInterface->GetMethod(i));
2529     }
2530     targetInterface->SetSerializable(sourceInterface->IsSerializable());
2531 }
2532 
MergeTypeDefinitions(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2533 void Parser::MergeTypeDefinitions(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2534 {
2535     for (size_t i = 0; i < sourceAst->GetTypeDefinitionNumber(); i++) {
2536         targetAst->AddTypeDefinition(sourceAst->GetTypeDefintion(i));
2537     }
2538 }
2539 
MergeSequenceableDef(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2540 void Parser::MergeSequenceableDef(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2541 {
2542     if (sourceAst->GetSequenceableDef() != nullptr) {
2543         targetAst->AddSequenceableDef(sourceAst->GetSequenceableDef());
2544     }
2545 }
2546 
MergeRawDataDef(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2547 void Parser::MergeRawDataDef(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2548 {
2549     if (sourceAst->GetRawDataDef() != nullptr) {
2550         targetAst->AddRawDataDef(sourceAst->GetRawDataDef());
2551     }
2552 }
2553 
MergeTypes(AutoPtr<AST> & targetAst,AutoPtr<AST> sourceAst)2554 void Parser::MergeTypes(AutoPtr<AST> &targetAst, AutoPtr<AST> sourceAst)
2555 {
2556     for (const auto &typePair : sourceAst->GetTypes()) {
2557         targetAst->AddType(typePair.second);
2558     }
2559 }
2560 
ModifyImport(StrAstMap & allAsts,std::string & genPackageName)2561 void Parser::ModifyImport(StrAstMap &allAsts, std::string &genPackageName)
2562 {
2563     for (const auto &astPair : allAsts) {
2564         StrAstMap modifiedImport;
2565         StrAstMap import = astPair.second->GetImports();
2566         for (const auto &importPair : import) {
2567             if (importPair.second->GetName() == astPair.second->GetName()) {
2568                 continue;
2569             }
2570             modifiedImport[importPair.second->GetName()] = importPair.second;
2571         }
2572         astPair.second->ClearImport();
2573         for (const auto &importPair : modifiedImport) {
2574             importPair.second->SetPackageName(genPackageName);
2575             astPair.second->AddImport(importPair.second);
2576         }
2577     }
2578 }
2579 
ModifyPackageNameAndVersion(StrAstMap & allAsts,std::string & genPackageName,std::vector<size_t> genVersion)2580 void Parser::ModifyPackageNameAndVersion(
2581     StrAstMap &allAsts, std::string &genPackageName, std::vector<size_t> genVersion)
2582 {
2583     for (const auto &astPair : allAsts) {
2584         astPair.second->SetPackageName(genPackageName);
2585         astPair.second->SetVersion(genVersion[0], genVersion[1]);
2586     }
2587 }
2588 
ModifyInterfaceNamespace(AutoPtr<ASTNamespace> & ns)2589 void Parser::ModifyInterfaceNamespace(AutoPtr<ASTNamespace> &ns)
2590 {
2591     for (const auto &astPair : allAsts_) {
2592         AutoPtr<ASTInterfaceType> interface = astPair.second->GetInterfaceDef();
2593         if (interface != nullptr) {
2594             interface->SetNamespace(ns);
2595         }
2596     }
2597 }
2598 } // namespace Idl
2599 } // namespace OHOS
2600