• 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     GetSourceOtherFileInclusions(headerFiles);
215 
216     for (const auto &file : headerFiles) {
217         sb.AppendFormat("%s\n", file.ToString().c_str());
218     }
219 }
220 
GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet & headerFiles) const221 void CppServiceStubCodeEmitter::GetSourceOtherLibInclusions(HeaderFile::HeaderFileSet &headerFiles) const
222 {
223     if (!interface_->IsSerializable()) {
224         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
225         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "string_ex");
226         headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdi_support");
227     } else {
228         const AST::TypeStringMap &types = ast_->GetTypes();
229         for (const auto &pair : types) {
230             AutoPtr<ASTType> type = pair.second;
231             if (type->GetTypeKind() == TypeKind::TYPE_UNION) {
232                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "securec");
233                 break;
234             }
235         }
236     }
237 
238     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
239         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
240             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
241             AutoPtr<ASTType> paramType = param->GetType();
242             if (param->GetAttribute() == ParamAttr::PARAM_IN &&
243                 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
244                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "iproxy_broker");
245             }
246 
247             if (param->GetAttribute() == ParamAttr::PARAM_OUT &&
248                 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
249                 headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "object_collector");
250             }
251         }
252     }
253 
254     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_base");
255     headerFiles.emplace(HeaderFileType::OTHER_MODULES_HEADER_FILE, "hdf_log");
256 }
257 
GetSourceOtherFileInclusions(HeaderFile::HeaderFileSet & headerFiles) const258 void CppServiceStubCodeEmitter::GetSourceOtherFileInclusions(HeaderFile::HeaderFileSet &headerFiles) const
259 {
260     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
261         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
262             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
263             AutoPtr<ASTType> paramType = param->GetType();
264             if (param->GetAttribute() == ParamAttr::PARAM_IN &&
265                 (param->GetType()->IsInterfaceType() || paramType->HasInnerType(TypeKind::TYPE_INTERFACE))) {
266                 AutoPtr<ASTInterfaceType> type = dynamic_cast<ASTInterfaceType *>(paramType.Get());
267                 std::string FileName = InterfaceToFilePath(paramType->ToString());
268                 headerFiles.emplace(HeaderFileType::OWN_MODULE_HEADER_FILE, FileName);
269             }
270         }
271     }
272 }
273 
EmitInterfaceGetMethodImpl(StringBuilder & sb,const std::string & prefix) const274 void CppServiceStubCodeEmitter::EmitInterfaceGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
275 {
276     if (!interface_->IsSerializable()) {
277         EmitGetMethodImpl(sb, prefix);
278         sb.Append(prefix).Append("\n");
279         EmitGetInstanceMethodImpl(sb, prefix);
280         sb.Append(prefix).Append("\n");
281     }
282 }
283 
EmitGetMethodImpl(StringBuilder & sb,const std::string & prefix) const284 void CppServiceStubCodeEmitter::EmitGetMethodImpl(StringBuilder &sb, const std::string &prefix) const
285 {
286     sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(bool isStub)\n",
287         EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
288         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
289     sb.Append(prefix).Append("{\n");
290     sb.Append(prefix + TAB).AppendFormat("return %s::Get(\"%s\", isStub);\n",
291         EmitDefinitionByInterface(interface_, interfaceName_).c_str(), FileName(implName_).c_str());
292     sb.Append(prefix).Append("}\n");
293 }
294 
EmitGetInstanceMethodImpl(StringBuilder & sb,const std::string & prefix) const295 void CppServiceStubCodeEmitter::EmitGetInstanceMethodImpl(StringBuilder &sb, const std::string &prefix) const
296 {
297     sb.Append(prefix).AppendFormat("sptr<%s> %s::Get(const std::string& serviceName, bool isStub)\n",
298         EmitDefinitionByInterface(interface_, interfaceName_).c_str(),
299         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
300     sb.Append(prefix).Append("{\n");
301 
302     sb.Append(prefix + TAB).Append("if (!isStub) {\n");
303     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
304     sb.Append(prefix + TAB).Append("}\n");
305 
306     sb.Append(prefix + TAB).AppendFormat("std::string desc = Str16ToStr8(%s::GetDescriptor());\n",
307         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
308     sb.Append(prefix + TAB).Append("void *impl = LoadHdiImpl(desc.c_str(), ");
309     sb.AppendFormat("serviceName == \"%s\" ? \"service\" : serviceName.c_str());\n", FileName(implName_).c_str());
310     sb.Append(prefix + TAB).Append("if (impl == nullptr) {\n");
311     sb.Append(prefix + TAB + TAB).Append("HDF_LOGE(\"failed to load hdi impl %{public}s\", desc.c_str());\n");
312     sb.Append(prefix + TAB + TAB).Append("return nullptr;\n");
313     sb.Append(prefix + TAB).Append("}\n");
314     sb.Append(prefix + TAB).AppendFormat("return reinterpret_cast<%s *>(impl);\n",
315         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
316     sb.Append(prefix).Append("}\n");
317 }
318 
EmitStubConstructorImpl(StringBuilder & sb,const std::string & prefix) const319 void CppServiceStubCodeEmitter::EmitStubConstructorImpl(StringBuilder &sb, const std::string &prefix) const
320 {
321     sb.Append(prefix).AppendFormat("%s::%s(const sptr<%s> &impl)\n",
322         EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(),
323         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
324     sb.Append(prefix + TAB).AppendFormat(": IPCObjectStub(%s::GetDescriptor()), impl_(impl)\n",
325         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
326     sb.Append(prefix).Append("{\n");
327     sb.Append(prefix).Append("}\n\n");
328 
329     sb.Append(prefix).AppendFormat(
330         "%s::~%s()\n", EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str());
331     sb.Append(prefix).Append("{\n");
332     sb.Append(prefix + TAB).Append("ObjectCollector::GetInstance().RemoveObject(impl_);\n");
333     sb.Append(prefix).Append("}\n");
334 }
335 
EmitStubOnRequestMethodImpl(StringBuilder & sb,const std::string & prefix)336 void CppServiceStubCodeEmitter::EmitStubOnRequestMethodImpl(StringBuilder &sb, const std::string &prefix)
337 {
338     sb.Append(prefix).AppendFormat(
339         "int32_t %s::OnRemoteRequest(uint32_t code, ", EmitDefinitionByInterface(interface_, stubName_).c_str());
340     sb.Append("MessageParcel& data, MessageParcel& reply, MessageOption& option)\n");
341     sb.Append(prefix).Append("{\n");
342 
343     sb.Append(prefix + TAB).Append("switch (code) {\n");
344     AutoPtr<ASTMethod> getVerMethod = interface_->GetVersionMethod();
345     sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(getVerMethod).c_str());
346     sb.Append(prefix + TAB + TAB + TAB)
347         .AppendFormat("return %sStub%s(data, reply, option);\n", baseName_.c_str(), getVerMethod->GetName().c_str());
348     AutoPtr<ASTInterfaceType> interface = interface_;
349     while (interface != nullptr) {
350         for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
351             sb.Append(prefix + TAB + TAB).AppendFormat("case %s:\n", EmitMethodCmdID(method).c_str());
352             sb.Append(prefix + TAB + TAB + TAB)
353                 .AppendFormat("return %sStub%s(data, reply, option);\n", baseName_.c_str(), method->GetName().c_str());
354         }
355         interface = interface->GetExtendsInterface();
356     }
357 
358     sb.Append(prefix + TAB + TAB).Append("default: {\n");
359     sb.Append(prefix + TAB + TAB + TAB)
360         .Append("HDF_LOGE(\"%{public}s: cmd %{public}d is not supported\", __func__, code);\n");
361     sb.Append(prefix + TAB + TAB + TAB).Append("return IPCObjectStub::OnRemoteRequest(code, data, reply, option);\n");
362     sb.Append(prefix + TAB + TAB).Append("}\n");
363     sb.Append(prefix + TAB).Append("}\n");
364     sb.Append("}\n");
365 }
366 
EmitStubMethodImpls(StringBuilder & sb,const std::string & prefix) const367 void CppServiceStubCodeEmitter::EmitStubMethodImpls(StringBuilder &sb, const std::string &prefix) const
368 {
369     AutoPtr<ASTInterfaceType> interface = interface_;
370     AutoPtr<ASTInterfaceType> mataInterface = interface_;
371     while (interface != nullptr) {
372         for (const auto &method : interface->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
373             EmitStubMethodImpl(interface, method, sb, prefix);
374             sb.Append("\n");
375         }
376         interface = interface->GetExtendsInterface();
377         if (interface != nullptr) {
378             mataInterface = interface;
379         }
380     }
381     AutoPtr<ASTMethod> verMethod = interface_->GetVersionMethod();
382     EmitStubMethodImpl(mataInterface, verMethod, sb, prefix);
383     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
384         sb.Append("\n");
385         EmitStubStaticMethodImpl(method, sb, prefix);
386     }
387     if (interface_->GetExtendsInterface() == nullptr) {
388         sb.Append("\n");
389         EmitStubStaticMethodImpl(verMethod, sb, prefix);
390     }
391 }
392 
EmitStubMethodImpl(AutoPtr<ASTInterfaceType> interface,const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const393 void CppServiceStubCodeEmitter::EmitStubMethodImpl(AutoPtr<ASTInterfaceType> interface,
394     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
395 {
396     sb.Append(prefix).AppendFormat("int32_t %s::%s%s(MessageParcel& %s, MessageParcel& %s, MessageOption& %s)\n",
397         EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(), method->GetName().c_str(),
398         dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str());
399     sb.Append(prefix).Append("{\n");
400     sb.Append(prefix + TAB).AppendFormat("return %s::%s%s_(%s, %s, %s, impl_);\n",
401         EmitDefinitionByInterface(interface, stubName_).c_str(),
402         stubName_.c_str(), method->GetName().c_str(),
403         dataParcelName_.c_str(), replyParcelName_.c_str(),
404         optionName_.c_str());
405     sb.Append("}\n");
406 }
407 
EmitStubStaticMethodImpl(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const408 void CppServiceStubCodeEmitter::EmitStubStaticMethodImpl(
409     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
410 {
411     sb.Append(prefix).AppendFormat(
412         "int32_t %s::%s%s_(MessageParcel& %s, MessageParcel& %s, MessageOption& %s, sptr<%s> impl)\n",
413         EmitDefinitionByInterface(interface_, stubName_).c_str(), stubName_.c_str(), method->GetName().c_str(),
414         dataParcelName_.c_str(), replyParcelName_.c_str(), optionName_.c_str(),
415         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
416     sb.Append(prefix).Append("{\n");
417 
418     // read interface token and check it
419     EmitStubReadInterfaceToken(dataParcelName_, sb, prefix + TAB);
420     sb.Append("\n");
421 
422     EmitStubReadMemFlag(method, dataParcelName_, sb, prefix + TAB);
423 
424     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
425         AutoPtr<ASTParameter> param = method->GetParameter(i);
426         if (param->GetAttribute() == ParamAttr::PARAM_IN) {
427             EmitReadMethodParameter(param, dataParcelName_, true, sb, prefix + TAB);
428             sb.Append("\n");
429         } else {
430             EmitLocalVariable(param, dataParcelName_, sb, prefix + TAB);
431             sb.Append("\n");
432         }
433     }
434 
435     EmitStubCallMethod(method, sb, prefix + TAB);
436     sb.Append("\n");
437 
438     if (!method->IsOneWay()) {
439         for (size_t i = 0; i < method->GetParameterNumber(); i++) {
440             AutoPtr<ASTParameter> param = method->GetParameter(i);
441             if (param->GetAttribute() == ParamAttr::PARAM_OUT) {
442                 EmitWriteMethodParameter(param, replyParcelName_, sb, prefix + TAB);
443                 sb.Append("\n");
444             }
445         }
446     }
447 
448     sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
449     sb.Append("}\n");
450 }
451 
EmitStubCallMethod(const AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const452 void CppServiceStubCodeEmitter::EmitStubCallMethod(
453     const AutoPtr<ASTMethod> &method, StringBuilder &sb, const std::string &prefix) const
454 {
455     sb.Append(prefix).Append("if (impl == nullptr) {\n");
456     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: impl is nullptr!\", __func__);\n");
457     sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
458     sb.Append(prefix).Append("}\n\n");
459 
460     sb.Append(prefix).AppendFormat("int32_t %s = impl->%s(", errorCodeName_.c_str(), method->GetName().c_str());
461     for (size_t i = 0; i < method->GetParameterNumber(); i++) {
462         AutoPtr<ASTParameter> param = method->GetParameter(i);
463         sb.Append(param->GetName());
464         if (i + 1 < method->GetParameterNumber()) {
465             sb.Append(", ");
466         }
467     }
468     sb.Append(");\n");
469 
470     sb.Append(prefix).AppendFormat("if (%s != HDF_SUCCESS) {\n", errorCodeName_.c_str());
471     sb.Append(prefix + TAB)
472         .AppendFormat("HDF_LOGE(\"%%{public}s failed, error code is %%{public}d\", __func__, %s);\n",
473         errorCodeName_.c_str());
474     sb.Append(prefix + TAB).AppendFormat("return %s;\n", errorCodeName_.c_str());
475     sb.Append(prefix).Append("}\n");
476 }
477 
EmitStubReadInterfaceToken(const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const478 void CppServiceStubCodeEmitter::EmitStubReadInterfaceToken(
479     const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
480 {
481     sb.Append(prefix).AppendFormat("if (%s.ReadInterfaceToken() != %s::GetDescriptor()) {\n", parcelName.c_str(),
482         EmitDefinitionByInterface(interface_, interfaceName_).c_str());
483     sb.Append(prefix + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: interface token check failed!\", __func__);\n");
484     sb.Append(prefix + TAB).AppendFormat("return HDF_ERR_INVALID_PARAM;\n");
485     sb.Append(prefix).Append("}\n");
486 }
487 
EmitStubReadMemFlag(const AutoPtr<ASTMethod> & method,const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const488 void CppServiceStubCodeEmitter::EmitStubReadMemFlag(const AutoPtr<ASTMethod> &method,
489     const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
490 {
491     if (NeedFlag(method)) {
492         sb.Append(prefix).AppendFormat("bool %s = false;\n", flagOfSetMemName_.c_str());
493         sb.Append(prefix).AppendFormat("if (!%s.ReadBool(%s)) {\n", parcelName.c_str(), flagOfSetMemName_.c_str());
494         sb.Append(prefix + TAB)
495             .AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n", flagOfSetMemName_.c_str());
496         sb.Append(prefix + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
497         sb.Append(prefix).Append("}\n");
498     }
499 }
500 
EmitLocalVariable(const AutoPtr<ASTParameter> & param,const std::string & parcelName,StringBuilder & sb,const std::string & prefix) const501 void CppServiceStubCodeEmitter::EmitLocalVariable(const AutoPtr<ASTParameter> &param,
502     const std::string &parcelName, StringBuilder &sb, const std::string &prefix) const
503 {
504     sb.Append(prefix).Append(param->EmitCppLocalVar()).Append("\n");
505     AutoPtr<ASTType> type = param->GetType();
506     if (!type->IsStringType() && !type->IsArrayType() && !type->IsListType()) {
507         return;
508     }
509 
510     sb.Append(prefix).AppendFormat("if (%s) {\n", flagOfSetMemName_.c_str());
511     std::string capacityName = "capacity";
512     sb.Append(prefix + TAB).AppendFormat("uint32_t %s = 0;\n", capacityName.c_str());
513     sb.Append(prefix + TAB).AppendFormat("if (!%s.ReadUint32(%s)) {\n", parcelName.c_str(), capacityName.c_str());
514     sb.Append(prefix + TAB + TAB).AppendFormat("HDF_LOGE(\"%%{public}s: failed to read %s\", __func__);\n",
515         capacityName.c_str());
516     sb.Append(prefix + TAB + TAB).Append("return HDF_ERR_INVALID_PARAM;\n");
517     sb.Append(prefix + TAB).Append("}\n");
518 
519     if (type->IsStringType()) {
520         sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(char), HDF_ERR_INVALID_PARAM);\n",
521             CHECK_VALUE_RETURN_MACRO, capacityName.c_str(), MAX_BUFF_SIZE_MACRO);
522     } else {
523         AutoPtr<ASTArrayType> arrayType = dynamic_cast<ASTArrayType *>(type.Get());
524         sb.Append(prefix + TAB).AppendFormat("%s(%s, >, %s / sizeof(%s), HDF_ERR_INVALID_PARAM);\n",
525             CHECK_VALUE_RETURN_MACRO, capacityName.c_str(), MAX_BUFF_SIZE_MACRO,
526             arrayType->GetElementType()->EmitCppType().c_str());
527     }
528     sb.Append(prefix + TAB).AppendFormat("%s.reserve(%s);\n", param->GetName().c_str(), capacityName.c_str());
529     sb.Append(prefix).Append("}\n");
530 }
531 
GetUtilMethods(UtilMethodMap & methods)532 void CppServiceStubCodeEmitter::GetUtilMethods(UtilMethodMap &methods)
533 {
534     for (const auto &method : interface_->GetMethodsBySystem(Options::GetInstance().GetSystemLevel())) {
535         for (size_t paramIndex = 0; paramIndex < method->GetParameterNumber(); paramIndex++) {
536             AutoPtr<ASTParameter> param = method->GetParameter(paramIndex);
537             AutoPtr<ASTType> paramType = param->GetType();
538             if (param->GetAttribute() == ParamAttr::PARAM_IN) {
539                 paramType->RegisterReadMethod(Options::GetInstance().GetLanguage(), SerMode::STUB_SER, methods);
540             } else {
541                 paramType->RegisterWriteMethod(Options::GetInstance().GetLanguage(), SerMode::STUB_SER, methods);
542             }
543         }
544     }
545 }
546 } // namespace HDI
547 } // namespace OHOS
548