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