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