• 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 #include "util/string_helper.h"
13 
14 namespace OHOS {
15 namespace HDI {
ResolveDirectory(const std::string & targetDirectory)16 bool CppClientProxyCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
17 {
18     if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
19         directory_ = GetFileParentPath(targetDirectory);
20     } else {
21         return false;
22     }
23 
24     if (!File::CreateParentDir(directory_)) {
25         Logger::E("CppClientProxyCodeEmitter", "Create '%s' failed!", directory_.c_str());
26         return false;
27     }
28 
29     return true;
30 }
31 
EmitCode()32 void CppClientProxyCodeEmitter::EmitCode()
33 {
34     switch (mode_) {
35         case GenMode::PASSTHROUGH: {
36             if (!interface_->IsSerializable()) {
37                 EmitPassthroughProxySourceFile();
38             }
39             break;
40         }
41         case GenMode::IPC: {
42             EmitProxyHeaderFile();
43             EmitProxySourceFile();
44         }
45         default:
46             break;
47     }
48 }
49 
EmitProxyHeaderFile()50 void CppClientProxyCodeEmitter::EmitProxyHeaderFile()
51 {
52     std::string filePath =
53         File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_ + "Proxy").c_str()));
54     File file(filePath, File::WRITE);
55     StringBuilder sb;
56 
57     EmitLicense(sb);
58     EmitHeadMacro(sb, proxyFullName_);
59     sb.Append("\n");
60     EmitProxyHeaderInclusions(sb);
61     sb.Append("\n");
62     EmitBeginNamespace(sb);
63     sb.Append("\n");
64     EmitProxyDecl(sb, "");
65     sb.Append("\n");
66     EmitEndNamespace(sb);
67     sb.Append("\n");
68     EmitTailMacro(sb, proxyFullName_);
69 
70     std::string data = sb.ToString();
71     file.WriteData(data.c_str(), data.size());
72     file.Flush();
73     file.Close();
74 }
75 
EmitProxyHeaderInclusions(StringBuilder & sb)76 void CppClientProxyCodeEmitter::EmitProxyHeaderInclusions(StringBuilder &sb)
77 {
78     HeaderFile::HeaderFileSet headerFiles;
79 
80     headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
81     if (interface_->GetExtendsInterface() != nullptr) {
82         headerFiles.emplace(
83             HeaderFileType::OWN_HEADER_FILE, EmitHeaderNameByInterface(interface_->GetExtendsInterface(), proxyName_));
84     }
85     GetHeaderOtherLibInclusions(headerFiles);
86 
87     for (const auto &file : headerFiles) {
88         sb.AppendFormat("%s\n", file.ToString().c_str());
89     }
90 }
91 
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const92 void CppClientProxyCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
93 {
94     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
95     if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
96         headerFiles.emplace(HeaderFileType::C_STD_HEADER_FILE, "unistd");
97     }
98 }
99 
EmitProxyDecl(StringBuilder & sb,const std::string & prefix)100 void CppClientProxyCodeEmitter::EmitProxyDecl(StringBuilder &sb, const std::string &prefix)
101 {
102     (void)prefix;
103     sb.AppendFormat("class %s : public IProxyBroker<%s> {\n", proxyName_.c_str(),
104         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
105     sb.Append("public:\n");
106     if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
107         EmitProxyDevmgrDeathRecipient(sb, TAB);
108         sb.Append("\n");
109     }
110     EmitProxyConstructor(sb, TAB);
111     sb.Append("\n");
112     EmitProxyMethodDecls(sb, TAB);
113     sb.Append("\n");
114     if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
115         EmitProxyPublicMembers(sb, TAB);
116     }
117     sb.Append("private:\n");
118     EmitProxyConstants(sb, TAB);
119     sb.Append("};\n");
120 }
121 
EmitProxyDevmgrDeathRecipient(StringBuilder & sb,const std::string & prefix) const122 void CppClientProxyCodeEmitter::EmitProxyDevmgrDeathRecipient(StringBuilder &sb, const std::string &prefix) const
123 {
124     std::string doubleTab = prefix + TAB;
125     sb.Append(prefix).AppendFormat("class %s : public IRemoteObject::DeathRecipient {\n",
126         devmgrDeathRecipientName_.c_str());
127     sb.Append(prefix).Append("public:\n");
128     sb.Append(doubleTab).AppendFormat("%s(wptr<%s> proxy) : proxy_(proxy) {} \n", devmgrDeathRecipientName_.c_str(),
129         EmitDefinitionByInterface(interface_, proxyName_).c_str());
130     sb.Append(doubleTab).AppendFormat("~%s() override = default;\n", devmgrDeathRecipientName_.c_str());
131     EmitProxyDevmgrDeathCallBack(sb, doubleTab);
132     sb.Append(prefix).Append("private:\n");
133     sb.Append(doubleTab).AppendFormat("wptr<%s> proxy_;\n",
134         EmitDefinitionByInterface(interface_, proxyName_).c_str());
135     sb.Append(prefix).Append("};\n");
136 }
137 
EmitProxyDevmgrDeathCallBack(StringBuilder & sb,const std::string & prefix) const138 void CppClientProxyCodeEmitter::EmitProxyDevmgrDeathCallBack(StringBuilder &sb, const std::string &prefix) const
139 {
140     std::string trebleTab = prefix + TAB;
141     sb.Append(prefix).Append("void OnRemoteDied(const wptr<IRemoteObject> &remote) override\n");
142     sb.Append(prefix).Append("{\n");
143     sb.Append(trebleTab).Append("int32_t result = HDF_FAILURE;\n");
144     sb.Append(trebleTab).Append("const int sleepInterval = 500000;\n");
145     sb.Append(trebleTab).Append("const int waitTimes = 10;\n");
146     sb.Append(trebleTab).Append("int currentTime = waitTimes;\n");
147     sb.Append(trebleTab).Append("do {\n");
148     sb.Append(trebleTab + TAB).Append("usleep(sleepInterval);\n");
149     sb.Append(trebleTab + TAB).Append("auto proxy = proxy_.promote();\n");
150     sb.Append(trebleTab + TAB).Append("if (proxy != nullptr) {\n");
151     sb.Append(trebleTab + TAB + TAB).AppendFormat("result = %s::Reconnect(proxy);\n",
152         EmitDefinitionByInterface(interface_, proxyName_).c_str());
153     sb.Append(trebleTab + TAB).Append("}\n");
154     sb.Append(trebleTab + TAB).Append("--currentTime;\n");
155     sb.Append(trebleTab).Append("} while (result != HDF_SUCCESS && currentTime >0);\n");
156     sb.Append(prefix).Append("}\n");
157 }
158 
EmitProxyConstructor(StringBuilder & sb,const std::string & prefix) const159 void CppClientProxyCodeEmitter::EmitProxyConstructor(StringBuilder &sb, const std::string &prefix) const
160 {
161     sb.Append(prefix).AppendFormat("explicit %s(const sptr<IRemoteObject>& remote)", proxyName_.c_str());
162     sb.AppendFormat(
163         " : IProxyBroker<%s>(remote) {\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
164     if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
165         sb.Append(prefix + TAB).Append("reconnectRemote_ = nullptr;\n");
166         sb.Append(prefix + TAB).Append("servMgr_ = nullptr;\n");
167         sb.Append(prefix + TAB).Append("deathRecipient_ = nullptr;\n");
168         sb.Append(prefix + TAB).Append("isReconnected_ = false;\n");
169     }
170     sb.Append(prefix).AppendFormat("}\n");
171     if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
172         sb.Append(prefix).AppendFormat("virtual ~%s() {\n", proxyName_.c_str());
173         sb.Append(prefix + TAB).AppendFormat("if (servMgr_ != nullptr && deathRecipient_ != nullptr) {\n");
174         sb.Append(prefix + TAB + TAB).AppendFormat("servMgr_->RemoveDeathRecipient(deathRecipient_);\n");
175         sb.Append(prefix + TAB).AppendFormat("}\n");
176         sb.Append(prefix).AppendFormat("}\n");
177     } else {
178         sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", proxyName_.c_str());
179     }
180 }
181 
EmitProxyMethodDecls(StringBuilder & sb,const std::string & prefix) const182 void CppClientProxyCodeEmitter::EmitProxyMethodDecls(StringBuilder &sb, const std::string &prefix) const
183 {
184     EmitProxyIsProxyMethodImpl(sb, prefix);
185     AutoPtr<ASTInterfaceType> interface = interface_;
186     while (interface != nullptr) {
187         for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
188             EmitProxyMethodDecl(method, sb, prefix);
189             sb.Append("\n");
190         }
191         interface = interface->GetExtendsInterface();
192     }
193     EmitProxyMethodDecl(interface_->GetVersionMethod(), sb, prefix);
194     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
195         sb.Append("\n");
196         EmitProxyStaticMethodDecl(method, sb, prefix);
197     }
198     if (interface_->GetExtendsInterface() == nullptr) {
199         sb.Append("\n");
200         EmitProxyStaticMethodDecl(interface_->GetVersionMethod(), sb, prefix);
201     }
202     if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
203         sb.Append("\n");
204         EmitProxyReconnectMethodDecl(sb, prefix);
205         sb.Append("\n");
206         EmitProxyGetRemoteMethodDecl(sb, prefix);
207     }
208 }
209 
EmitProxyMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const210 void CppClientProxyCodeEmitter::EmitProxyMethodDecl(
211     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
212 {
213     if (method->GetParameterNumber() == 0) {
214         sb.Append(prefix).AppendFormat("int32_t %s() override;\n", method->GetName().c_str());
215     } else {
216         StringBuilder paramStr;
217         paramStr.Append(prefix).AppendFormat("int32_t %s(", method->GetName().c_str());
218 
219         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
220             AutoPtr<ASTParameter> param = method->GetParameter(i);
221             EmitProxyMethodParameter(param, paramStr, "");
222             if (i + 1 < method->GetParameterNumber()) {
223                 paramStr.Append(", ");
224             }
225         }
226 
227         paramStr.Append(") override;");
228 
229         sb.Append(SpecificationParam(paramStr, prefix + TAB));
230         sb.Append("\n");
231     }
232 }
233 
EmitProxyStaticMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const234 void CppClientProxyCodeEmitter::EmitProxyStaticMethodDecl(
235     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
236 {
237     if (method->GetParameterNumber() == 0) {
238         sb.Append(prefix).AppendFormat(
239             "static int32_t %s_(const sptr<IRemoteObject> remote);\n", method->GetName().c_str());
240     } else {
241         StringBuilder paramStr;
242         paramStr.Append(prefix).AppendFormat("static 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             EmitProxyMethodParameter(param, paramStr, "");
247             paramStr.Append(", ");
248         }
249         paramStr.Append("const sptr<IRemoteObject> remote");
250 
251         paramStr.Append(");");
252 
253         sb.Append(SpecificationParam(paramStr, prefix + TAB));
254         sb.Append("\n");
255     }
256 }
257 
EmitProxyReconnectMethodDecl(StringBuilder & sb,const std::string & prefix) const258 void CppClientProxyCodeEmitter::EmitProxyReconnectMethodDecl(StringBuilder &sb, const std::string &prefix) const
259 {
260     sb.Append(prefix).AppendFormat("static int32_t Reconnect(sptr<%s> proxy);\n",
261         EmitDefinitionByInterface(interface_, proxyName_).c_str());
262 }
263 
EmitProxyGetRemoteMethodDecl(StringBuilder & sb,const std::string & prefix) const264 void CppClientProxyCodeEmitter::EmitProxyGetRemoteMethodDecl(StringBuilder &sb, const std::string &prefix) const
265 {
266     sb.Append(prefix).Append("sptr<IRemoteObject> GetCurrentRemote() {\n");
267     sb.Append(prefix + TAB).Append("return isReconnected_ ? reconnectRemote_ : Remote();\n");
268     sb.Append(prefix).Append("}\n");
269 }
270 
EmitProxyPublicMembers(StringBuilder & sb,const std::string & prefix) const271 void CppClientProxyCodeEmitter::EmitProxyPublicMembers(StringBuilder &sb, const std::string &prefix) const
272 {
273     sb.Append(prefix).Append("bool isReconnected_;\n");
274     sb.Append(prefix).Append("std::string serviceName_;\n");
275     sb.Append(prefix).AppendFormat("sptr<IRemoteObject> servMgr_;\n", devmgrVersionName_.c_str());
276     sb.Append(prefix).AppendFormat("sptr<%s::%s> deathRecipient_;\n",
277         EmitDefinitionByInterface(interface_, proxyName_).c_str(),
278         devmgrDeathRecipientName_.c_str());
279     sb.Append(prefix).Append("sptr<IRemoteObject> reconnectRemote_;\n");
280 }
281 
EmitProxyConstants(StringBuilder & sb,const std::string & prefix) const282 void CppClientProxyCodeEmitter::EmitProxyConstants(StringBuilder &sb, const std::string &prefix) const
283 {
284     sb.Append(prefix).AppendFormat(
285         "static inline BrokerDelegator<%s> delegator_;\n", EmitDefinitionByInterface(interface_, proxyName_).c_str());
286 }
287 
EmitProxyMethodParameter(const AutoPtr<ASTParameter> & param,StringBuilder & sb,const std::string & prefix) const288 void CppClientProxyCodeEmitter::EmitProxyMethodParameter(
289     const AutoPtr<ASTParameter> &param, StringBuilder &sb, const std::string &prefix) const
290 {
291     sb.Append(prefix).Append(param->EmitCppParameter());
292 }
293 
EmitPassthroughProxySourceFile()294 void CppClientProxyCodeEmitter::EmitPassthroughProxySourceFile()
295 {
296     std::string filePath =
297         File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(proxyName_).c_str()));
298     File file(filePath, File::WRITE);
299     StringBuilder sb;
300 
301     EmitLicense(sb);
302     EmitPassthroughProxySourceInclusions(sb);
303     sb.Append("\n");
304     EmitLogTagMacro(sb, FileName(proxyName_));
305     sb.Append("\n");
306     EmitBeginNamespace(sb);
307     EmitGetMethodImpl(sb, "");
308     sb.Append("\n");
309     EmitPassthroughGetInstanceMethodImpl(sb, "");
310     EmitEndNamespace(sb);
311 
312     std::string data = sb.ToString();
313     file.WriteData(data.c_str(), data.size());
314     file.Flush();
315     file.Close();
316 }
317 
EmitPassthroughProxySourceInclusions(StringBuilder & sb)318 void CppClientProxyCodeEmitter::EmitPassthroughProxySourceInclusions(StringBuilder &sb)
319 {
320     HeaderFile::HeaderFileSet headerFiles;
321 
322     headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
323     if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
324         headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "codecvt");
325         headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "locale");
326     } else {
327         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
328     }
329     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
330     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_core_log");
331 
332     for (const auto &file : headerFiles) {
333         sb.AppendFormat("%s\n", file.ToString().c_str());
334     }
335 }
336 
EmitPassthroughGetInstanceMethodImpl(StringBuilder & sb,const std::string & prefix) const337 void CppClientProxyCodeEmitter::EmitPassthroughGetInstanceMethodImpl(StringBuilder &sb,
338     const std::string &prefix) const
339 {
340     sb.Append(prefix).AppendFormat("%s %s::Get(const std::string &serviceName, bool isStub)\n",
341         interface_->EmitCppType().c_str(), interface_->GetName().c_str());
342     sb.Append(prefix).Append("{\n");
343     EmitProxyPassthroughtLoadImpl(sb, prefix + TAB);
344     sb.Append(prefix + TAB).Append("return nullptr;\n");
345     sb.Append(prefix).Append("}\n");
346 }
347 
EmitProxySourceFile()348 void CppClientProxyCodeEmitter::EmitProxySourceFile()
349 {
350     std::string filePath =
351         File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(proxyName_).c_str()));
352     File file(filePath, File::WRITE);
353     StringBuilder sb;
354 
355     EmitLicense(sb);
356     EmitProxySourceInclusions(sb);
357     sb.Append("\n");
358     EmitLogTagMacro(sb, FileName(proxyName_));
359     sb.Append("\n");
360     EmitBeginNamespace(sb);
361     sb.Append("\n");
362     UtilMethodMap utilMethods;
363     GetUtilMethods(utilMethods);
364     EmitUtilMethods(sb, "", utilMethods, true);
365     sb.Append("\n");
366     if (interface_->GetExtendsInterface() != nullptr) {
367         EmitProxyCastFromMethodImplTemplate(sb, "");
368         sb.Append("\n");
369     }
370     if (!interface_->IsSerializable()) {
371         EmitGetMethodImpl(sb, "");
372         sb.Append("\n");
373         EmitGetInstanceMethodImpl(sb, "");
374         sb.Append("\n");
375         EmitProxyCppReconnectMethodImpl(sb, "");
376         sb.Append("\n");
377     }
378     EmitProxyCastFromMethodImpls(sb, "");
379     EmitUtilMethods(sb, "", utilMethods, false);
380     EmitProxyMethodImpls(sb, "");
381     sb.Append("\n");
382     EmitEndNamespace(sb);
383 
384     std::string data = sb.ToString();
385     file.WriteData(data.c_str(), data.size());
386     file.Flush();
387     file.Close();
388 }
389 
EmitProxySourceInclusions(StringBuilder & sb)390 void CppClientProxyCodeEmitter::EmitProxySourceInclusions(StringBuilder &sb)
391 {
392     HeaderFile::HeaderFileSet headerFiles;
393     headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(proxyName_));
394     GetSourceOtherLibInclusions(headerFiles);
395     GetSourceOtherFileInclusions(headerFiles);
396 
397     for (const auto &file : headerFiles) {
398         sb.AppendFormat("%s\n", file.ToString().c_str());
399     }
400 }
401 
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const402 void CppClientProxyCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
403 {
404     if (!interface_->IsSerializable()) {
405         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iservmgr_hdi");
406     }
407     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
408     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_core_log");
409     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_option");
410     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_parcel");
411     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
412     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
413 
414     const AST::TypeStringMap &types = ast_->GetTypes();
415     for (const auto &pair : types) {
416         AutoPtr<ASTType> type = pair.second;
417         if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
418             headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
419             break;
420         }
421     }
422 
423     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
424         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
425             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
426             AutoPtr<ASTType> paramType = param->GetType();
427             if (param->GetAttribute() == ParamAttr::PARAM_IN &&
428                 (paramType->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
429                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
430             }
431 
432             if (param->GetAttribute() == ParamAttr::PARAM_OUT &&
433                 (paramType->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
434                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
435             }
436         }
437     }
438 }
439 
GetSourceOtherFileInclusions(HeaderFile::HeaderFileSet & headerFiles) const440 void CppClientProxyCodeEmitter::GetSourceOtherFileInclusions(HeaderFile::HeaderFileSet &headerFiles) const
441 {
442     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
443         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
444             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
445             AutoPtr<ASTType> paramType = param->GetType();
446             if (param->GetAttribute() == ParamAttr::PARAM_OUT &&
447                 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
448                 AutoPtr<ASTInterfaceType> type = dynamic_cast<ASTInterfaceType *>(paramType.Get());
449                 std::string FileName = InterfaceToFilePath(paramType->ToString());
450                 headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, FileName);
451             }
452         }
453     }
454 }
455 
EmitGetMethodImpl(StringBuilder & sb,const std::string & prefix) const456 void CppClientProxyCodeEmitter::EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
457 {
458     sb.Append(prefix).AppendFormat("%s %s::Get(bool isStub)\n", interface_->EmitCppType().c_str(),
459         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
460     sb.Append(prefix).Append("{\n");
461     sb.Append(prefix + TAB)
462         .AppendFormat("return %s::Get(\"%s\", isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str());
463     sb.Append(prefix).Append("}\n");
464 }
465 
EmitGetInstanceMethodImpl(StringBuilder & sb,const std::string & prefix)466 void CppClientProxyCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix)
467 {
468     std::string objName = "proxy";
469     std::string interfaceNamespace = GetNameSpaceByInterface(interface_, interfaceName_);
470     sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(const std::string& serviceName, bool isStub)\n",
471         EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
472         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
473     sb.Append(prefix).Append("{\n");
474     EmitProxyPassthroughtLoadImpl(sb, prefix + TAB);
475     sb.Append(prefix + TAB).AppendFormat("using namespace %s;\n", devmgrVersionName_.c_str());
476     sb.Append(prefix + TAB).Append("auto servMgr = IServiceManager::Get();\n");
477     sb.Append(prefix + TAB).Append("if (servMgr == nullptr) {\n");
478     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get IServiceManager failed!\", __func__);\n");
479     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
480     sb.Append(prefix + TAB).Append("}\n\n");
481     sb.Append(prefix + TAB).Append("sptr<IRemoteObject> remote = ");
482     sb.Append("servMgr->GetService(serviceName.c_str());\n");
483     sb.Append(prefix + TAB).Append("if (remote == nullptr) {\n");
484     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get remote object failed!\", __func__);\n");
485     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
486     sb.Append(prefix + TAB).Append("}\n\n");
487     sb.Append(prefix + TAB).AppendFormat("sptr<%s> %s = new %s(remote);\n",
488         EmitDefinitionByInterface(interface_, proxyName_).c_str(), objName.c_str(),
489         (interfaceNamespace +
490         (StringHelper::StartWith(interfaceName_, "I") ? interfaceName_.substr(1) : interfaceName_) +
491         "Proxy").c_str());
492     sb.Append(prefix + TAB).AppendFormat("if (%s == nullptr) {\n", objName.c_str());
493     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:iface_cast failed!\", __func__);\n");
494     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
495     sb.Append(prefix + TAB).Append("}\n\n");
496     EmitGetInstanceMethodInitProxyImpl(sb, prefix);
497 }
498 
EmitGetInstanceMethodInitProxyImpl(StringBuilder & sb,const std::string & prefix) const499 void CppClientProxyCodeEmitter::EmitGetInstanceMethodInitProxyImpl(StringBuilder &sb, const std::string &prefix) const
500 {
501     std::string objName = "proxy";
502     std::string serMajorName = "serMajorVer";
503     std::string serMinorName = "serMinorVer";
504     sb.Append(prefix + TAB).AppendFormat("%s->servMgr_ = ", objName.c_str());
505     sb.Append("OHOS::HDI::hdi_objcast<IServiceManager>(servMgr);\n");
506     sb.Append(prefix + TAB).AppendFormat("%s->deathRecipient_ = new %s::%s(%s);\n", objName.c_str(),
507         EmitDefinitionByInterface(interface_, proxyName_).c_str(),
508         devmgrDeathRecipientName_.c_str(), objName.c_str());
509     sb.Append(prefix + TAB).AppendFormat("%s->servMgr_->AddDeathRecipient(%s->deathRecipient_);\n",
510         objName.c_str(), objName.c_str());
511     sb.Append(prefix + TAB).AppendFormat("%s->isReconnected_ = false;\n", objName.c_str());
512     sb.Append(prefix + TAB).AppendFormat("%s->serviceName_ = serviceName;\n", objName.c_str());
513 
514     sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMajorName.c_str());
515     sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMinorName.c_str());
516     sb.Append(prefix + TAB).AppendFormat("int32_t %s = %s->GetVersion(%s, %s);\n",
517         errorCodeName_.c_str(), objName.c_str(), serMajorName.c_str(), serMinorName.c_str());
518     sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
519     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get version failed!\", __func__);\n");
520     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
521     sb.Append(prefix + TAB).Append("}\n\n");
522 
523     sb.Append(prefix + TAB).AppendFormat("if (%s != %d) {\n", serMajorName.c_str(), ast_->GetMajorVer());
524     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! ");
525     sb.Append("version of service:%u.%u");
526     sb.AppendFormat(", version of client:%d.%d\", __func__, ", ast_->GetMajorVer(), ast_->GetMinorVer());
527     sb.AppendFormat("%s, %s);\n", serMajorName.c_str(), serMinorName.c_str());
528     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
529     sb.Append(prefix + TAB).Append("}\n\n");
530     sb.Append(prefix + TAB).AppendFormat("return %s;\n", objName.c_str());
531     sb.Append(prefix).Append("}\n");
532 }
533 
EmitProxyCppReconnectMethodImpl(StringBuilder & sb,const std::string & prefix) const534 void CppClientProxyCodeEmitter::EmitProxyCppReconnectMethodImpl(StringBuilder &sb, const std::string &prefix) const
535 {
536     std::string doubleTab = prefix + TAB;
537     sb.Append(prefix).AppendFormat("int32_t %s::Reconnect(\n",
538         EmitDefinitionByInterface(interface_, proxyName_).c_str());
539     sb.Append(doubleTab).AppendFormat("sptr<%s> proxy) \n",
540         EmitDefinitionByInterface(interface_, proxyName_).c_str());
541     sb.Append(prefix).Append("{\n");
542     sb.Append(doubleTab).Append("if (proxy == nullptr) {\n");
543     sb.Append(doubleTab + TAB).Append("HDF_LOGW(\"Reconnect failed : input proxy is null\");\n");
544     sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
545     sb.Append(doubleTab).Append("}\n");
546     sb.Append(doubleTab).AppendFormat("using namespace %s;\n", devmgrVersionName_.c_str());
547     sb.Append(doubleTab).Append("proxy->isReconnected_ = false;\n");
548     sb.Append(doubleTab).Append("auto iServMgr = IServiceManager::Get();\n");
549     sb.Append(doubleTab).Append("if (iServMgr == nullptr) {\n");
550     sb.Append(doubleTab + TAB).Append("HDF_LOGW(\"Reconnect failed : iServMgr is null\");\n");
551     sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
552     sb.Append(doubleTab).Append("};\n");
553     sb.Append(doubleTab).Append("proxy->reconnectRemote_ = ");
554     sb.Append("iServMgr->GetService(proxy->serviceName_.c_str());\n");
555     sb.Append(doubleTab).Append("if (proxy->reconnectRemote_ == nullptr) {\n");
556     sb.Append(doubleTab + TAB).Append("HDF_LOGW(\"Reconnect failed : reconnectRemote_ is null\");\n");
557     sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
558     sb.Append(doubleTab).Append("}\n");
559     sb.Append(doubleTab).Append("proxy->servMgr_ = ");
560     sb.Append("OHOS::HDI::hdi_objcast<IServiceManager>(iServMgr);\n");
561     sb.Append(doubleTab).Append("if (proxy->servMgr_ == nullptr) {\n");
562     sb.Append(doubleTab + TAB).Append("HDF_LOGE(\"%{public}s:get IServiceManager failed!\", __func__);\n");
563     sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
564     sb.Append(doubleTab).Append("}\n");
565     sb.Append(doubleTab).Append("proxy->servMgr_->AddDeathRecipient(\n");
566     sb.Append(doubleTab + TAB).AppendFormat("new %s::%s(proxy));\n",
567         EmitDefinitionByInterface(interface_, proxyName_).c_str(), devmgrDeathRecipientName_.c_str());
568     sb.Append(doubleTab).Append("proxy->isReconnected_ = true;\n");
569     sb.Append(doubleTab).Append("return HDF_SUCCESS;\n");
570     sb.Append(prefix).Append("}\n");
571 }
572 
EmitProxyPassthroughtLoadImpl(StringBuilder & sb,const std::string & prefix) const573 void CppClientProxyCodeEmitter::EmitProxyPassthroughtLoadImpl(StringBuilder &sb, const std::string &prefix) const
574 {
575     sb.Append(prefix).AppendFormat("if (isStub) {\n");
576 
577     if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
578         sb.Append(prefix + TAB).Append("std::string desc = ");
579         sb.Append("std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(");
580         sb.AppendFormat("%s::GetDescriptor());\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
581     } else {
582         sb.Append(prefix + TAB).AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n",
583             EmitDefinitionByInterface(interface_, interfaceName_).c_str());
584     }
585     sb.Append(prefix + TAB).Append("void *impl = LoadHdiImpl(desc.c_str(), ");
586     sb.AppendFormat("serviceName == \"%s\" ? \"service\" : serviceName.c_str());\n", FileName(implName_).c_str());
587     sb.Append(prefix + TAB).Append("if (impl == nullptr) {\n");
588     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"failed to load hdi impl %{public}s\", desc.data());\n");
589     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
590     sb.Append(prefix + TAB).Append("}\n");
591 
592     if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
593         sb.Append(prefix + TAB).AppendFormat("return std::shared_ptr<%s>(reinterpret_cast<%s *>(impl));\n",
594             EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
595             EmitDefinitionByInterface(interface_, interfaceName_).c_str());
596     } else {
597         sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n",
598             EmitDefinitionByInterface(interface_, interfaceName_).c_str());
599     }
600     sb.Append(prefix).Append("}\n\n");
601 }
602 
EmitProxyMethodImpls(StringBuilder & sb,const std::string & prefix)603 void CppClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder &sb, const std::string &prefix)
604 {
605     AutoPtr<ASTInterfaceType> interface = interface_;
606     AutoPtr<ASTInterfaceType> metaInterface = interface_;
607     while (interface != nullptr) {
608         for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
609             EmitProxyMethodImpl(interface, method, sb, prefix);
610             sb.Append("\n");
611         }
612         interface = interface->GetExtendsInterface();
613         if (interface != nullptr) {
614             metaInterface = interface;
615         }
616     }
617     AutoPtr<ASTMethod> verMethod = interface_->GetVersionMethod();
618     EmitProxyMethodImpl(metaInterface, verMethod, sb, prefix);
619     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
620         sb.Append("\n");
621         EmitProxyStaticMethodImpl(method, sb, prefix);
622     }
623     if (interface_->GetExtendsInterface() == nullptr) {
624         sb.Append("\n");
625         EmitProxyStaticMethodImpl(interface_->GetVersionMethod(), sb, prefix);
626     }
627 }
628 
EmitProxyIsProxyMethodImpl(StringBuilder & sb,const std::string & prefix) const629 void CppClientProxyCodeEmitter::EmitProxyIsProxyMethodImpl(StringBuilder &sb, const std::string &prefix) const
630 {
631     sb.Append(prefix).Append("inline bool IsProxy() override\n");
632     sb.Append(prefix).Append("{\n");
633     sb.Append(prefix + TAB).Append("return true;\n");
634     sb.Append(prefix).Append("}\n\n");
635 }
636 
EmitProxyCastFromMethodImpls(StringBuilder & sb,const std::string & prefix) const637 void CppClientProxyCodeEmitter::EmitProxyCastFromMethodImpls(StringBuilder &sb, const std::string &prefix) const
638 {
639     AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
640     while (interface != nullptr) {
641         EmitProxyCastFromMethodImpl(interface, sb, prefix);
642         sb.Append(prefix).Append("\n");
643         interface = interface->GetExtendsInterface();
644     }
645 }
646 
EmitProxyCastFromMethodImpl(const AutoPtr<ASTInterfaceType> interface,StringBuilder & sb,const std::string & prefix) const647 void CppClientProxyCodeEmitter::EmitProxyCastFromMethodImpl(const AutoPtr<ASTInterfaceType> interface,
648     StringBuilder &sb, const std::string &prefix) const
649 {
650     std::string currentInterface = EmitDefinitionByInterface(interface_, interfaceName_);
651     std::string parentInterface = EmitDefinitionByInterface(interface, interfaceName_);
652 
653     sb.Append(prefix).AppendFormat("sptr<%s> %s::CastFrom(const sptr<%s> &parent)\n",
654         currentInterface.c_str(), currentInterface.c_str(), parentInterface.c_str());
655     sb.Append(prefix).Append("{\n");
656     sb.Append(prefix + TAB).AppendFormat("return CastFromTemplate<%s, %s>(parent);\n",
657         currentInterface.c_str(), parentInterface.c_str());
658     sb.Append(prefix).Append("}\n");
659 }
660 
EmitProxyCastFromMethodImplTemplate(StringBuilder & sb,const std::string & prefix) const661 void CppClientProxyCodeEmitter::EmitProxyCastFromMethodImplTemplate(StringBuilder &sb, const std::string &prefix) const
662 {
663     std::string serMajorName = "serMajorVer";
664     std::string serMinorName = "serMinorVer";
665 
666     sb.Append(prefix).Append("template<typename ChildType, typename ParentType>\n");
667     sb.Append(prefix).Append("static sptr<ChildType> CastFromTemplate(const sptr<ParentType> &parent)\n");
668     sb.Append(prefix).Append("{\n");
669     sb.Append(prefix + TAB).Append("if (parent == nullptr) {\n");
670     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:parent is nullptr!\", __func__);\n");
671     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
672     sb.Append(prefix + TAB).Append("}\n\n");
673 
674     sb.Append(prefix + TAB).Append("if (!parent->IsProxy()) {\n");
675     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:not proxy, not support castfrom!\", __func__);\n");
676     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
677     sb.Append(prefix + TAB).Append("}\n\n");
678 
679     sb.Append(prefix + TAB).AppendFormat("sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<ParentType>(parent);\n");
680     sb.Append(prefix + TAB).Append("if (remote == nullptr) {\n");
681     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:hdi_objcast failed!\", __func__);\n");
682     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
683     sb.Append(prefix + TAB).Append("}\n\n");
684 
685     sb.Append(prefix + TAB).AppendFormat("sptr<ChildType> proxy = OHOS::HDI::hdi_facecast<ChildType>(remote);\n");
686     sb.Append(prefix + TAB).Append("if (proxy == nullptr) {\n");
687     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:hdi_facecast failed!\", __func__);\n");
688     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
689     sb.Append(prefix + TAB).Append("}\n\n");
690 
691     sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMajorName.c_str());
692     sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMinorName.c_str());
693     sb.Append(prefix + TAB).AppendFormat("int32_t %s = proxy->GetVersion(%s, %s);\n",
694         errorCodeName_.c_str(), serMajorName.c_str(), serMinorName.c_str());
695     sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
696     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get version failed!\", __func__);\n");
697     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
698     sb.Append(prefix + TAB).Append("}\n\n");
699 
700     sb.Append(prefix + TAB).AppendFormat("if (%s != %d) {\n", serMajorName.c_str(), ast_->GetMajorVer());
701     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! ");
702     sb.Append("version of service:%u.%u");
703     sb.AppendFormat(", version of client:%d.%d\", __func__, ", ast_->GetMajorVer(), ast_->GetMinorVer());
704     sb.AppendFormat("%s, %s);\n", serMajorName.c_str(), serMinorName.c_str());
705     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
706     sb.Append(prefix + TAB).Append("}\n\n");
707 
708     sb.Append(prefix + TAB).Append("return proxy;\n");
709     sb.Append(prefix).Append("}\n");
710 }
711 
EmitProxyMethodImpl(const AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)712 void CppClientProxyCodeEmitter::EmitProxyMethodImpl(const AutoPtr<ASTInterfaceType> interface,
713     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
714 {
715     if (method->GetParameterNumber() == 0) {
716         sb.Append(prefix).AppendFormat(
717             "int32_t %s::%s()\n", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
718     } else {
719         StringBuilder paramStr;
720         paramStr.Append(prefix).AppendFormat(
721             "int32_t %s::%s(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
722         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
723             AutoPtr<ASTParameter> param = method->GetParameter(i);
724             EmitProxyMethodParameter(param, paramStr, "");
725             if (i + 1 < method->GetParameterNumber()) {
726                 paramStr.Append(", ");
727             }
728         }
729 
730         paramStr.Append(")");
731 
732         sb.Append(SpecificationParam(paramStr, prefix + TAB));
733         sb.Append("\n");
734     }
735     EmitProxyMethodBody(interface, method, sb, prefix);
736 }
737 
EmitProxyStaticMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)738 void CppClientProxyCodeEmitter::EmitProxyStaticMethodImpl(
739     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
740 {
741     if (method->GetParameterNumber() == 0) {
742         sb.Append(prefix).AppendFormat("int32_t %s::%s_(const sptr<IRemoteObject> remote)\n",
743             EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
744     } else {
745         StringBuilder paramStr;
746         paramStr.Append(prefix).AppendFormat(
747             "int32_t %s::%s_(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
748         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
749             AutoPtr<ASTParameter> param = method->GetParameter(i);
750             EmitProxyMethodParameter(param, paramStr, "");
751             paramStr.Append(", ");
752         }
753 
754         paramStr.Append("const sptr<IRemoteObject> remote)");
755         sb.Append(SpecificationParam(paramStr, prefix + TAB));
756         sb.Append("\n");
757     }
758     EmitProxyStaticMethodBody(method, sb, prefix);
759 }
760 
EmitProxyMethodBody(const AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)761 void CppClientProxyCodeEmitter::EmitProxyMethodBody(const AutoPtr<ASTInterfaceType> interface,
762     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
763 {
764     sb.Append(prefix).Append("{\n");
765     sb.Append(prefix + TAB).AppendFormat("return %s::%s_(",
766         EmitDefinitionByInterface(interface, proxyName_).c_str(), method->GetName().c_str());
767     if (method->GetParameterNumber() > 0) {
768         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
769             AutoPtr<ASTParameter> param = method->GetParameter(i);
770             sb.Append(param->GetName().c_str());
771             sb.Append(", ");
772         }
773     }
774     if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
775         sb.Append("GetCurrentRemote());\n");
776     } else {
777         sb.Append("Remote());\n");
778     }
779     sb.Append(prefix).Append("}\n");
780 }
781 
EmitProxyStaticMethodBody(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)782 void CppClientProxyCodeEmitter::EmitProxyStaticMethodBody(
783     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
784 {
785     std::string option = method->IsOneWay() ? "MessageOption::TF_ASYNC" : "MessageOption::TF_SYNC";
786     sb.Append(prefix).Append("{\n");
787     sb.Append(prefix + TAB).AppendFormat("MessageParcel %s;\n", dataParcelName_.c_str());
788     sb.Append(prefix + TAB).AppendFormat("MessageParcel %s;\n", replyParcelName_.c_str());
789     sb.Append(prefix + TAB).AppendFormat("MessageOption %s(%s);\n", optionName_.c_str(), option.c_str());
790     sb.Append("\n");
791 
792     // write interface token
793     EmitWriteInterfaceToken(dataParcelName_, sb, prefix + TAB);
794     sb.Append("\n");
795 
796     EmitWriteFlagOfNeedSetMem(method, dataParcelName_, sb, prefix + TAB);
797 
798     if (method->GetParameterNumber() > 0) {
799         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
800             AutoPtr<ASTParameter> param = method->GetParameter(i);
801             if (param->GetAttribute() == ParamAttr::PARAM_IN) {
802                 EmitWriteMethodParameter(param, dataParcelName_, sb, prefix + TAB);
803                 sb.Append("\n");
804             }
805         }
806     }
807     sb.Append(prefix + TAB).AppendFormat("if (remote == nullptr) {\n");
808     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid remote object!\", __func__);\n");
809     sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
810     sb.Append(prefix + TAB).Append("}\n\n");
811     sb.Append(prefix + TAB).AppendFormat("int32_t %s = remote->SendRequest(%s, %s, %s, %s);\n", errorCodeName_.c_str(),
812         EmitMethodCmdID(method).c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str());
813     sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
814     sb.Append(prefix + TAB + TAB).AppendFormat(
815         "HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n", errorCodeName_.c_str());
816     sb.Append(prefix + TAB + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
817     sb.Append(prefix + TAB).Append("}\n");
818 
819     if (!method->IsOneWay()) {
820         sb.Append("\n");
821         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
822             AutoPtr<ASTParameter> param = method->GetParameter(i);
823             if (param->GetAttribute() == ParamAttr::PARAM_OUT) {
824                 EmitReadMethodParameter(param, replyParcelName_, false, sb, prefix + TAB);
825                 sb.Append("\n");
826             }
827         }
828     }
829 
830     sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
831     sb.Append(prefix).Append("}\n");
832 }
833 
EmitWriteInterfaceToken(const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const834 void CppClientProxyCodeEmitter::EmitWriteInterfaceToken(
835     const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
836 {
837     sb.Append(prefix).AppendFormat("if (!%s.WriteInterfaceToken(%s::GetDescriptor())) {\n", parcelName.c_str(),
838         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
839     sb.Append(prefix + TAB)
840         .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write interface descriptor!\", __func__);\n");
841     sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
842     sb.Append(prefix).Append("}\n");
843 }
844 
EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> & method,const std::string & dataBufName,StringBuilder & sb,const std::string & prefix) const845 void CppClientProxyCodeEmitter::EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> &method,
846     const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const
847 {
848     if (NeedFlag(method)) {
849         sb.Append(prefix).AppendFormat("if (!%s.WriteBool(false)) {\n", dataBufName.c_str());
850         sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s:failed to write flag of memory setting!\", __func__);\n");
851         sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
852         sb.Append(prefix).Append("}\n\n");
853     }
854 }
855 
GetUtilMethods(UtilMethodMap & methods)856 void CppClientProxyCodeEmitter::GetUtilMethods(UtilMethodMap &methods)
857 {
858     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
859         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
860             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
861             AutoPtr<ASTType> paramType = param->GetType();
862             if (param->GetAttribute() == ParamAttr::PARAM_IN) {
863                 paramType->RegisterWriteMethod(Options::GetInstance().GetLanguage(), SerMode::PROXY_SER, methods);
864             } else {
865                 paramType->RegisterReadMethod(Options::GetInstance().GetLanguage(), SerMode::PROXY_SER, methods);
866             }
867         }
868     }
869 }
870 } // namespace HDI
871 } // namespace OHOS