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