• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  *
4  * HDF is dual licensed: you can use it either under the terms of
5  * the GPL, or the BSD license, at your option.
6  * See the LICENSE file in the root of this repository for complete details.
7  */
8 
9 #include "parser/parser.h"
10 #include <regex>
11 #include "ast/ast_array_type.h"
12 #include "ast/ast_enum_type.h"
13 #include "ast/ast_list_type.h"
14 #include "ast/ast_map_type.h"
15 #include "ast/ast_smq_type.h"
16 #include "ast/ast_parameter.h"
17 #include "ast/ast_sequenceable_type.h"
18 #include "ast/ast_struct_type.h"
19 #include "ast/ast_union_type.h"
20 #include "util/logger.h"
21 #include "util/string_builder.h"
22 
23 #define RE_DIGIT        "[0-9]+"
24 #define RE_IDENTIFIER   "[a-zA-Z_][a-zA-Z0-9_]*"
25 
26 #define RE_PACKAGE_NUM 3
27 #define RE_PACKAGE_INDEX 0
28 #define RE_PACKAGE_MAJOR_VER_INDEX 1
29 #define RE_PACKAGE_MINOR_VER_INDEX 2
30 
31 namespace OHOS {
32 namespace HDI {
33 const char* Parser::TAG = "Parser";
34 
35 static const std::regex rePackage(RE_IDENTIFIER "(?:\\." RE_IDENTIFIER ")*\\.[V|v]" "(" RE_DIGIT ")_(" RE_DIGIT ")");
36 static const std::regex reImport(RE_IDENTIFIER "(?:\\." RE_IDENTIFIER ")*\\.[V|v]" \
37                                  RE_DIGIT "_" RE_DIGIT "." RE_IDENTIFIER);
38 
Parser(const Options & options,const AutoPtr<ASTModule> & module)39 Parser::Parser(const Options& options, const AutoPtr<ASTModule>& module)
40     :options_(options), lexer_(nullptr), errors_(nullptr), ast_(nullptr), astModule_(module)
41 {}
42 
Parse(const String & sourceFile)43 bool Parser::Parse(const String& sourceFile)
44 {
45     lexer_ = std::make_shared<Lexer>();
46     bool ret = lexer_->OpenSourceFile(sourceFile);
47     if (!ret) {
48         Logger::E(TAG, "Fail to open file '%s'.", sourceFile.string());
49         return false;
50     }
51 
52     ret = ParseFile();
53     ret = CheckIntegrity() && ret;
54     ret = AddAst() && ret;
55     if (!ret || errors_ != nullptr) {
56         ShowError();
57         return false;
58     }
59 
60     if (options_.DoDumpAST()) {
61         String astStr = ast_->Dump("");
62         printf("%s\n", astStr.string());
63     }
64 
65     return ret;
66 }
67 
Parse(const String & sourceFile,std::shared_ptr<FileDetail> & fileDetailPtr)68 bool Parser::Parse(const String& sourceFile, std::shared_ptr<FileDetail>& fileDetailPtr)
69 {
70     lexer_ = std::make_shared<Lexer>();
71     bool ret = lexer_->OpenSourceFile(sourceFile);
72     if (!ret) {
73         Logger::E(TAG, "Fail to open file '%s'.", sourceFile.string());
74         return false;
75     }
76 
77     ret = ParseIdlDetail(fileDetailPtr);
78     if (!ret) {
79         ShowError();
80         return false;
81     }
82 
83     return ret;
84 }
85 
ParseIdlDetail(std::shared_ptr<FileDetail> & fileDetailPtr)86 bool Parser::ParseIdlDetail(std::shared_ptr<FileDetail>& fileDetailPtr)
87 {
88     bool ret = true;
89     fileDetailPtr = std::make_shared<FileDetail>();
90     fileDetailPtr->SetFilePath(lexer_->GetFilePath());
91 
92     Token token;
93     while ((token = lexer_->PeekToken()) != Token::END_OF_FILE) {
94         switch (token) {
95             case Token::PACKAGE:
96                 ret = ParseIdlPackage(fileDetailPtr) && ret;
97                 break;
98             case Token::IMPORT:
99                 ret = ParseIdlImport(fileDetailPtr) && ret;
100                 break;
101             default:
102                 lexer_->GetToken();
103                 break;
104         }
105     }
106     lexer_->GetToken();
107     return ret;
108 }
109 
ParseIdlPackage(std::shared_ptr<FileDetail> & fileDetailPtr)110 bool Parser::ParseIdlPackage(std::shared_ptr<FileDetail>& fileDetailPtr)
111 {
112     lexer_->GetToken();
113     String packageName;
114 
115     Token token = lexer_->PeekToken();
116     if (token != Token::IDENTIFIER) {
117         if (token == Token::SEMICOLON) {
118             LogError(String::Format("expected identifier before ';'."));
119             lexer_->GetToken();
120         } else {
121             LogError(String::Format("'%s' is an invalid package name.", lexer_->DumpToken().string()));
122         }
123         lexer_->SkipCurrentLine();
124         return false;
125     } else {
126         lexer_->GetToken();
127         packageName = lexer_->GetIdentifier();
128         token = lexer_->PeekToken();
129     }
130 
131     if (token != Token::SEMICOLON) {
132         LogError(String::Format("expected ';' before '%s'", lexer_->DumpToken().string()));
133         return false;
134     }
135 
136     // read ';'
137     lexer_->GetToken();
138 
139     if (packageName.IsEmpty()) {
140         LogError(String("Package name is not expected."));
141         return false;
142     } else if (!IsValidTypeName(packageName)) {
143         LogError(String::Format("Package name '%s' is illegal.", packageName.string()));
144         return false;
145     } else if (!CheckPackageName(lexer_->GetFilePath(), packageName)) {
146         LogError(String::Format("Package name '%s' does not match file apth '%s'.",
147             packageName.string(), lexer_->GetFilePath().string()));
148         return false;
149     }
150 
151     fileDetailPtr->SetPackageName(packageName);
152 
153     return true;
154 }
155 
ParseIdlImport(std::shared_ptr<FileDetail> & fileDetailPtr)156 bool Parser::ParseIdlImport(std::shared_ptr<FileDetail>& fileDetailPtr)
157 {
158     lexer_->GetToken();
159 
160     String importPkgName;
161     Token token = lexer_->PeekToken();
162     if (token != Token::IDENTIFIER) {
163         if (token == Token::SEMICOLON) {
164             LogError(String::Format("expected identifier before ';'."));
165             lexer_->GetToken();
166         } else {
167             LogError(String::Format("'%s' is an invalid import package name.", lexer_->DumpToken().string()));
168         }
169         lexer_->SkipCurrentLine();
170         return false;
171     }
172     lexer_->GetToken();
173     importPkgName = lexer_->GetIdentifier();
174 
175     token = lexer_->PeekToken();
176     if (token != Token::SEMICOLON) {
177         LogError(String::Format("expected ';' before '%s'.", lexer_->DumpToken().string()));
178         return false;
179     }
180 
181     // read ';'
182     lexer_->GetToken();
183     if (importPkgName.IsEmpty()) {
184         LogError(String("import package name is not expected."));
185         return false;
186     } else if (!IsValidTypeName(importPkgName)) {
187         LogError(String::Format("import package name '%s' is illegal.", importPkgName.string()));
188         return false;
189     }
190 
191     if (!fileDetailPtr->AddImport(importPkgName)) {
192         LogError(String::Format("the package of '%s' has been imported.", importPkgName.string()));
193         return false;
194     }
195 
196     return true;
197 }
198 
ParseFile()199 bool Parser::ParseFile()
200 {
201     bool ret = true;
202     ast_ = new AST();
203     ast_->SetIdlFile(lexer_->GetFilePath());
204     ParseLicense();
205 
206     Token token;
207     while ((token = lexer_->PeekToken()) != Token::END_OF_FILE) {
208         switch (token) {
209             case Token::PACKAGE:
210                 ret = ParsePackageName() && ret;
211                 continue;
212             case Token::IMPORT:
213                 ret = ParseImport() && ret;
214                 continue;
215             case Token::SEQUENCEABLE:
216                 ret = ParseSequenceable() && ret;
217                 continue;
218             case Token::BRACKETS_LEFT:
219                 ret = ParseAttribute() && ret;
220                 continue;
221             case Token::INTERFACE:
222                 ret = ParseInterface() && ret;
223                 continue;
224             case Token::COMMENT_LINE:
225                 lexer_->GetToken();
226                 continue;
227             case Token::ENUM:
228                 ret = ParseEnumDefine() && ret;
229                 continue;
230             case Token::STRUCT:
231                 ret = ParseStructDefine() && ret;
232                 continue;
233             case Token::UNION:
234                 ret = ParseUnionDefine() && ret;
235                 continue;
236             default:
237                 LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
238                 lexer_->GetToken();
239                 ret = false;
240                 continue;
241         }
242     }
243     lexer_->GetToken();
244     SetAstFileType();
245 
246     return ret;
247 }
248 
ParseLicense()249 bool Parser::ParseLicense()
250 {
251     Token token = lexer_->PeekToken(false);
252     if (token != Token::COMMENT_BLOCK) {
253         return false;
254     }
255 
256     lexer_->GetToken(false);
257 
258     ast_->SetLicense(lexer_->GetComment());
259 
260     return true;
261 }
262 
ParsePackageName()263 bool Parser::ParsePackageName()
264 {
265     lexer_->GetToken();
266     String packageFullName;
267     Token token = lexer_->PeekToken();
268     if (token != Token::IDENTIFIER) {
269         if (token == Token::SEMICOLON) {
270             LogError(String::Format("expected identifier before ';'."));
271         } else {
272             LogError(String::Format("'%s' is an invalid package name.", lexer_->DumpToken().string()));
273         }
274         lexer_->SkipCurrentLine();
275         lexer_->GetToken();
276         return false;
277     } else {
278         lexer_->GetToken();
279         packageFullName = lexer_->GetIdentifier();
280         token = lexer_->PeekToken();
281     }
282 
283     if (token != Token::SEMICOLON) {
284         LogError(String::Format("expected ';' before '%s'", lexer_->DumpToken().string()));
285         return false;
286     }
287 
288     // read ';'
289     lexer_->GetToken();
290     if (packageFullName.IsEmpty()) {
291         LogError(String("Package name is not expected."));
292         return false;
293     } else if (!IsValidTypeName(packageFullName)) {
294         LogError(String::Format("Package name '%s' is illegal.", packageFullName.string()));
295         return false;
296     } else if (!CheckPackageName(lexer_->GetFilePath(), packageFullName)) {
297         LogError(String::Format("Package name '%s' does not match file apth '%s'.",
298             packageFullName.string(), lexer_->GetFilePath().string()));
299         return false;
300     }
301 
302     if (!ParserPackageInfo(packageFullName)) {
303         LogError(String::Format("Parse package '%s' infomation failed.", packageFullName.string()));
304         return false;
305     }
306 
307     return true;
308 }
309 
ParserPackageInfo(const String & packageName)310 bool Parser::ParserPackageInfo(const String& packageName)
311 {
312     std::cmatch result;
313     if (!std::regex_match(packageName.string(), result, rePackage)) {
314         return false;
315     }
316 
317     if (result.size() < RE_PACKAGE_NUM) {
318         return false;
319     }
320 
321     ast_->SetPackageName(result.str(RE_PACKAGE_INDEX).c_str());
322     size_t majorVersion = std::atoi(result.str(RE_PACKAGE_MAJOR_VER_INDEX).c_str());
323     size_t minorVersion = std::atoi(result.str(RE_PACKAGE_MINOR_VER_INDEX).c_str());
324     ast_->SetVersion(majorVersion, minorVersion);
325     return true;
326 }
327 
ParseImport()328 bool Parser::ParseImport()
329 {
330     lexer_->GetToken();
331     String packageFullName;
332     Token token = lexer_->PeekToken();
333     if (token != Token::IDENTIFIER) {
334         if (token == Token::SEMICOLON) {
335             LogError(String::Format("expected identifier before ';'."));
336         } else {
337             LogError(String::Format("%s is an invalid import package name.", lexer_->DumpToken().string()));
338         }
339         lexer_->SkipCurrentLine();
340         lexer_->GetToken();
341         return false;
342     }
343     lexer_->GetToken();
344     packageFullName = lexer_->GetIdentifier();
345 
346     token = lexer_->PeekToken();
347     if (token != Token::SEMICOLON) {
348         LogError(String::Format("expected ';' before '%s'.", lexer_->DumpToken().string()));
349         return false;
350     }
351 
352     // read ';'
353     lexer_->GetToken();
354     if (packageFullName.IsEmpty()) {
355         LogError(String("import package name is not expected."));
356         return false;
357     } else if (!IsValidTypeName(packageFullName)) {
358         LogError(String::Format("import package name '%s' is illegal.", packageFullName.string()));
359         return false;
360     }
361 
362     AutoPtr<AST> importAst = astModule_->GetAst(packageFullName);
363     if (importAst == nullptr) {
364         LogError(String("not find import ast."));
365         return false;
366     }
367 
368     AutoPtr<ASTInterfaceType> interfaceType = importAst->GetInterfaceDef();
369     if (interfaceType != nullptr) {
370         interfaceType->SetSerializable(true);
371     }
372 
373     if (!ast_->AddImport(importAst)) {
374         LogError(String::Format("the package '%s' has been import", packageFullName.string()));
375         return false;
376     }
377     return true;
378 }
379 
ParseSequenceable()380 bool Parser::ParseSequenceable()
381 {
382     lexer_->GetToken();
383     String classFullName;
384 
385     Token token =  lexer_->PeekToken();
386     if (token != Token::IDENTIFIER) {
387         if (token == Token::SEMICOLON) {
388             LogError(String::Format("expected identifier before ';'."));
389         } else {
390             LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
391         }
392         lexer_->SkipCurrentLine();
393         lexer_->GetToken();
394         return false;
395     }
396     lexer_->GetToken();
397     classFullName = lexer_->GetIdentifier();
398 
399     token = lexer_->PeekToken();
400     if (token != Token::SEMICOLON) {
401         LogError(String::Format("expected ';' before '%s'.", lexer_->DumpToken().string()));
402         return false;
403     }
404     // read ';'
405     lexer_->GetToken();
406 
407     if (classFullName.IsEmpty()) {
408         LogError(String("class name is not expected."));
409         return false;
410     } else if (!IsValidTypeName(classFullName)) {
411         LogError(String::Format("class name '%s' is illegal.", classFullName.string()));
412         return false;
413     }
414 
415     AutoPtr<ASTSequenceableType> sequenceable = new ASTSequenceableType();
416     int index = classFullName.LastIndexOf('.');
417     if (index != -1) {
418         sequenceable->SetName(classFullName.Substring(index + 1));
419         sequenceable->SetNamespace(ast_->ParseNamespace(classFullName.Substring(0, index + 1)));
420     } else {
421         sequenceable->SetName(classFullName);
422     }
423 
424     AutoPtr<AST> sequenceableAst = new AST();
425     sequenceableAst->SetFullName(classFullName);
426     sequenceableAst->AddSequenceableDef(sequenceable);
427     sequenceableAst->SetAStFileType(ASTFileType::AST_SEQUENCEABLE);
428     ast_->AddImport(sequenceableAst);
429 
430     return true;
431 }
432 
ParseAttribute()433 bool Parser::ParseAttribute()
434 {
435     bool ret = true;
436     AutoPtr<Attribute> attributes = nullptr;
437 
438     if (!ParseAttributeBody(attributes)) {
439         return false;
440     }
441 
442     Token token = lexer_->PeekToken();
443     switch (token) {
444         case Token::ENUM:
445             ret = ParseEnumDefine(attributes) && ret;
446             break;
447         case Token::STRUCT:
448             ret = ParseStructDefine(attributes) && ret;
449             break;
450         case Token::UNION:
451             ret = ParseUnionDefine(attributes) && ret;
452             break;
453         case Token::INTERFACE:
454             ret = ParseInterface(attributes) && ret;
455             break;
456         default: {
457             LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
458             return false;
459         }
460     }
461     return ret;
462 }
463 
ParseInterface(const AutoPtr<Attribute> & attributes)464 bool Parser::ParseInterface(const AutoPtr<Attribute>& attributes)
465 {
466     lexer_->GetToken();
467     String interfaceName;
468 
469     Token token = lexer_->PeekToken();
470     if (token != Token::IDENTIFIER) {
471         LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
472         lexer_->Skip('}');
473         lexer_->GetToken();
474         return false;
475     }
476     lexer_->GetToken();
477     interfaceName = lexer_->GetIdentifier();
478 
479     token = lexer_->PeekToken();
480     if (token != Token::BRACES_LEFT) {
481         LogError(String::Format("expected '{' after the '%s'.", lexer_->DumpToken().string()));
482         lexer_->Skip('}');
483         lexer_->GetToken();
484         return false;
485     }
486     lexer_->GetToken();
487 
488     if (interfaceName.IsEmpty()) {
489         LogError(String("interface name is expected."));
490         return false;
491     }
492 
493     AutoPtr<ASTInterfaceType> interface = new ASTInterfaceType();
494     interface->SetName(interfaceName);
495     interface->SetNamespace(ast_->ParseNamespace(ast_->GetFullName()));
496 
497     if (!interface->GetName().Equals(ast_->GetName())) {
498         LogError(String::Format("Module name '%s' is not equal to interface name  '%s'.",
499             ast_->GetName().string(), interface->GetName().string()));
500     }
501 
502     interface->SetLicense(ast_->GetLicense());
503     if (attributes != nullptr) {
504         interface->SetOneWay(attributes->isOneWay);
505         interface->SetCallback(attributes->isCallback);
506         interface->SetFull(attributes->isFull);
507         interface->SetLite(attributes->isLite);
508     }
509     return ParseInterfaceBody(interface);
510 }
511 
ParseInterfaceBody(const AutoPtr<ASTInterfaceType> & interface)512 bool Parser::ParseInterfaceBody(const AutoPtr<ASTInterfaceType>& interface)
513 {
514     bool ret = true;
515     Token token = lexer_->PeekToken();
516     while (token != Token::BRACES_RIGHT && token != Token::END_OF_FILE) {
517         ret = ParseMethod(interface) && ret;
518         token = lexer_->PeekToken();
519     }
520 
521     if (token != Token::BRACES_RIGHT) {
522         LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
523         lexer_->SkipEof();
524         return false;
525     }
526     lexer_->GetToken();
527 
528     token = lexer_->PeekToken();
529     if (token == Token::SEMICOLON) {
530         lexer_->GetToken();
531     }
532 
533     if (ast_->GetInterfaceDef() != nullptr) {
534         LogError(String::Format("an interface class already exists int idl file."));
535         lexer_->SkipEof();
536         return false;
537     }
538 
539     SetVersionInterfaceMethod(interface);
540 
541     ast_->AddInterfaceDef(interface);
542     return ret;
543 }
544 
ParseMethod(const AutoPtr<ASTInterfaceType> & interface)545 bool Parser::ParseMethod(const AutoPtr<ASTInterfaceType>& interface)
546 {
547     AutoPtr<Attribute> attributes = nullptr;
548     if (!ParseAttributeBody(attributes)) {
549         return false;
550     }
551 
552     Token token = lexer_->PeekToken();
553     if (token != Token::IDENTIFIER) {
554         LogError(String("Method name is expected."));
555         if (token == Token::BRACES_RIGHT) {
556             return false;
557         }
558         // jump over colon
559         lexer_->GetToken();
560         while (token != Token::SEMICOLON && token != Token::END_OF_FILE) {
561             token = lexer_->PeekToken();
562             if (token == Token::BRACES_RIGHT) {
563                 break;
564             }
565             lexer_->GetToken();
566         }
567         return false;
568     }
569     lexer_->GetToken();
570 
571     AutoPtr<ASTMethod> method = new ASTMethod();
572     method->SetName(lexer_->GetIdentifier());
573 
574     if (attributes != nullptr) {
575         method->SetOneWay(attributes->isOneWay || interface->IsOneWay());
576         method->SetFull(attributes->isFull);
577         method->SetLite(attributes->isLite);
578     }
579 
580     if (!ParseParameterList(method)) {
581         return false;
582     }
583 
584     interface->AddMethod(method);
585     return true;
586 }
587 
SetVersionInterfaceMethod(const AutoPtr<ASTInterfaceType> & interface)588 void Parser::SetVersionInterfaceMethod(const AutoPtr<ASTInterfaceType>& interface)
589 {
590     AutoPtr<ASTMethod> method = new ASTMethod();
591     method->SetName("GetVersion");
592 
593     AutoPtr<ASTType> type = ast_->FindType("unsigned int");
594     if (type == nullptr) {
595         type = new ASTUintType();
596     }
597     AutoPtr<ASTParameter> majorParam = new ASTParameter("majorVer", ParamAttr::PARAM_OUT, type);
598     AutoPtr<ASTParameter> minorParam = new ASTParameter("minorVer", ParamAttr::PARAM_OUT, type);
599 
600     method->AddParameter(majorParam);
601     method->AddParameter(minorParam);
602     interface->AddVersionMethod(method);
603 }
604 
ParseAttributeBody(AutoPtr<Attribute> & attributes)605 bool Parser::ParseAttributeBody(AutoPtr<Attribute>& attributes)
606 {
607     Token token = lexer_->PeekToken();
608     if (token != Token::BRACKETS_LEFT) {
609         return true;
610     }
611     lexer_->GetToken();
612     attributes = new Attribute();
613     token = lexer_->PeekToken();
614     while (token != Token::BRACKETS_RIGHT) {
615         if (!ParseAttributeParam(attributes)) {
616             return false;
617         }
618 
619         token = lexer_->PeekToken();
620         if (token == Token::COMMA) {
621             lexer_->GetToken();
622             token = lexer_->PeekToken();
623         } else if (token == Token::BRACKETS_RIGHT) {
624             break;
625         } else {
626             LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
627             lexer_->Skip(Lexer::TokenToChar(Token::BRACKETS_RIGHT));
628             lexer_->GetToken();
629             return false;
630         }
631     }
632     lexer_->GetToken();
633     return true;
634 }
635 
ParseAttributeParam(AutoPtr<Attribute> & attributes)636 bool Parser::ParseAttributeParam(AutoPtr<Attribute>& attributes)
637 {
638     Token token = lexer_->GetToken();
639     switch (token) {
640         case Token::ONEWAY:
641             if (options_.DoGenerateKernelCode()) {
642                 LogError(String::Format("'%s' is not supported in kernel code.", lexer_->DumpToken().string()));
643                 lexer_->Skip(Lexer::TokenToChar(Token::BRACKETS_RIGHT));
644                 lexer_->GetToken();
645                 return false;
646             }
647             attributes->isOneWay = true;
648             break;
649         case Token::CALLBACK:
650             attributes->isCallback = true;
651             break;
652         case Token::FULL:
653             attributes->isFull = true;
654             break;
655         case Token::LITE:
656             attributes->isLite = true;
657             break;
658         default: {
659             LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
660             lexer_->Skip(Lexer::TokenToChar(Token::BRACKETS_RIGHT));
661             lexer_->GetToken();
662             return false;
663         }
664     }
665     return true;
666 }
667 
ParseParameterList(AutoPtr<ASTMethod> & method)668 bool Parser::ParseParameterList(AutoPtr<ASTMethod>& method)
669 {
670     bool ret = true;
671     Token token = lexer_->PeekToken();
672     if (token != Token::PARENTHESES_LEFT) {
673         LogError(String("'(' is expected."));
674         lexer_->Skip(';');
675         return false;
676     }
677     lexer_->GetToken();
678 
679     token = lexer_->PeekToken();
680     while (token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) {
681         ret = ParseParameter(method) && ret;
682         token = lexer_->PeekToken();
683         if (token == Token::COMMA) {
684             lexer_->GetToken();
685             token = lexer_->PeekToken();
686         } else if (token != Token::PARENTHESES_RIGHT) {
687             LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
688             lexer_->SkipCurrentLine(';');
689             lexer_->GetToken();
690             return false;
691         }
692     }
693 
694     lexer_->GetToken();
695     if (!ret) {
696         lexer_->SkipCurrentLine();
697         return false;
698     }
699 
700     token = lexer_->PeekToken();
701     if (token != Token::SEMICOLON) {
702         LogError(String("';' is expected."));
703         return false;
704     }
705     lexer_->GetToken();
706     return true;
707 }
708 
ParseParameter(const AutoPtr<ASTMethod> & method)709 bool Parser::ParseParameter(const AutoPtr<ASTMethod>& method)
710 {
711     AutoPtr<ASTParameter> parameter = new ASTParameter();
712     if (!ParseParamAttr(parameter)) {
713         return false;
714     }
715 
716     AutoPtr<ASTType> type = ParseType();
717 
718     Token token = lexer_->PeekToken();
719     if (type == nullptr) {
720         while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) {
721             lexer_->GetToken();
722             token = lexer_->PeekToken();
723         }
724         return false;
725     }
726 
727     if (token != Token::IDENTIFIER) {
728         LogError(String("Parameter name is expected."));
729         while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) {
730             lexer_->GetToken();
731             token = lexer_->PeekToken();
732         }
733         return false;
734     }
735     lexer_->GetToken();
736 
737     if (type->IsInterfaceType()) {
738         AutoPtr<ASTInterfaceType> interfaceType = dynamic_cast<ASTInterfaceType*>(type.Get());
739         if (interfaceType->IsCallback() && parameter->GetAttribute() != ParamAttr::PARAM_IN) {
740             LogError(String::Format("The attribute of callback interface parameter '%s' does not be 'in'",
741                 lexer_->GetIdentifier().string()));
742             return false;
743         }
744 
745         if (!interfaceType->IsCallback() && parameter->GetAttribute() != ParamAttr::PARAM_OUT) {
746             LogError(String::Format("The attribute of interface parameter '%s' does not be 'in'",
747                 lexer_->GetIdentifier().string()));
748             return false;
749         }
750     }
751 
752     parameter->SetName(lexer_->GetIdentifier());
753     parameter->SetType(type);
754 
755     if (method->IsOneWay() && parameter->GetAttribute() == ParamAttr::PARAM_OUT) {
756         LogError(String::Format("The attribute of parameter '%s' cannot be 'out'.", parameter->GetName().string()));
757         return false;
758     }
759 
760     method->AddParameter(parameter);
761     return true;
762 }
763 
ParseParamAttr(const AutoPtr<ASTParameter> & parameter)764 bool Parser::ParseParamAttr(const AutoPtr<ASTParameter>& parameter)
765 {
766     Token token = lexer_->PeekToken();
767     if (token != Token::BRACKETS_LEFT) {
768         LogError(String("'[' is expected."));
769         while (token != Token::COMMA && token != Token::PARENTHESES_RIGHT && token != Token::END_OF_FILE) {
770             lexer_->GetToken();
771             token = lexer_->PeekToken();
772         }
773         return false;
774     }
775     lexer_->GetToken();
776 
777     if (parameter == nullptr) {
778         return false;
779     }
780 
781     token = lexer_->PeekToken();
782     if (token == Token::IN) {
783         lexer_->GetToken();
784         parameter->SetAttribute(ParamAttr::PARAM_IN);
785     } else if (token == Token::OUT) {
786         lexer_->GetToken();
787         parameter->SetAttribute(ParamAttr::PARAM_OUT);
788     } else {
789         LogError(String::Format("'%s' is not a parameter property, it must be 'in' or 'out'.",
790             lexer_->DumpToken().string()));
791         while (token != Token::SEMICOLON && token != Token::END_OF_FILE) {
792             lexer_->GetToken();
793             token = lexer_->PeekToken();
794         }
795         return false;
796     }
797 
798     token = lexer_->PeekToken();
799     if (token != Token::BRACKETS_RIGHT) {
800         LogError(String::Format("']' is expected."));
801         while (token != Token::SEMICOLON && token != Token::END_OF_FILE) {
802             lexer_->GetToken();
803             token = lexer_->PeekToken();
804         }
805         return false;
806     }
807     lexer_->GetToken();
808 
809     return true;
810 }
811 
ParseType()812 AutoPtr<ASTType> Parser::ParseType()
813 {
814     int typeLineNo = lexer_->GetTokenLineNumber();
815     int typeColumnNo = lexer_->GetTokenColumnNumber();
816     AutoPtr<ASTType> type;
817 
818     Token token = lexer_->PeekToken();
819     if (IsPrimitiveType(token)) {
820         lexer_->GetToken();
821         type = ast_->FindType(lexer_->DumpToken());
822     } else if (token == Token::LIST) {
823         type = ParseList();
824     } else if (token == Token::MAP) {
825         type = ParseMap();
826     } else if (token == Token::SMEMQUEUE) {
827         type = ParseSharedMemQueueMetaType();
828     } else if (token == Token::ENUM || token == Token::STRUCT || token == Token::UNION) {
829         type = ParseCustomType();
830     } else if (token == Token::IDENTIFIER) {
831         lexer_->GetToken();
832         type = ast_->FindType(lexer_->GetIdentifier());
833     } else if (token == Token::UNSIGNED) {
834         lexer_->GetToken();
835         type = ParseUnsignedType(typeLineNo, typeColumnNo);
836     } else {
837         LogError(typeLineNo, typeColumnNo, String("Invalid type name."));
838         return nullptr;
839     }
840 
841     if (type == nullptr) {
842         LogError(typeLineNo, typeColumnNo, String::Format("Type '%s' was not declared in any idl file.",
843             lexer_->DumpToken().string()));
844     }
845 
846     token = lexer_->PeekToken();
847     if (token == Token::BRACKETS_LEFT) {
848         lexer_->GetToken();
849         type = ParseArrayType(type);
850     }
851 
852     if (!CheckType(typeLineNo, typeColumnNo, type)) {
853         return nullptr;
854     }
855 
856     return type;
857 }
858 
ParseUnsignedType(int typeLineNo,int typeColumnNo)859 AutoPtr<ASTType> Parser::ParseUnsignedType(int typeLineNo, int typeColumnNo)
860 {
861     AutoPtr<ASTType> type = nullptr;
862     String unsignedStr = lexer_->DumpToken();
863     Token token = lexer_->PeekToken();
864     switch (token) {
865         case Token::CHAR:
866         case Token::SHORT:
867         case Token::INTEGER:
868         case Token::LONG: {
869             type = ast_->FindType(unsignedStr + " " + lexer_->DumpToken());
870             lexer_->GetToken();
871             break;
872         }
873         default: {
874             LogError(typeLineNo, typeColumnNo,
875                 String::Format("'unsigned %s' type was not declared in the idl file.",
876                     lexer_->DumpToken().string()));
877             return nullptr;
878         }
879     }
880 
881     return type;
882 }
883 
ParseList()884 AutoPtr<ASTType> Parser::ParseList()
885 {
886     lexer_->GetToken();
887 
888     Token token = lexer_->PeekToken();
889     if (token != Token::ANGLE_BRACKETS_LEFT) {
890         LogError(String("'<' is expected."));
891         return nullptr;
892     }
893     lexer_->GetToken();
894 
895     AutoPtr<ASTType> type = ParseType();
896     if (type == nullptr) {
897         lexer_->SkipCurrentLine('>');
898         lexer_->GetToken();
899         return nullptr;
900     }
901 
902     token = lexer_->PeekToken();
903     if (token != Token::ANGLE_BRACKETS_RIGHT) {
904         LogError(String("'>' is expected."));
905         return nullptr;
906     }
907     lexer_->GetToken();
908 
909     AutoPtr<ASTListType> list = new ASTListType();
910     list->SetElementType(type);
911 
912     AutoPtr<ASTType> ret = ast_->FindType(list->ToString());
913     if (ret == nullptr) {
914         ast_->AddType(list.Get());
915         ret = list.Get();
916     }
917 
918     return ret;
919 }
920 
ParseMap()921 AutoPtr<ASTType> Parser::ParseMap()
922 {
923     lexer_->GetToken();
924 
925     Token token = lexer_->PeekToken();
926     if (token != Token::ANGLE_BRACKETS_LEFT) {
927         LogError(String("'<' is expected."));
928         return nullptr;
929     }
930     lexer_->GetToken();
931 
932     AutoPtr<ASTType> keyType = ParseType();
933     if (keyType == nullptr) {
934         lexer_->SkipCurrentLine('>');
935         return nullptr;
936     }
937 
938     token = lexer_->PeekToken();
939     if (token != Token::COMMA) {
940         LogError(String("',' is expected."));
941         return nullptr;
942     }
943     lexer_->GetToken();
944 
945     AutoPtr<ASTType> valueType = ParseType();
946     if (valueType == nullptr) {
947         lexer_->SkipCurrentLine('>');
948         return nullptr;
949     }
950 
951     token = lexer_->PeekToken();
952     if (token != Token::ANGLE_BRACKETS_RIGHT) {
953         LogError(String("'>' is expected."));
954         return nullptr;
955     }
956     lexer_->GetToken();
957 
958     AutoPtr<ASTMapType> map = new ASTMapType();
959     map->SetKeyType(keyType);
960     map->SetValueType(valueType);
961 
962     AutoPtr<ASTType> ret = ast_->FindType(map->ToString());
963     if (ret == nullptr) {
964         ast_->AddType(map.Get());
965         ret = map.Get();
966     }
967 
968     return ret;
969 }
970 
ParseSharedMemQueueMetaType()971 AutoPtr<ASTType> Parser::ParseSharedMemQueueMetaType()
972 {
973     lexer_->GetToken();
974 
975     Token token = lexer_->PeekToken();
976     if (token != Token::ANGLE_BRACKETS_LEFT) {
977         LogError(String("'<' is expected."));
978         return nullptr;
979     }
980     lexer_->GetToken();
981 
982     AutoPtr<ASTType> InnerType = ParseType();
983     if (InnerType == nullptr) {
984         lexer_->SkipCurrentLine('>');
985         return nullptr;
986     }
987 
988     token = lexer_->PeekToken();
989     if (token != Token::ANGLE_BRACKETS_RIGHT) {
990         LogError(String("'>' is expected."));
991         return nullptr;
992     }
993     lexer_->GetToken();
994 
995     AutoPtr<ASTSmqType> type = new ASTSmqType();
996     type->SetInnerType(InnerType);
997     AutoPtr<ASTType> ret = ast_->FindType(type->ToString());
998     if (ret == nullptr) {
999         ast_->AddType(type.Get());
1000         ret = type.Get();
1001     }
1002 
1003     return ret;
1004 }
1005 
ParseArrayType(const AutoPtr<ASTType> & elementType)1006 AutoPtr<ASTType> Parser::ParseArrayType(const AutoPtr<ASTType>& elementType)
1007 {
1008     Token token = lexer_->PeekToken();
1009     if (token != Token::BRACKETS_RIGHT) {
1010         LogError(String("']' is expected."));
1011         return nullptr;
1012     }
1013     lexer_->GetToken();
1014 
1015     if (elementType == nullptr) {
1016         return nullptr;
1017     }
1018 
1019     AutoPtr<ASTArrayType> arrayType = new ASTArrayType();
1020     arrayType->SetElementType(elementType);
1021     AutoPtr<ASTType> type = ast_->FindType(arrayType->ToString());
1022 
1023     if (type == nullptr) {
1024         ast_->AddType(arrayType.Get());
1025         type = static_cast<ASTType*>(arrayType.Get());
1026     }
1027 
1028     return type;
1029 }
1030 
ParseCustomType()1031 AutoPtr<ASTType> Parser::ParseCustomType()
1032 {
1033     Token token = lexer_->GetToken();
1034     String typePrefix;
1035     if (token == Token::ENUM) {
1036         typePrefix = "enum";
1037     } else if (token == Token::STRUCT) {
1038         typePrefix = "struct";
1039     } else if (token == Token::UNION) {
1040         typePrefix = "union";
1041     }
1042 
1043     token = lexer_->PeekToken();
1044     if (token != Token::IDENTIFIER) {
1045         LogError(String("custom type name is expected."));
1046         return nullptr;
1047     }
1048 
1049     String typeName = typePrefix + " " + lexer_->GetIdentifier();
1050     lexer_->GetToken();
1051     AutoPtr<ASTType> type = ast_->FindType(typeName);
1052     if (type != nullptr) {
1053         ast_->AddType(type);
1054     }
1055 
1056     return type;
1057 }
1058 
ParseEnumDefine(const AutoPtr<Attribute> & attributes)1059 bool Parser::ParseEnumDefine(const AutoPtr<Attribute>& attributes)
1060 {
1061     lexer_->GetToken();
1062     AutoPtr<ASTEnumType> type = new ASTEnumType();
1063 
1064     Token token = lexer_->PeekToken();
1065     if (token != Token::IDENTIFIER) {
1066         LogError(String("custom enum type name is expected."));
1067         return false;
1068     }
1069     type->SetName(lexer_->GetIdentifier());
1070     lexer_->GetToken();
1071 
1072     if (!ParseEnumBaseType(type)) {
1073         return false;
1074     }
1075 
1076     token = lexer_->PeekToken();
1077     if (token != Token::BRACES_LEFT) {
1078         lexer_->SkipCurrentLine(';');
1079         return false;
1080     }
1081     lexer_->GetToken();
1082 
1083     if (!ParseEnumMember(type)) {
1084         return false;
1085     }
1086 
1087     token = lexer_->PeekToken();
1088     if (token != Token::SEMICOLON) {
1089         LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
1090         lexer_->SkipCurrentLine();
1091         return false;
1092     }
1093     lexer_->GetToken();
1094 
1095     if (attributes != nullptr) {
1096         type->SetFull(attributes->isFull);
1097         type->SetLite(attributes->isLite);
1098     }
1099 
1100     ast_->AddTypeDefinition(type.Get());
1101     return true;
1102 }
1103 
ParseEnumBaseType(const AutoPtr<ASTEnumType> & type)1104 bool Parser::ParseEnumBaseType(const AutoPtr<ASTEnumType>& type)
1105 {
1106     Token token = lexer_->PeekToken();
1107     if (token == Token::COLON) {
1108         lexer_->GetToken();
1109         AutoPtr<ASTType> baseType = ParseType();
1110         if (baseType == nullptr) {
1111             LogError("no base type of enum type");
1112             lexer_->SkipCurrentLine(';');
1113             return false;
1114         }
1115         if (baseType->IsByteType() ||
1116             baseType->IsShortType() ||
1117             baseType->IsIntegerType() ||
1118             baseType->IsLongType() ||
1119             baseType->IsUcharType() ||
1120             baseType->IsUshortType() ||
1121             baseType->IsUintType() ||
1122             baseType->IsUlongType()) {
1123             ast_->AddType(baseType);
1124             type->SetBaseType(baseType);
1125             type->SetDisplayBase(true);
1126         } else {
1127             LogError("invaild base type of enum type");
1128             lexer_->SkipCurrentLine(';');
1129             return false;
1130         }
1131     }
1132 
1133     if (type->GetBaseType() == nullptr) {
1134         AutoPtr<ASTType> baseType = ast_->FindType("int");
1135         if (baseType == nullptr) {
1136             ast_->AddType(new ASTIntegerType());
1137             baseType = ast_->FindType("int");
1138         }
1139         type->SetBaseType(baseType);
1140     }
1141     return true;
1142 }
1143 
ParseEnumMember(const AutoPtr<ASTEnumType> & type)1144 bool Parser::ParseEnumMember(const AutoPtr<ASTEnumType>& type)
1145 {
1146     Token token = lexer_->PeekToken();
1147     while (token != Token::BRACES_RIGHT) {
1148         if (token != Token::IDENTIFIER) {
1149             lexer_->SkipCurrentLine(';');
1150             return false;
1151         }
1152         AutoPtr<ASTEnumValue> enumValue = new ASTEnumValue(lexer_->GetIdentifier());
1153         lexer_->GetToken();
1154 
1155         token = lexer_->PeekToken();
1156         if (token == Token::ASSIGN) {
1157             lexer_->GetToken();
1158             token = lexer_->PeekToken();
1159             if (token == Token::DIGIT) {
1160                 enumValue->SetValue(lexer_->GetDigit());
1161                 lexer_->GetToken();
1162                 token = lexer_->PeekToken();
1163             } else {
1164                 return false;
1165             }
1166         }
1167 
1168         if (token == Token::COMMA) {
1169             lexer_->GetToken();
1170             token = lexer_->PeekToken();
1171         } else if (token == Token::BRACES_RIGHT) {
1172         } else {
1173             lexer_->SkipCurrentLine(';');
1174             return false;
1175         }
1176         enumValue->SetType(type->GetBaseType());
1177         type->AddMember(enumValue);
1178     }
1179     lexer_->GetToken();
1180     return true;
1181 }
1182 
ParseStructDefine(const AutoPtr<Attribute> & attributes)1183 bool Parser::ParseStructDefine(const AutoPtr<Attribute>& attributes)
1184 {
1185     lexer_->GetToken();
1186 
1187     AutoPtr<ASTStructType> type = new ASTStructType();
1188     if (type == nullptr) {
1189         lexer_->SkipCurrentLine(';');
1190         return false;
1191     }
1192 
1193     Token token = lexer_->PeekToken();
1194     if (token != Token::IDENTIFIER) {
1195         LogError(String("custom struct type name is expected."));
1196         return false;
1197     }
1198     type->SetName(lexer_->GetIdentifier());
1199     lexer_->GetToken();
1200 
1201     if (!ParseStructMember(type)) {
1202         return false;
1203     }
1204 
1205     if (attributes != nullptr) {
1206         type->SetFull(attributes->isFull);
1207         type->SetLite(attributes->isLite);
1208     }
1209 
1210     ast_->AddTypeDefinition(type.Get());
1211     return true;
1212 }
1213 
ParseStructMember(const AutoPtr<ASTStructType> & type)1214 bool Parser::ParseStructMember(const AutoPtr<ASTStructType>& type)
1215 {
1216     Token token = lexer_->PeekToken();
1217     if (token != Token::BRACES_LEFT) {
1218         lexer_->SkipCurrentLine(';');
1219         return false;
1220     }
1221     lexer_->GetToken();
1222 
1223     token = lexer_->PeekToken();
1224     while (token != Token::BRACES_RIGHT) {
1225         AutoPtr<ASTType> member = ParseType();
1226         if (member == nullptr) {
1227             lexer_->SkipCurrentLine(';');
1228             return false;
1229         }
1230         String typeName = member->ToString();
1231 
1232         token = lexer_->PeekToken();
1233         if (token != Token::IDENTIFIER) {
1234             LogError(String("member name is expected."));
1235             return false;
1236         }
1237         String memberName = lexer_->GetIdentifier();
1238         lexer_->GetToken();
1239         type->AddMember(member, memberName);
1240 
1241         token = lexer_->PeekToken();
1242         if (token == Token::SEMICOLON) {
1243             lexer_->GetToken();
1244             token = lexer_->PeekToken();
1245         } else if (token == Token::BRACES_RIGHT) {
1246             break;
1247         } else {
1248             lexer_->SkipCurrentLine(';');
1249             return false;
1250         }
1251     }
1252     lexer_->GetToken();
1253 
1254     token = lexer_->PeekToken();
1255     if (token != Token::SEMICOLON) {
1256         LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
1257         lexer_->SkipCurrentLine();
1258         return false;
1259     }
1260     lexer_->GetToken();
1261     return true;
1262 }
1263 
ParseUnionDefine(const AutoPtr<Attribute> & attributes)1264 bool Parser::ParseUnionDefine(const AutoPtr<Attribute>& attributes)
1265 {
1266     lexer_->GetToken();
1267 
1268     AutoPtr<ASTUnionType> type = new ASTUnionType();
1269     if (type == nullptr) {
1270         lexer_->SkipCurrentLine(';');
1271         return false;
1272     }
1273 
1274     Token token = lexer_->PeekToken();
1275     if (token != Token::IDENTIFIER) {
1276         LogError(String("custom union type name is expected."));
1277         return false;
1278     }
1279     type->SetName(lexer_->GetIdentifier());
1280     lexer_->GetToken();
1281 
1282     if (!ParseUnionMember(type)) {
1283         return false;
1284     }
1285 
1286     if (attributes != nullptr) {
1287         type->SetFull(attributes->isFull);
1288         type->SetLite(attributes->isLite);
1289     }
1290 
1291     ast_->AddTypeDefinition(type.Get());
1292     return true;
1293 }
1294 
ParseUnionMember(const AutoPtr<ASTUnionType> & type)1295 bool Parser::ParseUnionMember(const AutoPtr<ASTUnionType>& type)
1296 {
1297     Token token = lexer_->PeekToken();
1298     if (token != Token::BRACES_LEFT) {
1299         lexer_->SkipCurrentLine(';');
1300         return false;
1301     }
1302     lexer_->GetToken();
1303 
1304     token = lexer_->PeekToken();
1305     while (token != Token::BRACES_RIGHT) {
1306         AutoPtr<ASTType> member = ParseType();
1307         if (member == nullptr) {
1308             lexer_->SkipCurrentLine(';');
1309             return false;
1310         }
1311         String typeName = member->ToString();
1312 
1313         token = lexer_->PeekToken();
1314         if (token != Token::IDENTIFIER) {
1315             LogError(String("member name is expected."));
1316             return false;
1317         }
1318         String memberName = lexer_->GetIdentifier();
1319         lexer_->GetToken();
1320         type->AddMember(member, memberName);
1321 
1322         token = lexer_->PeekToken();
1323         if (token == Token::SEMICOLON) {
1324             lexer_->GetToken();
1325             token = lexer_->PeekToken();
1326         } else if (token == Token::BRACES_RIGHT) {
1327             break;
1328         } else {
1329             lexer_->SkipCurrentLine(';');
1330             return false;
1331         }
1332     }
1333     lexer_->GetToken();
1334 
1335     token = lexer_->PeekToken();
1336     if (token != Token::SEMICOLON) {
1337         LogError(String::Format("'%s' is not expected.", lexer_->DumpToken().string()));
1338         lexer_->SkipCurrentLine();
1339         return false;
1340     }
1341     lexer_->GetToken();
1342     return true;
1343 }
1344 
CheckType(int lineNo,int columnNo,const AutoPtr<ASTType> & type)1345 bool Parser::CheckType(int lineNo, int columnNo, const AutoPtr<ASTType>& type)
1346 {
1347     if (type == nullptr) {
1348         return false;
1349     }
1350 
1351     if (options_.GetTargetLanguage().Equals("c")) {
1352         if (type->IsSequenceableType()) {
1353             LogError(lineNo, columnNo, String::Format("The sequenceable type is not supported by c language."));
1354             return false;
1355         }
1356 
1357         if (options_.DoGenerateKernelCode()) {
1358             switch (type->GetTypeKind()) {
1359                 case TypeKind::TYPE_FLOAT:
1360                 case TypeKind::TYPE_DOUBLE:
1361                 case TypeKind::TYPE_FILEDESCRIPTOR:
1362                 case TypeKind::TYPE_INTERFACE:
1363                     LogError(lineNo, columnNo, String::Format("The '%s' type is not supported by c language.",
1364                         lexer_->DumpToken().string()));
1365                     break;
1366                 default:
1367                     break;
1368             }
1369         }
1370     } else if (options_.GetTargetLanguage().Equals("java")) {
1371         switch (type->GetTypeKind()) {
1372             case TypeKind::TYPE_UCHAR:
1373             case TypeKind::TYPE_USHORT:
1374             case TypeKind::TYPE_UINT:
1375             case TypeKind::TYPE_ULONG:
1376             case TypeKind::TYPE_ENUM:
1377             case TypeKind::TYPE_STRUCT:
1378             case TypeKind::TYPE_UNION:
1379             case TypeKind::TYPE_UNKNOWN:
1380                 LogError(lineNo, columnNo, String::Format("The '%s' type is not supported by java language.",
1381                     lexer_->DumpToken().string()));
1382                 return false;
1383             default:
1384                 break;
1385         }
1386     }
1387 
1388     return true;
1389 }
1390 
SetAstFileType()1391 void Parser::SetAstFileType()
1392 {
1393     if (ast_->GetInterfaceDef() != nullptr) {
1394         if (ast_->GetInterfaceDef()->IsCallback()) {
1395             ast_->SetAStFileType(ASTFileType::AST_ICALLBACK);
1396         } else {
1397             ast_->SetAStFileType(ASTFileType::AST_IFACE);
1398         }
1399     } else {
1400         ast_->SetAStFileType(ASTFileType::AST_TYPES);
1401     }
1402 }
1403 
CheckIntegrity()1404 bool Parser::CheckIntegrity()
1405 {
1406     if (ast_ == nullptr) {
1407         LogError(String("ast is nullptr."));
1408         return false;
1409     }
1410 
1411     if (ast_->GetName().IsEmpty()) {
1412         LogError(String("ast's name is empty."));
1413         return false;
1414     }
1415 
1416     if (ast_->GetPackageName().IsEmpty()) {
1417         LogError(String("ast's package name is empty."));
1418         return false;
1419     }
1420 
1421     switch (ast_->GetASTFileType()) {
1422         case ASTFileType::AST_IFACE: {
1423             return CheckInterfaceAst();
1424         }
1425         case ASTFileType::AST_ICALLBACK: {
1426             return CheckCallbackAst();
1427         }
1428         case ASTFileType::AST_SEQUENCEABLE: {
1429             LogError(String("it's impossible that ast is sequenceable."));
1430             return false;
1431         }
1432         case ASTFileType::AST_TYPES: {
1433             if (ast_->GetInterfaceDef() != nullptr) {
1434                 LogError(String("custom ast cannot has interface."));
1435                 return false;
1436             }
1437             break;
1438         }
1439         default:
1440             break;
1441     }
1442 
1443     return true;
1444 }
1445 
CheckInterfaceAst()1446 bool Parser::CheckInterfaceAst()
1447 {
1448     AutoPtr<ASTInterfaceType> interface = ast_->GetInterfaceDef();
1449     if (interface == nullptr) {
1450         LogError(String("ast's interface is empty."));
1451         return false;
1452     }
1453 
1454     if (ast_->GetTypeDefinitionNumber() > 0) {
1455         LogError(String("interface ast cannot has custom types."));
1456         return false;
1457     }
1458 
1459     if (interface->GetMethodNumber() == 0) {
1460         LogError(String("interface ast has no method."));
1461         return false;
1462     }
1463     return true;
1464 }
1465 
CheckCallbackAst()1466 bool Parser::CheckCallbackAst()
1467 {
1468     AutoPtr<ASTInterfaceType> interface = ast_->GetInterfaceDef();
1469     if (interface == nullptr) {
1470         LogError(String("ast's interface is empty."));
1471         return false;
1472     }
1473 
1474     if (!interface->IsCallback()) {
1475         LogError(String("ast is callback, but ast's interface is not callback."));
1476         return false;
1477     }
1478     return true;
1479 }
1480 
IsValidTypeName(const String & typeName)1481 bool Parser::IsValidTypeName(const String& typeName)
1482 {
1483     if (typeName[0] == '.') {
1484         return false;
1485     }
1486 
1487     if (typeName[typeName.GetLength() - 1] == '.') {
1488         return false;
1489     }
1490 
1491     return true;
1492 }
1493 
1494 /*
1495 * For example
1496 * filePath: ./ohos/interface/foo/v1_0/IFoo.idl
1497 * package OHOS.Hdi.foo.v1_0;
1498 */
CheckPackageName(const String & filePath,const String & packageName)1499 bool Parser::CheckPackageName(const String& filePath, const String& packageName)
1500 {
1501     String pkgToPath = Options::GetInstance().GetPackagePath(packageName);
1502 
1503     int index = filePath.LastIndexOf(File::pathSeparator);
1504     if (index == -1) {
1505         return false;
1506     }
1507 
1508     String parentDir = filePath.Substring(0, index);
1509     if (parentDir.IndexOf(pkgToPath) == -1) {
1510         return false;
1511     }
1512 
1513     return parentDir.EndsWith(pkgToPath);
1514 }
1515 
AddAst()1516 bool Parser::AddAst()
1517 {
1518     if (ast_ == nullptr) {
1519         LogError(String("ast is nullptr."));
1520         return false;
1521     }
1522     astModule_->AddAST(ast_->GetFullName(), ast_);
1523     return true;
1524 }
1525 
LogError(const String & message)1526 void Parser::LogError(const String& message)
1527 {
1528     AutoPtr<ErrorInfo> error = new ErrorInfo();
1529 
1530     String sourceFile = lexer_->GetFilePath();
1531 #ifdef __MINGW32__
1532     error->file_ = sourceFile.Substring(sourceFile.LastIndexOf('\\') + 1);
1533 #else
1534     error->file_ = sourceFile.Substring(sourceFile.LastIndexOf('/') + 1);
1535 #endif
1536     error->lineNo_ = lexer_->GetTokenLineNumber();
1537     error->columnNo_ = lexer_->GetTokenColumnNumber();
1538     error->message_ = message;
1539 
1540     if (errors_ == nullptr) {
1541         errors_ = error;
1542     } else {
1543         AutoPtr<ErrorInfo> pos = errors_;
1544         while (pos->next_ != nullptr) {
1545             pos = pos->next_;
1546         }
1547         pos->next_ = error;
1548     }
1549 }
1550 
LogError(int lineNo,int columnNo,const String & message)1551 void Parser::LogError(int lineNo, int columnNo, const String& message)
1552 {
1553     AutoPtr<ErrorInfo> error = new ErrorInfo();
1554 
1555     String sourceFile = lexer_->GetFilePath();
1556 #ifdef __MINGW32__
1557     error->file_ = sourceFile.Substring(sourceFile.LastIndexOf('\\') + 1);
1558 #else
1559     error->file_ = sourceFile.Substring(sourceFile.LastIndexOf('/') + 1);
1560 #endif
1561     error->lineNo_ = lineNo;
1562     error->columnNo_ = columnNo;
1563     error->message_ = message;
1564 
1565     if (errors_ == nullptr) {
1566         errors_ = error;
1567     } else {
1568         AutoPtr<ErrorInfo> pos = errors_;
1569         while (pos->next_ != nullptr) {
1570             pos = pos->next_;
1571         }
1572         pos->next_ = error;
1573     }
1574 }
1575 
ShowError()1576 void Parser::ShowError()
1577 {
1578     AutoPtr<ErrorInfo> error = errors_;
1579     while (error != nullptr) {
1580         Logger::E(TAG, "%s[line %d, column %d] %s", error->file_.string(),
1581             error->lineNo_, error->columnNo_, error->message_.string());
1582         error = error->next_;
1583     }
1584 }
1585 } // namespace HDI
1586 } // namespace OHOS