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