1ca0551cfSopenharmony_ci/*
2ca0551cfSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
3ca0551cfSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4ca0551cfSopenharmony_ci * you may not use this file except in compliance with the License.
5ca0551cfSopenharmony_ci * You may obtain a copy of the License at
6ca0551cfSopenharmony_ci *
7ca0551cfSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8ca0551cfSopenharmony_ci *
9ca0551cfSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10ca0551cfSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11ca0551cfSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12ca0551cfSopenharmony_ci * See the License for the specific language governing permissions and
13ca0551cfSopenharmony_ci * limitations under the License.
14ca0551cfSopenharmony_ci */
15ca0551cfSopenharmony_ci
16ca0551cfSopenharmony_ci#include "parser/parser.h"
17ca0551cfSopenharmony_ci#include <cstdio>
18ca0551cfSopenharmony_ci#include "ast/ast_array_type.h"
19ca0551cfSopenharmony_ci#include "ast/ast_list_type.h"
20ca0551cfSopenharmony_ci#include "ast/ast_map_type.h"
21ca0551cfSopenharmony_ci#include "ast/ast_parameter.h"
22ca0551cfSopenharmony_ci#include "ast/ast_sequenceable_type.h"
23ca0551cfSopenharmony_ci#include "util/logger.h"
24ca0551cfSopenharmony_ci#include "util/string_builder.h"
25ca0551cfSopenharmony_ci
26ca0551cfSopenharmony_cinamespace OHOS {
27ca0551cfSopenharmony_cinamespace Idl {
28ca0551cfSopenharmony_ciconst char* Parser::tag = "Parser";
29ca0551cfSopenharmony_ci
30ca0551cfSopenharmony_ciParser::Parser(const Options& options)
31ca0551cfSopenharmony_ci    : options_(options)
32ca0551cfSopenharmony_ci{}
33ca0551cfSopenharmony_ci
34ca0551cfSopenharmony_cibool Parser::Parse(const String& sourceFile)
35ca0551cfSopenharmony_ci{
36ca0551cfSopenharmony_ci    bool ret = lexer_.OpenSourceFile(sourceFile);
37ca0551cfSopenharmony_ci    if (!ret) {
38ca0551cfSopenharmony_ci        Logger::E(tag, "Fail to open file \"%s\".", sourceFile.string());
39ca0551cfSopenharmony_ci        return false;
40ca0551cfSopenharmony_ci    }
41ca0551cfSopenharmony_ci    ret = ParseFile();
42ca0551cfSopenharmony_ci    ret = CheckIntegrity() && ret;
43ca0551cfSopenharmony_ci    if (!ret) {
44ca0551cfSopenharmony_ci        ShowError();
45ca0551cfSopenharmony_ci        return false;
46ca0551cfSopenharmony_ci    }
47ca0551cfSopenharmony_ci    if (options_.DoDumpAST()) {
48ca0551cfSopenharmony_ci        String astStr = module_->Dump("");
49ca0551cfSopenharmony_ci        printf("%s\n", astStr.string());
50ca0551cfSopenharmony_ci    }
51ca0551cfSopenharmony_ci    return ret;
52ca0551cfSopenharmony_ci}
53ca0551cfSopenharmony_ci
54ca0551cfSopenharmony_cibool Parser::ParseFile()
55ca0551cfSopenharmony_ci{
56ca0551cfSopenharmony_ci    bool ret = true;
57ca0551cfSopenharmony_ci
58ca0551cfSopenharmony_ci    module_ = new ASTModule();
59ca0551cfSopenharmony_ci    module_->SetIdlFile(lexer_.GetSourceFile()->GetPath());
60ca0551cfSopenharmony_ci
61ca0551cfSopenharmony_ci    ParseLicense();
62ca0551cfSopenharmony_ci
63ca0551cfSopenharmony_ci    Token token;
64ca0551cfSopenharmony_ci    while ((token = lexer_.PeekToken()) != Token::END_OF_FILE) {
65ca0551cfSopenharmony_ci        switch (token) {
66ca0551cfSopenharmony_ci            case Token::BRACKETS_LEFT:
67ca0551cfSopenharmony_ci            case Token::INTERFACE:
68ca0551cfSopenharmony_ci                ret = ParseInterface() && ret;
69ca0551cfSopenharmony_ci                continue;
70ca0551cfSopenharmony_ci            case Token::SEQUENCEABLE:
71ca0551cfSopenharmony_ci                ret = ParseSequenceable() && ret;
72ca0551cfSopenharmony_ci                continue;
73ca0551cfSopenharmony_ci            case Token::COMMENT_LINE:
74ca0551cfSopenharmony_ci                lexer_.GetToken();
75ca0551cfSopenharmony_ci                continue;
76ca0551cfSopenharmony_ci            default:
77ca0551cfSopenharmony_ci                LogError(token, String::Format("%s is not expected.", lexer_.DumpToken().string()));
78ca0551cfSopenharmony_ci                lexer_.GetToken();
79ca0551cfSopenharmony_ci                ret = false;
80ca0551cfSopenharmony_ci                continue;
81ca0551cfSopenharmony_ci        }
82ca0551cfSopenharmony_ci    }
83ca0551cfSopenharmony_ci    lexer_.GetToken();
84ca0551cfSopenharmony_ci
85ca0551cfSopenharmony_ci    return ret;
86ca0551cfSopenharmony_ci}
87ca0551cfSopenharmony_ci
88ca0551cfSopenharmony_cibool Parser::ParseLicense()
89ca0551cfSopenharmony_ci{
90ca0551cfSopenharmony_ci    Token token = lexer_.PeekToken(false);
91ca0551cfSopenharmony_ci    if (token != Token::COMMENT_BLOCK) {
92ca0551cfSopenharmony_ci        return false;
93ca0551cfSopenharmony_ci    }
94ca0551cfSopenharmony_ci
95ca0551cfSopenharmony_ci    lexer_.GetToken(false);
96ca0551cfSopenharmony_ci
97ca0551cfSopenharmony_ci    module_->SetLicense(lexer_.GetComment());
98ca0551cfSopenharmony_ci
99ca0551cfSopenharmony_ci    return true;
100ca0551cfSopenharmony_ci}
101ca0551cfSopenharmony_ci
102ca0551cfSopenharmony_cibool Parser::ParseInterface()
103ca0551cfSopenharmony_ci{
104ca0551cfSopenharmony_ci    bool ret = true;
105ca0551cfSopenharmony_ci    bool hasProperties = false;
106ca0551cfSopenharmony_ci    bool oneway = false;
107ca0551cfSopenharmony_ci    Token token = lexer_.GetToken();
108ca0551cfSopenharmony_ci    if (token == Token::BRACKETS_LEFT) {
109ca0551cfSopenharmony_ci        token = lexer_.PeekToken();
110ca0551cfSopenharmony_ci        if (token != Token::ONEWAY) {
111ca0551cfSopenharmony_ci            LogError(Token::IDENTIFIER,
112ca0551cfSopenharmony_ci                String::Format("\"%s\" is an illegal interface property.", lexer_.DumpToken().string()));
113ca0551cfSopenharmony_ci            if (token != Token::BRACKETS_RIGHT) {
114ca0551cfSopenharmony_ci                lexer_.SkipCurrentLine(Lexer::TokenToChar(Token::BRACKETS_RIGHT));
115ca0551cfSopenharmony_ci            }
116ca0551cfSopenharmony_ci            ret = false;
117ca0551cfSopenharmony_ci        }
118ca0551cfSopenharmony_ci        lexer_.GetToken();
119ca0551cfSopenharmony_ci        oneway = true;
120ca0551cfSopenharmony_ci        hasProperties = true;
121ca0551cfSopenharmony_ci        token = lexer_.PeekToken();
122ca0551cfSopenharmony_ci        if (token != Token::BRACKETS_RIGHT) {
123ca0551cfSopenharmony_ci            LogError(Token::IDENTIFIER, String("\"]\" is expected."));
124ca0551cfSopenharmony_ci            while (token != Token::BRACKETS_RIGHT && token != Token::INTERFACE && token != Token::END_OF_FILE) {
125ca0551cfSopenharmony_ci                lexer_.GetToken();
126ca0551cfSopenharmony_ci                token = lexer_.PeekToken();
127ca0551cfSopenharmony_ci            }
128ca0551cfSopenharmony_ci            ret = false;
129ca0551cfSopenharmony_ci        } else {
130ca0551cfSopenharmony_ci            lexer_.GetToken();
131ca0551cfSopenharmony_ci        }
132ca0551cfSopenharmony_ci
133ca0551cfSopenharmony_ci        token = lexer_.PeekToken();
134ca0551cfSopenharmony_ci        if (token != Token::INTERFACE) {
135ca0551cfSopenharmony_ci            LogError(Token::IDENTIFIER, String("\"interface\" is expected."));
136ca0551cfSopenharmony_ci            ret = false;
137ca0551cfSopenharmony_ci        } else {
138ca0551cfSopenharmony_ci            lexer_.GetToken();
139ca0551cfSopenharmony_ci        }
140ca0551cfSopenharmony_ci    }
141ca0551cfSopenharmony_ci    String interfaceFullName;
142ca0551cfSopenharmony_ci    bool middleRes = ParseInterfaceMiddle(token, interfaceFullName);
143ca0551cfSopenharmony_ci    if (!middleRes) {
144ca0551cfSopenharmony_ci        return middleRes;
145ca0551cfSopenharmony_ci    }
146ca0551cfSopenharmony_ci    return ParseInterfaceEnd(token, interfaceFullName, hasProperties, oneway, ret);
147ca0551cfSopenharmony_ci}
148ca0551cfSopenharmony_ci
149ca0551cfSopenharmony_cibool Parser::ParseInterfaceMiddle(Token& token, String& interfaceFullName)
150ca0551cfSopenharmony_ci{
151ca0551cfSopenharmony_ci    token = lexer_.PeekToken();
152ca0551cfSopenharmony_ci    if (token != Token::IDENTIFIER) {
153ca0551cfSopenharmony_ci        LogError(token, String::Format("%s is not expected.", lexer_.DumpToken().string()));
154ca0551cfSopenharmony_ci        lexer_.SkipCurrentLine();
155ca0551cfSopenharmony_ci        return false;
156ca0551cfSopenharmony_ci    } else {
157ca0551cfSopenharmony_ci        lexer_.GetToken();
158ca0551cfSopenharmony_ci        interfaceFullName = lexer_.GetIdentifier();
159ca0551cfSopenharmony_ci        token = lexer_.PeekToken();
160ca0551cfSopenharmony_ci    }
161ca0551cfSopenharmony_ci    if (token != Token::SEMICOLON && token != Token::BRACES_LEFT) {
162ca0551cfSopenharmony_ci        LogError(token, String::Format("%s is not expected.", lexer_.DumpToken().string()));
163ca0551cfSopenharmony_ci        lexer_.SkipCurrentLine();
164ca0551cfSopenharmony_ci        return false;
165ca0551cfSopenharmony_ci    }
166ca0551cfSopenharmony_ci
167ca0551cfSopenharmony_ci    if (interfaceFullName.IsEmpty()) {
168ca0551cfSopenharmony_ci        LogError(Token::IDENTIFIER, String("Interface name is expected."));
169ca0551cfSopenharmony_ci        return false;
170ca0551cfSopenharmony_ci    } else if (!IsValidTypeName(interfaceFullName)) {
171ca0551cfSopenharmony_ci        LogError(Token::IDENTIFIER, String::Format("Interface name \"%s\" is illegal.", interfaceFullName.string()));
172ca0551cfSopenharmony_ci        return false;
173ca0551cfSopenharmony_ci    } else if (interfaceFullName.IndexOf(".") == -1) {
174ca0551cfSopenharmony_ci        if (!(options_.GetTargetLanguage().Equals("ts")) && !(options_.GetTargetLanguage().Equals("rust"))) {
175ca0551cfSopenharmony_ci            LogError(Token::IDENTIFIER, String::Format("Interface name \"%s\" does not have namespace.",
176ca0551cfSopenharmony_ci            interfaceFullName.string()));
177ca0551cfSopenharmony_ci            return false;
178ca0551cfSopenharmony_ci        }
179ca0551cfSopenharmony_ci    }
180ca0551cfSopenharmony_ci    return true;
181ca0551cfSopenharmony_ci}
182ca0551cfSopenharmony_ci
183ca0551cfSopenharmony_cibool Parser::ParseInterfaceEnd(Token& token, String& interfaceFullName, bool hasProperties, bool oneway, bool ret)
184ca0551cfSopenharmony_ci{
185ca0551cfSopenharmony_ci    AutoPtr<ASTInterfaceType> interface = new ASTInterfaceType();
186ca0551cfSopenharmony_ci    parsingInterface_ = interface;
187ca0551cfSopenharmony_ci    int index = interfaceFullName.LastIndexOf('.');
188ca0551cfSopenharmony_ci    if (index != -1) {
189ca0551cfSopenharmony_ci        interface->SetName(interfaceFullName.Substring(index + 1));
190ca0551cfSopenharmony_ci        interface->SetNamespace(module_->ParseNamespace(interfaceFullName.Substring(0, index + 1)));
191ca0551cfSopenharmony_ci    } else {
192ca0551cfSopenharmony_ci        interface->SetName(interfaceFullName);
193ca0551cfSopenharmony_ci        interface->SetNamespace(NameSpaceEmpty());
194ca0551cfSopenharmony_ci    }
195ca0551cfSopenharmony_ci    // read ';'
196ca0551cfSopenharmony_ci    lexer_.GetToken();
197ca0551cfSopenharmony_ci    if (token == Token::SEMICOLON) {
198ca0551cfSopenharmony_ci        if (hasProperties) {
199ca0551cfSopenharmony_ci            LogError(Token::IDENTIFIER, String("Interface forward declaration should not have properties."));
200ca0551cfSopenharmony_ci            return false;
201ca0551cfSopenharmony_ci        }
202ca0551cfSopenharmony_ci        interface->SetExternal(true);
203ca0551cfSopenharmony_ci        module_->AddInterface(interface);
204ca0551cfSopenharmony_ci        return true;
205ca0551cfSopenharmony_ci    } else {
206ca0551cfSopenharmony_ci        if (!interface->GetName().Equals(module_->GetName())) {
207ca0551cfSopenharmony_ci            LogError(Token::IDENTIFIER, String::Format("Module name \"%s\" is not equal to interface name  \"%s\".",
208ca0551cfSopenharmony_ci                module_->GetName().string(), interface->GetName().string()));
209ca0551cfSopenharmony_ci            return false;
210ca0551cfSopenharmony_ci        }
211ca0551cfSopenharmony_ci
212ca0551cfSopenharmony_ci        interface->SetLicense(module_->GetLicense());
213ca0551cfSopenharmony_ci        interface->SetOneway(oneway);
214ca0551cfSopenharmony_ci
215ca0551cfSopenharmony_ci        while (token != Token::BRACES_RIGHT && token != Token::END_OF_FILE) {
216ca0551cfSopenharmony_ci            ret = ParseMethod(interface) && ret;
217ca0551cfSopenharmony_ci            token = lexer_.PeekToken();
218ca0551cfSopenharmony_ci        }
219ca0551cfSopenharmony_ci
220ca0551cfSopenharmony_ci        if (token != Token::BRACES_RIGHT) {
221ca0551cfSopenharmony_ci            ret = false;
222ca0551cfSopenharmony_ci        } else {
223ca0551cfSopenharmony_ci            lexer_.GetToken();
224ca0551cfSopenharmony_ci            module_->AddInterface(interface);
225ca0551cfSopenharmony_ci        }
226ca0551cfSopenharmony_ci        return ret;
227ca0551cfSopenharmony_ci    }
228ca0551cfSopenharmony_ci    return true;
229ca0551cfSopenharmony_ci}
230ca0551cfSopenharmony_ci
231ca0551cfSopenharmony_cibool Parser::ParseMethodProperties(bool& oneway, bool& cacheable, int& cacheTime)
232ca0551cfSopenharmony_ci{
233ca0551cfSopenharmony_ci    Token token;
234ca0551cfSopenharmony_ci    bool isParseOneway = false;
235ca0551cfSopenharmony_ci
236ca0551cfSopenharmony_ci    oneway = false;
237ca0551cfSopenharmony_ci    cacheable = false;
238ca0551cfSopenharmony_ci    lexer_.GetToken();
239ca0551cfSopenharmony_ci    token = lexer_.PeekToken();
240ca0551cfSopenharmony_ci    while (token != Token::BRACKETS_RIGHT && token != Token::END_OF_FILE) {
241ca0551cfSopenharmony_ci        lexer_.GetToken();
242ca0551cfSopenharmony_ci        if (token != Token::ONEWAY && token != Token::CACHEABLE) {
243ca0551cfSopenharmony_ci            LogError(Token::IDENTIFIER, String::Format("\"%s\" is an illegal method property.",
244ca0551cfSopenharmony_ci                lexer_.DumpToken().string()));
245ca0551cfSopenharmony_ci            break;
246ca0551cfSopenharmony_ci        }
247ca0551cfSopenharmony_ci
248ca0551cfSopenharmony_ci        if (token == Token::ONEWAY && isParseOneway == false) {
249ca0551cfSopenharmony_ci            oneway = true;
250ca0551cfSopenharmony_ci            isParseOneway = true;
251ca0551cfSopenharmony_ci        } else if (token == Token::CACHEABLE && cacheable == false) {
252ca0551cfSopenharmony_ci            if (!lexer_.ParseCacheable(cacheTime)) {
253ca0551cfSopenharmony_ci                LogError(Token::CACHEABLE, "cacheable time format is incorrect.");
254ca0551cfSopenharmony_ci                return false;
255ca0551cfSopenharmony_ci            }
256ca0551cfSopenharmony_ci            cacheable = true;
257ca0551cfSopenharmony_ci        } else {
258ca0551cfSopenharmony_ci            return false;
259ca0551cfSopenharmony_ci        }
260ca0551cfSopenharmony_ci
261ca0551cfSopenharmony_ci        token = lexer_.PeekToken();
262ca0551cfSopenharmony_ci        if (token == Token::COMMA) {
263ca0551cfSopenharmony_ci            lexer_.GetToken();
264ca0551cfSopenharmony_ci            token = lexer_.PeekToken();
265ca0551cfSopenharmony_ci        }
266ca0551cfSopenharmony_ci    }
267ca0551cfSopenharmony_ci
268ca0551cfSopenharmony_ci    if (token != Token::BRACKETS_RIGHT) {
269ca0551cfSopenharmony_ci        LogError(Token::IDENTIFIER, String("\"]\" is expected."));
270ca0551cfSopenharmony_ci        return false;
271ca0551cfSopenharmony_ci    } else {
272ca0551cfSopenharmony_ci        lexer_.GetToken();
273ca0551cfSopenharmony_ci    }
274ca0551cfSopenharmony_ci    return true;
275ca0551cfSopenharmony_ci}
276ca0551cfSopenharmony_ci
277ca0551cfSopenharmony_civoid Parser::SetMethodAttr(ASTMethod* method, ASTType *returnType, bool oneway, bool cacheable, int cacheTime)
278ca0551cfSopenharmony_ci{
279ca0551cfSopenharmony_ci    method->SetName(lexer_.GetIdentifier());
280ca0551cfSopenharmony_ci    method->SetOneway(oneway);
281ca0551cfSopenharmony_ci    method->SetReturnType(returnType);
282ca0551cfSopenharmony_ci    if (cacheable == true) {
283ca0551cfSopenharmony_ci        method->SetCacheable(cacheTime);
284ca0551cfSopenharmony_ci        module_->SetHasCacheableProxyMethods(true);
285ca0551cfSopenharmony_ci    }
286ca0551cfSopenharmony_ci
287ca0551cfSopenharmony_ci    return;
288ca0551cfSopenharmony_ci}
289ca0551cfSopenharmony_ci
290ca0551cfSopenharmony_cibool Parser::ParseMethodName(Token& token, ASTType* type, ASTInterfaceType* interface)
291ca0551cfSopenharmony_ci{
292ca0551cfSopenharmony_ci    if (type == nullptr) {
293ca0551cfSopenharmony_ci        token = lexer_.PeekToken();
294ca0551cfSopenharmony_ci        if (token == Token::BRACES_RIGHT) {
295ca0551cfSopenharmony_ci            return false;
296ca0551cfSopenharmony_ci        }
297ca0551cfSopenharmony_ci        // jump over colon
298ca0551cfSopenharmony_ci        lexer_.GetToken();
299ca0551cfSopenharmony_ci        while (token != Token::SEMICOLON && token != Token::END_OF_FILE) {
300ca0551cfSopenharmony_ci            token = lexer_.PeekToken();
301ca0551cfSopenharmony_ci            if (token == Token::BRACES_RIGHT) {
302ca0551cfSopenharmony_ci                break;
303ca0551cfSopenharmony_ci            }
304ca0551cfSopenharmony_ci            lexer_.GetToken();
305ca0551cfSopenharmony_ci        }
306ca0551cfSopenharmony_ci        return false;
307ca0551cfSopenharmony_ci    }
308ca0551cfSopenharmony_ci    if (interface->IsOneway()) {
309ca0551cfSopenharmony_ci        if (!type->IsVoidType()) {
310ca0551cfSopenharmony_ci            LogError(token, String("void return type expected in oneway interface."));
311ca0551cfSopenharmony_ci            return false;
312ca0551cfSopenharmony_ci        }
313ca0551cfSopenharmony_ci    }
314ca0551cfSopenharmony_ci    token = lexer_.PeekToken();
315ca0551cfSopenharmony_ci    if (token != Token::IDENTIFIER) {
316ca0551cfSopenharmony_ci        LogError(token, String("Method name is expected."));
317ca0551cfSopenharmony_ci        if (token == Token::BRACES_RIGHT) {
318ca0551cfSopenharmony_ci            return false;
319ca0551cfSopenharmony_ci        }
320ca0551cfSopenharmony_ci        // jump over colon
321ca0551cfSopenharmony_ci        lexer_.GetToken();
322ca0551cfSopenharmony_ci        while (token != Token::SEMICOLON && token != Token::END_OF_FILE) {
323ca0551cfSopenharmony_ci            token = lexer_.PeekToken();
324ca0551cfSopenharmony_ci            if (token == Token::BRACES_RIGHT) {
325ca0551cfSopenharmony_ci                break;
326ca0551cfSopenharmony_ci            }
327ca0551cfSopenharmony_ci            lexer_.GetToken();
328ca0551cfSopenharmony_ci        }
329ca0551cfSopenharmony_ci        return false;
330ca0551cfSopenharmony_ci    }
331ca0551cfSopenharmony_ci    return true;
332ca0551cfSopenharmony_ci}
333ca0551cfSopenharmony_ci
334ca0551cfSopenharmony_cibool Parser::ParseMethodBrackets(Token& token, ASTMethod* method, bool& ret)
335ca0551cfSopenharmony_ci{
336ca0551cfSopenharmony_ci    if (method->IsOneway()) {
337ca0551cfSopenharmony_ci        if (!method->GetReturnType()->IsVoidType()) {
338ca0551cfSopenharmony_ci            LogError(token, String("void return type expected in oneway method."));
339ca0551cfSopenharmony_ci            return false;
340ca0551cfSopenharmony_ci        }
341ca0551cfSopenharmony_ci    }
342ca0551cfSopenharmony_ci    token = lexer_.PeekToken();
343ca0551cfSopenharmony_ci    if (token != Token::PARENTHESES_LEFT) {
344ca0551cfSopenharmony_ci        LogError(token, String("\"(\" is expected."));
345ca0551cfSopenharmony_ci        if (token == Token::BRACES_RIGHT) {
346ca0551cfSopenharmony_ci            return false;
347ca0551cfSopenharmony_ci        }
348ca0551cfSopenharmony_ci        // jump over colon
349ca0551cfSopenharmony_ci        lexer_.GetToken();
350ca0551cfSopenharmony_ci        while (token != Token::SEMICOLON && token != Token::END_OF_FILE) {
351ca0551cfSopenharmony_ci            token = lexer_.PeekToken();
352ca0551cfSopenharmony_ci            if (token == Token::BRACES_RIGHT) {
353ca0551cfSopenharmony_ci                break;
354ca0551cfSopenharmony_ci            }
355ca0551cfSopenharmony_ci            lexer_.GetToken();
356ca0551cfSopenharmony_ci        }
357ca0551cfSopenharmony_ci        return false;
358ca0551cfSopenharmony_ci    }
359ca0551cfSopenharmony_ci    token = lexer_.GetToken();
360ca0551cfSopenharmony_ci
361ca0551cfSopenharmony_ci    token = lexer_.PeekToken();
362ca0551cfSopenharmony_ci    while (token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) {
363ca0551cfSopenharmony_ci        ret = ParseParameter(method) && ret;
364ca0551cfSopenharmony_ci        token = lexer_.PeekToken();
365ca0551cfSopenharmony_ci        if (token == Token::COMMA) {
366ca0551cfSopenharmony_ci            lexer_.GetToken();
367ca0551cfSopenharmony_ci            token = lexer_.PeekToken();
368ca0551cfSopenharmony_ci        }
369ca0551cfSopenharmony_ci    }
370ca0551cfSopenharmony_ci    return true;
371ca0551cfSopenharmony_ci}
372ca0551cfSopenharmony_ci
373ca0551cfSopenharmony_cibool Parser::ParseMethod(ASTInterfaceType* interface)
374ca0551cfSopenharmony_ci{
375ca0551cfSopenharmony_ci    bool ret = true;
376ca0551cfSopenharmony_ci    bool oneway = false;
377ca0551cfSopenharmony_ci    bool cacheable = false;
378ca0551cfSopenharmony_ci    int cacheTime;
379ca0551cfSopenharmony_ci    Token token = lexer_.PeekToken();
380ca0551cfSopenharmony_ci    if ((token == Token::BRACKETS_LEFT) && (ParseMethodProperties(oneway, cacheable, cacheTime) == false)) {
381ca0551cfSopenharmony_ci        return false;
382ca0551cfSopenharmony_ci    }
383ca0551cfSopenharmony_ci
384ca0551cfSopenharmony_ci    AutoPtr<ASTType> type = ParseType();
385ca0551cfSopenharmony_ci    if (!ParseMethodName(token, type, interface)) {
386ca0551cfSopenharmony_ci        return false;
387ca0551cfSopenharmony_ci    }
388ca0551cfSopenharmony_ci
389ca0551cfSopenharmony_ci    token = lexer_.GetToken();
390ca0551cfSopenharmony_ci    AutoPtr<ASTMethod> method = new ASTMethod();
391ca0551cfSopenharmony_ci    if (method == nullptr) {
392ca0551cfSopenharmony_ci        LogError(token, String("method is nullptr."));
393ca0551cfSopenharmony_ci        return false;
394ca0551cfSopenharmony_ci    }
395ca0551cfSopenharmony_ci    SetMethodAttr(method, type, oneway, cacheable, cacheTime);
396ca0551cfSopenharmony_ci    if (!ParseMethodBrackets(token, method, ret)) {
397ca0551cfSopenharmony_ci        return false;
398ca0551cfSopenharmony_ci    }
399ca0551cfSopenharmony_ci
400ca0551cfSopenharmony_ci    if (interface->IsOneway() || method->IsOneway()) {
401ca0551cfSopenharmony_ci        for (size_t i = 0; i< method->GetParameterNumber(); i++) {
402ca0551cfSopenharmony_ci            auto parameter = method->GetParameter(i);
403ca0551cfSopenharmony_ci            if (parameter->IsOutParameter()) {
404ca0551cfSopenharmony_ci                LogError(token, String("out parameter type not expected in oneway method."));
405ca0551cfSopenharmony_ci                return false;
406ca0551cfSopenharmony_ci            }
407ca0551cfSopenharmony_ci        }
408ca0551cfSopenharmony_ci    }
409ca0551cfSopenharmony_ci    lexer_.GetToken();
410ca0551cfSopenharmony_ci    if (!ret) {
411ca0551cfSopenharmony_ci        lexer_.SkipCurrentLine();
412ca0551cfSopenharmony_ci        return false;
413ca0551cfSopenharmony_ci    }
414ca0551cfSopenharmony_ci
415ca0551cfSopenharmony_ci    token = lexer_.PeekToken();
416ca0551cfSopenharmony_ci    if (token != Token::SEMICOLON) {
417ca0551cfSopenharmony_ci        LogError(token, String("\";\" is expected."));
418ca0551cfSopenharmony_ci        if (token != Token::BRACES_RIGHT) {
419ca0551cfSopenharmony_ci            lexer_.SkipCurrentLine(Lexer::TokenToChar(Token::BRACES_RIGHT));
420ca0551cfSopenharmony_ci        }
421ca0551cfSopenharmony_ci        return false;
422ca0551cfSopenharmony_ci    }
423ca0551cfSopenharmony_ci    lexer_.GetToken();
424ca0551cfSopenharmony_ci
425ca0551cfSopenharmony_ci    interface->AddMethod(method);
426ca0551cfSopenharmony_ci
427ca0551cfSopenharmony_ci    return ret;
428ca0551cfSopenharmony_ci}
429ca0551cfSopenharmony_ci
430ca0551cfSopenharmony_cibool Parser::ParseParameterPeek(Token& token)
431ca0551cfSopenharmony_ci{
432ca0551cfSopenharmony_ci    if (token != Token::BRACKETS_LEFT) {
433ca0551cfSopenharmony_ci        LogError(token, String("\"[\" is expected."));
434ca0551cfSopenharmony_ci        // jump to ',' or ')'
435ca0551cfSopenharmony_ci        while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) {
436ca0551cfSopenharmony_ci            lexer_.GetToken();
437ca0551cfSopenharmony_ci            token = lexer_.PeekToken();
438ca0551cfSopenharmony_ci        }
439ca0551cfSopenharmony_ci        return false;
440ca0551cfSopenharmony_ci    }
441ca0551cfSopenharmony_ci    return true;
442ca0551cfSopenharmony_ci}
443ca0551cfSopenharmony_ci
444ca0551cfSopenharmony_cibool Parser::ParseParameterInOut(Token& token, ASTParameter* parameter)
445ca0551cfSopenharmony_ci{
446ca0551cfSopenharmony_ci    token = lexer_.PeekToken();
447ca0551cfSopenharmony_ci    while (token != Token::BRACKETS_RIGHT && token != Token::END_OF_FILE) {
448ca0551cfSopenharmony_ci        switch (token) {
449ca0551cfSopenharmony_ci            case Token::IN:
450ca0551cfSopenharmony_ci                lexer_.GetToken();
451ca0551cfSopenharmony_ci                parameter->SetInParameter(true);
452ca0551cfSopenharmony_ci                break;
453ca0551cfSopenharmony_ci            case Token::OUT:
454ca0551cfSopenharmony_ci                lexer_.GetToken();
455ca0551cfSopenharmony_ci                parameter->SetOutParameter(true);
456ca0551cfSopenharmony_ci                break;
457ca0551cfSopenharmony_ci            case Token::INOUT:
458ca0551cfSopenharmony_ci                lexer_.GetToken();
459ca0551cfSopenharmony_ci                parameter->SetInParameter(true);
460ca0551cfSopenharmony_ci                parameter->SetOutParameter(true);
461ca0551cfSopenharmony_ci                break;
462ca0551cfSopenharmony_ci            default:
463ca0551cfSopenharmony_ci                LogError(token, String("\"in\" or \"out\" or \"inout\" is expected."));
464ca0551cfSopenharmony_ci                break;
465ca0551cfSopenharmony_ci        }
466ca0551cfSopenharmony_ci        token = lexer_.PeekToken();
467ca0551cfSopenharmony_ci        if (token == Token::COMMA) {
468ca0551cfSopenharmony_ci            lexer_.GetToken();
469ca0551cfSopenharmony_ci            token = lexer_.PeekToken();
470ca0551cfSopenharmony_ci            continue;
471ca0551cfSopenharmony_ci        }
472ca0551cfSopenharmony_ci        if (token != Token::BRACKETS_RIGHT) {
473ca0551cfSopenharmony_ci            LogError(token, String("\",\" or \"]\" is expected."));
474ca0551cfSopenharmony_ci            // jump to ',' or ')'
475ca0551cfSopenharmony_ci            while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) {
476ca0551cfSopenharmony_ci                lexer_.GetToken();
477ca0551cfSopenharmony_ci                token = lexer_.PeekToken();
478ca0551cfSopenharmony_ci            }
479ca0551cfSopenharmony_ci            return false;
480ca0551cfSopenharmony_ci        }
481ca0551cfSopenharmony_ci    }
482ca0551cfSopenharmony_ci    return true;
483ca0551cfSopenharmony_ci}
484ca0551cfSopenharmony_ci
485ca0551cfSopenharmony_cibool Parser::ParseParameter(ASTMethod* method)
486ca0551cfSopenharmony_ci{
487ca0551cfSopenharmony_ci    Token token = lexer_.PeekToken();
488ca0551cfSopenharmony_ci    if (!ParseParameterPeek(token)) {
489ca0551cfSopenharmony_ci        return false;
490ca0551cfSopenharmony_ci    }
491ca0551cfSopenharmony_ci    lexer_.GetToken();
492ca0551cfSopenharmony_ci
493ca0551cfSopenharmony_ci    AutoPtr<ASTParameter> parameter = new ASTParameter();
494ca0551cfSopenharmony_ci    if (parameter == nullptr) {
495ca0551cfSopenharmony_ci        return false;
496ca0551cfSopenharmony_ci    }
497ca0551cfSopenharmony_ci
498ca0551cfSopenharmony_ci    if (!ParseParameterInOut(token, parameter)) {
499ca0551cfSopenharmony_ci        return false;
500ca0551cfSopenharmony_ci    }
501ca0551cfSopenharmony_ci
502ca0551cfSopenharmony_ci    // read ']'
503ca0551cfSopenharmony_ci    lexer_.GetToken();
504ca0551cfSopenharmony_ci
505ca0551cfSopenharmony_ci    AutoPtr<ASTType> type = ParseType();
506ca0551cfSopenharmony_ci    if (type == nullptr) {
507ca0551cfSopenharmony_ci        // jump to ',' or ')'
508ca0551cfSopenharmony_ci        while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) {
509ca0551cfSopenharmony_ci            lexer_.GetToken();
510ca0551cfSopenharmony_ci            token = lexer_.PeekToken();
511ca0551cfSopenharmony_ci        }
512ca0551cfSopenharmony_ci        return false;
513ca0551cfSopenharmony_ci    }
514ca0551cfSopenharmony_ci
515ca0551cfSopenharmony_ci    token = lexer_.PeekToken();
516ca0551cfSopenharmony_ci    if (token != Token::IDENTIFIER) {
517ca0551cfSopenharmony_ci        LogError(token, String("Parameter name is expected."));
518ca0551cfSopenharmony_ci        // jump to ',' or ')'
519ca0551cfSopenharmony_ci        while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) {
520ca0551cfSopenharmony_ci            lexer_.GetToken();
521ca0551cfSopenharmony_ci            token = lexer_.PeekToken();
522ca0551cfSopenharmony_ci        }
523ca0551cfSopenharmony_ci        return false;
524ca0551cfSopenharmony_ci    }
525ca0551cfSopenharmony_ci    lexer_.GetToken();
526ca0551cfSopenharmony_ci
527ca0551cfSopenharmony_ci    parameter->SetName(lexer_.GetIdentifier());
528ca0551cfSopenharmony_ci    parameter->SetType(type);
529ca0551cfSopenharmony_ci    method->AddParameter(parameter);
530ca0551cfSopenharmony_ci
531ca0551cfSopenharmony_ci    return true;
532ca0551cfSopenharmony_ci}
533ca0551cfSopenharmony_ci
534ca0551cfSopenharmony_ciAutoPtr<ASTType> Parser::ParseType()
535ca0551cfSopenharmony_ci{
536ca0551cfSopenharmony_ci    AutoPtr<ASTType> type;
537ca0551cfSopenharmony_ci
538ca0551cfSopenharmony_ci    Token token = lexer_.PeekToken();
539ca0551cfSopenharmony_ci    if (IsPrimitiveType(token)) {
540ca0551cfSopenharmony_ci        lexer_.GetToken();
541ca0551cfSopenharmony_ci        type = module_->FindType(lexer_.DumpToken());
542ca0551cfSopenharmony_ci    } else if (token == Token::LIST) {
543ca0551cfSopenharmony_ci        type = ParseList();
544ca0551cfSopenharmony_ci    } else if (token == Token::MAP) {
545ca0551cfSopenharmony_ci        type = ParseMap();
546ca0551cfSopenharmony_ci    } else if (token == Token::IDENTIFIER) {
547ca0551cfSopenharmony_ci        lexer_.GetToken();
548ca0551cfSopenharmony_ci        if (parsingInterface_ != nullptr &&
549ca0551cfSopenharmony_ci            parsingInterface_->GetName().Equals(lexer_.GetIdentifier())) {
550ca0551cfSopenharmony_ci            type = parsingInterface_.Get();
551ca0551cfSopenharmony_ci        } else {
552ca0551cfSopenharmony_ci            type = module_->FindType(lexer_.GetIdentifier());
553ca0551cfSopenharmony_ci        }
554ca0551cfSopenharmony_ci    } else {
555ca0551cfSopenharmony_ci        LogError(token, String("Type name is expected."));
556ca0551cfSopenharmony_ci        return nullptr;
557ca0551cfSopenharmony_ci    }
558ca0551cfSopenharmony_ci
559ca0551cfSopenharmony_ci    if (type == nullptr || type.Get() == nullptr) {
560ca0551cfSopenharmony_ci        LogError(token, String::Format("Type \"%s\" was not declared in the module.", lexer_.DumpToken().string()));
561ca0551cfSopenharmony_ci        return nullptr;
562ca0551cfSopenharmony_ci    }
563ca0551cfSopenharmony_ci
564ca0551cfSopenharmony_ci    token = lexer_.PeekToken();
565ca0551cfSopenharmony_ci    if (token == Token::BRACKETS_LEFT) {
566ca0551cfSopenharmony_ci        lexer_.GetToken();
567ca0551cfSopenharmony_ci        token = lexer_.PeekToken();
568ca0551cfSopenharmony_ci        if (token != Token::BRACKETS_RIGHT) {
569ca0551cfSopenharmony_ci            LogError(token, String("\"]\" is expected."));
570ca0551cfSopenharmony_ci            return nullptr;
571ca0551cfSopenharmony_ci        }
572ca0551cfSopenharmony_ci        lexer_.GetToken();
573ca0551cfSopenharmony_ci
574ca0551cfSopenharmony_ci        AutoPtr<ASTArrayType> arrayType = new ASTArrayType();
575ca0551cfSopenharmony_ci        if (arrayType == nullptr) {
576ca0551cfSopenharmony_ci            LogError(token, String("arrayType is nullptr."));
577ca0551cfSopenharmony_ci            return nullptr;
578ca0551cfSopenharmony_ci        }
579ca0551cfSopenharmony_ci        arrayType->SetElementType(type);
580ca0551cfSopenharmony_ci
581ca0551cfSopenharmony_ci        type = module_->FindType(arrayType->ToString());
582ca0551cfSopenharmony_ci        if (type == nullptr) {
583ca0551cfSopenharmony_ci            module_->AddType(arrayType);
584ca0551cfSopenharmony_ci            type = static_cast<ASTType*>(arrayType.Get());
585ca0551cfSopenharmony_ci        }
586ca0551cfSopenharmony_ci    }
587ca0551cfSopenharmony_ci
588ca0551cfSopenharmony_ci    return type;
589ca0551cfSopenharmony_ci}
590ca0551cfSopenharmony_ci
591ca0551cfSopenharmony_ciAutoPtr<ASTType> Parser::ParseList()
592ca0551cfSopenharmony_ci{
593ca0551cfSopenharmony_ci    lexer_.GetToken();
594ca0551cfSopenharmony_ci
595ca0551cfSopenharmony_ci    Token token = lexer_.PeekToken();
596ca0551cfSopenharmony_ci    if (token != Token::ANGLE_BRACKETS_LEFT) {
597ca0551cfSopenharmony_ci        LogError(token, String("\"<\" is expected."));
598ca0551cfSopenharmony_ci        return nullptr;
599ca0551cfSopenharmony_ci    }
600ca0551cfSopenharmony_ci    lexer_.GetToken();
601ca0551cfSopenharmony_ci
602ca0551cfSopenharmony_ci    AutoPtr<ASTType> type = ParseType();
603ca0551cfSopenharmony_ci    if (type == nullptr) {
604ca0551cfSopenharmony_ci        lexer_.SkipCurrentLine('>');
605ca0551cfSopenharmony_ci        return nullptr;
606ca0551cfSopenharmony_ci    }
607ca0551cfSopenharmony_ci
608ca0551cfSopenharmony_ci    token = lexer_.PeekToken();
609ca0551cfSopenharmony_ci    if (token != Token::ANGLE_BRACKETS_RIGHT) {
610ca0551cfSopenharmony_ci        LogError(token, String("\">\" is expected."));
611ca0551cfSopenharmony_ci        return nullptr;
612ca0551cfSopenharmony_ci    }
613ca0551cfSopenharmony_ci    lexer_.GetToken();
614ca0551cfSopenharmony_ci
615ca0551cfSopenharmony_ci    AutoPtr<ASTListType> list = new ASTListType();
616ca0551cfSopenharmony_ci    list->SetElementType(type);
617ca0551cfSopenharmony_ci
618ca0551cfSopenharmony_ci    AutoPtr<ASTType> ret = module_->FindType(list->ToString());
619ca0551cfSopenharmony_ci    if (ret == nullptr) {
620ca0551cfSopenharmony_ci        module_->AddType(list);
621ca0551cfSopenharmony_ci        ret = list.Get();
622ca0551cfSopenharmony_ci    }
623ca0551cfSopenharmony_ci
624ca0551cfSopenharmony_ci    return ret;
625ca0551cfSopenharmony_ci}
626ca0551cfSopenharmony_ci
627ca0551cfSopenharmony_ciAutoPtr<ASTType> Parser::ParseMap()
628ca0551cfSopenharmony_ci{
629ca0551cfSopenharmony_ci    lexer_.GetToken();
630ca0551cfSopenharmony_ci
631ca0551cfSopenharmony_ci    Token token = lexer_.PeekToken();
632ca0551cfSopenharmony_ci    if (token != Token::ANGLE_BRACKETS_LEFT) {
633ca0551cfSopenharmony_ci        LogError(token, String("\"<\" is expected."));
634ca0551cfSopenharmony_ci        return nullptr;
635ca0551cfSopenharmony_ci    }
636ca0551cfSopenharmony_ci    lexer_.GetToken();
637ca0551cfSopenharmony_ci
638ca0551cfSopenharmony_ci    AutoPtr<ASTType> keyType = ParseType();
639ca0551cfSopenharmony_ci    if (keyType == nullptr) {
640ca0551cfSopenharmony_ci        lexer_.SkipCurrentLine('>');
641ca0551cfSopenharmony_ci        return nullptr;
642ca0551cfSopenharmony_ci    }
643ca0551cfSopenharmony_ci
644ca0551cfSopenharmony_ci    token = lexer_.PeekToken();
645ca0551cfSopenharmony_ci    if (token != Token::COMMA) {
646ca0551cfSopenharmony_ci        LogError(token, String("\",\" is expected."));
647ca0551cfSopenharmony_ci        return nullptr;
648ca0551cfSopenharmony_ci    }
649ca0551cfSopenharmony_ci    lexer_.GetToken();
650ca0551cfSopenharmony_ci
651ca0551cfSopenharmony_ci    AutoPtr<ASTType> valueType = ParseType();
652ca0551cfSopenharmony_ci    if (valueType == nullptr) {
653ca0551cfSopenharmony_ci        lexer_.SkipCurrentLine('>');
654ca0551cfSopenharmony_ci        return nullptr;
655ca0551cfSopenharmony_ci    }
656ca0551cfSopenharmony_ci
657ca0551cfSopenharmony_ci    token = lexer_.PeekToken();
658ca0551cfSopenharmony_ci    if (token != Token::ANGLE_BRACKETS_RIGHT) {
659ca0551cfSopenharmony_ci        LogError(token, String("\">\" is expected."));
660ca0551cfSopenharmony_ci        return nullptr;
661ca0551cfSopenharmony_ci    }
662ca0551cfSopenharmony_ci    lexer_.GetToken();
663ca0551cfSopenharmony_ci
664ca0551cfSopenharmony_ci    AutoPtr<ASTMapType> map = new ASTMapType();
665ca0551cfSopenharmony_ci    map->SetKeyType(keyType);
666ca0551cfSopenharmony_ci    map->SetValueType(valueType);
667ca0551cfSopenharmony_ci
668ca0551cfSopenharmony_ci    AutoPtr<ASTType> ret = module_->FindType(map->ToString());
669ca0551cfSopenharmony_ci    if (ret == nullptr) {
670ca0551cfSopenharmony_ci        module_->AddType(map);
671ca0551cfSopenharmony_ci        ret = map.Get();
672ca0551cfSopenharmony_ci    }
673ca0551cfSopenharmony_ci
674ca0551cfSopenharmony_ci    return ret;
675ca0551cfSopenharmony_ci}
676ca0551cfSopenharmony_ci
677ca0551cfSopenharmony_cibool Parser::ParseSequenceable()
678ca0551cfSopenharmony_ci{
679ca0551cfSopenharmony_ci    lexer_.GetToken();
680ca0551cfSopenharmony_ci
681ca0551cfSopenharmony_ci    String classFullName;
682ca0551cfSopenharmony_ci
683ca0551cfSopenharmony_ci    Token token = lexer_.PeekToken();
684ca0551cfSopenharmony_ci    if (token != Token::IDENTIFIER) {
685ca0551cfSopenharmony_ci        LogError(token, String::Format("%s is not expected.", lexer_.DumpToken().string()));
686ca0551cfSopenharmony_ci        lexer_.SkipCurrentLine();
687ca0551cfSopenharmony_ci        return false;
688ca0551cfSopenharmony_ci    } else {
689ca0551cfSopenharmony_ci        lexer_.GetToken();
690ca0551cfSopenharmony_ci        classFullName = lexer_.GetIdentifier();
691ca0551cfSopenharmony_ci        token = lexer_.PeekToken();
692ca0551cfSopenharmony_ci    }
693ca0551cfSopenharmony_ci
694ca0551cfSopenharmony_ci    if (token != Token::SEMICOLON) {
695ca0551cfSopenharmony_ci        LogError(token, String::Format("%s is not expected.", lexer_.DumpToken().string()));
696ca0551cfSopenharmony_ci        lexer_.SkipCurrentLine();
697ca0551cfSopenharmony_ci        return false;
698ca0551cfSopenharmony_ci    }
699ca0551cfSopenharmony_ci
700ca0551cfSopenharmony_ci    // read ';'
701ca0551cfSopenharmony_ci    lexer_.GetToken();
702ca0551cfSopenharmony_ci
703ca0551cfSopenharmony_ci    if (classFullName.IsEmpty()) {
704ca0551cfSopenharmony_ci        LogError(Token::IDENTIFIER, String("Class name is expected."));
705ca0551cfSopenharmony_ci        return false;
706ca0551cfSopenharmony_ci    } else if (!IsValidTypeName(classFullName)) {
707ca0551cfSopenharmony_ci        LogError(Token::IDENTIFIER, String::Format("Class name \"%s\" is illegal.", classFullName.string()));
708ca0551cfSopenharmony_ci        return false;
709ca0551cfSopenharmony_ci    }
710ca0551cfSopenharmony_ci
711ca0551cfSopenharmony_ci    AutoPtr<ASTSequenceableType> sequenceable = new ASTSequenceableType();
712ca0551cfSopenharmony_ci    int index = classFullName.LastIndexOf('.');
713ca0551cfSopenharmony_ci    if (index != -1) {
714ca0551cfSopenharmony_ci        sequenceable->SetName(classFullName.Substring(index + 1));
715ca0551cfSopenharmony_ci        sequenceable->SetNamespace(module_->ParseNamespace(classFullName.Substring(0, index + 1)));
716ca0551cfSopenharmony_ci    } else {
717ca0551cfSopenharmony_ci        sequenceable->SetName(classFullName);
718ca0551cfSopenharmony_ci        sequenceable->SetNamespace(NameSpaceEmpty());
719ca0551cfSopenharmony_ci    }
720ca0551cfSopenharmony_ci    module_->AddSequenceable(sequenceable);
721ca0551cfSopenharmony_ci
722ca0551cfSopenharmony_ci    return true;
723ca0551cfSopenharmony_ci}
724ca0551cfSopenharmony_ci
725ca0551cfSopenharmony_cibool Parser::CheckIntegrity()
726ca0551cfSopenharmony_ci{
727ca0551cfSopenharmony_ci    bool definedInterface = false;
728ca0551cfSopenharmony_ci    size_t interfaceNumber = module_->GetInterfaceNumber();
729ca0551cfSopenharmony_ci    for (size_t i = 0; i < interfaceNumber; i++) {
730ca0551cfSopenharmony_ci        if (!module_->GetInterface(i)->IsExternal()) {
731ca0551cfSopenharmony_ci            definedInterface = true;
732ca0551cfSopenharmony_ci            break;
733ca0551cfSopenharmony_ci        }
734ca0551cfSopenharmony_ci    }
735ca0551cfSopenharmony_ci    if (!definedInterface) {
736ca0551cfSopenharmony_ci        LogError(Token::UNKNOWN, String("An interface is not defined."));
737ca0551cfSopenharmony_ci        return false;
738ca0551cfSopenharmony_ci    }
739ca0551cfSopenharmony_ci
740ca0551cfSopenharmony_ci    return true;
741ca0551cfSopenharmony_ci}
742ca0551cfSopenharmony_ci
743ca0551cfSopenharmony_cibool Parser::IsValidTypeName(const String& typeName)
744ca0551cfSopenharmony_ci{
745ca0551cfSopenharmony_ci    if (typeName[0] == '.') {
746ca0551cfSopenharmony_ci        return false;
747ca0551cfSopenharmony_ci    }
748ca0551cfSopenharmony_ci
749ca0551cfSopenharmony_ci    if (typeName[typeName.GetLength() - 1] == '.') {
750ca0551cfSopenharmony_ci        return false;
751ca0551cfSopenharmony_ci    }
752ca0551cfSopenharmony_ci
753ca0551cfSopenharmony_ci    return true;
754ca0551cfSopenharmony_ci}
755ca0551cfSopenharmony_ci
756ca0551cfSopenharmony_civoid Parser::LogError(Token token, const String& message)
757ca0551cfSopenharmony_ci{
758ca0551cfSopenharmony_ci    AutoPtr<ErrorInfo> error = new ErrorInfo();
759ca0551cfSopenharmony_ci
760ca0551cfSopenharmony_ci    String sourceFile = lexer_.GetSourceFile()->GetPath();
761ca0551cfSopenharmony_ci#ifdef __MINGW32__
762ca0551cfSopenharmony_ci    error->file_ = sourceFile.Substring(sourceFile.LastIndexOf('\\') + 1);
763ca0551cfSopenharmony_ci#else
764ca0551cfSopenharmony_ci    error->file_ = sourceFile.Substring(sourceFile.LastIndexOf('/') + 1);
765ca0551cfSopenharmony_ci#endif
766ca0551cfSopenharmony_ci    error->lineNo_ = lexer_.GetTokenLineNumber();
767ca0551cfSopenharmony_ci    error->columnNo_ = lexer_.GetTokenColumnNumber();
768ca0551cfSopenharmony_ci    error->message_ = message;
769ca0551cfSopenharmony_ci
770ca0551cfSopenharmony_ci    if (errors_ == nullptr) {
771ca0551cfSopenharmony_ci        errors_ = error;
772ca0551cfSopenharmony_ci    } else {
773ca0551cfSopenharmony_ci        ErrorInfo* pos = errors_;
774ca0551cfSopenharmony_ci        while (pos->next_ != nullptr) {
775ca0551cfSopenharmony_ci            pos = pos->next_;
776ca0551cfSopenharmony_ci        }
777ca0551cfSopenharmony_ci        pos->next_ = error;
778ca0551cfSopenharmony_ci    }
779ca0551cfSopenharmony_ci}
780ca0551cfSopenharmony_ci
781ca0551cfSopenharmony_civoid Parser::ShowError()
782ca0551cfSopenharmony_ci{
783ca0551cfSopenharmony_ci    ErrorInfo* error = errors_;
784ca0551cfSopenharmony_ci    while (error != nullptr) {
785ca0551cfSopenharmony_ci        Logger::E(tag, "%s[line %d, column %d] %s", error->file_.string(),
786ca0551cfSopenharmony_ci            error->lineNo_, error->columnNo_, error->message_.string());
787ca0551cfSopenharmony_ci        error = error->next_;
788ca0551cfSopenharmony_ci    }
789ca0551cfSopenharmony_ci}
790ca0551cfSopenharmony_ci
791ca0551cfSopenharmony_ciAutoPtr<ASTNamespace> Parser::NameSpaceEmpty()
792ca0551cfSopenharmony_ci{
793ca0551cfSopenharmony_ci    AutoPtr<ASTNamespace> currNspace = nullptr;
794ca0551cfSopenharmony_ci    currNspace = module_->FindNamespace("");
795ca0551cfSopenharmony_ci    if (currNspace == nullptr) {
796ca0551cfSopenharmony_ci        currNspace = new ASTNamespace("");
797ca0551cfSopenharmony_ci        module_->AddNamespace(currNspace);
798ca0551cfSopenharmony_ci    }
799ca0551cfSopenharmony_ci    return currNspace;
800ca0551cfSopenharmony_ci}
801ca0551cfSopenharmony_ci} // namespace Idl
802ca0551cfSopenharmony_ci} // namespace OHOS
803