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