• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "sa_cpp_client_proxy_code_emitter.h"
17 #include "util/file.h"
18 #include "util/string_helper.h"
19 
20 namespace OHOS {
21 namespace Idl {
EmitCode()22 void SaCppClientProxyCodeEmitter::EmitCode()
23 {
24     SaTypeEmitter::circleCount_ = 0;
25     EmitInterfaceProxyHeaderFile();
26     EmitInterfaceProxyCppFile();
27 }
28 
EmitInterfaceProxyHeaderFile()29 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyHeaderFile()
30 {
31     std::string filePath =
32         File::AdapterPath(StringHelper::Format("%s/%s.h", directory_.c_str(), FileName(baseName_ + "Proxy").c_str()));
33     File file(filePath, File::WRITE);
34     StringBuilder sb;
35 
36     EmitLicense(sb);
37     EmitHeadMacro(sb, proxyFullName_);
38 
39     sb.Append("\n").Append("#include <iremote_proxy.h>\n");
40     EmitSecurecInclusion(sb);
41     sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).c_str());
42     if (ast_ != nullptr && ast_->GetHasCacheableProxyMethods()) {
43         sb.Append("#include \"api_cache_manager.h\"\n");
44     }
45     sb.Append("\n");
46     EmitInterfaceProxyInHeaderFile(sb);
47     EmitTailMacro(sb, proxyFullName_);
48 
49     std::string data = sb.ToString();
50     file.WriteData(data.c_str(), data.size());
51     file.Flush();
52     file.Close();
53 }
54 
EmitInterfaceProxyInHeaderFile(StringBuilder & sb)55 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyInHeaderFile(StringBuilder &sb)
56 {
57     EmitBeginNamespace(sb);
58     EmitImportUsingNamespace(sb);
59     sb.AppendFormat("class %s : public IRemoteProxy<%s> {\n", proxyName_.c_str(), interfaceName_.c_str());
60     sb.Append("public:\n");
61     EmitInterfaceProxyConstructor(sb, TAB);
62     sb.Append("\n");
63     EmitInterfaceProxyMethodDecls(sb, TAB);
64     sb.Append("\n");
65     sb.Append("private:\n");
66     EmitInterfaceProxyConstants(sb, TAB);
67     sb.Append("};\n");
68     EmitEndNamespace(sb);
69 }
70 
EmitInterfaceProxyRegisterDeathRecipient(StringBuilder & sb,const std::string & prefix) const71 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyRegisterDeathRecipient(StringBuilder &sb,
72     const std::string &prefix) const
73 {
74     sb.Append(prefix).Append("if (remote_) {\n");
75     sb.Append(prefix + TAB).Append("if (!remote->IsProxyObject()) {\n");
76     if (logOn_) {
77         sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"remote is not proxy object!\");\n");
78     }
79     sb.Append(prefix + TAB + TAB).Append("return;\n")
80         .Append(prefix + TAB).Append("}\n")
81         .Append(prefix + TAB)
82         .AppendFormat("deathRecipient_ = new (std::nothrow) %s(*this);\n", deathRecipientName_.c_str())
83         .Append(prefix + TAB).Append("if (!deathRecipient_) {\n");
84     if (logOn_) {
85         sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"deathRecipient_ is nullptr!\");\n");
86     }
87     sb.Append(prefix + TAB + TAB).Append("return;\n")
88         .Append(prefix + TAB).Append("}\n")
89         .Append(prefix + TAB).Append("if (!remote->AddDeathRecipient(deathRecipient_)) {\n");
90     if (logOn_) {
91         sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"AddDeathRecipient failed!\");\n");
92     }
93     sb.Append(prefix + TAB + TAB).Append("return;\n")
94         .Append(prefix + TAB).Append("}\n")
95         .Append(prefix + TAB).Append("remote_ = remote;\n")
96         .Append(prefix).Append("}\n");
97 }
98 
EmitInterfaceProxyAddCacheApi(StringBuilder & sb,const std::string & prefix) const99 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyAddCacheApi(StringBuilder &sb, const std::string &prefix) const
100 {
101     sb.Append(prefix).Append("{\n");
102     size_t methodNumber = interface_->GetMethodNumber();
103     for (size_t i = 0; i < methodNumber; i++) {
104         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
105         if (!method->GetCacheable() || method->IsOneWay()) {
106             continue;
107         }
108         std::string overloadname = "";
109         SACppCodeEmitter::CheckMethodOverload(method, i, overloadname);
110         int32_t cacheableTime = method->GetCacheableTime();
111         if (cacheableTime != 0) {
112             sb.Append(prefix).Append("ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(),\n")
113                 .Append(prefix + TAB).AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s), %d);\n",
114                 interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str(), cacheableTime);
115         } else {
116             sb.Append(prefix).Append("ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(),\n")
117                 .Append(prefix + TAB).AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s), 0);\n",
118                 interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str());
119         }
120     }
121     sb.Append("\n");
122     EmitInterfaceProxyRegisterDeathRecipient(sb, prefix + TAB);
123     sb.Append(prefix).Append("}\n");
124 }
125 
EmitInterfaceProxyUnRegisterDeathRecipient(StringBuilder & sb,const std::string & prefix) const126 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyUnRegisterDeathRecipient(StringBuilder &sb,
127     const std::string &prefix) const
128 {
129     sb.Append(prefix).Append("{\n");
130     sb.Append(prefix + TAB).Append("if (remote_ == nullptr) {\n");
131     sb.Append(prefix + TAB).Append(TAB).Append("return;\n");
132     sb.Append(prefix + TAB).Append("}\n");
133     sb.Append(prefix + TAB).Append("if (deathRecipient_ == nullptr) {\n");
134     sb.Append(prefix + TAB).Append(TAB).Append("return;\n");
135     sb.Append(prefix + TAB).Append("}\n");
136     sb.Append(prefix + TAB).Append("remote_->RemoveDeathRecipient(deathRecipient_);\n");
137     sb.Append(prefix + TAB).Append("remote_ = nullptr;\n");
138     size_t methodNumber = interface_->GetMethodNumber();
139     if (methodNumber > 0) {
140         sb.Append("\n");
141         for (size_t i = 0; i < methodNumber; i++) {
142             AutoPtr<ASTMethod> method = interface_->GetMethod(i);
143             std::string overloadname = "";
144             SACppCodeEmitter::CheckMethodOverload(method, i, overloadname);
145             if (method->GetCacheable() && !method->IsOneWay()) {
146                 sb.Append(prefix).Append("ApiCacheManager::GetInstance().DelCacheApi(GetDescriptor(),\n")
147                     .Append(prefix + TAB).AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s));\n",
148                     interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str());
149             }
150         }
151     }
152     sb.Append(prefix).Append("}\n");
153 }
154 
EmitInterfaceProxyConstructor(StringBuilder & sb,const std::string & prefix) const155 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyConstructor(StringBuilder &sb, const std::string &prefix) const
156 {
157     sb.Append(prefix).AppendFormat("explicit %s(\n", proxyName_.c_str());
158     sb.Append(prefix + TAB).Append("const sptr<IRemoteObject>& remote)\n");
159     sb.Append(prefix + TAB).AppendFormat(": IRemoteProxy<%s>(remote)\n", interfaceName_.c_str());
160     if (ast_->GetHasCacheableProxyMethods()) {
161         EmitInterfaceProxyAddCacheApi(sb, prefix);
162     } else {
163         sb.Append(prefix).Append("{}\n");
164     }
165     sb.Append("\n");
166     sb.Append(prefix).AppendFormat("virtual ~%s()\n", proxyName_.c_str());
167     if (ast_->GetHasCacheableProxyMethods()) {
168         EmitInterfaceProxyUnRegisterDeathRecipient(sb, prefix);
169     } else {
170         sb.Append(prefix).Append("{}\n");
171     }
172 }
173 
EmitInterfaceProxyMethodDecls(StringBuilder & sb,const std::string & prefix) const174 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodDecls(StringBuilder &sb, const std::string &prefix) const
175 {
176     size_t methodNumber = interface_->GetMethodNumber();
177     for (size_t i = 0; i < methodNumber; i++) {
178         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
179         EmitInterfaceProxyMethodDecl(method, sb, prefix);
180         if (i != methodNumber - 1) {
181             sb.Append("\n");
182         }
183     }
184 }
185 
EmitInterfaceProxyMethodDecl(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const186 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodDecl(AutoPtr<ASTMethod> &method, StringBuilder &sb,
187     const std::string &prefix) const
188 {
189     if (method->IsMacro()) {
190         sb.AppendFormat("#%s %s\n", method->GetMacroType().c_str(), method->GetMacroVal().c_str());
191     }
192     sb.Append(prefix).AppendFormat("ErrCode %s(", method->GetName().c_str());
193     EmitInterfaceMethodParams(method, sb, prefix + TAB);
194     sb.Append(") override;\n");
195     if (method->IsMacro()) {
196         sb.Append("#endif\n");
197     }
198 }
199 
EmitInterfaceProxyDeathRecipient(StringBuilder & sb,const std::string & prefix) const200 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyDeathRecipient(StringBuilder &sb, const std::string &prefix) const
201 {
202     sb.Append(prefix).AppendFormat("class %s : public IRemoteObject::DeathRecipient {\n", deathRecipientName_.c_str());
203     sb.Append(prefix).Append("public:\n");
204     sb.Append(prefix + TAB).AppendFormat("explicit %s(%s &client) : client_(client) {}\n", deathRecipientName_.c_str(),
205         proxyName_.c_str());
206     sb.Append(prefix + TAB).AppendFormat("~%s() override = default;\n", deathRecipientName_.c_str());
207     sb.Append(prefix + TAB).Append("void OnRemoteDied(const wptr<IRemoteObject> &remote) override\n");
208     sb.Append(prefix + TAB).Append("{\n");
209     sb.Append(prefix + TAB + TAB).Append("client_.OnRemoteDied(remote);\n");
210     sb.Append(prefix + TAB).Append("}\n");
211     sb.Append(prefix).Append("private:\n");
212     sb.Append(prefix + TAB).AppendFormat("%s &client_;\n", proxyName_.c_str());
213     sb.Append(prefix).Append("};\n\n");
214 
215     sb.Append(prefix).Append("void OnRemoteDied(const wptr<IRemoteObject> &remoteObject)\n");
216     sb.Append(prefix).Append("{\n");
217     sb.Append(prefix + TAB).Append("(void)remoteObject;\n");
218     sb.Append(prefix + TAB).Append("ApiCacheManager::GetInstance().ClearCache(GetDescriptor());\n");
219     sb.Append(prefix).Append("}\n");
220     sb.Append(prefix).Append("sptr<IRemoteObject> remote_ = nullptr;\n");
221     sb.Append(prefix).Append("sptr<IRemoteObject::DeathRecipient> deathRecipient_ = nullptr;\n");
222 }
223 
EmitInterfaceProxyConstants(StringBuilder & sb,const std::string & prefix)224 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyConstants(StringBuilder &sb, const std::string &prefix)
225 {
226     if (ast_->GetHasCacheableProxyMethods()) {
227         EmitInterfaceProxyDeathRecipient(sb, prefix);
228     }
229     sb.Append(prefix).AppendFormat("static inline BrokerDelegator<%s> delegator_;\n", proxyName_.c_str());
230 
231     EmitInterfaceProxyIpcCapacityValues(sb, prefix);
232 }
233 
EmitInterfaceProxyIpcCapacityValues(StringBuilder & sb,const std::string & prefix)234 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyIpcCapacityValues(StringBuilder &sb, const std::string &prefix)
235 {
236     size_t methodNumber = interface_->GetMethodNumber();
237     for (size_t i = 0; i < methodNumber; i++) {
238         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
239         if (method->HasIpcInCapacity()) {
240             sb.Append(prefix).AppendFormat("static constexpr size_t CAPACITY_%s_%d = %s << 10;\n",
241                 ConstantName(method->GetName()).c_str(), method->GetIpcCode(), method->GetIpcInCapacity().c_str());
242         }
243     }
244 }
245 
EmitInterfaceProxyCppFile()246 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyCppFile()
247 {
248     std::string filePath =
249         File::AdapterPath(StringHelper::Format("%s/%s.cpp", directory_.c_str(), FileName(proxyName_).c_str()));
250     File file(filePath, File::WRITE);
251     StringBuilder sb;
252 
253     EmitLicense(sb);
254     sb.AppendFormat("#include \"%s.h\"\n", FileName(proxyName_).c_str());
255     if (logOn_) {
256         sb.Append("#include \"hilog/log.h\"\n");
257     }
258     if (hitraceOn_) {
259         sb.Append("#include \"hitrace_meter.h\"\n");
260     }
261     sb.Append("\n");
262     if (logOn_) {
263         sb.Append("using OHOS::HiviewDFX::HiLog;\n\n");
264     }
265     EmitBeginNamespace(sb);
266     EmitImportUsingNamespace(sb);
267     EmitInterfaceProxyMethodImpls(sb, "");
268     EmitEndNamespace(sb);
269 
270     std::string data = sb.ToString();
271     file.WriteData(data.c_str(), data.size());
272     file.Flush();
273     file.Close();
274 }
275 
EmitInterfaceProxyMethodImpls(StringBuilder & sb,const std::string & prefix) const276 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodImpls(StringBuilder &sb, const std::string &prefix) const
277 {
278     size_t methodNumber = interface_->GetMethodNumber();
279     for (size_t i = 0; i < methodNumber; i++) {
280         AutoPtr<ASTMethod> method = interface_->GetMethod(i);
281         std::string overloadname = "";
282         SACppCodeEmitter::CheckMethodOverload(method, i, overloadname);
283         SACppCodeEmitter::SetOverloadName(overloadname);
284         EmitInterfaceProxyMethodImpl(method, sb, prefix);
285         if (i != methodNumber - 1) {
286             sb.Append("\n");
287         }
288     }
289 }
290 
EmitInterfaceProxyMethodImpl(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const291 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodImpl(AutoPtr<ASTMethod> &method, StringBuilder &sb,
292     const std::string &prefix) const
293 {
294     if (method->IsMacro()) {
295         sb.AppendFormat("#%s %s\n", method->GetMacroType().c_str(), method->GetMacroVal().c_str());
296     }
297     sb.Append(prefix).AppendFormat("ErrCode %s::%s(", proxyName_.c_str(), method->GetName().c_str());
298     EmitInterfaceMethodParams(method, sb, prefix + TAB);
299     sb.Append(")\n");
300     EmitInterfaceProxyMethodBody(method, sb, prefix);
301     if (method->IsMacro()) {
302         sb.Append("#endif\n");
303     }
304 }
305 
EmitInterfaceProxyMethodPreSendRequest(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const306 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodPreSendRequest(AutoPtr<ASTMethod> &method, StringBuilder &sb,
307     const std::string &prefix) const
308 {
309     if ((method->GetCacheable()) && (!method->IsOneWay())) {
310         std::string overloadname = SACppCodeEmitter::GetOverloadName();
311         sb.Append(prefix).Append("bool hitCache = ApiCacheManager::GetInstance().PreSendRequest(GetDescriptor(),\n")
312             .Append(prefix + TAB).AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s), data, reply);",
313             interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str());
314         sb.Append("\n");
315         sb.Append(prefix).Append("if (hitCache) {\n");
316         EmitInterfaceProxyMethodErrCode(method, sb, prefix);
317         EmitInterfaceProxyMethodReply(method, sb, prefix);
318         sb.Append(prefix + TAB).Append("return ERR_OK;\n");
319         sb.Append(prefix).Append("}\n\n");
320     }
321 }
322 
EmitInterfaceProxyMethodPostSendRequest(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const323 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodPostSendRequest(AutoPtr<ASTMethod> &method, StringBuilder &sb,
324     const std::string &prefix) const
325 {
326     std::string overloadname = SACppCodeEmitter::GetOverloadName();
327     sb.Append(prefix + TAB).Append("ApiCacheManager::GetInstance().PostSendRequest(GetDescriptor(),\n")
328         .Append(prefix + TAB + TAB).AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s), data, reply);\n",
329         interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str());
330 }
331 
EmitInterfaceSetIpcCapacity(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const332 void SaCppClientProxyCodeEmitter::EmitInterfaceSetIpcCapacity(AutoPtr<ASTMethod> &method, StringBuilder &sb,
333     const std::string &prefix) const
334 {
335     std::string capacity = StringHelper::Format("CAPACITY_%s_%d", ConstantName(method->GetName()).c_str(),
336         method->GetIpcCode());
337     sb.Append(prefix).AppendFormat("if (!data.SetMaxCapacity(%s)) {\n", capacity.c_str());
338     if (logOn_) {
339         sb.Append(prefix + TAB).AppendFormat(
340             "HiLog::Error(LABEL, \"Failed to set maximum capacity to %%zu\", %s);\n",
341             capacity.c_str());
342     }
343     sb.Append(prefix + TAB).Append("return ERR_INVALID_VALUE;\n");
344     sb.Append(prefix).Append("}\n\n");
345 }
346 
EmitInterfaceProxyMethodBody(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const347 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodBody(AutoPtr<ASTMethod> &method, StringBuilder &sb,
348     const std::string &prefix) const
349 {
350     sb.Append(prefix).Append("{\n");
351     if (hitraceOn_) {
352         sb.Append(prefix + TAB).AppendFormat("HITRACE_METER_NAME(%s, __PRETTY_FUNCTION__);\n", hitraceTag_.c_str());
353     }
354     sb.Append(prefix + TAB).Append("MessageParcel data;\n");
355     sb.Append(prefix + TAB).Append("MessageParcel reply;\n");
356     std::string option = "MessageOption::TF_SYNC";
357     if (method->IsMessageOption()) {
358         option = method->GetMessageOption();
359     } else if (method->IsOneWay()) {
360         option = "MessageOption::TF_ASYNC";
361     }
362     sb.Append(prefix + TAB).AppendFormat("MessageOption option(%s);\n\n", option.c_str());
363     if (method->HasIpcInCapacity()) {
364         EmitInterfaceSetIpcCapacity(method, sb, prefix + TAB);
365     }
366     sb.Append(prefix + TAB).Append("if (!data.WriteInterfaceToken(GetDescriptor())) {\n");
367     if (logOn_) {
368         sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"Write interface token failed!\");\n");
369     }
370     sb.Append(prefix + TAB + TAB).Append("return ERR_INVALID_VALUE;\n").Append(prefix + TAB).Append("}\n\n");
371     size_t paramNumber = method->GetParameterNumber();
372     for (size_t i = 0; i < paramNumber; i++) {
373         AutoPtr<ASTParameter> param = method->GetParameter(i);
374         if (param->GetAttribute() & ASTParamAttr::PARAM_IN) {
375             EmitWriteMethodParameter(param, "data.", sb, prefix + TAB);
376         }
377     }
378     if (paramNumber > 0) {
379         sb.Append('\n');
380     }
381     EmitInterfaceProxyMethodPreSendRequest(method, sb, prefix + TAB);
382     sb.Append(prefix + TAB).Append("sptr<IRemoteObject> remote = Remote();\n");
383     sb.Append(prefix + TAB).Append("if (!remote) {\n");
384     if (logOn_) {
385         sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"Remote is nullptr!\");\n");
386     }
387     sb.Append(prefix + TAB + TAB).Append("return ERR_INVALID_DATA;\n").Append(prefix + TAB).Append("}\n");
388     std::string overloadname = SACppCodeEmitter::GetOverloadName();
389     sb.Append(prefix + TAB).Append("int32_t result = remote->SendRequest(\n").Append(prefix + TAB + TAB)
390         .AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s), data, reply, option);\n",
391         interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str());
392     sb.Append(prefix + TAB).Append("if (FAILED(result)) {\n");
393     if (logOn_) {
394         sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"Send request failed!\");\n");
395     }
396     sb.Append(prefix + TAB).Append("    return result;\n").Append(prefix + TAB).Append("}\n");
397     EmitInterfaceProxyMethodRetValue(method, sb, prefix);
398 }
399 
EmitInterfaceProxyMethodErrCode(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const400 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodErrCode(AutoPtr<ASTMethod> &method, StringBuilder &sb,
401     const std::string &prefix) const
402 {
403     sb.Append(prefix + TAB).Append("ErrCode errCode = reply.ReadInt32();\n");
404     sb.Append(prefix + TAB).Append("if (FAILED(errCode)) {\n");
405     if (logOn_) {
406         std::string overloadname = SACppCodeEmitter::GetOverloadName();
407         sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"Read result failed, code is: %{public}d.\",\n")
408             .Append(prefix + TAB + TAB + TAB)
409             .AppendFormat("static_cast<uint32_t>(%sIpcCode::COMMAND_%s));\n",
410             interface_->GetName().c_str(), ConstantName(method->GetName() + overloadname).c_str());
411     }
412     sb.Append(prefix + TAB).Append("    return errCode;\n");
413     sb.Append(prefix + TAB).Append("}\n");
414 }
415 
EmitInterfaceProxyMethodReply(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const416 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodReply(AutoPtr<ASTMethod> &method, StringBuilder &sb,
417     const std::string &prefix) const
418 {
419     size_t paramNumber = method->GetParameterNumber();
420     for (size_t i = 0; i < paramNumber; i++) {
421         AutoPtr<ASTParameter> param = method->GetParameter(i);
422         TypeKind paramTypeKind = param->GetType()->GetTypeKind();
423         const std::string name = param->GetName();
424         if ((paramTypeKind == TypeKind::TYPE_ARRAY || paramTypeKind == TypeKind::TYPE_LIST ||
425             paramTypeKind == TypeKind::TYPE_SET) && param->GetAttribute() == ASTParamAttr::PARAM_INOUT) {
426             sb.Append(prefix + TAB).AppendFormat("%s.clear();\n", name.c_str());
427         }
428         if (param != nullptr && (param->GetAttribute() & ASTParamAttr::PARAM_OUT)) {
429             EmitReadMethodParameter(param, "reply.", false, sb, prefix + TAB);
430         }
431     }
432     AutoPtr<ASTType> returnType = method->GetReturnType();
433     if (returnType != nullptr && (returnType->GetTypeKind() != TypeKind::TYPE_VOID)) {
434         AutoPtr<SaTypeEmitter> typeEmitter = GetTypeEmitter(returnType);
435         if (typeEmitter != nullptr) {
436             typeEmitter->EmitCppReadVar("reply.", "funcResult", sb, prefix + TAB, false);
437         }
438     }
439 }
440 
EmitInterfaceProxyMethodRetValue(AutoPtr<ASTMethod> & method,StringBuilder & sb,const std::string & prefix) const441 void SaCppClientProxyCodeEmitter::EmitInterfaceProxyMethodRetValue(AutoPtr<ASTMethod> &method, StringBuilder &sb,
442     const std::string &prefix) const
443 {
444     if (!method->IsOneWay()) {
445         sb.Append("\n");
446         EmitInterfaceProxyMethodErrCode(method, sb, prefix);
447         sb.Append("\n");
448         if (method->GetCacheable()) {
449             EmitInterfaceProxyMethodPostSendRequest(method, sb, prefix);
450         }
451         EmitInterfaceProxyMethodReply(method, sb, prefix);
452     }
453     sb.Append(prefix + TAB).Append("return ERR_OK;\n");
454     sb.Append(prefix).Append("}\n");
455 }
456 
457 } // namespace Idl
458 } // namespace OHOS