• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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_client_proxy_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 CppClientProxyCodeEmitter::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("CppClientProxyCodeEmitter", "Create '%s' failed!", directory_.c_str());
25         return false;
26     }
27 
28     return true;
29 }
30 
EmitCode()31 void CppClientProxyCodeEmitter::EmitCode()
32 {
33     switch (mode_) {
34         case GenMode::PASSTHROUGH: {
35             if (!interface_->IsSerializable()) {
36                 EmitPassthroughProxySourceFile();
37             }
38             break;
39         }
40         case GenMode::IPC: {
41             EmitProxyHeaderFile();
42             EmitProxySourceFile();
43         }
44         default:
45             break;
46     }
47 }
48 
EmitProxyHeaderFile()49 void CppClientProxyCodeEmitter::EmitProxyHeaderFile()
50 {
51     std::string filePath =
52         File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_ + "Proxy").c_str()));
53     File file(filePath, File::WRITE);
54     StringBuilder sb;
55 
56     EmitLicense(sb);
57     EmitHeadMacro(sb, proxyFullName_);
58     sb.Append("\n");
59     EmitProxyHeaderInclusions(sb);
60     sb.Append("\n");
61     EmitBeginNamespace(sb);
62     sb.Append("\n");
63     EmitProxyDecl(sb, "");
64     sb.Append("\n");
65     EmitEndNamespace(sb);
66     sb.Append("\n");
67     EmitTailMacro(sb, proxyFullName_);
68 
69     std::string data = sb.ToString();
70     file.WriteData(data.c_str(), data.size());
71     file.Flush();
72     file.Close();
73 }
74 
EmitProxyHeaderInclusions(StringBuilder & sb)75 void CppClientProxyCodeEmitter::EmitProxyHeaderInclusions(StringBuilder &sb)
76 {
77     HeaderFile::HeaderFileSet headerFiles;
78 
79     headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
80     if (interface_->GetExtendsInterface() != nullptr) {
81         headerFiles.emplace(
82             HeaderFileType::OWN_HEADER_FILE, EmitHeaderNameByInterface(interface_->GetExtendsInterface(), proxyName_));
83     }
84     GetHeaderOtherLibInclusions(headerFiles);
85 
86     for (const auto &file : headerFiles) {
87         sb.AppendFormat("%s\n", file.ToString().c_str());
88     }
89 }
90 
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const91 void CppClientProxyCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
92 {
93     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
94 }
95 
EmitProxyDecl(StringBuilder & sb,const std::string & prefix)96 void CppClientProxyCodeEmitter::EmitProxyDecl(StringBuilder &sb, const std::string &prefix)
97 {
98     (void)prefix;
99     sb.AppendFormat("class %s : public IProxyBroker<%s> {\n", proxyName_.c_str(),
100         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
101     sb.Append("public:\n");
102     EmitProxyConstructor(sb, TAB);
103     sb.Append("\n");
104     EmitProxyMethodDecls(sb, TAB);
105     sb.Append("\n");
106     sb.Append("private:\n");
107     EmitProxyConstants(sb, TAB);
108     sb.Append("};\n");
109 }
110 
EmitProxyConstructor(StringBuilder & sb,const std::string & prefix) const111 void CppClientProxyCodeEmitter::EmitProxyConstructor(StringBuilder &sb, const std::string &prefix) const
112 {
113     sb.Append(prefix).AppendFormat("explicit %s(const sptr<IRemoteObject>& remote)", proxyName_.c_str());
114     sb.AppendFormat(
115         " : IProxyBroker<%s>(remote) {}\n\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
116     sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", proxyName_.c_str());
117 }
118 
EmitProxyMethodDecls(StringBuilder & sb,const std::string & prefix) const119 void CppClientProxyCodeEmitter::EmitProxyMethodDecls(StringBuilder &sb, const std::string &prefix) const
120 {
121     AutoPtr<ASTInterfaceType> interface = interface_;
122     while (interface != nullptr) {
123         for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
124             EmitProxyMethodDecl(method, sb, prefix);
125             sb.Append("\n");
126         }
127         interface = interface->GetExtendsInterface();
128     }
129     EmitProxyMethodDecl(interface_->GetVersionMethod(), sb, prefix);
130     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
131         sb.Append("\n");
132         EmitProxyStaticMethodDecl(method, sb, prefix);
133     }
134     if (interface_->GetExtendsInterface() == nullptr) {
135         sb.Append("\n");
136         EmitProxyStaticMethodDecl(interface_->GetVersionMethod(), sb, prefix);
137     }
138 }
139 
EmitProxyMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const140 void CppClientProxyCodeEmitter::EmitProxyMethodDecl(
141     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
142 {
143     if (method->GetParameterNumber() == 0) {
144         sb.Append(prefix).AppendFormat("int32_t %s() override;\n", method->GetName().c_str());
145     } else {
146         StringBuilder paramStr;
147         paramStr.Append(prefix).AppendFormat("int32_t %s(", method->GetName().c_str());
148 
149         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
150             AutoPtr<ASTParameter> param = method->GetParameter(i);
151             EmitProxyMethodParameter(param, paramStr, "");
152             if (i + 1 < method->GetParameterNumber()) {
153                 paramStr.Append(", ");
154             }
155         }
156 
157         paramStr.Append(") override;");
158 
159         sb.Append(SpecificationParam(paramStr, prefix + TAB));
160         sb.Append("\n");
161     }
162 }
163 
EmitProxyStaticMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const164 void CppClientProxyCodeEmitter::EmitProxyStaticMethodDecl(
165     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
166 {
167     if (method->GetParameterNumber() == 0) {
168         sb.Append(prefix).AppendFormat(
169             "static int32_t %s_(const sptr<IRemoteObject> remote);\n", method->GetName().c_str());
170     } else {
171         StringBuilder paramStr;
172         paramStr.Append(prefix).AppendFormat("static int32_t %s_(", method->GetName().c_str());
173 
174         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
175             AutoPtr<ASTParameter> param = method->GetParameter(i);
176             EmitProxyMethodParameter(param, paramStr, "");
177             paramStr.Append(", ");
178         }
179         paramStr.Append("const sptr<IRemoteObject> remote");
180 
181         paramStr.Append(");");
182 
183         sb.Append(SpecificationParam(paramStr, prefix + TAB));
184         sb.Append("\n");
185     }
186 }
187 
EmitProxyConstants(StringBuilder & sb,const std::string & prefix) const188 void CppClientProxyCodeEmitter::EmitProxyConstants(StringBuilder &sb, const std::string &prefix) const
189 {
190     sb.Append(prefix).AppendFormat(
191         "static inline BrokerDelegator<%s> delegator_;\n", EmitDefinitionByInterface(interface_, proxyName_).c_str());
192 }
193 
EmitProxyMethodParameter(const AutoPtr<ASTParameter> & param,StringBuilder & sb,const std::string & prefix) const194 void CppClientProxyCodeEmitter::EmitProxyMethodParameter(
195     const AutoPtr<ASTParameter> &param, StringBuilder &sb, const std::string &prefix) const
196 {
197     sb.Append(prefix).Append(param->EmitCppParameter());
198 }
199 
EmitPassthroughProxySourceFile()200 void CppClientProxyCodeEmitter::EmitPassthroughProxySourceFile()
201 {
202     std::string filePath =
203         File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(proxyName_).c_str()));
204     File file(filePath, File::WRITE);
205     StringBuilder sb;
206 
207     EmitLicense(sb);
208     EmitPassthroughProxySourceInclusions(sb);
209     sb.Append("\n");
210     EmitLogTagMacro(sb, FileName(proxyName_));
211     sb.Append("\n");
212     EmitBeginNamespace(sb);
213     EmitGetMethodImpl(sb, "");
214     sb.Append("\n");
215     EmitPassthroughGetInstanceMethodImpl(sb, "");
216     EmitEndNamespace(sb);
217 
218     std::string data = sb.ToString();
219     file.WriteData(data.c_str(), data.size());
220     file.Flush();
221     file.Close();
222 }
223 
EmitPassthroughProxySourceInclusions(StringBuilder & sb)224 void CppClientProxyCodeEmitter::EmitPassthroughProxySourceInclusions(StringBuilder &sb)
225 {
226     HeaderFile::HeaderFileSet headerFiles;
227 
228     headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
229     if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
230         headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "codecvt");
231         headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "locale");
232     } else {
233         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
234     }
235     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
236     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
237 
238     for (const auto &file : headerFiles) {
239         sb.AppendFormat("%s\n", file.ToString().c_str());
240     }
241 }
242 
EmitPassthroughGetInstanceMethodImpl(StringBuilder & sb,const std::string & prefix) const243 void CppClientProxyCodeEmitter::EmitPassthroughGetInstanceMethodImpl(StringBuilder &sb,
244     const std::string &prefix) const
245 {
246     sb.Append(prefix).AppendFormat("%s %s::Get(const std::string &serviceName, bool isStub)\n",
247         interface_->EmitCppType().c_str(), interface_->GetName().c_str());
248     sb.Append(prefix).Append("{\n");
249     EmitProxyPassthroughtLoadImpl(sb, prefix + TAB);
250     sb.Append(prefix + TAB).Append("return nullptr;\n");
251     sb.Append(prefix).Append("}\n");
252 }
253 
EmitProxySourceFile()254 void CppClientProxyCodeEmitter::EmitProxySourceFile()
255 {
256     std::string filePath =
257         File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(proxyName_).c_str()));
258     File file(filePath, File::WRITE);
259     StringBuilder sb;
260 
261     EmitLicense(sb);
262     EmitProxySourceInclusions(sb);
263     sb.Append("\n");
264     EmitLogTagMacro(sb, FileName(proxyName_));
265     sb.Append("\n");
266     EmitBeginNamespace(sb);
267     sb.Append("\n");
268     UtilMethodMap utilMethods;
269     GetUtilMethods(utilMethods);
270     EmitUtilMethods(sb, "", utilMethods, true);
271     sb.Append("\n");
272     if (!interface_->IsSerializable()) {
273         EmitGetMethodImpl(sb, "");
274         sb.Append("\n");
275         EmitGetInstanceMethodImpl(sb, "");
276         sb.Append("\n");
277     }
278     EmitUtilMethods(sb, "", utilMethods, false);
279     EmitProxyMethodImpls(sb, "");
280     sb.Append("\n");
281     EmitEndNamespace(sb);
282 
283     std::string data = sb.ToString();
284     file.WriteData(data.c_str(), data.size());
285     file.Flush();
286     file.Close();
287 }
288 
EmitProxySourceInclusions(StringBuilder & sb)289 void CppClientProxyCodeEmitter::EmitProxySourceInclusions(StringBuilder &sb)
290 {
291     HeaderFile::HeaderFileSet headerFiles;
292     headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(proxyName_));
293     GetSourceOtherLibInclusions(headerFiles);
294 
295     for (const auto &file : headerFiles) {
296         sb.AppendFormat("%s\n", file.ToString().c_str());
297     }
298 }
299 
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const300 void CppClientProxyCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
301 {
302     if (!interface_->IsSerializable()) {
303         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iservmgr_hdi");
304     }
305     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
306     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
307     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_option");
308     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_parcel");
309     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
310     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
311 
312     const AST::TypeStringMap &types = ast_->GetTypes();
313     for (const auto &pair : types) {
314         AutoPtr<ASTType> type = pair.second;
315         if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
316             headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
317             break;
318         }
319     }
320 
321     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
322         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
323             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
324             AutoPtr<ASTType> paramType = param->GetType();
325             if (param->GetAttribute() == ParamAttr::PARAM_IN &&
326                 (paramType->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
327                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
328             }
329 
330             if (param->GetAttribute() == ParamAttr::PARAM_OUT &&
331                 (paramType->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
332                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
333             }
334         }
335     }
336 }
337 
EmitGetMethodImpl(StringBuilder & sb,const std::string & prefix) const338 void CppClientProxyCodeEmitter::EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
339 {
340     sb.Append(prefix).AppendFormat("%s %s::Get(bool isStub)\n", interface_->EmitCppType().c_str(),
341         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
342     sb.Append(prefix).Append("{\n");
343     sb.Append(prefix + TAB)
344         .AppendFormat("return %s::Get(\"%s\", isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str());
345     sb.Append(prefix).Append("}\n");
346 }
347 
EmitGetInstanceMethodImpl(StringBuilder & sb,const std::string & prefix)348 void CppClientProxyCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix)
349 {
350     std::string objName = "proxy";
351     std::string serMajorName = "serMajorVer";
352     std::string serMinorName = "serMinorVer";
353     sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(const std::string& serviceName, bool isStub)\n",
354         EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
355         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
356     sb.Append(prefix).Append("{\n");
357     EmitProxyPassthroughtLoadImpl(sb, prefix + TAB);
358     sb.Append(prefix + TAB).Append("using namespace OHOS::HDI::ServiceManager::V1_0;\n");
359     sb.Append(prefix + TAB).Append("auto servMgr = IServiceManager::Get();\n");
360     sb.Append(prefix + TAB).Append("if (servMgr == nullptr) {\n");
361     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get IServiceManager failed!\", __func__);\n");
362     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
363     sb.Append(prefix + TAB).Append("}\n\n");
364     sb.Append(prefix + TAB).Append("sptr<IRemoteObject> remote = ");
365     sb.Append("servMgr->GetService(serviceName.c_str());\n");
366     sb.Append(prefix + TAB).Append("if (remote == nullptr) {\n");
367     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get remote object failed!\", __func__);\n");
368     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
369     sb.Append(prefix + TAB).Append("}\n\n");
370     sb.Append(prefix + TAB).AppendFormat("sptr<%s> %s = OHOS::HDI::hdi_facecast<%s>(remote);\n",
371         EmitDefinitionByInterface(interface_, interfaceName_).c_str(), objName.c_str(),
372         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
373     sb.Append(prefix + TAB).AppendFormat("if (%s == nullptr) {\n", objName.c_str());
374     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:iface_cast failed!\", __func__);\n");
375     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
376     sb.Append(prefix + TAB).Append("}\n\n");
377 
378     sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMajorName.c_str());
379     sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMinorName.c_str());
380     sb.Append(prefix + TAB).AppendFormat("int32_t %s = %s->GetVersion(%s, %s);\n",
381         errorCodeName_.c_str(), objName.c_str(), serMajorName.c_str(), serMinorName.c_str());
382     sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
383     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get version failed!\", __func__);\n");
384     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
385     sb.Append(prefix + TAB).Append("}\n\n");
386 
387     sb.Append(prefix + TAB).AppendFormat("if (%s != %d) {\n", serMajorName.c_str(), ast_->GetMajorVer());
388     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! ");
389     sb.Append("version of service:%u.%u");
390     sb.AppendFormat(", version of client:%d.%d\", __func__, ", ast_->GetMajorVer(), ast_->GetMinorVer());
391     sb.AppendFormat("%s, %s);\n", serMajorName.c_str(), serMinorName.c_str());
392     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
393     sb.Append(prefix + TAB).Append("}\n\n");
394     sb.Append(prefix + TAB).AppendFormat("return %s;\n", objName.c_str());
395     sb.Append(prefix).Append("}\n");
396 }
397 
EmitProxyPassthroughtLoadImpl(StringBuilder & sb,const std::string & prefix) const398 void CppClientProxyCodeEmitter::EmitProxyPassthroughtLoadImpl(StringBuilder &sb, const std::string &prefix) const
399 {
400     sb.Append(prefix).AppendFormat("if (isStub) {\n");
401 
402     if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
403         sb.Append(prefix + TAB).Append("std::string desc = ");
404         sb.Append("std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(");
405         sb.AppendFormat("%s::GetDescriptor());\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
406     } else {
407         sb.Append(prefix + TAB).AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n",
408             EmitDefinitionByInterface(interface_, interfaceName_).c_str());
409     }
410     sb.Append(prefix + TAB).Append("void *impl = LoadHdiImpl(desc.c_str(), ");
411     sb.AppendFormat("serviceName == \"%s\" ? \"service\" : serviceName.c_str());\n", FileName(implName_).c_str());
412     sb.Append(prefix + TAB).Append("if (impl == nullptr) {\n");
413     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"failed to load hdi impl %{public}s\", desc.data());\n");
414     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
415     sb.Append(prefix + TAB).Append("}\n");
416 
417     if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
418         sb.Append(prefix + TAB).AppendFormat("return std::shared_ptr<%s>(reinterpret_cast<%s *>(impl));\n",
419             EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
420             EmitDefinitionByInterface(interface_, interfaceName_).c_str());
421     } else {
422         sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n",
423             EmitDefinitionByInterface(interface_, interfaceName_).c_str());
424     }
425     sb.Append(prefix).Append("}\n\n");
426 }
427 
EmitProxyMethodImpls(StringBuilder & sb,const std::string & prefix)428 void CppClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder &sb, const std::string &prefix)
429 {
430     AutoPtr<ASTInterfaceType> interface = interface_;
431     AutoPtr<ASTInterfaceType> metaInterface = interface_;
432     while (interface != nullptr) {
433         for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
434             EmitProxyMethodImpl(interface, method, sb, prefix);
435             sb.Append("\n");
436         }
437         interface = interface->GetExtendsInterface();
438         if (interface != nullptr) {
439             metaInterface = interface;
440         }
441     }
442     AutoPtr<ASTMethod> verMethod = interface_->GetVersionMethod();
443     EmitProxyMethodImpl(metaInterface, verMethod, sb, prefix);
444     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
445         sb.Append("\n");
446         EmitProxyStaticMethodImpl(method, sb, prefix);
447     }
448     if (interface_->GetExtendsInterface() == nullptr) {
449         sb.Append("\n");
450         EmitProxyStaticMethodImpl(interface_->GetVersionMethod(), sb, prefix);
451     }
452 }
453 
EmitProxyMethodImpl(const AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)454 void CppClientProxyCodeEmitter::EmitProxyMethodImpl(const AutoPtr<ASTInterfaceType> interface,
455     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
456 {
457     if (method->GetParameterNumber() == 0) {
458         sb.Append(prefix).AppendFormat(
459             "int32_t %s::%s()\n", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
460     } else {
461         StringBuilder paramStr;
462         paramStr.Append(prefix).AppendFormat(
463             "int32_t %s::%s(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
464         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
465             AutoPtr<ASTParameter> param = method->GetParameter(i);
466             EmitProxyMethodParameter(param, paramStr, "");
467             if (i + 1 < method->GetParameterNumber()) {
468                 paramStr.Append(", ");
469             }
470         }
471 
472         paramStr.Append(")");
473 
474         sb.Append(SpecificationParam(paramStr, prefix + TAB));
475         sb.Append("\n");
476     }
477     EmitProxyMethodBody(interface, method, sb, prefix);
478 }
479 
EmitProxyStaticMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)480 void CppClientProxyCodeEmitter::EmitProxyStaticMethodImpl(
481     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
482 {
483     if (method->GetParameterNumber() == 0) {
484         sb.Append(prefix).AppendFormat("int32_t %s::%s_(const sptr<IRemoteObject> remote)\n",
485             EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
486     } else {
487         StringBuilder paramStr;
488         paramStr.Append(prefix).AppendFormat(
489             "int32_t %s::%s_(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
490         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
491             AutoPtr<ASTParameter> param = method->GetParameter(i);
492             EmitProxyMethodParameter(param, paramStr, "");
493             paramStr.Append(", ");
494         }
495 
496         paramStr.Append("const sptr<IRemoteObject> remote)");
497         sb.Append(SpecificationParam(paramStr, prefix + TAB));
498         sb.Append("\n");
499     }
500     EmitProxyStaticMethodBody(method, sb, prefix);
501 }
502 
EmitProxyMethodBody(const AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)503 void CppClientProxyCodeEmitter::EmitProxyMethodBody(const AutoPtr<ASTInterfaceType> interface,
504     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
505 {
506     sb.Append(prefix).Append("{\n");
507     sb.Append(prefix + TAB).AppendFormat("return %s::%s_(",
508         EmitDefinitionByInterface(interface, proxyName_).c_str(), method->GetName().c_str());
509     if (method->GetParameterNumber() > 0) {
510         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
511             AutoPtr<ASTParameter> param = method->GetParameter(i);
512             sb.Append(param->GetName().c_str());
513             sb.Append(", ");
514         }
515     }
516     sb.Append("Remote());\n");
517     sb.Append(prefix).Append("}\n");
518 }
519 
EmitProxyStaticMethodBody(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)520 void CppClientProxyCodeEmitter::EmitProxyStaticMethodBody(
521     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
522 {
523     std::string option = method->IsOneWay() ? "MessageOption::TF_ASYNC" : "MessageOption::TF_SYNC";
524     sb.Append(prefix).Append("{\n");
525     sb.Append(prefix + TAB).AppendFormat("MessageParcel %s;\n", dataParcelName_.c_str());
526     sb.Append(prefix + TAB).AppendFormat("MessageParcel %s;\n", replyParcelName_.c_str());
527     sb.Append(prefix + TAB).AppendFormat("MessageOption %s(%s);\n", optionName_.c_str(), option.c_str());
528     sb.Append("\n");
529 
530     // write interface token
531     EmitWriteInterfaceToken(dataParcelName_, sb, prefix + TAB);
532     sb.Append("\n");
533 
534     EmitWriteFlagOfNeedSetMem(method, dataParcelName_, sb, prefix + TAB);
535 
536     if (method->GetParameterNumber() > 0) {
537         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
538             AutoPtr<ASTParameter> param = method->GetParameter(i);
539             if (param->GetAttribute() == ParamAttr::PARAM_IN) {
540                 EmitWriteMethodParameter(param, dataParcelName_, sb, prefix + TAB);
541                 sb.Append("\n");
542             }
543         }
544     }
545 
546     sb.Append(prefix + TAB).AppendFormat("int32_t %s = remote->SendRequest(%s, %s, %s, %s);\n", errorCodeName_.c_str(),
547         EmitMethodCmdID(method).c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str());
548     sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
549     sb.Append(prefix + TAB + TAB).AppendFormat(
550         "HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n", errorCodeName_.c_str());
551     sb.Append(prefix + TAB + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
552     sb.Append(prefix + TAB).Append("}\n");
553 
554     if (!method->IsOneWay()) {
555         sb.Append("\n");
556         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
557             AutoPtr<ASTParameter> param = method->GetParameter(i);
558             if (param->GetAttribute() == ParamAttr::PARAM_OUT) {
559                 EmitReadMethodParameter(param, replyParcelName_, false, sb, prefix + TAB);
560                 sb.Append("\n");
561             }
562         }
563     }
564 
565     sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
566     sb.Append(prefix).Append("}\n");
567 }
568 
EmitWriteInterfaceToken(const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const569 void CppClientProxyCodeEmitter::EmitWriteInterfaceToken(
570     const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
571 {
572     sb.Append(prefix).AppendFormat("if (!%s.WriteInterfaceToken(%s::GetDescriptor())) {\n", parcelName.c_str(),
573         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
574     sb.Append(prefix + TAB)
575         .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write interface descriptor!\", __func__);\n");
576     sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
577     sb.Append(prefix).Append("}\n");
578 }
579 
EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> & method,const std::string & dataBufName,StringBuilder & sb,const std::string & prefix) const580 void CppClientProxyCodeEmitter::EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> &method,
581     const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const
582 {
583     if (NeedFlag(method)) {
584         sb.Append(prefix).AppendFormat("if (!%s.WriteBool(false)) {\n", dataBufName.c_str());
585         sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s:failed to write flag of memory setting!\", __func__);\n");
586         sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
587         sb.Append(prefix).Append("}\n\n");
588     }
589 }
590 
GetUtilMethods(UtilMethodMap & methods)591 void CppClientProxyCodeEmitter::GetUtilMethods(UtilMethodMap &methods)
592 {
593     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
594         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
595             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
596             AutoPtr<ASTType> paramType = param->GetType();
597             if (param->GetAttribute() == ParamAttr::PARAM_IN) {
598                 paramType->RegisterWriteMethod(Options::GetInstance().GetLanguage(), SerMode::PROXY_SER, methods);
599             } else {
600                 paramType->RegisterReadMethod(Options::GetInstance().GetLanguage(), SerMode::PROXY_SER, methods);
601             }
602         }
603     }
604 }
605 } // namespace HDI
606 } // namespace OHOS