• 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 = static_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 
539     sb.Append(prefix + TAB).AppendFormat("if (%s < %d) {\n", serMinorName.c_str(), ast_->GetMinorVer());
540     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check Minor version failed! \"\n");
541     sb.Append(prefix + TAB + TAB + TAB);
542     sb.AppendFormat("\"client minor version(%u) should be less or equal to server minor version(%%u).", \
543         ast_->GetMinorVer());
544     sb.AppendFormat("\", __func__, %s);\n", serMinorName.c_str());
545     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
546     sb.Append(prefix + TAB).Append("}\n\n");
547 
548     sb.Append(prefix + TAB).AppendFormat("return %s;\n", objName.c_str());
549     sb.Append(prefix).Append("}\n");
550 }
551 
EmitProxyCppReconnectMethodImpl(StringBuilder & sb,const std::string & prefix) const552 void CppClientProxyCodeEmitter::EmitProxyCppReconnectMethodImpl(StringBuilder &sb, const std::string &prefix) const
553 {
554     std::string doubleTab = prefix + TAB;
555     sb.Append(prefix).AppendFormat("int32_t %s::Reconnect(\n",
556         EmitDefinitionByInterface(interface_, proxyName_).c_str());
557     sb.Append(doubleTab).AppendFormat("sptr<%s> proxy) \n",
558         EmitDefinitionByInterface(interface_, proxyName_).c_str());
559     sb.Append(prefix).Append("{\n");
560     sb.Append(doubleTab).Append("if (proxy == nullptr) {\n");
561     sb.Append(doubleTab + TAB).Append("HDF_LOGW(\"Reconnect failed : input proxy is null\");\n");
562     sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
563     sb.Append(doubleTab).Append("}\n");
564     sb.Append(doubleTab).AppendFormat("using namespace %s;\n", devmgrVersionName_.c_str());
565     sb.Append(doubleTab).Append("proxy->isReconnected_ = false;\n");
566     sb.Append(doubleTab).Append("auto iServMgr = IServiceManager::Get();\n");
567     sb.Append(doubleTab).Append("if (iServMgr == nullptr) {\n");
568     sb.Append(doubleTab + TAB).Append("HDF_LOGW(\"Reconnect failed : iServMgr is null\");\n");
569     sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
570     sb.Append(doubleTab).Append("};\n");
571     sb.Append(doubleTab).Append("proxy->reconnectRemote_ = ");
572     sb.Append("iServMgr->GetService(proxy->serviceName_.c_str());\n");
573     sb.Append(doubleTab).Append("if (proxy->reconnectRemote_ == nullptr) {\n");
574     sb.Append(doubleTab + TAB).Append("HDF_LOGW(\"Reconnect failed : reconnectRemote_ is null\");\n");
575     sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
576     sb.Append(doubleTab).Append("}\n");
577     sb.Append(doubleTab).Append("proxy->servMgr_ = ");
578     sb.Append("OHOS::HDI::hdi_objcast<IServiceManager>(iServMgr);\n");
579     sb.Append(doubleTab).Append("if (proxy->servMgr_ == nullptr) {\n");
580     sb.Append(doubleTab + TAB).Append("HDF_LOGE(\"%{public}s:get IServiceManager failed!\", __func__);\n");
581     sb.Append(doubleTab + TAB).Append("return HDF_FAILURE;\n");
582     sb.Append(doubleTab).Append("}\n");
583     sb.Append(doubleTab).Append("proxy->servMgr_->AddDeathRecipient(\n");
584     sb.Append(doubleTab + TAB).AppendFormat("new %s::%s(proxy));\n",
585         EmitDefinitionByInterface(interface_, proxyName_).c_str(), devmgrDeathRecipientName_.c_str());
586     sb.Append(doubleTab).Append("proxy->isReconnected_ = true;\n");
587     sb.Append(doubleTab).Append("return HDF_SUCCESS;\n");
588     sb.Append(prefix).Append("}\n");
589 }
590 
GetNameSpaceByInterface(AutoPtr<ASTInterfaceType> interface,const std::string & name)591 std::string CppClientProxyCodeEmitter::GetNameSpaceByInterface(AutoPtr<ASTInterfaceType> interface,
592     const std::string &name)
593 {
594     std::string value = EmitDefinitionByInterface(interface, name);
595     if (value.empty()) {
596         return "";
597     }
598     size_t index = value.rfind(':');
599     return (index == std::string::npos) ? value : value.substr(0, index + 1);
600 }
601 
EmitProxyPassthroughtLoadImpl(StringBuilder & sb,const std::string & prefix) const602 void CppClientProxyCodeEmitter::EmitProxyPassthroughtLoadImpl(StringBuilder &sb, const std::string &prefix) const
603 {
604     sb.Append(prefix).AppendFormat("if (isStub) {\n");
605 
606     if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
607         sb.Append(prefix + TAB).Append("std::string desc = ");
608         sb.Append("std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(");
609         sb.AppendFormat("%s::GetDescriptor());\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
610     } else {
611         sb.Append(prefix + TAB).AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n",
612             EmitDefinitionByInterface(interface_, interfaceName_).c_str());
613     }
614     sb.Append(prefix + TAB).AppendFormat("std::string svrName = (serviceName == \"%s\") ? \"service\" : "
615         "serviceName;\n", FileName(implName_).c_str());
616 
617     if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
618         sb.Append(prefix + TAB).AppendFormat("std::shared_ptr<%s> impl = \\\n", \
619             EmitDefinitionByInterface(interface_, interfaceName_).c_str());
620     } else {
621         sb.Append(prefix + TAB).AppendFormat("sptr<%s> impl = \\\n", \
622             EmitDefinitionByInterface(interface_, interfaceName_).c_str());
623     }
624     sb.Append(prefix + TAB + TAB).AppendFormat("reinterpret_cast<%s *>(LoadHdiImpl(desc.c_str(), svrName.c_str()));\n",
625         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
626     sb.Append(prefix + TAB).Append("if (impl == nullptr) {\n");
627     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"failed to load hdi impl %{public}s\", desc.data());\n");
628     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n").Append(prefix + TAB).Append("}\n");
629     std::string serMajorName = "serMajorVer";
630     std::string serMinorName = "serMinorVer";
631     sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMajorName.c_str());
632     sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMinorName.c_str());
633     sb.Append(prefix + TAB).AppendFormat("int32_t %s = impl->GetVersion(%s, %s);\n",
634         HdiTypeEmitter::errorCodeName_.c_str(), serMajorName.c_str(), serMinorName.c_str());
635     sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", HdiTypeEmitter::errorCodeName_.c_str());
636     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: get version failed!\", __func__);\n");
637     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n").Append(prefix + TAB).Append("}\n\n");
638     sb.Append(prefix + TAB).AppendFormat("if (%s != %d) {\n", serMajorName.c_str(), ast_->GetMajorVer());
639     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! version of service:%u.%u");
640     sb.AppendFormat(", version of client:%d.%d\", __func__, ", ast_->GetMajorVer(), ast_->GetMinorVer());
641     sb.AppendFormat("%s, %s);\n", serMajorName.c_str(), serMinorName.c_str());
642     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n").Append(prefix + TAB).Append("}\n");
643     sb.Append(prefix + TAB).AppendFormat("if (%s < %d) {\n", serMinorName.c_str(), ast_->GetMinorVer());
644     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check Minor version failed! \"\n");
645     sb.Append(prefix + TAB + TAB + TAB).AppendFormat("\"client minor version(%u) should be less or equal to "
646         "implementation minor version(%%u).", ast_->GetMinorVer());
647     sb.AppendFormat("\", __func__, %s);\n", serMinorName.c_str());
648     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n").Append(prefix + TAB).Append("}\n\n");
649     sb.Append(prefix + TAB).Append("return impl;\n").Append(prefix).Append("}\n\n");
650 }
651 
EmitProxyMethodImpls(StringBuilder & sb,const std::string & prefix)652 void CppClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder &sb, const std::string &prefix)
653 {
654     AutoPtr<ASTInterfaceType> interface = interface_;
655     AutoPtr<ASTInterfaceType> metaInterface = interface_;
656     while (interface != nullptr) {
657         for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
658             EmitProxyMethodImpl(interface, method, sb, prefix);
659             sb.Append("\n");
660         }
661         interface = interface->GetExtendsInterface();
662         if (interface != nullptr) {
663             metaInterface = interface;
664         }
665     }
666     AutoPtr<ASTMethod> verMethod = interface_->GetVersionMethod();
667     EmitProxyMethodImpl(metaInterface, verMethod, sb, prefix);
668     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
669         sb.Append("\n");
670         EmitProxyStaticMethodImpl(method, sb, prefix);
671     }
672     if (interface_->GetExtendsInterface() == nullptr) {
673         sb.Append("\n");
674         EmitProxyStaticMethodImpl(interface_->GetVersionMethod(), sb, prefix);
675     }
676 }
677 
EmitProxyIsProxyMethodImpl(StringBuilder & sb,const std::string & prefix) const678 void CppClientProxyCodeEmitter::EmitProxyIsProxyMethodImpl(StringBuilder &sb, const std::string &prefix) const
679 {
680     sb.Append(prefix).Append("inline bool IsProxy() override\n");
681     sb.Append(prefix).Append("{\n");
682     sb.Append(prefix + TAB).Append("return true;\n");
683     sb.Append(prefix).Append("}\n\n");
684 }
685 
EmitProxyCastFromMethodImpls(StringBuilder & sb,const std::string & prefix) const686 void CppClientProxyCodeEmitter::EmitProxyCastFromMethodImpls(StringBuilder &sb, const std::string &prefix) const
687 {
688     AutoPtr<ASTInterfaceType> interface = interface_->GetExtendsInterface();
689     while (interface != nullptr) {
690         EmitProxyCastFromMethodImpl(interface, sb, prefix);
691         sb.Append(prefix).Append("\n");
692         interface = interface->GetExtendsInterface();
693     }
694 }
695 
EmitProxyCastFromMethodImpl(const AutoPtr<ASTInterfaceType> interface,StringBuilder & sb,const std::string & prefix) const696 void CppClientProxyCodeEmitter::EmitProxyCastFromMethodImpl(const AutoPtr<ASTInterfaceType> interface,
697     StringBuilder &sb, const std::string &prefix) const
698 {
699     std::string currentInterface = EmitDefinitionByInterface(interface_, interfaceName_);
700     std::string parentInterface = EmitDefinitionByInterface(interface, interfaceName_);
701 
702     sb.Append(prefix).AppendFormat("sptr<%s> %s::CastFrom(const sptr<%s> &parent)\n",
703         currentInterface.c_str(), currentInterface.c_str(), parentInterface.c_str());
704     sb.Append(prefix).Append("{\n");
705     sb.Append(prefix + TAB).AppendFormat("return CastFromTemplate<%s, %s>(parent);\n",
706         currentInterface.c_str(), parentInterface.c_str());
707     sb.Append(prefix).Append("}\n");
708 }
709 
EmitProxyCastFromMethodImplTemplate(StringBuilder & sb,const std::string & prefix) const710 void CppClientProxyCodeEmitter::EmitProxyCastFromMethodImplTemplate(StringBuilder &sb, const std::string &prefix) const
711 {
712     std::string serMajorName = "serMajorVer";
713     std::string serMinorName = "serMinorVer";
714 
715     sb.Append(prefix).Append("template<typename ChildType, typename ParentType>\n");
716     sb.Append(prefix).Append("static sptr<ChildType> CastFromTemplate(const sptr<ParentType> &parent)\n");
717     sb.Append(prefix).Append("{\n");
718     sb.Append(prefix + TAB).Append("if (parent == nullptr) {\n");
719     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:parent is nullptr!\", __func__);\n");
720     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
721     sb.Append(prefix + TAB).Append("}\n\n");
722 
723     sb.Append(prefix + TAB).Append("if (!parent->IsProxy()) {\n");
724     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:not proxy, not support castfrom!\", __func__);\n");
725     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
726     sb.Append(prefix + TAB).Append("}\n\n");
727 
728     sb.Append(prefix + TAB).AppendFormat("sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<ParentType>(parent);\n");
729     sb.Append(prefix + TAB).Append("if (remote == nullptr) {\n");
730     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:hdi_objcast failed!\", __func__);\n");
731     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
732     sb.Append(prefix + TAB).Append("}\n\n");
733 
734     sb.Append(prefix + TAB).AppendFormat("sptr<ChildType> proxy = OHOS::HDI::hdi_facecast<ChildType>(remote);\n");
735     sb.Append(prefix + TAB).Append("if (proxy == nullptr) {\n");
736     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:hdi_facecast failed!\", __func__);\n");
737     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
738     sb.Append(prefix + TAB).Append("}\n\n");
739 
740     sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMajorName.c_str());
741     sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMinorName.c_str());
742     sb.Append(prefix + TAB).AppendFormat("int32_t %s = proxy->GetVersion(%s, %s);\n",
743         HdiTypeEmitter::errorCodeName_.c_str(), serMajorName.c_str(), serMinorName.c_str());
744     sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", HdiTypeEmitter::errorCodeName_.c_str());
745     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get version failed!\", __func__);\n");
746     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n").Append(prefix + TAB).Append("}\n\n");
747 
748     sb.Append(prefix + TAB).AppendFormat("if (%s != %d) {\n", serMajorName.c_str(), ast_->GetMajorVer());
749     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! ");
750     sb.Append("version of service:%u.%u");
751     sb.AppendFormat(", version of client:%d.%d\", __func__, ", ast_->GetMajorVer(), ast_->GetMinorVer());
752     sb.AppendFormat("%s, %s);\n", serMajorName.c_str(), serMinorName.c_str());
753     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
754     sb.Append(prefix + TAB).Append("}\n\n");
755 
756     sb.Append(prefix + TAB).AppendFormat("if (%s < %d) {\n", serMinorName.c_str(), ast_->GetMinorVer());
757     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check Minor version failed! \"\n");
758     sb.Append(prefix + TAB + TAB + TAB);
759     sb.AppendFormat("\"client minor version(%u) should be less or equal to server minor version(%%u).", \
760         ast_->GetMinorVer());
761     sb.AppendFormat("\", __func__, %s);\n", serMinorName.c_str());
762     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n").Append(prefix + TAB).Append("}\n\n");
763 
764     sb.Append(prefix + TAB).Append("return proxy;\n").Append(prefix).Append("}\n");
765 }
766 
EmitProxyMethodImpl(const AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)767 void CppClientProxyCodeEmitter::EmitProxyMethodImpl(const AutoPtr<ASTInterfaceType> interface,
768     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
769 {
770     if (method->GetParameterNumber() == 0) {
771         sb.Append(prefix).AppendFormat(
772             "int32_t %s::%s()\n", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
773     } else {
774         StringBuilder paramStr;
775         paramStr.Append(prefix).AppendFormat(
776             "int32_t %s::%s(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
777         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
778             AutoPtr<ASTParameter> param = method->GetParameter(i);
779             EmitInterfaceMethodParameter(param, paramStr, "");
780             if (i + 1 < method->GetParameterNumber()) {
781                 paramStr.Append(", ");
782             }
783         }
784 
785         paramStr.Append(")");
786 
787         sb.Append(SpecificationParam(paramStr, prefix + TAB));
788         sb.Append("\n");
789     }
790     EmitProxyMethodBody(interface, method, sb, prefix);
791 }
792 
EmitProxyStaticMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)793 void CppClientProxyCodeEmitter::EmitProxyStaticMethodImpl(
794     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
795 {
796     if (method->GetParameterNumber() == 0) {
797         sb.Append(prefix).AppendFormat("int32_t %s::%s_(const sptr<IRemoteObject> remote)\n",
798             EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
799     } else {
800         StringBuilder paramStr;
801         paramStr.Append(prefix).AppendFormat(
802             "int32_t %s::%s_(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
803         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
804             AutoPtr<ASTParameter> param = method->GetParameter(i);
805             EmitInterfaceMethodParameter(param, paramStr, "");
806             paramStr.Append(", ");
807         }
808 
809         paramStr.Append("const sptr<IRemoteObject> remote)");
810         sb.Append(SpecificationParam(paramStr, prefix + TAB));
811         sb.Append("\n");
812     }
813     EmitProxyStaticMethodBody(method, sb, prefix);
814 }
815 
EmitProxyMethodBody(const AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)816 void CppClientProxyCodeEmitter::EmitProxyMethodBody(const AutoPtr<ASTInterfaceType> interface,
817     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
818 {
819     sb.Append(prefix).Append("{\n");
820     sb.Append(prefix + TAB).AppendFormat("return %s::%s_(",
821         EmitDefinitionByInterface(interface, proxyName_).c_str(), method->GetName().c_str());
822     if (method->GetParameterNumber() > 0) {
823         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
824             AutoPtr<ASTParameter> param = method->GetParameter(i);
825             sb.Append(param->GetName().c_str());
826             sb.Append(", ");
827         }
828     }
829     if (!interface_->IsSerializable() && (!interface_->IsCallback())) {
830         sb.Append("GetCurrentRemote());\n");
831     } else {
832         sb.Append("Remote());\n");
833     }
834     sb.Append(prefix).Append("}\n");
835 }
836 
EmitProxyStaticMethodBody(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)837 void CppClientProxyCodeEmitter::EmitProxyStaticMethodBody(
838     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
839 {
840     std::string option = method->IsOneWay() ? "MessageOption::TF_ASYNC" : "MessageOption::TF_SYNC";
841     sb.Append(prefix).Append("{\n");
842     sb.Append(prefix + TAB).AppendFormat("MessageParcel %s;\n", HdiTypeEmitter::dataParcelName_.c_str());
843     sb.Append(prefix + TAB).AppendFormat("MessageParcel %s;\n", HdiTypeEmitter::replyParcelName_.c_str());
844     sb.Append(prefix + TAB).AppendFormat("MessageOption %s(%s);\n", optionName_.c_str(), option.c_str());
845     sb.Append("\n");
846 
847     // write interface token
848     EmitWriteInterfaceToken(HdiTypeEmitter::dataParcelName_, sb, prefix + TAB);
849     sb.Append("\n");
850 
851     EmitWriteFlagOfNeedSetMem(method, HdiTypeEmitter::dataParcelName_, sb, prefix + TAB);
852 
853     if (method->GetParameterNumber() > 0) {
854         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
855             AutoPtr<ASTParameter> param = method->GetParameter(i);
856             if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
857                 EmitWriteMethodParameter(param, HdiTypeEmitter::dataParcelName_, sb, prefix + TAB);
858                 sb.Append("\n");
859             }
860         }
861     }
862     sb.Append(prefix + TAB).AppendFormat("if (remote == nullptr) {\n");
863     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s: invalid remote object!\", __func__);\n");
864     sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_OBJECT;\n");
865     sb.Append(prefix + TAB).Append("}\n\n");
866     sb.Append(prefix + TAB).AppendFormat("int32_t %s = remote->SendRequest(%s, %s, %s, %s);\n",
867         HdiTypeEmitter::errorCodeName_.c_str(), EmitMethodCmdID(method).c_str(),
868         HdiTypeEmitter::dataParcelName_.c_str(), HdiTypeEmitter::replyParcelName_.c_str(), optionName_.c_str());
869     sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", HdiTypeEmitter::errorCodeName_.c_str());
870     sb.Append(prefix + TAB + TAB).AppendFormat(
871         "HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n",
872         HdiTypeEmitter::errorCodeName_.c_str());
873     sb.Append(prefix + TAB + TAB).AppendFormat("return %s;\n", HdiTypeEmitter::errorCodeName_.c_str());
874     sb.Append(prefix + TAB).Append("}\n");
875 
876     if (!method->IsOneWay()) {
877         sb.Append("\n");
878         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
879             AutoPtr<ASTParameter> param = method->GetParameter(i);
880             if (param->GetAttribute() == ASTParamAttr::PARAM_OUT) {
881                 EmitReadMethodParameter(param, TypeMode::PARAM_OUT, sb, prefix + TAB);
882                 sb.Append("\n");
883             }
884         }
885     }
886 
887     sb.Append(prefix + TAB).AppendFormat("return %s;\n", HdiTypeEmitter::errorCodeName_.c_str());
888     sb.Append(prefix).Append("}\n");
889 }
890 
EmitWriteInterfaceToken(const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const891 void CppClientProxyCodeEmitter::EmitWriteInterfaceToken(
892     const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
893 {
894     sb.Append(prefix).AppendFormat("if (!%s.WriteInterfaceToken(%s::GetDescriptor())) {\n", parcelName.c_str(),
895         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
896     sb.Append(prefix + TAB)
897         .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write interface descriptor!\", __func__);\n");
898     sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
899     sb.Append(prefix).Append("}\n");
900 }
901 
EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> & method,const std::string & dataBufName,StringBuilder & sb,const std::string & prefix) const902 void CppClientProxyCodeEmitter::EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> &method,
903     const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const
904 {
905     if (NeedFlag(method)) {
906         sb.Append(prefix).AppendFormat("if (!%s.WriteBool(false)) {\n", dataBufName.c_str());
907         sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s:failed to write flag of memory setting!\", __func__);\n");
908         sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
909         sb.Append(prefix).Append("}\n\n");
910     }
911 }
912 
EmitUtilMethods(StringBuilder & sb,bool isDecl)913 void CppClientProxyCodeEmitter::EmitUtilMethods(StringBuilder &sb, bool isDecl)
914 {
915     UtilMethodMap methods;
916     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
917         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
918             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
919             AutoPtr<HdiTypeEmitter> typeEmitter = GetTypeEmitter(param->GetType());
920             if (typeEmitter == nullptr) {
921                 continue;
922             }
923             if (param->GetAttribute() == ASTParamAttr::PARAM_IN) {
924                 typeEmitter->EmitCppWriteMethods(methods, "", "", isDecl);
925             } else {
926                 typeEmitter->EmitCppReadMethods(methods, "", "", isDecl);
927             }
928         }
929     }
930     EmitUtilMethodMap(sb, methods);
931 }
932 } // namespace Idl
933 } // namespace OHOS