• 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 "codegen/cpp_interface_code_emitter.h"
10 #include "util/file.h"
11 #include "util/logger.h"
12 
13 namespace OHOS {
14 namespace HDI {
ResolveDirectory(const std::string & targetDirectory)15 bool CppInterfaceCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
16 {
17     if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
18         directory_ = GetFileParentPath(targetDirectory);
19     } else {
20         return false;
21     }
22 
23     if (!File::CreateParentDir(directory_)) {
24         Logger::E("CppInterfaceCodeEmitter", "Create '%s' failed!", directory_.c_str());
25         return false;
26     }
27 
28     return true;
29 }
30 
EmitCode()31 void CppInterfaceCodeEmitter::EmitCode()
32 {
33     switch (mode_) {
34         case GenMode::PASSTHROUGH:
35         case GenMode::IPC: {
36             EmitInterfaceHeaderFile();
37             break;
38         }
39         default:
40             break;
41     }
42 }
43 
EmitInterfaceHeaderFile()44 void CppInterfaceCodeEmitter::EmitInterfaceHeaderFile()
45 {
46     std::string filePath =
47         File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(interfaceName_).c_str()));
48     File file(filePath, File::WRITE);
49     StringBuilder sb;
50 
51     EmitLicense(sb);
52     EmitHeadMacro(sb, interfaceFullName_);
53     sb.Append("\n");
54     EmitInterfaceInclusions(sb);
55     if (!Options::GetInstance().DoPassthrough()) {
56         sb.Append("\n");
57         EmitInterfaceBuffSizeMacro(sb);
58     }
59     sb.Append("\n");
60     EmitBeginNamespace(sb);
61     EmitUsingNamespace(sb);
62     if (!Options::GetInstance().DoPassthrough()) {
63         sb.Append("\n");
64         if (interface_->GetExtendsInterface() == nullptr) {
65             EmitInterfaceMethodCommands(sb, "");
66         } else {
67             EmitInterfaceMethodCommandsWithExtends(sb, "");
68         }
69     }
70     sb.Append("\n");
71     EmitInterfaceDefinition(sb);
72     EmitEndNamespace(sb);
73     sb.Append("\n");
74     EmitTailMacro(sb, interfaceFullName_);
75 
76     std::string data = sb.ToString();
77     file.WriteData(data.c_str(), data.size());
78     file.Flush();
79     file.Close();
80 }
81 
EmitInterfaceInclusions(StringBuilder & sb)82 void CppInterfaceCodeEmitter::EmitInterfaceInclusions(StringBuilder &sb)
83 {
84     HeaderFile::HeaderFileSet headerFiles;
85 
86     GetStdlibInclusions(headerFiles);
87     GetImportInclusions(headerFiles);
88     GetHeaderOtherLibInclusions(headerFiles);
89 
90     for (const auto &file : headerFiles) {
91         sb.AppendFormat("%s\n", file.ToString().c_str());
92     }
93 }
94 
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const95 void CppInterfaceCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
96 {
97     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
98     headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdint");
99     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_base");
100     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
101 }
102 
EmitInterfaceVersionMacro(StringBuilder & sb) const103 void CppInterfaceCodeEmitter::EmitInterfaceVersionMacro(StringBuilder &sb) const
104 {
105     sb.AppendFormat("#define %s %u\n", majorVerName_.c_str(), ast_->GetMajorVer());
106     sb.AppendFormat("#define %s %u\n", minorVerName_.c_str(), ast_->GetMinorVer());
107 }
108 
EmitInterfaceDefinition(StringBuilder & sb)109 void CppInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder &sb)
110 {
111     AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
112     if (interface != nullptr) {
113         sb.AppendFormat("class %s : public %s {\n", interfaceName_.c_str(),
114             EmitDefinitionByInterface(interface, interfaceName_).c_str());
115     } else {
116         sb.AppendFormat("class %s : public HdiBase {\n", interfaceName_.c_str());
117     }
118     sb.Append("public:\n");
119     EmitInterfaceDescriptor(sb, TAB);
120     sb.Append("\n");
121     EmitInterfaceDestruction(sb, TAB);
122     sb.Append("\n");
123     if (!interface_->IsSerializable()) {
124         EmitGetMethodDecl(sb, TAB);
125         sb.Append("\n");
126     }
127     EmitInterfaceMethodsDecl(sb, TAB);
128     sb.Append("\n");
129     EmitGetDescMethod(sb, TAB);
130     sb.Append("};\n");
131 }
132 
EmitGetDescMethod(StringBuilder & sb,const std::string & prefix) const133 void CppInterfaceCodeEmitter::EmitGetDescMethod(StringBuilder &sb, const std::string &prefix) const
134 {
135     AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
136     if (interface == nullptr) {
137         sb.Append(prefix).Append("virtual const std::u16string GetDesc()");
138     } else {
139         sb.Append(prefix).Append("const std::u16string GetDesc() override");
140     }
141     sb.Append("\n");
142     sb.Append(prefix).Append("{").Append("\n");
143     sb.Append(prefix + TAB).Append("return metaDescriptor_;\n");
144     sb.Append(prefix).Append("}\n");
145 }
146 
EmitInterfaceDescriptor(StringBuilder & sb,const std::string & prefix) const147 void CppInterfaceCodeEmitter::EmitInterfaceDescriptor(StringBuilder &sb, const std::string &prefix) const
148 {
149     (void)prefix;
150     sb.Append(TAB).AppendFormat("DECLARE_HDI_DESCRIPTOR(u\"%s\");\n", interfaceFullName_.c_str());
151 }
152 
EmitGetMethodDecl(StringBuilder & sb,const std::string & prefix) const153 void CppInterfaceCodeEmitter::EmitGetMethodDecl(StringBuilder &sb, const std::string &prefix) const
154 {
155     sb.Append(prefix).AppendFormat("static %s Get(bool isStub = false);\n", interface_->EmitCppType().c_str());
156     sb.Append(prefix).AppendFormat(
157         "static %s Get(const std::string &serviceName, bool isStub = false);\n", interface_->EmitCppType().c_str());
158 }
159 
EmitInterfaceDestruction(StringBuilder & sb,const std::string & prefix) const160 void CppInterfaceCodeEmitter::EmitInterfaceDestruction(StringBuilder &sb, const std::string &prefix) const
161 {
162     sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", interface_->GetName().c_str());
163 }
164 
EmitInterfaceMethodsDecl(StringBuilder & sb,const std::string & prefix)165 void CppInterfaceCodeEmitter::EmitInterfaceMethodsDecl(StringBuilder &sb, const std::string &prefix)
166 {
167     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
168         EmitInterfaceMethodDecl(method, sb, prefix);
169         sb.Append("\n");
170     }
171 
172     EmitInterfaceGetVersionMethod(sb, prefix);
173 }
174 
EmitInterfaceMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const175 void CppInterfaceCodeEmitter::EmitInterfaceMethodDecl(
176     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
177 {
178     if (method->GetParameterNumber() == 0) {
179         sb.Append(prefix).AppendFormat("virtual int32_t %s() = 0;\n", method->GetName().c_str());
180     } else {
181         StringBuilder paramStr;
182         paramStr.Append(prefix).AppendFormat("virtual int32_t %s(", method->GetName().c_str());
183         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
184             AutoPtr<ASTParameter> param = method->GetParameter(i);
185             EmitInterfaceMethodParameter(param, paramStr, "");
186             if (i + 1 < method->GetParameterNumber()) {
187                 paramStr.Append(", ");
188             }
189         }
190 
191         paramStr.Append(") = 0;");
192         sb.Append(SpecificationParam(paramStr, prefix + TAB));
193         sb.Append("\n");
194     }
195 }
196 
EmitInterfaceGetVersionMethod(StringBuilder & sb,const std::string & prefix) const197 void CppInterfaceCodeEmitter::EmitInterfaceGetVersionMethod(StringBuilder &sb, const std::string &prefix) const
198 {
199     AutoPtr<ASTMethod> method = interface_->GetVersionMethod();
200     if (interface_->GetExtendsInterface() == nullptr) {
201         sb.Append(prefix).AppendFormat("virtual int32_t %s(", method->GetName().c_str());
202     } else {
203         sb.Append(prefix).AppendFormat("int32_t %s(", method->GetName().c_str());
204     }
205     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
206         AutoPtr<ASTParameter> param = method->GetParameter(i);
207         EmitInterfaceMethodParameter(param, sb, "");
208         if (i + 1 < method->GetParameterNumber()) {
209             sb.Append(", ");
210         }
211     }
212     sb.Append(")");
213     if (interface_->GetExtendsInterface() != nullptr) {
214         sb.Append(" override");
215     }
216     sb.Append("\n");
217     sb.Append(prefix).Append("{\n");
218 
219     AutoPtr<ASTParameter> majorParam = method->GetParameter(0);
220     sb.Append(prefix + TAB).AppendFormat("%s = %d;\n", majorParam->GetName().c_str(), ast_->GetMajorVer());
221     AutoPtr<ASTParameter> minorParam = method->GetParameter(1);
222     sb.Append(prefix + TAB).AppendFormat("%s = %d;\n", minorParam->GetName().c_str(), ast_->GetMinorVer());
223 
224     sb.Append(prefix + TAB).Append("return HDF_SUCCESS;\n");
225     sb.Append(prefix).Append("}\n");
226 }
227 
EmitInterfaceMethodParameter(const AutoPtr<ASTParameter> & param,StringBuilder & sb,const std::string & prefix) const228 void CppInterfaceCodeEmitter::EmitInterfaceMethodParameter(
229     const AutoPtr<ASTParameter> &param, StringBuilder &sb, const std::string &prefix) const
230 {
231     sb.Append(prefix).Append(param->EmitCppParameter());
232 }
233 
EmitInterfaceMethodCommandsWithExtends(StringBuilder & sb,const std::string & prefix)234 void CppInterfaceCodeEmitter::EmitInterfaceMethodCommandsWithExtends(StringBuilder &sb, const std::string &prefix)
235 {
236     size_t extendMethods = 0;
237     AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
238     while (interface != nullptr) {
239         extendMethods += interface->GetMethodNumber();
240         interface = interface->GetExtendsInterface();
241     }
242 
243     sb.Append(prefix).AppendFormat("enum {\n");
244     for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
245         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
246         sb.Append(prefix + TAB)
247             .Append(EmitMethodCmdID(method))
248             .AppendFormat(" = %d", extendMethods + i + 1)
249             .Append(",\n");
250     }
251     sb.Append(prefix).Append("};\n");
252 }
253 } // namespace HDI
254 } // namespace OHOS