1 /*
2 * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "codegen/cpp_client_proxy_code_emitter.h"
10 #include "util/file.h"
11 #include "util/logger.h"
12
13 namespace OHOS {
14 namespace HDI {
ResolveDirectory(const std::string & targetDirectory)15 bool CppClientProxyCodeEmitter::ResolveDirectory(const std::string &targetDirectory)
16 {
17 if (ast_->GetASTFileType() == ASTFileType::AST_IFACE || ast_->GetASTFileType() == ASTFileType::AST_ICALLBACK) {
18 directory_ = GetFileParentPath(targetDirectory);
19 } else {
20 return false;
21 }
22
23 if (!File::CreateParentDir(directory_)) {
24 Logger::E("CppClientProxyCodeEmitter", "Create '%s' failed!", directory_.c_str());
25 return false;
26 }
27
28 return true;
29 }
30
EmitCode()31 void CppClientProxyCodeEmitter::EmitCode()
32 {
33 switch (mode_) {
34 case GenMode::PASSTHROUGH: {
35 if (!interface_->IsSerializable()) {
36 EmitPassthroughProxySourceFile();
37 }
38 break;
39 }
40 case GenMode::IPC: {
41 EmitProxyHeaderFile();
42 EmitProxySourceFile();
43 }
44 default:
45 break;
46 }
47 }
48
EmitProxyHeaderFile()49 void CppClientProxyCodeEmitter::EmitProxyHeaderFile()
50 {
51 std::string filePath =
52 File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_ + "Proxy").c_str()));
53 File file(filePath, File::WRITE);
54 StringBuilder sb;
55
56 EmitLicense(sb);
57 EmitHeadMacro(sb, proxyFullName_);
58 sb.Append("\n");
59 EmitProxyHeaderInclusions(sb);
60 sb.Append("\n");
61 EmitBeginNamespace(sb);
62 sb.Append("\n");
63 EmitProxyDecl(sb, "");
64 sb.Append("\n");
65 EmitEndNamespace(sb);
66 sb.Append("\n");
67 EmitTailMacro(sb, proxyFullName_);
68
69 std::string data = sb.ToString();
70 file.WriteData(data.c_str(), data.size());
71 file.Flush();
72 file.Close();
73 }
74
EmitProxyHeaderInclusions(StringBuilder & sb)75 void CppClientProxyCodeEmitter::EmitProxyHeaderInclusions(StringBuilder &sb)
76 {
77 HeaderFile::HeaderFileSet headerFiles;
78
79 headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
80 if (interface_->GetExtendsInterface() != nullptr) {
81 headerFiles.emplace(
82 HeaderFileType::OWN_HEADER_FILE, EmitHeaderNameByInterface(interface_->GetExtendsInterface(), proxyName_));
83 }
84 GetHeaderOtherLibInclusions(headerFiles);
85
86 for (const auto &file : headerFiles) {
87 sb.AppendFormat("%s\n", file.ToString().c_str());
88 }
89 }
90
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const91 void CppClientProxyCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
92 {
93 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
94 }
95
EmitProxyDecl(StringBuilder & sb,const std::string & prefix)96 void CppClientProxyCodeEmitter::EmitProxyDecl(StringBuilder &sb, const std::string &prefix)
97 {
98 (void)prefix;
99 sb.AppendFormat("class %s : public IProxyBroker<%s> {\n", proxyName_.c_str(),
100 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
101 sb.Append("public:\n");
102 EmitProxyConstructor(sb, TAB);
103 sb.Append("\n");
104 EmitProxyMethodDecls(sb, TAB);
105 sb.Append("\n");
106 sb.Append("private:\n");
107 EmitProxyConstants(sb, TAB);
108 sb.Append("};\n");
109 }
110
EmitProxyConstructor(StringBuilder & sb,const std::string & prefix) const111 void CppClientProxyCodeEmitter::EmitProxyConstructor(StringBuilder &sb, const std::string &prefix) const
112 {
113 sb.Append(prefix).AppendFormat("explicit %s(const sptr<IRemoteObject>& remote)", proxyName_.c_str());
114 sb.AppendFormat(
115 " : IProxyBroker<%s>(remote) {}\n\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
116 sb.Append(prefix).AppendFormat("virtual ~%s() = default;\n", proxyName_.c_str());
117 }
118
EmitProxyMethodDecls(StringBuilder & sb,const std::string & prefix) const119 void CppClientProxyCodeEmitter::EmitProxyMethodDecls(StringBuilder &sb, const std::string &prefix) const
120 {
121 AutoPtr<ASTInterfaceType> interface = interface_;
122 while (interface != nullptr) {
123 for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
124 EmitProxyMethodDecl(method, sb, prefix);
125 sb.Append("\n");
126 }
127 interface = interface->GetExtendsInterface();
128 }
129 EmitProxyMethodDecl(interface_->GetVersionMethod(), sb, prefix);
130 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
131 sb.Append("\n");
132 EmitProxyStaticMethodDecl(method, sb, prefix);
133 }
134 if (interface_->GetExtendsInterface() == nullptr) {
135 sb.Append("\n");
136 EmitProxyStaticMethodDecl(interface_->GetVersionMethod(), sb, prefix);
137 }
138 }
139
EmitProxyMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const140 void CppClientProxyCodeEmitter::EmitProxyMethodDecl(
141 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
142 {
143 if (method->GetParameterNumber() == 0) {
144 sb.Append(prefix).AppendFormat("int32_t %s() override;\n", method->GetName().c_str());
145 } else {
146 StringBuilder paramStr;
147 paramStr.Append(prefix).AppendFormat("int32_t %s(", method->GetName().c_str());
148
149 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
150 AutoPtr<ASTParameter> param = method->GetParameter(i);
151 EmitProxyMethodParameter(param, paramStr, "");
152 if (i + 1 < method->GetParameterNumber()) {
153 paramStr.Append(", ");
154 }
155 }
156
157 paramStr.Append(") override;");
158
159 sb.Append(SpecificationParam(paramStr, prefix + TAB));
160 sb.Append("\n");
161 }
162 }
163
EmitProxyStaticMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const164 void CppClientProxyCodeEmitter::EmitProxyStaticMethodDecl(
165 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
166 {
167 if (method->GetParameterNumber() == 0) {
168 sb.Append(prefix).AppendFormat(
169 "static int32_t %s_(const sptr<IRemoteObject> remote);\n", method->GetName().c_str());
170 } else {
171 StringBuilder paramStr;
172 paramStr.Append(prefix).AppendFormat("static int32_t %s_(", method->GetName().c_str());
173
174 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
175 AutoPtr<ASTParameter> param = method->GetParameter(i);
176 EmitProxyMethodParameter(param, paramStr, "");
177 paramStr.Append(", ");
178 }
179 paramStr.Append("const sptr<IRemoteObject> remote");
180
181 paramStr.Append(");");
182
183 sb.Append(SpecificationParam(paramStr, prefix + TAB));
184 sb.Append("\n");
185 }
186 }
187
EmitProxyConstants(StringBuilder & sb,const std::string & prefix) const188 void CppClientProxyCodeEmitter::EmitProxyConstants(StringBuilder &sb, const std::string &prefix) const
189 {
190 sb.Append(prefix).AppendFormat(
191 "static inline BrokerDelegator<%s> delegator_;\n", EmitDefinitionByInterface(interface_, proxyName_).c_str());
192 }
193
EmitProxyMethodParameter(const AutoPtr<ASTParameter> & param,StringBuilder & sb,const std::string & prefix) const194 void CppClientProxyCodeEmitter::EmitProxyMethodParameter(
195 const AutoPtr<ASTParameter> ¶m, StringBuilder &sb, const std::string &prefix) const
196 {
197 sb.Append(prefix).Append(param->EmitCppParameter());
198 }
199
EmitPassthroughProxySourceFile()200 void CppClientProxyCodeEmitter::EmitPassthroughProxySourceFile()
201 {
202 std::string filePath =
203 File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(proxyName_).c_str()));
204 File file(filePath, File::WRITE);
205 StringBuilder sb;
206
207 EmitLicense(sb);
208 EmitPassthroughProxySourceInclusions(sb);
209 sb.Append("\n");
210 EmitLogTagMacro(sb, FileName(proxyName_));
211 sb.Append("\n");
212 EmitBeginNamespace(sb);
213 EmitGetMethodImpl(sb, "");
214 sb.Append("\n");
215 EmitPassthroughGetInstanceMethodImpl(sb, "");
216 EmitEndNamespace(sb);
217
218 std::string data = sb.ToString();
219 file.WriteData(data.c_str(), data.size());
220 file.Flush();
221 file.Close();
222 }
223
EmitPassthroughProxySourceInclusions(StringBuilder & sb)224 void CppClientProxyCodeEmitter::EmitPassthroughProxySourceInclusions(StringBuilder &sb)
225 {
226 HeaderFile::HeaderFileSet headerFiles;
227
228 headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
229 if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
230 headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "codecvt");
231 headerFiles.emplace(HeaderFileType::CPP_STD_HEADER_FILE, "locale");
232 } else {
233 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
234 }
235 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
236 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
237
238 for (const auto &file : headerFiles) {
239 sb.AppendFormat("%s\n", file.ToString().c_str());
240 }
241 }
242
EmitPassthroughGetInstanceMethodImpl(StringBuilder & sb,const std::string & prefix) const243 void CppClientProxyCodeEmitter::EmitPassthroughGetInstanceMethodImpl(StringBuilder &sb,
244 const std::string &prefix) const
245 {
246 sb.Append(prefix).AppendFormat("%s %s::Get(const std::string &serviceName, bool isStub)\n",
247 interface_->EmitCppType().c_str(), interface_->GetName().c_str());
248 sb.Append(prefix).Append("{\n");
249 EmitProxyPassthroughtLoadImpl(sb, prefix + TAB);
250 sb.Append(prefix + TAB).Append("return nullptr;\n");
251 sb.Append(prefix).Append("}\n");
252 }
253
EmitProxySourceFile()254 void CppClientProxyCodeEmitter::EmitProxySourceFile()
255 {
256 std::string filePath =
257 File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(proxyName_).c_str()));
258 File file(filePath, File::WRITE);
259 StringBuilder sb;
260
261 EmitLicense(sb);
262 EmitProxySourceInclusions(sb);
263 sb.Append("\n");
264 EmitLogTagMacro(sb, FileName(proxyName_));
265 sb.Append("\n");
266 EmitBeginNamespace(sb);
267 sb.Append("\n");
268 UtilMethodMap utilMethods;
269 GetUtilMethods(utilMethods);
270 EmitUtilMethods(sb, "", utilMethods, true);
271 sb.Append("\n");
272 if (!interface_->IsSerializable()) {
273 EmitGetMethodImpl(sb, "");
274 sb.Append("\n");
275 EmitGetInstanceMethodImpl(sb, "");
276 sb.Append("\n");
277 }
278 EmitUtilMethods(sb, "", utilMethods, false);
279 EmitProxyMethodImpls(sb, "");
280 sb.Append("\n");
281 EmitEndNamespace(sb);
282
283 std::string data = sb.ToString();
284 file.WriteData(data.c_str(), data.size());
285 file.Flush();
286 file.Close();
287 }
288
EmitProxySourceInclusions(StringBuilder & sb)289 void CppClientProxyCodeEmitter::EmitProxySourceInclusions(StringBuilder &sb)
290 {
291 HeaderFile::HeaderFileSet headerFiles;
292 headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(proxyName_));
293 GetSourceOtherLibInclusions(headerFiles);
294
295 for (const auto &file : headerFiles) {
296 sb.AppendFormat("%s\n", file.ToString().c_str());
297 }
298 }
299
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const300 void CppClientProxyCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
301 {
302 if (!interface_->IsSerializable()) {
303 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iservmgr_hdi");
304 }
305 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
306 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
307 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_option");
308 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_parcel");
309 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
310 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
311
312 const AST::TypeStringMap &types = ast_->GetTypes();
313 for (const auto &pair : types) {
314 AutoPtr<ASTType> type = pair.second;
315 if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
316 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
317 break;
318 }
319 }
320
321 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
322 for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
323 AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
324 AutoPtr<ASTType> paramType = param->GetType();
325 if (param->GetAttribute() == ParamAttr::PARAM_IN &&
326 (paramType->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
327 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
328 }
329
330 if (param->GetAttribute() == ParamAttr::PARAM_OUT &&
331 (paramType->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
332 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
333 }
334 }
335 }
336 }
337
EmitGetMethodImpl(StringBuilder & sb,const std::string & prefix) const338 void CppClientProxyCodeEmitter::EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
339 {
340 sb.Append(prefix).AppendFormat("%s %s::Get(bool isStub)\n", interface_->EmitCppType().c_str(),
341 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
342 sb.Append(prefix).Append("{\n");
343 sb.Append(prefix + TAB)
344 .AppendFormat("return %s::Get(\"%s\", isStub);\n", interfaceName_.c_str(), FileName(implName_).c_str());
345 sb.Append(prefix).Append("}\n");
346 }
347
EmitGetInstanceMethodImpl(StringBuilder & sb,const std::string & prefix)348 void CppClientProxyCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix)
349 {
350 std::string objName = "proxy";
351 std::string serMajorName = "serMajorVer";
352 std::string serMinorName = "serMinorVer";
353 sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(const std::string& serviceName, bool isStub)\n",
354 EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
355 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
356 sb.Append(prefix).Append("{\n");
357 EmitProxyPassthroughtLoadImpl(sb, prefix + TAB);
358 sb.Append(prefix + TAB).Append("using namespace OHOS::HDI::ServiceManager::V1_0;\n");
359 sb.Append(prefix + TAB).Append("auto servMgr = IServiceManager::Get();\n");
360 sb.Append(prefix + TAB).Append("if (servMgr == nullptr) {\n");
361 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get IServiceManager failed!\", __func__);\n");
362 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
363 sb.Append(prefix + TAB).Append("}\n\n");
364 sb.Append(prefix + TAB).Append("sptr<IRemoteObject> remote = ");
365 sb.Append("servMgr->GetService(serviceName.c_str());\n");
366 sb.Append(prefix + TAB).Append("if (remote == nullptr) {\n");
367 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get remote object failed!\", __func__);\n");
368 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
369 sb.Append(prefix + TAB).Append("}\n\n");
370 sb.Append(prefix + TAB).AppendFormat("sptr<%s> %s = OHOS::HDI::hdi_facecast<%s>(remote);\n",
371 EmitDefinitionByInterface(interface_, interfaceName_).c_str(), objName.c_str(),
372 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
373 sb.Append(prefix + TAB).AppendFormat("if (%s == nullptr) {\n", objName.c_str());
374 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:iface_cast failed!\", __func__);\n");
375 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
376 sb.Append(prefix + TAB).Append("}\n\n");
377
378 sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMajorName.c_str());
379 sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", serMinorName.c_str());
380 sb.Append(prefix + TAB).AppendFormat("int32_t %s = %s->GetVersion(%s, %s);\n",
381 errorCodeName_.c_str(), objName.c_str(), serMajorName.c_str(), serMinorName.c_str());
382 sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
383 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:get version failed!\", __func__);\n");
384 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
385 sb.Append(prefix + TAB).Append("}\n\n");
386
387 sb.Append(prefix + TAB).AppendFormat("if (%s != %d) {\n", serMajorName.c_str(), ast_->GetMajorVer());
388 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"%{public}s:check version failed! ");
389 sb.Append("version of service:%u.%u");
390 sb.AppendFormat(", version of client:%d.%d\", __func__, ", ast_->GetMajorVer(), ast_->GetMinorVer());
391 sb.AppendFormat("%s, %s);\n", serMajorName.c_str(), serMinorName.c_str());
392 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
393 sb.Append(prefix + TAB).Append("}\n\n");
394 sb.Append(prefix + TAB).AppendFormat("return %s;\n", objName.c_str());
395 sb.Append(prefix).Append("}\n");
396 }
397
EmitProxyPassthroughtLoadImpl(StringBuilder & sb,const std::string & prefix) const398 void CppClientProxyCodeEmitter::EmitProxyPassthroughtLoadImpl(StringBuilder &sb, const std::string &prefix) const
399 {
400 sb.Append(prefix).AppendFormat("if (isStub) {\n");
401
402 if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
403 sb.Append(prefix + TAB).Append("std::string desc = ");
404 sb.Append("std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.to_bytes(");
405 sb.AppendFormat("%s::GetDescriptor());\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
406 } else {
407 sb.Append(prefix + TAB).AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n",
408 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
409 }
410 sb.Append(prefix + TAB).Append("void *impl = LoadHdiImpl(desc.c_str(), ");
411 sb.AppendFormat("serviceName == \"%s\" ? \"service\" : serviceName.c_str());\n", FileName(implName_).c_str());
412 sb.Append(prefix + TAB).Append("if (impl == nullptr) {\n");
413 sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"failed to load hdi impl %{public}s\", desc.data());\n");
414 sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
415 sb.Append(prefix + TAB).Append("}\n");
416
417 if (Options::GetInstance().GetSystemLevel() == SystemLevel::LITE) {
418 sb.Append(prefix + TAB).AppendFormat("return std::shared_ptr<%s>(reinterpret_cast<%s *>(impl));\n",
419 EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
420 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
421 } else {
422 sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n",
423 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
424 }
425 sb.Append(prefix).Append("}\n\n");
426 }
427
EmitProxyMethodImpls(StringBuilder & sb,const std::string & prefix)428 void CppClientProxyCodeEmitter::EmitProxyMethodImpls(StringBuilder &sb, const std::string &prefix)
429 {
430 AutoPtr<ASTInterfaceType> interface = interface_;
431 AutoPtr<ASTInterfaceType> metaInterface = interface_;
432 while (interface != nullptr) {
433 for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
434 EmitProxyMethodImpl(interface, method, sb, prefix);
435 sb.Append("\n");
436 }
437 interface = interface->GetExtendsInterface();
438 if (interface != nullptr) {
439 metaInterface = interface;
440 }
441 }
442 AutoPtr<ASTMethod> verMethod = interface_->GetVersionMethod();
443 EmitProxyMethodImpl(metaInterface, verMethod, sb, prefix);
444 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
445 sb.Append("\n");
446 EmitProxyStaticMethodImpl(method, sb, prefix);
447 }
448 if (interface_->GetExtendsInterface() == nullptr) {
449 sb.Append("\n");
450 EmitProxyStaticMethodImpl(interface_->GetVersionMethod(), sb, prefix);
451 }
452 }
453
EmitProxyMethodImpl(const AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)454 void CppClientProxyCodeEmitter::EmitProxyMethodImpl(const AutoPtr<ASTInterfaceType> interface,
455 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
456 {
457 if (method->GetParameterNumber() == 0) {
458 sb.Append(prefix).AppendFormat(
459 "int32_t %s::%s()\n", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
460 } else {
461 StringBuilder paramStr;
462 paramStr.Append(prefix).AppendFormat(
463 "int32_t %s::%s(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
464 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
465 AutoPtr<ASTParameter> param = method->GetParameter(i);
466 EmitProxyMethodParameter(param, paramStr, "");
467 if (i + 1 < method->GetParameterNumber()) {
468 paramStr.Append(", ");
469 }
470 }
471
472 paramStr.Append(")");
473
474 sb.Append(SpecificationParam(paramStr, prefix + TAB));
475 sb.Append("\n");
476 }
477 EmitProxyMethodBody(interface, method, sb, prefix);
478 }
479
EmitProxyStaticMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)480 void CppClientProxyCodeEmitter::EmitProxyStaticMethodImpl(
481 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
482 {
483 if (method->GetParameterNumber() == 0) {
484 sb.Append(prefix).AppendFormat("int32_t %s::%s_(const sptr<IRemoteObject> remote)\n",
485 EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
486 } else {
487 StringBuilder paramStr;
488 paramStr.Append(prefix).AppendFormat(
489 "int32_t %s::%s_(", EmitDefinitionByInterface(interface_, proxyName_).c_str(), method->GetName().c_str());
490 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
491 AutoPtr<ASTParameter> param = method->GetParameter(i);
492 EmitProxyMethodParameter(param, paramStr, "");
493 paramStr.Append(", ");
494 }
495
496 paramStr.Append("const sptr<IRemoteObject> remote)");
497 sb.Append(SpecificationParam(paramStr, prefix + TAB));
498 sb.Append("\n");
499 }
500 EmitProxyStaticMethodBody(method, sb, prefix);
501 }
502
EmitProxyMethodBody(const AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)503 void CppClientProxyCodeEmitter::EmitProxyMethodBody(const AutoPtr<ASTInterfaceType> interface,
504 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
505 {
506 sb.Append(prefix).Append("{\n");
507 sb.Append(prefix + TAB).AppendFormat("return %s::%s_(",
508 EmitDefinitionByInterface(interface, proxyName_).c_str(), method->GetName().c_str());
509 if (method->GetParameterNumber() > 0) {
510 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
511 AutoPtr<ASTParameter> param = method->GetParameter(i);
512 sb.Append(param->GetName().c_str());
513 sb.Append(", ");
514 }
515 }
516 sb.Append("Remote());\n");
517 sb.Append(prefix).Append("}\n");
518 }
519
EmitProxyStaticMethodBody(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix)520 void CppClientProxyCodeEmitter::EmitProxyStaticMethodBody(
521 const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix)
522 {
523 std::string option = method->IsOneWay() ? "MessageOption::TF_ASYNC" : "MessageOption::TF_SYNC";
524 sb.Append(prefix).Append("{\n");
525 sb.Append(prefix + TAB).AppendFormat("MessageParcel %s;\n", dataParcelName_.c_str());
526 sb.Append(prefix + TAB).AppendFormat("MessageParcel %s;\n", replyParcelName_.c_str());
527 sb.Append(prefix + TAB).AppendFormat("MessageOption %s(%s);\n", optionName_.c_str(), option.c_str());
528 sb.Append("\n");
529
530 // write interface token
531 EmitWriteInterfaceToken(dataParcelName_, sb, prefix + TAB);
532 sb.Append("\n");
533
534 EmitWriteFlagOfNeedSetMem(method, dataParcelName_, sb, prefix + TAB);
535
536 if (method->GetParameterNumber() > 0) {
537 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
538 AutoPtr<ASTParameter> param = method->GetParameter(i);
539 if (param->GetAttribute() == ParamAttr::PARAM_IN) {
540 EmitWriteMethodParameter(param, dataParcelName_, sb, prefix + TAB);
541 sb.Append("\n");
542 }
543 }
544 }
545
546 sb.Append(prefix + TAB).AppendFormat("int32_t %s = remote->SendRequest(%s, %s, %s, %s);\n", errorCodeName_.c_str(),
547 EmitMethodCmdID(method).c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str());
548 sb.Append(prefix + TAB).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
549 sb.Append(prefix + TAB + TAB).AppendFormat(
550 "HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n", errorCodeName_.c_str());
551 sb.Append(prefix + TAB + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
552 sb.Append(prefix + TAB).Append("}\n");
553
554 if (!method->IsOneWay()) {
555 sb.Append("\n");
556 for (size_t i = 0; i < method->GetParameterNumber(); i++) {
557 AutoPtr<ASTParameter> param = method->GetParameter(i);
558 if (param->GetAttribute() == ParamAttr::PARAM_OUT) {
559 EmitReadMethodParameter(param, replyParcelName_, false, sb, prefix + TAB);
560 sb.Append("\n");
561 }
562 }
563 }
564
565 sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
566 sb.Append(prefix).Append("}\n");
567 }
568
EmitWriteInterfaceToken(const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const569 void CppClientProxyCodeEmitter::EmitWriteInterfaceToken(
570 const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
571 {
572 sb.Append(prefix).AppendFormat("if (!%s.WriteInterfaceToken(%s::GetDescriptor())) {\n", parcelName.c_str(),
573 EmitDefinitionByInterface(interface_, interfaceName_).c_str());
574 sb.Append(prefix + TAB)
575 .AppendFormat("HDF_LOGE(\"%%{public}s: failed to write interface descriptor!\", __func__);\n");
576 sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
577 sb.Append(prefix).Append("}\n");
578 }
579
EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> & method,const std::string & dataBufName,StringBuilder & sb,const std::string & prefix) const580 void CppClientProxyCodeEmitter::EmitWriteFlagOfNeedSetMem(const AutoPtr<ASTMethod> &method,
581 const std::string &dataBufName, StringBuilder &sb, const std::string &prefix) const
582 {
583 if (NeedFlag(method)) {
584 sb.Append(prefix).AppendFormat("if (!%s.WriteBool(false)) {\n", dataBufName.c_str());
585 sb.Append(prefix + TAB).Append("HDF_LOGE(\"%{public}s:failed to write flag of memory setting!\", __func__);\n");
586 sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
587 sb.Append(prefix).Append("}\n\n");
588 }
589 }
590
GetUtilMethods(UtilMethodMap & methods)591 void CppClientProxyCodeEmitter::GetUtilMethods(UtilMethodMap &methods)
592 {
593 for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
594 for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
595 AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
596 AutoPtr<ASTType> paramType = param->GetType();
597 if (param->GetAttribute() == ParamAttr::PARAM_IN) {
598 paramType->RegisterWriteMethod(Options::GetInstance().GetLanguage(), SerMode::PROXY_SER, methods);
599 } else {
600 paramType->RegisterReadMethod(Options::GetInstance().GetLanguage(), SerMode::PROXY_SER, methods);
601 }
602 }
603 }
604 }
605 } // namespace HDI
606 } // namespace OHOS