• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "cpp_interface_code_emitter.h"
17 #include "util/file.h"
18 #include "util/logger.h"
19 
20 namespace OHOS {
21 namespace Idl {
ResolveDirectory(const std::string & targetDirectory)22 bool CppInterfaceCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
23 {
24     if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
25         directory_ = GetFileParentPath(targetDirectory);
26     } else {
27         return false;
28     }
29 
30     if (!File::CreateParentDir(directory_)) {
31         Logger::E("CppInterfaceCodeEmitter", "Create '%s' failed!", directory_.c_str());
32         return false;
33     }
34 
35     return true;
36 }
37 
EmitCode()38 void CppInterfaceCodeEmitter::EmitCode()
39 {
40     switch (mode_) {
41         case GenMode::PASSTHROUGH:
42         case GenMode::IPC: {
43             EmitInterfaceHeaderFile();
44             break;
45         }
46         default:
47             break;
48     }
49 }
50 
EmitInterfaceHeaderFile()51 void CppInterfaceCodeEmitter::EmitInterfaceHeaderFile()
52 {
53     std::string filePath =
54         File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(interfaceName_).c_str()));
55     File file(filePath, File::WRITE);
56     StringBuilder sb;
57 
58     EmitLicense(sb);
59     EmitHeadMacro(sb, interfaceFullName_);
60     sb.Append("\n");
61     EmitInterfaceInclusions(sb);
62     if (!Options::GetInstance().DoPassthrough()) {
63         sb.Append("\n");
64         EmitInterfaceBuffSizeMacro(sb);
65     }
66     sb.Append("\n");
67     EmitBeginNamespace(sb);
68     EmitUsingNamespace(sb);
69     if (!Options::GetInstance().DoPassthrough()) {
70         sb.Append("\n");
71         if (interface_->GetExtendsInterface() == nullptr) {
72             EmitInterfaceMethodCommands(sb, "");
73         } else {
74             EmitInterfaceMethodCommandsWithExtends(sb, "");
75         }
76     }
77     sb.Append("\n");
78     EmitInterfaceDefinition(sb);
79     EmitEndNamespace(sb);
80     sb.Append("\n");
81     EmitTailMacro(sb, interfaceFullName_);
82 
83     std::string data = sb.ToString();
84     file.WriteData(data.c_str(), data.size());
85     file.Flush();
86     file.Close();
87 }
88 
EmitInterfaceInclusions(StringBuilder & sb)89 void CppInterfaceCodeEmitter::EmitInterfaceInclusions(StringBuilder &sb)
90 {
91     HeaderFile::HeaderFileSet headerFiles;
92 
93     GetStdlibInclusions(headerFiles);
94     GetImportInclusions(headerFiles);
95     GetHeaderOtherLibInclusions(headerFiles);
96 
97     for (const auto &file : headerFiles) {
98         sb.AppendFormat("%s\n", file.ToString().c_str());
99     }
100 }
101 
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const102 void CppInterfaceCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
103 {
104     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
105     headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "stdint");
106     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_base");
107     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
108 }
109 
EmitInterfaceVersionMacro(StringBuilder & sb) const110 void CppInterfaceCodeEmitter::EmitInterfaceVersionMacro(StringBuilder &sb) const
111 {
112     sb.AppendFormat("#define %s %u\n", majorVerName_.c_str(), ast_->GetMajorVer());
113     sb.AppendFormat("#define %s %u\n", minorVerName_.c_str(), ast_->GetMinorVer());
114 }
115 
EmitInterfaceDefinition(StringBuilder & sb)116 void CppInterfaceCodeEmitter::EmitInterfaceDefinition(StringBuilder &sb)
117 {
118     AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
119     if (interface != nullptr) {
120         sb.AppendFormat("class %s : public %s {\n", interfaceName_.c_str(),
121             EmitDefinitionByInterface(interface, interfaceName_).c_str());
122     } else {
123         sb.AppendFormat("class %s : public HdiBase {\n", interfaceName_.c_str());
124     }
125     sb.Append("public:\n");
126     EmitInterfaceDescriptor(sb, TAB);
127     sb.Append("\n");
128     EmitInterfaceDestruction(sb, TAB);
129     sb.Append("\n");
130     if (!interface_->IsSerializable()) {
131         EmitGetMethodDecl(sb, TAB);
132         sb.Append("\n");
133     }
134     if (interface_->GetExtendsInterface() != nullptr) {
135         EmitCastFromDecl(sb, TAB);
136         sb.Append("\n");
137     }
138     EmitInterfaceMethodsDecl(sb, TAB);
139     sb.Append("\n");
140     EmitGetDescMethod(sb, TAB);
141     sb.Append("};\n");
142 }
143 
EmitGetDescMethod(StringBuilder & sb,const std::string & prefix) const144 void CppInterfaceCodeEmitter::EmitGetDescMethod(StringBuilder &sb, const std::string &prefix) const
145 {
146     AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
147     if (interface == nullptr) {
148         sb.Append(prefix).Append("virtual const std::u16string GetDesc()");
149     } else {
150         sb.Append(prefix).Append("const std::u16string GetDesc() override");
151     }
152     sb.Append("\n");
153     sb.Append(prefix).Append("{").Append("\n");
154     sb.Append(prefix + TAB).Append("return metaDescriptor_;\n");
155     sb.Append(prefix).Append("}\n");
156 }
157 
EmitInterfaceDescriptor(StringBuilder & sb,const std::string & prefix) const158 void CppInterfaceCodeEmitter::EmitInterfaceDescriptor(StringBuilder &sb, const std::string &prefix) const
159 {
160     (void)prefix;
161     sb.Append(TAB).AppendFormat("DECLARE_HDI_DESCRIPTOR(u\"%s\");\n", interfaceFullName_.c_str());
162 }
163 
EmitCastFromDecl(StringBuilder & sb,const std::string & prefix) const164 void CppInterfaceCodeEmitter::EmitCastFromDecl(StringBuilder &sb, const std::string &prefix) const
165 {
166     std::string currentInterface = EmitDefinitionByInterface(interface_, interfaceName_);
167 
168     AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
169     while (interface != nullptr) {
170         std::string parentInterface = EmitDefinitionByInterface(interface, interfaceName_);
171         sb.Append(prefix).AppendFormat("static sptr<%s> CastFrom(const sptr<%s> &parent);\n",
172             currentInterface.c_str(), parentInterface.c_str());
173         interface = interface->GetExtendsInterface();
174     }
175 }
176 
EmitGetMethodDecl(StringBuilder & sb,const std::string & prefix) const177 void CppInterfaceCodeEmitter::EmitGetMethodDecl(StringBuilder &sb, const std::string &prefix) const
178 {
179     AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(interface_.Get());
180     if (typeEmitter == nullptr) {
181         return;
182     }
183     std::string typeName = typeEmitter->EmitCppType();
184     sb.Append(prefix).AppendFormat("static %s Get(bool isStub = false);\n", typeName.c_str());
185     sb.Append(prefix).AppendFormat("static %s Get(const std::string &serviceName, bool isStub = false);\n",
186         typeName.c_str());
187 }
188 
EmitInterfaceDestruction(StringBuilder & sb,const std::string & prefix) const189 void CppInterfaceCodeEmitter::EmitInterfaceDestruction(StringBuilder &sb, const std::string &prefix) const
190 {
191     sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", interface_->GetName().c_str());
192 }
193 
EmitInterfaceMethodsDecl(StringBuilder & sb,const std::string & prefix)194 void CppInterfaceCodeEmitter::EmitInterfaceMethodsDecl(StringBuilder &sb, const std::string &prefix)
195 {
196     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
197         EmitInterfaceMethodDecl(method, sb, prefix);
198         sb.Append("\n");
199     }
200 
201     EmitInterfaceGetVersionMethod(sb, prefix);
202     if (interface_->GetExtendsInterface() == nullptr) {
203         sb.Append("\n");
204         EmitInterfaceIsProxyMethod(sb, prefix);
205     }
206 }
207 
EmitInterfaceMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const208 void CppInterfaceCodeEmitter::EmitInterfaceMethodDecl(
209     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
210 {
211     if (interface_->GetExtendsInterface() != nullptr && method->IsOverload()) {
212         sb.Append(prefix).AppendFormat("using %s::%s;\n",
213             EmitDefinitionByInterface(interface_->GetExtendsInterface(), interfaceName_).c_str(),
214             method->GetName().c_str());
215     }
216 
217     if (method->GetParameterNumber() == 0) {
218         sb.Append(prefix).AppendFormat("virtual int32_t %s() = 0;\n", method->GetName().c_str());
219     } else {
220         StringBuilder paramStr;
221         paramStr.Append(prefix).AppendFormat("virtual int32_t %s(", method->GetName().c_str());
222         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
223             AutoPtr<ASTParameter> param = method->GetParameter(i);
224             EmitInterfaceMethodParameter(param, paramStr, "");
225             if (i + 1 < method->GetParameterNumber()) {
226                 paramStr.Append(", ");
227             }
228         }
229 
230         paramStr.Append(") = 0;");
231         sb.Append(SpecificationParam(paramStr, prefix + TAB));
232         sb.Append("\n");
233     }
234 }
235 
EmitInterfaceGetVersionMethod(StringBuilder & sb,const std::string & prefix) const236 void CppInterfaceCodeEmitter::EmitInterfaceGetVersionMethod(StringBuilder &sb, const std::string &prefix) const
237 {
238     AutoPtr<ASTMethod> method = interface_->GetVersionMethod();
239     if (interface_->GetExtendsInterface() == nullptr) {
240         sb.Append(prefix).AppendFormat("virtual int32_t %s(", method->GetName().c_str());
241     } else {
242         sb.Append(prefix).AppendFormat("int32_t %s(", method->GetName().c_str());
243     }
244     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
245         AutoPtr<ASTParameter> param = method->GetParameter(i);
246         EmitInterfaceMethodParameter(param, sb, "");
247         if (i + 1 < method->GetParameterNumber()) {
248             sb.Append(", ");
249         }
250     }
251     sb.Append(")");
252     if (interface_->GetExtendsInterface() != nullptr) {
253         sb.Append(" override");
254     }
255     sb.Append("\n");
256     sb.Append(prefix).Append("{\n");
257 
258     AutoPtr<ASTParameter> majorParam = method->GetParameter(0);
259     sb.Append(prefix + TAB).AppendFormat("%s = %d;\n", majorParam->GetName().c_str(), ast_->GetMajorVer());
260     AutoPtr<ASTParameter> minorParam = method->GetParameter(1);
261     sb.Append(prefix + TAB).AppendFormat("%s = %d;\n", minorParam->GetName().c_str(), ast_->GetMinorVer());
262 
263     sb.Append(prefix + TAB).Append("return HDF_SUCCESS;\n");
264     sb.Append(prefix).Append("}\n");
265 }
266 
EmitInterfaceIsProxyMethod(StringBuilder & sb,const std::string & prefix) const267 void CppInterfaceCodeEmitter::EmitInterfaceIsProxyMethod(StringBuilder &sb, const std::string &prefix) const
268 {
269     sb.Append(prefix).AppendFormat("virtual bool %s(", "IsProxy");
270     sb.Append(")\n");
271     sb.Append(prefix).Append("{\n");
272     sb.Append(prefix + TAB).Append("return false;\n");
273     sb.Append(prefix).Append("}\n");
274 }
275 
EmitInterfaceMethodCommandsWithExtends(StringBuilder & sb,const std::string & prefix)276 void CppInterfaceCodeEmitter::EmitInterfaceMethodCommandsWithExtends(StringBuilder &sb, const std::string &prefix)
277 {
278     size_t extendMethods = 0;
279     AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
280     while (interface != nullptr) {
281         extendMethods += interface->GetMethodNumber();
282         interface = interface->GetExtendsInterface();
283     }
284 
285     sb.Append(prefix).AppendFormat("enum {\n");
286     for (size_t i = 0; i < interface_->GetMethodNumber(); i++) {
287         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
288         sb.Append(prefix + TAB)
289             .Append(EmitMethodCmdID(method))
290             .AppendFormat(" = %d", extendMethods + i + 1)
291             .Append(",\n");
292     }
293     sb.Append(prefix).Append("};\n");
294 }
295 } // namespace Idl
296 } // namespace OHOS