• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_service_stub_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 CppServiceStubCodeEmitter::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("CppServiceStubCodeEmitter", "Create '%s' failed!", directory_.c_str());
25         return false;
26     }
27 
28     return true;
29 }
30 
EmitCode()31 void CppServiceStubCodeEmitter::EmitCode()
32 {
33     if (mode_ == GenMode::IPC) {
34         EmitStubHeaderFile();
35         EmitStubSourceFile();
36     }
37 }
38 
EmitStubHeaderFile()39 void CppServiceStubCodeEmitter::EmitStubHeaderFile()
40 {
41     std::string filePath =
42         File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(stubName_).c_str()));
43     File file(filePath, File::WRITE);
44     StringBuilder sb;
45 
46     EmitLicense(sb);
47     EmitHeadMacro(sb, stubFullName_);
48     sb.Append("\n");
49     EmitStubHeaderInclusions(sb);
50     sb.Append("\n");
51     EmitStubDecl(sb);
52     sb.Append("\n");
53     EmitTailMacro(sb, stubFullName_);
54 
55     std::string data = sb.ToString();
56     file.WriteData(data.c_str(), data.size());
57     file.Flush();
58     file.Close();
59 }
60 
EmitStubHeaderInclusions(StringBuilder & sb)61 void CppServiceStubCodeEmitter::EmitStubHeaderInclusions(StringBuilder &sb)
62 {
63     HeaderFile::HeaderFileSet headerFiles;
64 
65     headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, EmitVersionHeaderName(interfaceName_));
66     if (interface_->GetExtendsInterface() != nullptr) {
67         headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE,
68             EmitHeaderNameByInterface(interface_->GetExtendsInterface(), stubName_));
69     }
70     GetHeaderOtherLibInclusions(headerFiles);
71 
72     for (const auto &file : headerFiles) {
73         sb.AppendFormat("%s\n", file.ToString().c_str());
74     }
75 }
76 
GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const77 void CppServiceStubCodeEmitter::GetHeaderOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
78 {
79     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_parcel");
80     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "message_option");
81     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "ipc_object_stub");
82     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
83     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "refbase");
84 }
85 
EmitStubDecl(StringBuilder & sb)86 void CppServiceStubCodeEmitter::EmitStubDecl(StringBuilder &sb)
87 {
88     EmitBeginNamespace(sb);
89     sb.Append("\n");
90     EmitStubUsingNamespace(sb);
91     sb.AppendFormat("class %s : public IPCObjectStub {\n", stubName_.c_str());
92     EmitStubBody(sb, TAB);
93     sb.Append("};\n");
94     EmitEndNamespace(sb);
95 }
96 
EmitStubUsingNamespace(StringBuilder & sb) const97 void CppServiceStubCodeEmitter::EmitStubUsingNamespace(StringBuilder &sb) const
98 {
99     sb.Append("using namespace OHOS;\n");
100 }
101 
EmitStubBody(StringBuilder & sb,const std::string & prefix) const102 void CppServiceStubCodeEmitter::EmitStubBody(StringBuilder &sb, const std::string &prefix) const
103 {
104     sb.Append("public:\n");
105     EmitStubConstructorDecl(sb, prefix);
106     sb.Append("\n");
107     EmitStubOnRequestDecl(sb, prefix);
108     sb.Append("\n");
109     EmitStubMethodDecls(sb, prefix);
110     sb.Append("\n");
111     EmitStubPrivateData(sb, prefix);
112 }
113 
EmitStubConstructorDecl(StringBuilder & sb,const std::string & prefix) const114 void CppServiceStubCodeEmitter::EmitStubConstructorDecl(StringBuilder &sb, const std::string &prefix) const
115 {
116     sb.Append(prefix).AppendFormat("explicit %s(const sptr<%s> &impl);\n", stubName_.c_str(), interfaceName_.c_str());
117     sb.Append(prefix).AppendFormat("virtual ~%s();\n", stubName_.c_str());
118 }
119 
EmitStubOnRequestDecl(StringBuilder & sb,const std::string & prefix) const120 void CppServiceStubCodeEmitter::EmitStubOnRequestDecl(StringBuilder &sb, const std::string &prefix) const
121 {
122     sb.Append(prefix).Append("int32_t OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, ");
123     sb.Append("MessageOption &option) override;\n");
124 }
125 
EmitStubMethodDecls(StringBuilder & sb,const std::string & prefix) const126 void CppServiceStubCodeEmitter::EmitStubMethodDecls(StringBuilder &sb, const std::string &prefix) const
127 {
128     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
129         EmitStubStaticMethodDecl(method, sb, prefix);
130         sb.Append("\n");
131     }
132     if (interface_->GetExtendsInterface() == nullptr) {
133         EmitStubStaticMethodDecl(interface_->GetVersionMethod(), sb, prefix);
134         sb.Append("\n");
135     }
136 
137     sb.Append("private:\n");
138     AutoPtr<ASTInterfaceType> interface = interface_;
139     while (interface != nullptr) {
140         for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
141             EmitStubMethodDecl(method, sb, prefix);
142             sb.Append("\n");
143         }
144         interface = interface->GetExtendsInterface();
145     }
146     EmitStubMethodDecl(interface_->GetVersionMethod(), sb, prefix);
147     sb.Append("\n");
148 }
149 
EmitStubMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const150 void CppServiceStubCodeEmitter::EmitStubMethodDecl(
151     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
152 {
153     sb.Append(prefix).AppendFormat("int32_t %s%s(MessageParcel& %s, MessageParcel& %s, MessageOption& %s);\n",
154         stubName_.c_str(), method->GetName().c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(),
155         optionName_.c_str());
156 }
157 
EmitStubStaticMethodDecl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const158 void CppServiceStubCodeEmitter::EmitStubStaticMethodDecl(
159     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
160 {
161     sb.Append(prefix).AppendFormat(
162         "static int32_t %s%s_(MessageParcel& %s, MessageParcel& %s, MessageOption& %s, sptr<%s> impl);\n",
163         stubName_.c_str(), method->GetName().c_str(), dataParcelName_.c_str(), replyParcelName_.c_str(),
164         optionName_.c_str(), EmitDefinitionByInterface(interface_, interfaceName_).c_str());
165 }
166 
EmitStubPrivateData(StringBuilder & sb,const std::string & prefix) const167 void CppServiceStubCodeEmitter::EmitStubPrivateData(StringBuilder &sb, const std::string &prefix) const
168 {
169     sb.Append(prefix).AppendFormat("static inline ObjectDelegator<%s, %s> objDelegator_;\n",
170         EmitDefinitionByInterface(interface_, stubName_).c_str(),
171         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
172     sb.Append(prefix).AppendFormat("sptr<%s> impl_;\n", EmitDefinitionByInterface(interface_, interfaceName_).c_str());
173 }
174 
EmitStubSourceFile()175 void CppServiceStubCodeEmitter::EmitStubSourceFile()
176 {
177     std::string filePath =
178         File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(stubName_).c_str()));
179     File file(filePath, File::WRITE);
180     StringBuilder sb;
181 
182     EmitLicense(sb);
183     EmitStubSourceInclusions(sb);
184     sb.Append("\n");
185     EmitLogTagMacro(sb, FileName(stubName_));
186     sb.Append("\n");
187     EmitBeginNamespace(sb);
188     UtilMethodMap utilMethods;
189     GetUtilMethods(utilMethods);
190     EmitUtilMethods(sb, "", utilMethods, true);
191     sb.Append("\n");
192     EmitUtilMethods(sb, "", utilMethods, false);
193     sb.Append("\n");
194     EmitInterfaceGetMethodImpl(sb, "");
195     sb.Append("\n");
196     EmitStubConstructorImpl(sb, "");
197     sb.Append("\n");
198     EmitStubOnRequestMethodImpl(sb, "");
199     sb.Append("\n");
200     EmitStubMethodImpls(sb, "");
201     EmitEndNamespace(sb);
202 
203     std::string data = sb.ToString();
204     file.WriteData(data.c_str(), data.size());
205     file.Flush();
206     file.Close();
207 }
208 
EmitStubSourceInclusions(StringBuilder & sb)209 void CppServiceStubCodeEmitter::EmitStubSourceInclusions(StringBuilder &sb)
210 {
211     HeaderFile::HeaderFileSet headerFiles;
212     headerFiles.emplace(HeaderFileType::OWN_HEADER_FILE, EmitVersionHeaderName(stubName_));
213     GetSourceOtherLibInclusions(headerFiles);
214 
215     for (const auto &file : headerFiles) {
216         sb.AppendFormat("%s\n", file.ToString().c_str());
217     }
218 }
219 
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const220 void CppServiceStubCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
221 {
222     if (!interface_->IsSerializable()) {
223         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
224         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
225         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
226     } else {
227         const AST::TypeStringMap &types = ast_->GetTypes();
228         for (const auto &pair : types) {
229             AutoPtr<ASTType> type = pair.second;
230             if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
231                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
232                 break;
233             }
234         }
235     }
236 
237     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
238         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
239             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
240             AutoPtr<ASTType> paramType = param->GetType();
241             if (param->GetAttribute() == ParamAttr::PARAM_IN &&
242                 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
243                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
244             }
245 
246             if (param->GetAttribute() == ParamAttr::PARAM_OUT &&
247                 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
248                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
249             }
250         }
251     }
252 
253     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
254     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
255 }
256 
EmitInterfaceGetMethodImpl(StringBuilder & sb,const std::string & prefix) const257 void CppServiceStubCodeEmitter::EmitInterfaceGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
258 {
259     if (!interface_->IsSerializable()) {
260         EmitGetMethodImpl(sb, prefix);
261         sb.Append(prefix).Append("\n");
262         EmitGetInstanceMethodImpl(sb, prefix);
263         sb.Append(prefix).Append("\n");
264     }
265 }
266 
EmitGetMethodImpl(StringBuilder & sb,const std::string & prefix) const267 void CppServiceStubCodeEmitter::EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
268 {
269     sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(bool isStub)\n",
270         EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
271         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
272     sb.Append(prefix).Append("{\n");
273     sb.Append(prefix + TAB).AppendFormat("return %s::Get(\"%s\", isStub);\n",
274         EmitDefinitionByInterface(interface_, interfaceName_).c_str(), FileName(implName_).c_str());
275     sb.Append(prefix).Append("}\n");
276 }
277 
EmitGetInstanceMethodImpl(StringBuilder & sb,const std::string & prefix) const278 void CppServiceStubCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix) const
279 {
280     sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(const std::string& serviceName, bool isStub)\n",
281         EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
282         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
283     sb.Append(prefix).Append("{\n");
284 
285     sb.Append(prefix + TAB).Append("if (!isStub) {\n");
286     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
287     sb.Append(prefix + TAB).Append("}\n");
288 
289     sb.Append(prefix + TAB).AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n",
290         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
291     sb.Append(prefix + TAB).Append("void *impl = LoadHdiImpl(desc.c_str(), ");
292     sb.AppendFormat("serviceName == \"%s\" ? \"service\" : serviceName.c_str());\n", FileName(implName_).c_str());
293     sb.Append(prefix + TAB).Append("if (impl == nullptr) {\n");
294     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"failed to load hdi impl %{public}s\", desc.c_str());\n");
295     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
296     sb.Append(prefix + TAB).Append("}\n");
297     sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n",
298         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
299     sb.Append(prefix).Append("}\n");
300 }
301 
EmitStubConstructorImpl(StringBuilder & sb,const std::string & prefix) const302 void CppServiceStubCodeEmitter::EmitStubConstructorImpl(StringBuilder &sb, const std::string &prefix) const
303 {
304     sb.Append(prefix).AppendFormat("%s::%s(const sptr<%s> &impl)\n",
305         EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(),
306         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
307     sb.Append(prefix + TAB).AppendFormat(": IPCObjectStub(%s::GetDescriptor()), impl_(impl)\n",
308         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
309     sb.Append(prefix).Append("{\n");
310     sb.Append(prefix).Append("}\n\n");
311 
312     sb.Append(prefix).AppendFormat(
313         "%s::~%s()\n", EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str());
314     sb.Append(prefix).Append("{\n");
315     sb.Append(prefix + TAB).Append("ObjectCollector::GetInstance().RemoveObject(impl_);\n");
316     sb.Append(prefix).Append("}\n");
317 }
318 
EmitStubOnRequestMethodImpl(StringBuilder & sb,const std::string & prefix)319 void CppServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix)
320 {
321     sb.Append(prefix).AppendFormat(
322         "int32_t %s::OnRemoteRequest(uint32_t code, ", EmitDefinitionByInterface(interface_, stubName_).c_str());
323     sb.Append("MessageParcel& data, MessageParcel& reply, MessageOption& option)\n");
324     sb.Append(prefix).Append("{\n");
325 
326     sb.Append(prefix + TAB).Append("switch (code) {\n");
327     AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
328     sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).c_str());
329     sb.Append(prefix + TAB + TAB + TAB)
330         .AppendFormat("return %sStub%s(data, reply, option);\n", baseName_.c_str(), getVerMethod->GetName().c_str());
331     AutoPtr<ASTInterfaceType> interface = interface_;
332     while (interface != nullptr) {
333         for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
334             sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(method).c_str());
335             sb.Append(prefix + TAB + TAB + TAB)
336                 .AppendFormat("return %sStub%s(data, reply, option);\n", baseName_.c_str(), method->GetName().c_str());
337         }
338         interface = interface->GetExtendsInterface();
339     }
340 
341     sb.Append(prefix + TAB + TAB).Append("default: {\n");
342     sb.Append(prefix + TAB + TAB + TAB)
343         .Append("HDF_LOGE(\"%{public}s: cmd %{public}d is not supported\", __func__, code);\n");
344     sb.Append(prefix + TAB + TAB + TAB).Append("return IPCObjectStub::OnRemoteRequest(code, data, reply, option);\n");
345     sb.Append(prefix + TAB + TAB).Append("}\n");
346     sb.Append(prefix + TAB).Append("}\n");
347     sb.Append("}\n");
348 }
349 
EmitStubMethodImpls(StringBuilder & sb,const std::string & prefix) const350 void CppServiceStubCodeEmitter::EmitStubMethodImpls(StringBuilder &sb, const std::string &prefix) const
351 {
352     AutoPtr<ASTInterfaceType> interface = interface_;
353     AutoPtr<ASTInterfaceType> mataInterface = interface_;
354     while (interface != nullptr) {
355         for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
356             EmitStubMethodImpl(interface, method, sb, prefix);
357             sb.Append("\n");
358         }
359         interface = interface->GetExtendsInterface();
360         if (interface != nullptr) {
361             mataInterface = interface;
362         }
363     }
364     AutoPtr<ASTMethod> verMethod = interface_->GetVersionMethod();
365     EmitStubMethodImpl(mataInterface, verMethod, sb, prefix);
366     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
367         sb.Append("\n");
368         EmitStubStaticMethodImpl(method, sb, prefix);
369     }
370     if (interface_->GetExtendsInterface() == nullptr) {
371         sb.Append("\n");
372         EmitStubStaticMethodImpl(verMethod, sb, prefix);
373     }
374 }
375 
EmitStubMethodImpl(AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const376 void CppServiceStubCodeEmitter::EmitStubMethodImpl(AutoPtr<ASTInterfaceType> interface,
377     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
378 {
379     sb.Append(prefix).AppendFormat("int32_t %s::%s%s(MessageParcel& %s, MessageParcel& %s, MessageOption& %s)\n",
380         EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(), method->GetName().c_str(),
381         dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str());
382     sb.Append(prefix).Append("{\n");
383     sb.Append(prefix + TAB).AppendFormat("return %s::%s%s_(%s, %s, %s, impl_);\n",
384         EmitDefinitionByInterface(interface, stubName_).c_str(),
385         stubName_.c_str(), method->GetName().c_str(),
386         dataParcelName_.c_str(), replyParcelName_.c_str(),
387         optionName_.c_str());
388     sb.Append("}\n");
389 }
390 
EmitStubStaticMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const391 void CppServiceStubCodeEmitter::EmitStubStaticMethodImpl(
392     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
393 {
394     sb.Append(prefix).AppendFormat(
395         "int32_t %s::%s%s_(MessageParcel& %s, MessageParcel& %s, MessageOption& %s, sptr<%s> impl)\n",
396         EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(), method->GetName().c_str(),
397         dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str(),
398         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
399     sb.Append(prefix).Append("{\n");
400 
401     // read interface token and check it
402     EmitStubReadInterfaceToken(dataParcelName_, sb, prefix + TAB);
403     sb.Append("\n");
404 
405     EmitStubReadMemFlag(method, dataParcelName_, sb, prefix + TAB);
406 
407     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
408         AutoPtr<ASTParameter> param = method->GetParameter(i);
409         if (param->GetAttribute() == ParamAttr::PARAM_IN) {
410             EmitReadMethodParameter(param, dataParcelName_, true, sb, prefix + TAB);
411             sb.Append("\n");
412         } else {
413             EmitLocalVariable(param, dataParcelName_, sb, prefix + TAB);
414             sb.Append("\n");
415         }
416     }
417 
418     EmitStubCallMethod(method, sb, prefix + TAB);
419     sb.Append("\n");
420 
421     if (!method->IsOneWay()) {
422         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
423             AutoPtr<ASTParameter> param = method->GetParameter(i);
424             if (param->GetAttribute() == ParamAttr::PARAM_OUT) {
425                 EmitWriteMethodParameter(param, replyParcelName_, sb, prefix + TAB);
426                 sb.Append("\n");
427             }
428         }
429     }
430 
431     sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
432     sb.Append("}\n");
433 }
434 
EmitStubCallMethod(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const435 void CppServiceStubCodeEmitter::EmitStubCallMethod(
436     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
437 {
438     sb.Append(prefix).Append("if (impl == nullptr) {\n");
439     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: impl is nullptr!\", __func__);\n");
440     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
441     sb.Append(prefix).Append("}\n\n");
442 
443     sb.Append(prefix).AppendFormat("int32_t %s = impl->%s(", errorCodeName_.c_str(), method->GetName().c_str());
444     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
445         AutoPtr<ASTParameter> param = method->GetParameter(i);
446         sb.Append(param->GetName());
447         if (i + 1 < method->GetParameterNumber()) {
448             sb.Append(", ");
449         }
450     }
451     sb.Append(");\n");
452 
453     sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
454     sb.Append(prefix + TAB)
455         .AppendFormat("HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n",
456         errorCodeName_.c_str());
457     sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
458     sb.Append(prefix).Append("}\n");
459 }
460 
EmitStubReadInterfaceToken(const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const461 void CppServiceStubCodeEmitter::EmitStubReadInterfaceToken(
462     const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
463 {
464     sb.Append(prefix).AppendFormat("if (%s.ReadInterfaceToken() != %s::GetDescriptor()) {\n", parcelName.c_str(),
465         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
466     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: interface token check failed!\", __func__);\n");
467     sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
468     sb.Append(prefix).Append("}\n");
469 }
470 
EmitStubReadMemFlag(const AutoPtr<ASTMethod> & method,const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const471 void CppServiceStubCodeEmitter::EmitStubReadMemFlag(const AutoPtr<ASTMethod> &method,
472     const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
473 {
474     if (NeedFlag(method)) {
475         sb.Append(prefix).AppendFormat("bool %s = false;\n", flagOfSetMemName_.c_str());
476         sb.Append(prefix).AppendFormat("if (!%s.ReadBool(%s)) {\n", parcelName.c_str(), flagOfSetMemName_.c_str());
477         sb.Append(prefix + TAB)
478             .AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", flagOfSetMemName_.c_str());
479         sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
480         sb.Append(prefix).Append("}\n");
481     }
482 }
483 
EmitLocalVariable(const AutoPtr<ASTParameter> & param,const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const484 void CppServiceStubCodeEmitter::EmitLocalVariable(const AutoPtr<ASTParameter> &param,
485     const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
486 {
487     sb.Append(prefix).Append(param->EmitCppLocalVar()).Append("\n");
488     AutoPtr<ASTType> type = param->GetType();
489     if (!type->IsStringType() && !type->IsArrayType() && !type->IsListType()) {
490         return;
491     }
492 
493     sb.Append(prefix).AppendFormat("if (%s) {\n", flagOfSetMemName_.c_str());
494     std::string capacityName = "capacity";
495     sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", capacityName.c_str());
496     sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint32(%s)) {\n", parcelName.c_str(), capacityName.c_str());
497     sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n",
498         capacityName.c_str());
499     sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
500     sb.Append(prefix + TAB).Append("}\n");
501 
502     if (type->IsStringType()) {
503         sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(char), HDF_ERR_INVALID_PARAM);\n",
504             CHECK_VALUE_RETURN_MACRO, capacityName.c_str(), MAX_BUFF_SIZE_MACRO);
505     } else {
506         AutoPtr<ASTArrayType> arrayType = dynamic_cast<ASTArrayType *>(type.Get());
507         sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(%s), HDF_ERR_INVALID_PARAM);\n",
508             CHECK_VALUE_RETURN_MACRO, capacityName.c_str(), MAX_BUFF_SIZE_MACRO,
509             arrayType->GetElementType()->EmitCppType().c_str());
510     }
511     sb.Append(prefix + TAB).AppendFormat("%s.reserve(%s);\n", param->GetName().c_str(), capacityName.c_str());
512     sb.Append(prefix).Append("}\n");
513 }
514 
GetUtilMethods(UtilMethodMap & methods)515 void CppServiceStubCodeEmitter::GetUtilMethods(UtilMethodMap &methods)
516 {
517     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
518         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
519             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
520             AutoPtr<ASTType> paramType = param->GetType();
521             if (param->GetAttribute() == ParamAttr::PARAM_IN) {
522                 paramType->RegisterReadMethod(Options::GetInstance().GetLanguage(), SerMode::STUB_SER, methods);
523             } else {
524                 paramType->RegisterWriteMethod(Options::GetInstance().GetLanguage(), SerMode::STUB_SER, methods);
525             }
526         }
527     }
528 }
529 } // namespace HDI
530 } // namespace OHOS
531