1 /*
2  * Copyright (c) 2022-2023 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 <sstream>
17 #include "securec.h"
18 #include "util/file.h"
19 #include "codegen/cpp_code_emitter.h"
20 
21 namespace OHOS {
22 namespace Idl {
EmitInterface()23 void CppCodeEmitter::EmitInterface()
24 {
25     EmitInterfaceHeaderFile();
26 }
27 
EmitInterfaceHeaderFile()28 void CppCodeEmitter::EmitInterfaceHeaderFile()
29 {
30     String filePath = String::Format("%s/%s.h", directory_.string(), FileName(interfaceName_).string());
31     File file(filePath, File::WRITE);
32 
33     StringBuilder sb;
34 
35     EmitLicense(sb);
36     sb.Append("\n");
37     EmitHeadMacro(sb, interfaceFullName_);
38     sb.Append("\n");
39     EmitInterfaceInclusions(sb);
40     sb.Append("\n");
41     if (EmitInterfaceUsings(sb)) {
42         sb.Append("\n");
43     }
44     EmitInterfaceDefinition(sb);
45     EmitTailMacro(sb, interfaceFullName_);
46 
47     String data = sb.ToString();
48     file.WriteData(data.string(), data.GetLength());
49     file.Flush();
50     file.Close();
51 }
52 
EmitInterfaceInclusions(StringBuilder & sb)53 void CppCodeEmitter::EmitInterfaceInclusions(StringBuilder& sb)
54 {
55     EmitInterfaceStdlibInclusions(sb);
56     EmitInterfaceDBinderInclusions(sb);
57     EmitInterfaceSelfDefinedTypeInclusions(sb);
58 }
59 
EmitInterfaceStdlibInclusions(StringBuilder & sb)60 void CppCodeEmitter::EmitInterfaceStdlibInclusions(StringBuilder& sb)
61 {
62     bool includeString = false;
63     bool includeList = false;
64     bool includeMap = false;
65     bool includeNum = false;
66     if (metaComponent_ == nullptr) {
67         return;
68     }
69     for (int i = 0; i < metaComponent_->typeNumber_; i++) {
70         MetaType* mt = metaComponent_->types_[i];
71         switch (mt->kind_) {
72             case TypeKind::Byte: {
73                 if (!includeNum) {
74                     sb.Append("#include <cstdint>\n");
75                     includeNum = true;
76                 }
77                 break;
78             }
79             case TypeKind::String: {
80                 if (!includeString) {
81                     sb.Append("#include <string_ex.h>\n");
82                     includeString = true;
83                 }
84                 break;
85             }
86             case TypeKind::Array:
87             case TypeKind::List: {
88                 if (!includeList) {
89                     sb.Append("#include <vector>\n");
90                     includeList = true;
91                 }
92                 break;
93             }
94             case TypeKind::Map: {
95                 if (!includeMap) {
96                     sb.Append("#include <unordered_map>\n");
97                     includeMap = true;
98                 }
99                 break;
100             }
101             default:
102                 break;
103         }
104     }
105 }
106 
EmitInterfaceDBinderInclusions(StringBuilder & sb)107 void CppCodeEmitter::EmitInterfaceDBinderInclusions(StringBuilder& sb)
108 {
109     sb.Append("#include <iremote_broker.h>\n");
110     if (logOn_) {
111         sb.Append("#include \"hilog/log.h\"\n");
112     }
113 }
114 
GetFilePath(const String & fpnp)115 String CppCodeEmitter::GetFilePath(const String& fpnp)
116 {
117     int pos = fpnp.IndexOf("..");
118     if (pos == -1) {
119         return String();
120     }
121     String res = fpnp.Substring(0, pos + 1);
122     return res;
123 }
124 
GetFilePathNoPoint(const String & fpnp)125 String CppCodeEmitter::GetFilePathNoPoint(const String& fpnp)
126 {
127     int pos = fpnp.IndexOf("..");
128     if (pos == -1) {
129         return String();
130     }
131     String res = fpnp.Substring(0, pos);
132     return res;
133 }
134 
GetNamespace(const String & fpnp)135 String CppCodeEmitter::GetNamespace(const String& fpnp)
136 {
137     int pos = fpnp.IndexOf("..");
138     if (pos == -1) {
139         return fpnp;
140     }
141     String res = fpnp.Substring(pos + 2);
142     return res;
143 }
144 
EmitInterfaceSelfDefinedTypeInclusions(StringBuilder & sb)145 void CppCodeEmitter::EmitInterfaceSelfDefinedTypeInclusions(StringBuilder& sb)
146 {
147     for (int i = 0; i < metaComponent_->sequenceableNumber_; i++) {
148         MetaSequenceable* mp = metaComponent_->sequenceables_[i];
149         if (mp == nullptr) {
150             continue;
151         }
152         String filePath = GetFilePathNoPoint(String(mp->namespace_));
153         String fileName;
154         String sequenceName = mp->name_;
155         filePath.IsEmpty() ? fileName = FileName(sequenceName) : fileName = FileName(filePath);
156         sb.Append("#include ").AppendFormat("\"%s.h\"\n", fileName.string());
157     }
158 
159     for (int i = 0; i < metaComponent_->interfaceNumber_; i++) {
160         MetaInterface* mi = metaComponent_->interfaces_[i];
161         if (mi->external_) {
162             String filePath = GetFilePath(String(mi->namespace_));
163             String fileName = FileName(filePath + mi->name_);
164             sb.Append("#include ").AppendFormat("\"%s.h\"\n", fileName.string());
165         }
166     }
167 }
168 
EmitInterfaceUsings(StringBuilder & sb)169 bool CppCodeEmitter::EmitInterfaceUsings(StringBuilder& sb)
170 {
171     bool ret = false;
172     for (int i = 0; i < metaComponent_->sequenceableNumber_; i++) {
173         MetaSequenceable* mp = metaComponent_->sequenceables_[i];
174         String np = GetNamespace(String(mp->namespace_));
175         if (np.IsEmpty()) {
176             continue;
177         }
178         String fullName = CppFullName(np + mp->name_);
179         sb.Append("using ").AppendFormat("%s;\n", fullName.string());
180         ret = true;
181     }
182 
183     for (int i = 0; i < metaComponent_->interfaceNumber_; i++) {
184         MetaInterface* mi = metaComponent_->interfaces_[i];
185         if (mi->external_) {
186             String np = GetNamespace(String(mi->namespace_));
187             if (np.IsEmpty()) {
188                 continue;
189             }
190             String fullName = CppFullName(np + mi->name_);
191             sb.Append("using ").AppendFormat("%s;\n", fullName.string());
192             ret = true;
193         }
194     }
195     return ret;
196 }
197 
EmitInterfaceDefinition(StringBuilder & sb)198 void CppCodeEmitter::EmitInterfaceDefinition(StringBuilder& sb)
199 {
200     EmitBeginNamespace(sb);
201     sb.AppendFormat("class %s : public IRemoteBroker {\n", metaInterface_->name_);
202     sb.Append("public:\n");
203     EmitInterfaceBody(sb, TAB);
204     EmitInterfaceMemberVariables(sb, TAB);
205     sb.Append("};\n");
206     EmitEndNamespace(sb);
207 }
208 
EmitInterfaceBody(StringBuilder & sb,const String & prefix)209 void CppCodeEmitter::EmitInterfaceBody(StringBuilder& sb, const String& prefix)
210 {
211     String nameWithoutPath = GetNamespace(interfaceFullName_);
212     sb.Append(TAB).AppendFormat("DECLARE_INTERFACE_DESCRIPTOR(u\"%s\");\n", nameWithoutPath.string());
213     sb.Append("\n");
214     EmitInterfaceMethods(sb, TAB);
215 }
216 
EmitInterfaceMethods(StringBuilder & sb,const String & prefix)217 void CppCodeEmitter::EmitInterfaceMethods(StringBuilder& sb, const String& prefix)
218 {
219     if (metaInterface_->methodNumber_ > 0) {
220         for (int i = 0; i < metaInterface_->methodNumber_; i++) {
221             MetaMethod* mm = metaInterface_->methods_[i];
222             EmitInterfaceMethod(mm, sb, prefix);
223             if (i != metaInterface_->methodNumber_ - 1) {
224                 sb.Append("\n");
225             }
226         }
227     }
228 }
229 
EmitInterfaceMethod(MetaMethod * mm,StringBuilder & sb,const String & prefix)230 void CppCodeEmitter::EmitInterfaceMethod(MetaMethod* mm, StringBuilder& sb, const String& prefix)
231 {
232     MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
233     if (mm->parameterNumber_ == 0 && returnType->kind_ == TypeKind::Void) {
234         sb.Append(prefix).AppendFormat("virtual ErrCode %s() = 0;\n", mm->name_);
235     } else {
236         sb.Append(prefix).AppendFormat("virtual ErrCode %s(\n", mm->name_);
237         for (int i = 0; i < mm->parameterNumber_; i++) {
238             MetaParameter* mp = mm->parameters_[i];
239             EmitInterfaceMethodParameter(mp, sb, prefix + TAB);
240             if (i != mm->parameterNumber_ - 1 || returnType->kind_ != TypeKind::Void) {
241                 sb.Append(",\n");
242             }
243         }
244         if (returnType->kind_ != TypeKind::Void) {
245             EmitInterfaceMethodReturn(returnType, sb, prefix + TAB);
246         }
247         sb.Append(") = 0;\n");
248     }
249 }
250 
EmitInterfaceMethodParameter(MetaParameter * mp,StringBuilder & sb,const String & prefix)251 void CppCodeEmitter::EmitInterfaceMethodParameter(MetaParameter* mp, StringBuilder& sb, const String& prefix)
252 {
253     sb.Append(prefix);
254 
255     MetaType* mt = metaComponent_->types_[mp->typeIndex_];
256     const std::string name = mp->name_;
257     sb.AppendFormat("%s %s", EmitType(mt, mp->attributes_, false).string(), name.c_str());
258 }
259 
EmitInterfaceMethodReturn(MetaType * mt,StringBuilder & sb,const String & prefix)260 void CppCodeEmitter::EmitInterfaceMethodReturn(MetaType* mt, StringBuilder& sb, const String& prefix)
261 {
262     sb.Append(prefix).AppendFormat("%s result", EmitType(mt, ATTR_OUT, false).string());
263 }
264 
EmitInterfaceMemberVariables(StringBuilder & sb,const String & prefix)265 void CppCodeEmitter::EmitInterfaceMemberVariables(StringBuilder& sb, const String& prefix)
266 {
267     sb.Append("protected:\n");
268     if (!domainId_.IsNull() && !logTag_.IsNull()) {
269         sb.Append(prefix).AppendFormat(
270             "static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, %s, \"%s\"};\n",
271             domainId_.string(), logTag_.string());
272     }
273     sb.Append(prefix).Append("const int VECTOR_MAX_SIZE = 102400;\n");
274     sb.Append(prefix).Append("const int LIST_MAX_SIZE = 102400;\n");
275     sb.Append(prefix).Append("const int MAP_MAX_SIZE = 102400;\n");
276 }
277 
EmitInterfaceProxy()278 void CppCodeEmitter::EmitInterfaceProxy()
279 {
280     EmitInterfaceProxyHeaderFile();
281     EmitInterfaceProxyCppFile();
282 }
283 
EmitInterfaceProxyHeaderFile()284 void CppCodeEmitter::EmitInterfaceProxyHeaderFile()
285 {
286     String filePath = String::Format("%s/%s.h", directory_.string(), FileName(proxyName_).string());
287     File file(filePath, File::WRITE);
288 
289     StringBuilder sb;
290 
291     EmitLicense(sb);
292     sb.Append("\n");
293     EmitHeadMacro(sb, proxyFullName_);
294     sb.Append("\n");
295     sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string());
296     sb.Append("#include <iremote_proxy.h>\n");
297     if (metaComponent_->hasCacheableProxyMethods_ == true) {
298         sb.Append("#include \"api_cache_manager.h\"\n");
299     }
300     sb.Append("\n");
301     EmitInterfaceProxyInHeaderFile(sb);
302     EmitTailMacro(sb, proxyFullName_);
303 
304     String data = sb.ToString();
305     file.WriteData(data.string(), data.GetLength());
306     file.Flush();
307     file.Close();
308 }
309 
EmitInterfaceProxyInHeaderFile(StringBuilder & sb)310 void CppCodeEmitter::EmitInterfaceProxyInHeaderFile(StringBuilder& sb)
311 {
312     EmitBeginNamespace(sb);
313     sb.AppendFormat("class %s : public IRemoteProxy<%s> {\n", proxyName_.string(), interfaceName_.string());
314     sb.Append("public:\n");
315     EmitInterfaceProxyConstructor(sb, TAB);
316     sb.Append("\n");
317     EmitInterfaceProxyMethodDecls(sb, TAB);
318     sb.Append("\n");
319     sb.Append("private:\n");
320     EmitInterfaceProxyConstants(sb, TAB);
321     sb.Append("};\n");
322     EmitEndNamespace(sb);
323 }
324 
EmitInterfaceProxyRegisterDeathRecipient(StringBuilder & sb,const String & prefix)325 void CppCodeEmitter::EmitInterfaceProxyRegisterDeathRecipient(StringBuilder& sb, const String& prefix)
326 {
327     sb.Append(prefix).Append("if (remote != nullptr) {\n");
328     sb.Append(prefix + TAB).Append("if (!remote->IsProxyObject()) {\n");
329     if (logOn_) {
330         sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"remote is not proxy object!\");\n");
331     }
332     sb.Append(prefix + TAB + TAB).Append("return;\n");
333     sb.Append(prefix + TAB).Append("}\n");
334     sb.Append(prefix + TAB).AppendFormat("deathRecipient_ = new (std::nothrow) %s(*this);\n",
335         deathRecipientName_.string());
336     sb.Append(prefix + TAB).Append("if (deathRecipient_ == nullptr) {\n");
337     if (logOn_) {
338         sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"deathRecipient_ is nullptr!\");\n");
339     }
340     sb.Append(prefix + TAB + TAB).Append("return;\n");
341     sb.Append(prefix + TAB).Append("}\n");
342     sb.Append(prefix + TAB).Append("if (!remote->AddDeathRecipient(deathRecipient_)) {\n");
343     if (logOn_) {
344         sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"AddDeathRecipient failed!\");\n");
345     }
346     sb.Append(prefix + TAB + TAB).Append("return;\n");
347     sb.Append(prefix + TAB).Append("}\n");
348     sb.Append(prefix + TAB).Append("remote_ = remote;\n");
349     sb.Append(prefix).Append("}\n");
350 }
351 
EmitInterfaceProxyAddCacheAbleAPI(StringBuilder & sb,const String & prefix)352 void CppCodeEmitter::EmitInterfaceProxyAddCacheAbleAPI(StringBuilder& sb, const String& prefix)
353 {
354     sb.Append("\n");
355     if (metaComponent_->hasCacheableProxyMethods_ == false) {
356         return;
357     }
358     for (int i = 0; i < metaInterface_->methodNumber_; i++) {
359         MetaMethod* mm = metaInterface_->methods_[i];
360         if (mm->cacheable_ == false) {
361             continue;
362         }
363         if (mm->cacheabletime_ != 0) {
364             sb.Append(prefix + TAB).AppendFormat(
365                 "ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(), COMMAND_%s, %d000);\n",
366                 ConstantName(mm->name_).string(), mm->cacheabletime_);
367         } else {
368             sb.Append(prefix + TAB).AppendFormat(
369                 "ApiCacheManager::GetInstance().AddCacheApi(GetDescriptor(), COMMAND_%s, 0);\n",
370                 ConstantName(mm->name_).string());
371         }
372     }
373     sb.Append("\n");
374     EmitInterfaceProxyRegisterDeathRecipient(sb, prefix + TAB);
375 }
376 
EmitInterfaceProxyUnRegisterDeathRecipient(StringBuilder & sb,const String & prefix)377 void CppCodeEmitter::EmitInterfaceProxyUnRegisterDeathRecipient(StringBuilder& sb, const String& prefix)
378 {
379     sb.Append(prefix).Append("if (remote_ == nullptr) {\n");
380     sb.Append(prefix).Append(TAB).Append("return;\n");
381     sb.Append(prefix).Append("}\n");
382     sb.Append(prefix).Append("if (deathRecipient_ == nullptr) {\n");
383     sb.Append(prefix).Append(TAB).Append("return;\n");
384     sb.Append(prefix).Append("}\n");
385     sb.Append(prefix).Append("remote_->RemoveDeathRecipient(deathRecipient_);\n");
386     sb.Append(prefix).Append("remote_ = nullptr;\n");
387     if (metaInterface_->methodNumber_ > 0) {
388         sb.Append("\n");
389         for (int i = 0; i < metaInterface_->methodNumber_; i++) {
390             MetaMethod* mm = metaInterface_->methods_[i];
391             if (mm->cacheable_) {
392                 sb.Append(prefix).AppendFormat(
393                     "ApiCacheManager::GetInstance().DelCacheApi(GetDescriptor(), COMMAND_%s);\n",
394                     ConstantName(mm->name_).string());
395             }
396         }
397     }
398 }
399 
EmitInterfaceProxyConstructor(StringBuilder & sb,const String & prefix)400 void CppCodeEmitter::EmitInterfaceProxyConstructor(StringBuilder& sb, const String& prefix)
401 {
402     sb.Append(prefix).AppendFormat("explicit %s(\n", proxyName_.string());
403     sb.Append(prefix + TAB).Append("const sptr<IRemoteObject>& remote)\n");
404     sb.Append(prefix + TAB).AppendFormat(": IRemoteProxy<%s>(remote)\n", interfaceName_.string());
405     sb.Append(prefix).Append("{");
406     EmitInterfaceProxyAddCacheAbleAPI(sb, prefix);
407     sb.Append(prefix).Append("}\n\n");
408     sb.Append(prefix).AppendFormat("virtual ~%s()\n", proxyName_.string());
409     sb.Append(prefix).Append("{\n");
410     if (metaComponent_->hasCacheableProxyMethods_) {
411         EmitInterfaceProxyUnRegisterDeathRecipient(sb, prefix + TAB);
412     }
413     sb.Append(prefix).Append("}\n");
414 }
415 
EmitInterfaceProxyMethodDecls(StringBuilder & sb,const String & prefix)416 void CppCodeEmitter::EmitInterfaceProxyMethodDecls(StringBuilder& sb, const String& prefix)
417 {
418     if (metaInterface_->methodNumber_ > 0) {
419         for (int i = 0; i < metaInterface_->methodNumber_; i++) {
420             MetaMethod* mm = metaInterface_->methods_[i];
421             EmitInterfaceProxyMethodDecl(mm, sb, prefix);
422             if (i != metaInterface_->methodNumber_ - 1) {
423                 sb.Append("\n");
424             }
425         }
426     }
427 }
428 
EmitInterfaceProxyMethodDecl(MetaMethod * mm,StringBuilder & sb,const String & prefix)429 void CppCodeEmitter::EmitInterfaceProxyMethodDecl(MetaMethod* mm, StringBuilder& sb, const String& prefix)
430 {
431     MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
432     if (mm->parameterNumber_ == 0 && returnType->kind_ == TypeKind::Void) {
433         sb.Append(prefix).AppendFormat("ErrCode %s() override;\n", mm->name_);
434     } else {
435         sb.Append(prefix).AppendFormat("ErrCode %s(\n", mm->name_);
436         for (int i = 0; i < mm->parameterNumber_; i++) {
437             MetaParameter* mp = mm->parameters_[i];
438             EmitInterfaceMethodParameter(mp, sb, prefix + TAB);
439             if (i != mm->parameterNumber_ - 1 || returnType->kind_ != TypeKind::Void) {
440                 sb.Append(",\n");
441             }
442         }
443         if (returnType->kind_ != TypeKind::Void) {
444             EmitInterfaceMethodReturn(returnType, sb, prefix + TAB);
445         }
446         sb.Append(") override;\n");
447     }
448 }
449 
EmitInterfaceProxyDeathRecipient(StringBuilder & sb,const String & prefix)450 void CppCodeEmitter::EmitInterfaceProxyDeathRecipient(StringBuilder& sb, const String& prefix)
451 {
452     sb.Append(prefix).AppendFormat("class %s : public IRemoteObject::DeathRecipient {\n", deathRecipientName_.string());
453     sb.Append(prefix).Append("public:\n");
454     sb.Append(prefix + TAB).AppendFormat("explicit %s(%s &client) : client_(client) {}\n", deathRecipientName_.string(),
455         proxyName_.string());
456     sb.Append(prefix + TAB).AppendFormat("~%s() override = default;\n", deathRecipientName_.string());
457     sb.Append(prefix + TAB).Append("void OnRemoteDied(const wptr<IRemoteObject> &remote) override\n");
458     sb.Append(prefix + TAB).Append("{\n");
459     sb.Append(prefix + TAB + TAB).Append("client_.OnRemoteDied(remote);\n");
460     sb.Append(prefix + TAB).Append("}\n");
461     sb.Append(prefix).Append("private:\n");
462     sb.Append(prefix + TAB).AppendFormat("%s &client_;\n", proxyName_.string());
463     sb.Append(prefix).Append("};\n\n");
464 
465     sb.Append(prefix).Append("void OnRemoteDied(const wptr<IRemoteObject> &remoteObject)\n");
466     sb.Append(prefix).Append("{\n");
467     sb.Append(prefix + TAB).Append("(void)remoteObject;\n");
468     sb.Append(prefix + TAB).Append("ApiCacheManager::GetInstance().ClearCache(GetDescriptor());\n");
469     sb.Append(prefix).Append("}\n");
470     sb.Append(prefix).Append("sptr<IRemoteObject> remote_ = nullptr;\n");
471     sb.Append(prefix).Append("sptr<IRemoteObject::DeathRecipient> deathRecipient_ = nullptr;\n");
472 }
473 
EmitInterfaceProxyConstants(StringBuilder & sb,const String & prefix)474 void CppCodeEmitter::EmitInterfaceProxyConstants(StringBuilder& sb, const String& prefix)
475 {
476     if (metaComponent_->hasCacheableProxyMethods_) {
477         EmitInterfaceProxyDeathRecipient(sb, prefix);
478     }
479     EmitInterfaceMethodCommands(sb, prefix);
480     sb.Append("\n");
481     sb.Append(prefix).AppendFormat("static inline BrokerDelegator<%s> delegator_;\n", proxyName_.string());
482 }
483 
EmitInterfaceProxyCppFile()484 void CppCodeEmitter::EmitInterfaceProxyCppFile()
485 {
486     String filePath = String::Format("%s/%s.cpp", directory_.string(), FileName(proxyName_).string());
487     File file(filePath, File::WRITE);
488 
489     StringBuilder sb;
490 
491     EmitLicense(sb);
492     sb.Append("\n");
493     sb.AppendFormat("#include \"%s.h\"\n", FileName(proxyName_).string());
494     if (logOn_) {
495         sb.Append("#include \"hilog/log.h\"\n");
496     }
497     if (hitraceOn_) {
498         sb.Append("#include \"hitrace_meter.h\"\n");
499     }
500     sb.Append("\n");
501     if (logOn_) {
502         sb.Append("using OHOS::HiviewDFX::HiLog;\n\n");
503     }
504     EmitBeginNamespace(sb);
505     EmitInterfaceProxyMethodImpls(sb, "");
506     EmitEndNamespace(sb);
507 
508     String data = sb.ToString();
509     file.WriteData(data.string(), data.GetLength());
510     file.Flush();
511     file.Close();
512 }
513 
EmitInterfaceProxyMethodImpls(StringBuilder & sb,const String & prefix)514 void CppCodeEmitter::EmitInterfaceProxyMethodImpls(StringBuilder& sb, const String& prefix)
515 {
516     if (metaInterface_->methodNumber_ > 0) {
517         for (int i = 0; i < metaInterface_->methodNumber_; i++) {
518             MetaMethod* mm = metaInterface_->methods_[i];
519             EmitInterfaceProxyMethodImpl(mm, sb, prefix);
520             if (i != metaInterface_->methodNumber_ - 1) {
521                 sb.Append("\n");
522             }
523         }
524     }
525 }
526 
EmitInterfaceProxyMethodImpl(MetaMethod * mm,StringBuilder & sb,const String & prefix)527 void CppCodeEmitter::EmitInterfaceProxyMethodImpl(MetaMethod* mm, StringBuilder& sb, const String& prefix)
528 {
529     MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
530     if (mm->parameterNumber_ == 0 && returnType->kind_ == TypeKind::Void) {
531         sb.Append(prefix).AppendFormat("ErrCode %s::%s()\n", proxyName_.string(), mm->name_);
532     } else {
533         sb.Append(prefix).AppendFormat("ErrCode %s::%s(\n", proxyName_.string(), mm->name_);
534         for (int i = 0; i < mm->parameterNumber_; i++) {
535             MetaParameter* mp = mm->parameters_[i];
536             EmitInterfaceMethodParameter(mp, sb, prefix + TAB);
537             if (i != mm->parameterNumber_ - 1 || returnType->kind_ != TypeKind::Void) {
538                 sb.Append(",\n");
539             }
540         }
541         if (returnType->kind_ != TypeKind::Void) {
542             EmitInterfaceMethodReturn(returnType, sb, prefix + TAB);
543         }
544         sb.Append(")\n");
545     }
546     EmitInterfaceProxyMethodBody(mm, sb, prefix);
547 }
548 
EmitInterfaceProxyMethodPreSendRequest(MetaMethod * mm,StringBuilder & sb,const String & prefix)549 void CppCodeEmitter::EmitInterfaceProxyMethodPreSendRequest(MetaMethod* mm, StringBuilder& sb, const String& prefix)
550 {
551     if ((mm->cacheable_ == true) && ((mm->properties_ & METHOD_PROPERTY_ONEWAY) == 0)) {
552         sb.Append("\n");
553         sb.Append(prefix + TAB).AppendFormat(
554             "bool hitCache = ApiCacheManager::GetInstance().PreSendRequest(GetDescriptor(), COMMAND_%s, data, reply);",
555             ConstantName(mm->name_).string());
556         sb.Append("\n");
557         sb.Append(prefix + TAB).Append("if (hitCache == true) {\n");
558         EmitInterfaceProxyMethodErrCode(sb, prefix + TAB);
559         EmitInterfaceProxyMethodReply(mm, sb, prefix + TAB);
560         sb.Append(prefix + TAB + TAB).Append("return ERR_OK;\n");
561         sb.Append(prefix + TAB).Append("}\n\n");
562     }
563 }
564 
EmitInterfaceProxyMethodPostSendRequest(MetaMethod * mm,StringBuilder & sb,const String & prefix)565 void CppCodeEmitter::EmitInterfaceProxyMethodPostSendRequest(MetaMethod* mm, StringBuilder& sb, const String& prefix)
566 {
567     sb.Append(prefix + TAB).AppendFormat(
568         "ApiCacheManager::GetInstance().PostSendRequest(GetDescriptor(), COMMAND_%s, data, reply);\n",
569         ConstantName(mm->name_).string());
570 }
571 
EmitInterfaceProxyMethodBody(MetaMethod * mm,StringBuilder & sb,const String & prefix)572 void CppCodeEmitter::EmitInterfaceProxyMethodBody(MetaMethod* mm, StringBuilder& sb, const String& prefix)
573 {
574     sb.Append(prefix).Append("{\n");
575     if (hitraceOn_) {
576         sb.Append(prefix + TAB).AppendFormat("HITRACE_METER_NAME(%s, __PRETTY_FUNCTION__);\n",
577             hitraceTag_.string());
578     }
579     sb.Append(prefix + TAB).Append("MessageParcel data;\n");
580     sb.Append(prefix + TAB).Append("MessageParcel reply;\n");
581     sb.Append(prefix + TAB).AppendFormat("MessageOption option(%s);\n",
582         (mm->properties_ & METHOD_PROPERTY_ONEWAY) != 0 ? "MessageOption::TF_ASYNC" : "MessageOption::TF_SYNC");
583     sb.Append("\n");
584     sb.Append(prefix + TAB).Append("if (!data.WriteInterfaceToken(GetDescriptor())) {\n");
585     if (logOn_) {
586         sb.Append(prefix + TAB).Append(TAB).Append("HiLog::Error(LABEL, \"Write interface token failed!\");\n");
587     }
588     sb.Append(prefix + TAB).Append(TAB).Append("return ERR_INVALID_VALUE;\n");
589     sb.Append(prefix + TAB).Append("}\n");
590     sb.Append("\n");
591 
592     for (int i = 0; i < mm->parameterNumber_; i++) {
593         MetaParameter* mp = mm->parameters_[i];
594         if ((mp->attributes_ & ATTR_IN) != 0) {
595             EmitWriteMethodParameter(mp, "data.", sb, prefix + TAB);
596         }
597     }
598     EmitInterfaceProxyMethodPreSendRequest(mm, sb, prefix);
599     sb.Append(prefix + TAB).Append("sptr<IRemoteObject> remote = Remote();\n");
600     sb.Append(prefix + TAB).Append("if (remote == nullptr) {\n");
601     if (logOn_) {
602         sb.Append(prefix + TAB).Append(TAB).Append("HiLog::Error(LABEL, \"Remote is nullptr!\");\n");
603     }
604     sb.Append(prefix + TAB).Append(TAB).Append("return ERR_INVALID_DATA;\n");
605     sb.Append(prefix + TAB).Append("}\n\n");
606     sb.Append(prefix + TAB).AppendFormat("int32_t result = remote->SendRequest(COMMAND_%s, data, reply, option);\n",
607         ConstantName(mm->name_).string());
608     sb.Append(prefix + TAB).Append("if (FAILED(result)) {\n");
609     if (logOn_) {
610         sb.Append(prefix + TAB).Append(TAB).Append("HiLog::Error(LABEL, \"Send request failed!\");\n");
611     }
612     sb.Append(prefix + TAB).Append("    return result;\n");
613     sb.Append(prefix + TAB).Append("}\n");
614     EmitInterfaceProxyMethodRetValue(mm, sb, prefix);
615     sb.Append(prefix).Append("}\n");
616 }
617 
EmitInterfaceProxyMethodErrCode(StringBuilder & sb,const String & prefix)618 void CppCodeEmitter::EmitInterfaceProxyMethodErrCode(StringBuilder& sb, const String& prefix)
619 {
620     sb.Append(prefix + TAB).Append("ErrCode errCode = reply.ReadInt32();\n");
621     sb.Append(prefix + TAB).Append("if (FAILED(errCode)) {\n");
622     if (logOn_) {
623         sb.Append(prefix + TAB + TAB).Append("HiLog::Error(LABEL, \"Read Int32 failed!\");\n");
624     }
625     sb.Append(prefix + TAB).Append("    return errCode;\n");
626     sb.Append(prefix + TAB).Append("}\n");
627 }
628 
EmitInterfaceProxyMethodReply(MetaMethod * mm,StringBuilder & sb,const String & prefix)629 void CppCodeEmitter::EmitInterfaceProxyMethodReply(MetaMethod* mm, StringBuilder& sb, const String& prefix)
630 {
631     for (int i = 0; i < mm->parameterNumber_; i++) {
632         MetaParameter* mp = mm->parameters_[i];
633         if ((mp->attributes_ & ATTR_OUT) != 0) {
634             EmitReadMethodParameter(mp, "reply.", sb, prefix + TAB);
635         }
636     }
637     MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
638     if (returnType->kind_ != TypeKind::Void) {
639         EmitReadVariable("reply.", "result", returnType, sb, prefix + TAB, false);
640     }
641 }
642 
EmitInterfaceProxyMethodRetValue(MetaMethod * mm,StringBuilder & sb,const String & prefix)643 void CppCodeEmitter::EmitInterfaceProxyMethodRetValue(MetaMethod* mm, StringBuilder& sb, const String& prefix)
644 {
645     if ((mm->properties_ & METHOD_PROPERTY_ONEWAY) == 0) {
646         EmitInterfaceProxyMethodErrCode(sb, prefix);
647         sb.Append("\n");
648         if (mm->cacheable_ == true) {
649             EmitInterfaceProxyMethodPostSendRequest(mm, sb, prefix);
650         }
651         EmitInterfaceProxyMethodReply(mm, sb, prefix);
652     }
653     sb.Append(prefix + TAB).Append("return ERR_OK;\n");
654 }
655 
EmitWriteMethodParameter(MetaParameter * mp,const String & parcelName,StringBuilder & sb,const String & prefix)656 void CppCodeEmitter::EmitWriteMethodParameter(MetaParameter* mp, const String& parcelName, StringBuilder& sb,
657     const String& prefix)
658 {
659     MetaType* mt = metaComponent_->types_[mp->typeIndex_];
660     const std::string name = mp->name_;
661     EmitWriteVariable(parcelName, name, mt, sb, prefix);
662 }
663 
EmitReadMethodParameter(MetaParameter * mp,const String & parcelName,StringBuilder & sb,const String & prefix)664 void CppCodeEmitter::EmitReadMethodParameter(MetaParameter* mp, const String& parcelName, StringBuilder& sb,
665     const String& prefix)
666 {
667     MetaType* mt = metaComponent_->types_[mp->typeIndex_];
668     const std::string name = mp->name_;
669     EmitReadVariable(parcelName, name, mt, sb, prefix, false);
670 }
671 
EmitInterfaceStub()672 void CppCodeEmitter::EmitInterfaceStub()
673 {
674     EmitInterfaceStubHeaderFile();
675     EmitInterfaceStubCppFile();
676 }
677 
EmitInterfaceStubHeaderFile()678 void CppCodeEmitter::EmitInterfaceStubHeaderFile()
679 {
680     String filePath = String::Format("%s/%s.h", directory_.string(), FileName(stubName_).string());
681     File file(filePath, File::WRITE);
682 
683     StringBuilder sb;
684 
685     EmitLicense(sb);
686     sb.Append("\n");
687     EmitHeadMacro(sb, stubFullName_);
688     sb.Append("\n");
689     sb.AppendFormat("#include \"%s.h\"\n", FileName(interfaceName_).string());
690     sb.Append("#include <iremote_stub.h>\n");
691     sb.Append("\n");
692     EmitInterfaceStubInHeaderFile(sb);
693     EmitTailMacro(sb, stubFullName_);
694 
695     String data = sb.ToString();
696     file.WriteData(data.string(), data.GetLength());
697     file.Flush();
698     file.Close();
699 }
700 
EmitInterfaceStubInHeaderFile(StringBuilder & sb)701 void CppCodeEmitter::EmitInterfaceStubInHeaderFile(StringBuilder& sb)
702 {
703     EmitBeginNamespace(sb);
704     sb.AppendFormat("class %s : public IRemoteStub<%s> {\n", stubName_.string(), interfaceName_.string());
705     sb.Append("public:\n");
706     EmitInterfaceStubMethodDecls(sb, TAB);
707     sb.Append("\n");
708     sb.Append("private:\n");
709     EmitInterfaceStubConstants(sb, TAB);
710     sb.Append("};\n");
711     EmitEndNamespace(sb);
712 }
713 
EmitInterfaceStubMethodDecls(StringBuilder & sb,const String & prefix)714 void CppCodeEmitter::EmitInterfaceStubMethodDecls(StringBuilder& sb, const String& prefix)
715 {
716     sb.Append(prefix).Append("int32_t OnRemoteRequest(\n");
717     sb.Append(prefix + TAB).Append("uint32_t code,\n");
718     sb.Append(prefix + TAB).Append("MessageParcel& data,\n");
719     sb.Append(prefix + TAB).Append("MessageParcel& reply,\n");
720     sb.Append(prefix + TAB).Append("MessageOption& option) override;\n");
721 }
722 
EmitInterfaceStubConstants(StringBuilder & sb,const String & prefix)723 void CppCodeEmitter::EmitInterfaceStubConstants(StringBuilder& sb, const String& prefix)
724 {
725     EmitInterfaceMethodCommands(sb, prefix);
726 }
727 
EmitInterfaceStubCppFile()728 void CppCodeEmitter::EmitInterfaceStubCppFile()
729 {
730     String filePath = String::Format("%s/%s.cpp", directory_.string(), FileName(stubName_).string());
731     File file(filePath, File::WRITE);
732 
733     StringBuilder sb;
734 
735     EmitLicense(sb);
736     sb.Append("\n");
737     sb.AppendFormat("#include \"%s.h\"\n", FileName(stubName_).string());
738     if (logOn_) {
739         sb.Append("#include \"hilog/log.h\"\n");
740     }
741     if (hitraceOn_) {
742         sb.Append("#include \"hitrace_meter.h\"\n");
743     }
744     sb.Append("\n");
745     if (logOn_) {
746         sb.Append("using OHOS::HiviewDFX::HiLog;\n\n");
747     }
748     EmitBeginNamespace(sb);
749     EmitInterfaceStubMethodImpls(sb, "");
750     EmitEndNamespace(sb);
751 
752     String data = sb.ToString();
753     file.WriteData(data.string(), data.GetLength());
754     file.Flush();
755     file.Close();
756 }
757 
EmitInterfaceStubMethodImpls(StringBuilder & sb,const String & prefix)758 void CppCodeEmitter::EmitInterfaceStubMethodImpls(StringBuilder& sb, const String& prefix)
759 {
760     sb.Append(prefix).AppendFormat("int32_t %s::OnRemoteRequest(\n", stubName_.string());
761     sb.Append(prefix + TAB).Append("uint32_t code,\n");
762     sb.Append(prefix + TAB).Append("MessageParcel& data,\n");
763     sb.Append(prefix + TAB).Append("MessageParcel& reply,\n");
764     sb.Append(prefix + TAB).Append("MessageOption& option)\n");
765     sb.Append(prefix).Append("{\n");
766     if (hitraceOn_) {
767     sb.Append(prefix + TAB).AppendFormat("HITRACE_METER_NAME(%s, __PRETTY_FUNCTION__);\n",
768         hitraceTag_.string());
769     }
770     sb.Append(prefix + TAB).Append("std::u16string localDescriptor = GetDescriptor();\n");
771     sb.Append(prefix + TAB).Append("std::u16string remoteDescriptor = data.ReadInterfaceToken();\n");
772     sb.Append(prefix + TAB).Append("if (localDescriptor != remoteDescriptor) {\n");
773     sb.Append(prefix + TAB).Append(TAB).Append("return ERR_TRANSACTION_FAILED;\n");
774     sb.Append(prefix + TAB).Append("}\n");
775     sb.Append(prefix + TAB).Append("switch (code) {\n");
776     for (int i = 0; i < metaInterface_->methodNumber_; i++) {
777         MetaMethod* mm = metaInterface_->methods_[i];
778         EmitInterfaceStubMethodImpl(mm, sb, prefix + TAB + TAB);
779     }
780     sb.Append(prefix + TAB).Append(TAB).Append("default:\n");
781     sb.Append(prefix + TAB).Append(TAB).Append(TAB).Append(
782         "return IPCObjectStub::OnRemoteRequest(code, data, reply, option);\n");
783     sb.Append(prefix + TAB).Append("}\n\n");
784     sb.Append(prefix + TAB).Append("return ERR_TRANSACTION_FAILED;\n");
785     sb.Append(prefix).Append("}\n");
786 }
787 
EmitInterfaceStubMethodImplReturn(MetaMethod * mm,StringBuilder & sb,const String & prefix,MetaType * returnType)788 void CppCodeEmitter::EmitInterfaceStubMethodImplReturn(MetaMethod* mm,
789     StringBuilder& sb, const String& prefix, MetaType* returnType)
790 {
791     if (returnType->kind_ != TypeKind::Void) {
792         if ((returnType->kind_ == TypeKind::Sequenceable) || (returnType->kind_ == TypeKind::Interface)) {
793             sb.Append(prefix + TAB).AppendFormat("%s result = nullptr;\n",
794                 EmitType(returnType, ATTR_IN, true).string());
795         } else {
796             sb.Append(prefix + TAB).AppendFormat("%s result;\n", EmitType(returnType, ATTR_IN, true).string());
797         }
798     }
799     if (mm->parameterNumber_ == 0 && returnType->kind_ == TypeKind::Void) {
800         sb.Append(prefix + TAB).AppendFormat("ErrCode errCode = %s();\n", mm->name_);
801     } else {
802         sb.Append(prefix + TAB).AppendFormat("ErrCode errCode = %s(", mm->name_);
803         for (int i = 0; i < mm->parameterNumber_; i++) {
804             MetaParameter* mp = mm->parameters_[i];
805             if (mp == nullptr) {
806                 continue;
807             }
808             const std::string name = mp->name_;
809             MetaType* mGetType = metaComponent_->types_[mp->typeIndex_];
810             if (mGetType != nullptr && mGetType->kind_ == TypeKind::Sequenceable && !mp->isSequenceableForOut_) {
811                 const std::string parameterName = "*" + name;
812                 sb.Append(parameterName.c_str());
813             } else {
814                 sb.Append(name.c_str());
815             }
816 
817             if (i != mm->parameterNumber_ - 1 || returnType->kind_ != TypeKind::Void) {
818                 sb.Append(", ");
819             }
820         }
821         if (returnType->kind_ != TypeKind::Void) {
822             EmitReturnParameter("result", returnType, sb);
823         }
824         sb.AppendFormat(");\n", mm->name_);
825     }
826 }
827 
EmitInterfaceStubMethodImpl(MetaMethod * mm,StringBuilder & sb,const String & prefix)828 void CppCodeEmitter::EmitInterfaceStubMethodImpl(MetaMethod* mm, StringBuilder& sb, const String& prefix)
829 {
830     sb.Append(prefix).AppendFormat("case COMMAND_%s: {\n", ConstantName(mm->name_).string());
831     for (int i = 0; i < mm->parameterNumber_; i++) {
832         MetaParameter* mp = mm->parameters_[i];
833         if ((mp->attributes_ & ATTR_IN) != 0) {
834             MetaType* mt = metaComponent_->types_[mp->typeIndex_];
835             const std::string name = mp->name_;
836             EmitReadVariable("data.", name, mt, sb, prefix + TAB);
837         } else if ((mp->attributes_ & ATTR_OUT) != 0) {
838             EmitLocalVariable(mp, sb, prefix + TAB);
839         }
840     }
841     MetaType* returnType = metaComponent_->types_[mm->returnTypeIndex_];
842     if (returnType == nullptr) {
843         return;
844     }
845     EmitInterfaceStubMethodImplReturn(mm, sb, prefix, returnType);
846 
847     sb.Append(prefix + TAB).Append("if (!reply.WriteInt32(errCode)) {\n");
848     if (logOn_) {
849         sb.Append(prefix + TAB).Append(TAB).Append("HiLog::Error(LABEL, \"Write Int32 failed!\");\n");
850     }
851     sb.Append(prefix + TAB).Append(TAB).Append("return ERR_INVALID_VALUE;\n");
852     sb.Append(prefix + TAB).Append("}\n");
853     bool hasOutParameter = false;
854     for (int i = 0; i < mm->parameterNumber_; i++) {
855         MetaParameter* mp = mm->parameters_[i];
856         if ((mp->attributes_ & ATTR_OUT) != 0) {
857             hasOutParameter = true;
858         }
859     }
860     if (hasOutParameter || returnType->kind_ != TypeKind::Void) {
861         sb.Append(prefix + TAB).Append("if (SUCCEEDED(errCode)) {\n");
862         for (int i = 0; i < mm->parameterNumber_; i++) {
863             MetaParameter* mp = mm->parameters_[i];
864             if ((mp->attributes_ & ATTR_OUT) != 0) {
865                 EmitWriteMethodParameter(mp, "reply.", sb, prefix + TAB + TAB);
866             }
867         }
868         if (returnType->kind_ != TypeKind::Void) {
869             EmitWriteVariable("reply.", "result", returnType, sb, prefix + TAB + TAB);
870         }
871         sb.Append(prefix + TAB).Append("}\n");
872     }
873     sb.Append(prefix + TAB).Append("return ERR_NONE;\n");
874     sb.Append(prefix).Append("}\n");
875 }
876 
EmitInterfaceMethodCommands(StringBuilder & sb,const String & prefix)877 void CppCodeEmitter::EmitInterfaceMethodCommands(StringBuilder& sb, const String& prefix)
878 {
879     for (int i = 0; i < metaInterface_->methodNumber_; i++) {
880         MetaMethod* mm = metaInterface_->methods_[i];
881         sb.Append(prefix).AppendFormat("static constexpr int32_t COMMAND_%s = MIN_TRANSACTION_ID + %d;\n",
882             ConstantName(mm->name_).string(), i);
883     }
884 }
885 
EmitLicense(StringBuilder & sb)886 void CppCodeEmitter::EmitLicense(StringBuilder& sb)
887 {
888     sb.Append(metaInterface_->license_).Append("\n");
889 }
890 
EmitHeadMacro(StringBuilder & sb,const String & fullName)891 void CppCodeEmitter::EmitHeadMacro(StringBuilder& sb, const String& fullName)
892 {
893     String macroName = MacroName(fullName);
894     sb.Append("#ifndef ").Append(macroName).Append("\n");
895     sb.Append("#define ").Append(macroName).Append("\n");
896 }
897 
EmitTailMacro(StringBuilder & sb,const String & fullName)898 void CppCodeEmitter::EmitTailMacro(StringBuilder& sb, const String& fullName)
899 {
900     String macroName = MacroName(fullName);
901     sb.Append("#endif // ").Append(macroName).Append("\n\n");
902 }
903 
EmitBeginNamespace(StringBuilder & sb)904 void CppCodeEmitter::EmitBeginNamespace(StringBuilder& sb)
905 {
906     String nspace = GetNamespace(metaInterface_->namespace_);
907     int index = nspace.IndexOf('.');
908     while (index != -1) {
909         sb.AppendFormat("namespace %s {\n", nspace.Substring(0, index).string());
910         nspace = nspace.Substring(index + 1);
911         index = nspace.IndexOf('.');
912     }
913 }
914 
EmitEndNamespace(StringBuilder & sb)915 void CppCodeEmitter::EmitEndNamespace(StringBuilder& sb)
916 {
917     String nspace = GetNamespace(metaInterface_->namespace_);
918     nspace = nspace.Substring(0, nspace.GetLength() - 1);
919     while (!nspace.IsEmpty()) {
920         int index = nspace.LastIndexOf('.');
921         sb.AppendFormat("} // namespace %s\n", index != -1 ?
922             nspace.Substring(index + 1, nspace.GetLength()).string() : nspace.string());
923         nspace = nspace.Substring(0, index);
924     }
925 }
926 
EmitWriteVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix)927 void CppCodeEmitter::EmitWriteVariable(const String& parcelName, const std::string& name, MetaType* mt,
928     StringBuilder& sb, const String& prefix)
929 {
930     switch (mt->kind_) {
931         case TypeKind::Boolean:
932             sb.Append(prefix).AppendFormat("if (!%sWriteInt32(%s ? 1 : 0)) {\n", parcelName.string(), name.c_str());
933             if (logOn_) {
934                 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
935                     name.c_str());
936             }
937             sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
938             sb.Append(prefix).Append("}\n");
939             break;
940         case TypeKind::Char:
941         case TypeKind::Byte:
942         case TypeKind::Short:
943         case TypeKind::Integer:
944             sb.Append(prefix).AppendFormat("if (!%sWriteInt32(%s)) {\n", parcelName.string(), name.c_str());
945             if (logOn_) {
946                 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
947                     name.c_str());
948             }
949             sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
950             sb.Append(prefix).Append("}\n");
951             break;
952         case TypeKind::Long:
953             sb.Append(prefix).AppendFormat("if (!%sWriteInt64(%s)) {\n", parcelName.string(), name.c_str());
954             if (logOn_) {
955                 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
956                     name.c_str());
957             }
958             sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
959             sb.Append(prefix).Append("}\n");
960             break;
961         default:
962             EmitWriteVariableFloat(parcelName, name, mt, sb, prefix);
963             break;
964     }
965 }
966 
EmitWriteVariableFloat(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix)967 void CppCodeEmitter::EmitWriteVariableFloat(
968     const String& parcelName, const std::string& name, MetaType* mt, StringBuilder& sb, const String& prefix)
969 {
970     switch (mt->kind_) {
971         case TypeKind::Float:
972             sb.Append(prefix).AppendFormat("if (!%sWriteFloat(%s)) {\n", parcelName.string(), name.c_str());
973             if (logOn_) {
974                 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
975                     name.c_str());
976             }
977             sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
978             sb.Append(prefix).Append("}\n");
979             break;
980         case TypeKind::Double:
981             sb.Append(prefix).AppendFormat("if (!%sWriteDouble(%s)) {\n", parcelName.string(), name.c_str());
982             if (logOn_) {
983                 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
984                     name.c_str());
985             }
986             sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
987             sb.Append(prefix).Append("}\n");
988             break;
989         default:
990             EmitWriteVariableComplex(parcelName, name, mt, sb, prefix);
991             break;
992     }
993 }
994 
EmitWriteVariableComplex(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix)995 void CppCodeEmitter::EmitWriteVariableComplex(
996     const String& parcelName, const std::string& name, MetaType* mt, StringBuilder& sb, const String& prefix)
997 {
998     switch (mt->kind_) {
999         case TypeKind::Array:
1000         case TypeKind::List: {
1001             sb.Append(prefix).AppendFormat("if (%s.size() > static_cast<size_t>(VECTOR_MAX_SIZE)) {\n", name.c_str());
1002             if (logOn_) {
1003                 if (mt != nullptr && mt->kind_ == TypeKind::Array) {
1004                     sb.Append(prefix).Append(TAB).Append(
1005                         "HiLog::Error(LABEL, \"The vector/array size exceeds the security limit!\");\n");
1006                 } else {
1007                     sb.Append(prefix).Append(TAB).AppendFormat(
1008                         "HiLog::Error(LABEL, \"The list size exceeds the security limit!\");\n");
1009                 }
1010             }
1011             sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1012             sb.Append(prefix).Append("}\n");
1013             sb.Append(prefix).AppendFormat("%sWriteInt32(%s.size());\n", parcelName.string(), name.c_str());
1014             sb.Append(prefix).AppendFormat("for (auto it = %s.begin(); it != %s.end(); ++it) {\n",
1015                 name.c_str(), name.c_str());
1016             if (mt != nullptr) {
1017                 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1018                 EmitWriteVariable(parcelName, "(*it)", innerType, sb, prefix + TAB);
1019                 sb.Append(prefix).Append("}\n");
1020             }
1021             break;
1022         }
1023         case TypeKind::Map: {
1024             sb.Append(prefix).AppendFormat("if (%s.size() > static_cast<size_t>(MAP_MAX_SIZE)) {\n", name.c_str());
1025             if (logOn_) {
1026                 sb.Append(prefix).Append(TAB).AppendFormat(
1027                     "HiLog::Error(LABEL, \"The map size exceeds the security limit!\");\n");
1028             }
1029             sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1030             sb.Append(prefix).Append("}\n");
1031             sb.Append("\n");
1032             sb.Append(prefix).AppendFormat("%sWriteInt32(%s.size());\n", parcelName.string(), name.c_str());
1033             sb.Append(prefix).AppendFormat("for (auto it = %s.begin(); it != %s.end(); ++it) {\n",
1034                 name.c_str(), name.c_str());
1035             MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1036             MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
1037             EmitWriteVariable(parcelName, "(it->first)", keyType, sb, prefix + TAB);
1038             EmitWriteVariable(parcelName, "(it->second)", valueType, sb, prefix + TAB);
1039             sb.Append(prefix).Append("}\n");
1040             break;
1041         }
1042         default:
1043             EmitWriteVariableObject(parcelName, name, mt, sb, prefix);
1044             break;
1045     }
1046 }
1047 
EmitWriteVariableObject(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix)1048 void CppCodeEmitter::EmitWriteVariableObject(
1049     const String& parcelName, const std::string& name, MetaType* mt, StringBuilder& sb, const String& prefix)
1050 {
1051     switch (mt->kind_) {
1052         case TypeKind::String:
1053             sb.Append(prefix).AppendFormat("if (!%sWriteString16(Str8ToStr16(%s))) {\n", parcelName.string(),
1054                 name.c_str());
1055             if (logOn_) {
1056                 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
1057                     name.c_str());
1058             }
1059             sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1060             sb.Append(prefix).Append("}\n");
1061             break;
1062         case TypeKind::Sequenceable:
1063             sb.Append(prefix).AppendFormat("if (!%sWriteParcelable(&%s)) {\n", parcelName.string(), name.c_str());
1064             if (logOn_) {
1065                 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
1066                     name.c_str());
1067             }
1068             sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1069             sb.Append(prefix).Append("}\n");
1070             break;
1071         case TypeKind::Interface:
1072             sb.Append(prefix).AppendFormat("if (%s == nullptr) {\n", name.c_str());
1073             if (logOn_) {
1074                 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"%s is nullptr!\");\n", name.c_str());
1075             }
1076             sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1077             sb.Append(prefix).Append("}\n");
1078             sb.Append(prefix).AppendFormat(
1079                 "if (!%sWriteRemoteObject(%s->AsObject())) {\n", parcelName.string(), name.c_str());
1080             if (logOn_) {
1081                 sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Write [%s] failed!\");\n",
1082                     name.c_str());
1083             }
1084             sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1085             sb.Append(prefix).Append("}\n");
1086             break;
1087         default:
1088             break;
1089     }
1090 }
1091 
EmitReadVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix,bool emitType)1092 void CppCodeEmitter::EmitReadVariable(const String& parcelName, const std::string& name, MetaType* mt,
1093     StringBuilder& sb, const String& prefix, bool emitType)
1094 {
1095     switch (mt->kind_) {
1096         case TypeKind::Boolean:
1097             if (emitType) {
1098                 sb.Append(prefix).AppendFormat("%s %s = %sReadInt32() == 1 ? true : false;\n",
1099                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
1100             } else {
1101                 sb.Append(prefix).AppendFormat("%s = %sReadInt32() == 1 ? true : false;\n",
1102                     name.c_str(), parcelName.string());
1103             }
1104             break;
1105         case TypeKind::Char:
1106         case TypeKind::Byte:
1107         case TypeKind::Short:
1108             if (emitType) {
1109                 sb.Append(prefix).AppendFormat("%s %s = (%s)%sReadInt32();\n", EmitType(mt, ATTR_IN, true).string(),
1110                     name.c_str(), EmitType(mt, ATTR_IN, true).string(), parcelName.string());
1111             } else {
1112                 sb.Append(prefix).AppendFormat("%s = (%s)%sReadInt32();\n", name.c_str(),
1113                     EmitType(mt, ATTR_IN, true).string(), parcelName.string());
1114             }
1115             break;
1116         case TypeKind::Integer:
1117             if (emitType) {
1118                 sb.Append(prefix).AppendFormat("%s %s = %sReadInt32();\n",
1119                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
1120             } else {
1121                 sb.Append(prefix).AppendFormat("%s = %sReadInt32();\n", name.c_str(), parcelName.string());
1122             }
1123             break;
1124         case TypeKind::Long:
1125             if (emitType) {
1126                 sb.Append(prefix).AppendFormat("%s %s = %sReadInt64();\n",
1127                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
1128             } else {
1129                 sb.Append(prefix).AppendFormat("%s = %sReadInt64();\n", name.c_str(), parcelName.string());
1130             }
1131             break;
1132         default:
1133             EmitReadVariableFloat(parcelName, name, mt, sb, prefix, emitType);
1134             break;
1135     }
1136 }
1137 
EmitReadVariableFloat(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix,bool emitType)1138 void CppCodeEmitter::EmitReadVariableFloat(const String& parcelName, const std::string& name, MetaType* mt,
1139     StringBuilder& sb, const String& prefix, bool emitType)
1140 {
1141     switch (mt->kind_) {
1142         case TypeKind::Float:
1143             if (emitType) {
1144                 sb.Append(prefix).AppendFormat("%s %s = %sReadFloat();\n",
1145                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
1146             } else {
1147                 sb.Append(prefix).AppendFormat("%s = %sReadFloat();\n", name.c_str(), parcelName.string());
1148             }
1149             break;
1150         case TypeKind::Double:
1151             if (emitType) {
1152                 sb.Append(prefix).AppendFormat("%s %s = %sReadDouble();\n",
1153                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
1154             } else {
1155                 sb.Append(prefix).AppendFormat("%s = %sReadDouble();\n", name.c_str(), parcelName.string());
1156             }
1157             break;
1158         default:
1159             EmitReadVariableComplex(parcelName, name, mt, sb, prefix, emitType);
1160             break;
1161     }
1162 }
1163 
EmitReadVariableComplex(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix,bool emitType)1164 void CppCodeEmitter::EmitReadVariableComplex(const String& parcelName, const std::string& name, MetaType* mt,
1165     StringBuilder& sb, const String& prefix, bool emitType)
1166 {
1167     switch (mt->kind_) {
1168         case TypeKind::String:
1169             if (emitType) {
1170                 sb.Append(prefix).AppendFormat("%s %s = Str16ToStr8(%sReadString16());\n",
1171                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string());
1172             } else {
1173                 sb.Append(prefix).AppendFormat("%s = Str16ToStr8(%sReadString16());\n",
1174                     name.c_str(), parcelName.string());
1175             }
1176             break;
1177         case TypeKind::Map: {
1178             if (emitType) {
1179                 sb.Append(prefix).AppendFormat("%s %s;\n", EmitType(mt, ATTR_IN, true).string(), name.c_str());
1180             }
1181             sb.Append(prefix).AppendFormat("int32_t %sSize = %sReadInt32();\n", name.c_str(), parcelName.string());
1182             sb.Append(prefix).AppendFormat("for (int32_t i = 0; i < %sSize; ++i) {\n", name.c_str());
1183             MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1184             MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
1185             EmitReadVariable(parcelName, "key", keyType, sb, prefix + TAB);
1186             EmitReadVariable(parcelName, "value", valueType, sb, prefix + TAB);
1187             sb.Append(prefix + TAB).AppendFormat("%s[key] = value;\n", name.c_str());
1188             sb.Append(prefix).Append("}\n");
1189             break;
1190         }
1191         default:
1192             EmitReadVariableList(parcelName, name, mt, sb, prefix, emitType);
1193             break;
1194     }
1195 }
1196 
EmitReadVariableList(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix,bool emitType)1197 void CppCodeEmitter::EmitReadVariableList(const String& parcelName, const std::string& name, MetaType* mt,
1198     StringBuilder& sb, const String& prefix, bool emitType)
1199 {
1200     switch (mt->kind_) {
1201         case TypeKind::Array:
1202         case TypeKind::List: {
1203             if (emitType) {
1204                 sb.Append(prefix).AppendFormat("%s %s;\n", EmitType(mt, ATTR_IN, true).string(), name.c_str());
1205             }
1206             sb.Append(prefix).AppendFormat("int32_t %sSize = %sReadInt32();\n", name.c_str(), parcelName.string());
1207             sb.Append(prefix).AppendFormat("if (%sSize > static_cast<int32_t>(VECTOR_MAX_SIZE)) {\n", name.c_str());
1208             if (logOn_) {
1209                 sb.Append(prefix + TAB)
1210                     .Append("HiLog::Error(LABEL, \"The vector/array size exceeds the security limit!\");\n");
1211             }
1212             sb.Append(prefix + TAB).Append("return ERR_INVALID_DATA;\n");
1213             sb.Append(prefix).Append("}\n");
1214             circleCount++;
1215             std::stringstream circleCountStr;
1216             circleCountStr << circleCount;
1217             std::string iStr = "i" + circleCountStr.str();
1218             std::string valueStr = "value" + circleCountStr.str();
1219             sb.Append(prefix).AppendFormat("for (int32_t %s = 0; %s < %sSize; ++%s) {\n",
1220                 iStr.c_str(), iStr.c_str(), name.c_str(), iStr.c_str());
1221             MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1222             EmitReadVariable(parcelName, valueStr.c_str(), innerType, sb, prefix + TAB);
1223             if (innerType->kind_ == TypeKind::Sequenceable) {
1224                 sb.Append(prefix + TAB).AppendFormat("%s.push_back(*%s);\n", name.c_str(), valueStr.c_str());
1225             } else {
1226                 sb.Append(prefix + TAB).AppendFormat("%s.push_back(%s);\n", name.c_str(), valueStr.c_str());
1227             }
1228             sb.Append(prefix).Append("}\n");
1229             break;
1230         }
1231         default:
1232             EmitReadVariableObject(parcelName, name, mt, sb, prefix, emitType);
1233             break;
1234     }
1235 }
1236 
EmitReadVariableObject(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & sb,const String & prefix,bool emitType)1237 void CppCodeEmitter::EmitReadVariableObject(const String& parcelName, const std::string& name, MetaType* mt,
1238     StringBuilder& sb, const String& prefix, bool emitType)
1239 {
1240     switch (mt->kind_) {
1241         case TypeKind::Sequenceable: {
1242             MetaSequenceable* mp = metaComponent_->sequenceables_[mt->index_];
1243             if (mp == nullptr) {
1244                 break;
1245             }
1246             if (emitType) {
1247                 readSequenceable_ = true;
1248                 sb.Append(prefix).AppendFormat("std::unique_ptr<%s> %s(%sReadParcelable<%s>());\n\n",
1249                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), parcelName.string(), mp->name_);
1250                 sb.Append(prefix).AppendFormat("if (!%s) {\n", name.c_str());
1251                 if (logOn_) {
1252                     sb.Append(prefix).Append(TAB).AppendFormat(
1253                         "HiLog::Error(LABEL, \"Read [%s] failed!\");\n", mp->name_);
1254                 }
1255                 sb.Append(prefix).Append(TAB).Append("return ERR_INVALID_DATA;\n");
1256                 sb.Append(prefix).Append("}\n");
1257             } else {
1258                 sb.Append(prefix).AppendFormat("std::unique_ptr<%s> info(%sReadParcelable<%s>());\n",
1259                     mp->name_, parcelName.string(), mp->name_);
1260                 sb.Append(prefix).Append("if (info != nullptr) {\n");
1261                 sb.Append(prefix).Append(TAB).AppendFormat("%s = *info;\n", name.c_str());
1262                 sb.Append(prefix).Append("}\n\n");
1263             }
1264             break;
1265         }
1266         case TypeKind::Interface: {
1267             MetaInterface* mi = metaComponent_->interfaces_[mt->index_];
1268             if (emitType) {
1269                 sb.Append(prefix).AppendFormat("%s %s = iface_cast<%s>(%sReadRemoteObject());\n",
1270                     EmitType(mt, ATTR_IN, true).string(), name.c_str(), mi->name_, parcelName.string());
1271                 sb.Append(prefix).AppendFormat("if (%s == nullptr) {\n", name.c_str());
1272                 if (logOn_) {
1273                     sb.Append(prefix).Append(TAB).AppendFormat("HiLog::Error(LABEL, \"Read [%s] failed!\");\n",
1274                         name.c_str());
1275                 }
1276                 sb.Append(prefix).Append(TAB).AppendFormat("return ERR_INVALID_DATA;\n");
1277                 sb.Append(prefix).Append("}\n\n");
1278             } else {
1279                 sb.Append(prefix).AppendFormat("%s = iface_cast<%s>(%sReadRemoteObject());\n",
1280                     name.c_str(),  mi->name_, parcelName.string());
1281             }
1282             break;
1283         }
1284         default:
1285             break;
1286     }
1287 }
1288 
EmitLocalVariable(MetaParameter * mp,StringBuilder & sb,const String & prefix)1289 void CppCodeEmitter::EmitLocalVariable(MetaParameter* mp, StringBuilder& sb, const String& prefix)
1290 {
1291     MetaType* mt = metaComponent_->types_[mp->typeIndex_];
1292     const std::string name = mp->name_;
1293     if ((mt->kind_ == TypeKind::Sequenceable) || (mt->kind_ == TypeKind::Interface)) {
1294         createSequenceableForOut_ = true;
1295         mp->isSequenceableForOut_ = true;
1296         sb.Append(prefix).AppendFormat("%s %s;\n", EmitType(mt, ATTR_IN, true).string(), name.c_str());
1297     } else {
1298         sb.Append(prefix).AppendFormat("%s %s;\n", EmitType(mt, ATTR_IN, true).string(), name.c_str());
1299     }
1300 }
1301 
EmitReturnParameter(const String & name,MetaType * mt,StringBuilder & sb)1302 void CppCodeEmitter::EmitReturnParameter(const String& name, MetaType* mt, StringBuilder& sb)
1303 {
1304     switch (mt->kind_) {
1305         case TypeKind::Char:
1306         case TypeKind::Boolean:
1307         case TypeKind::Byte:
1308         case TypeKind::Short:
1309         case TypeKind::Integer:
1310         case TypeKind::Long:
1311         case TypeKind::Float:
1312         case TypeKind::Double:
1313         case TypeKind::String:
1314         case TypeKind::Sequenceable:
1315         case TypeKind::Interface:
1316         case TypeKind::List:
1317         case TypeKind::Map:
1318         case TypeKind::Array:
1319             sb.Append(name);
1320             break;
1321         default:
1322             break;
1323     }
1324 }
1325 
EmitType(MetaType * mt,unsigned int attributes,bool isInnerType)1326 String CppCodeEmitter::EmitType(MetaType* mt, unsigned int attributes, bool isInnerType)
1327 {
1328     switch (mt->kind_) {
1329         case TypeKind::Char:
1330             enteredVector_ = false;
1331             if (attributes & ATTR_IN) {
1332                 return "zchar";
1333             } else {
1334                 return "zchar&";
1335             }
1336         case TypeKind::Boolean:
1337             enteredVector_ = false;
1338             if (attributes & ATTR_IN) {
1339                 return "bool";
1340             } else {
1341                 return "bool&";
1342             }
1343         case TypeKind::Byte:
1344             enteredVector_ = false;
1345             if (attributes & ATTR_IN) {
1346                 return "int8_t";
1347             } else {
1348                 return "int8_t&";
1349             }
1350         case TypeKind::Short:
1351             enteredVector_ = false;
1352             if (attributes & ATTR_IN) {
1353                 return "short";
1354             } else {
1355                 return "short&";
1356             }
1357         case TypeKind::Integer:
1358             enteredVector_ = false;
1359             if (attributes & ATTR_IN) {
1360                 return "int32_t";
1361             } else {
1362                 return "int32_t&";
1363             }
1364         case TypeKind::Long:
1365             enteredVector_ = false;
1366             if (attributes & ATTR_IN) {
1367                 return "long";
1368             } else {
1369                 return "long&";
1370             }
1371         default:
1372             return EmitFloatType(mt, attributes, isInnerType);
1373     }
1374 }
1375 
1376 
EmitFloatType(MetaType * mt,unsigned int attributes,bool isInnerType)1377 String CppCodeEmitter::EmitFloatType(MetaType* mt, unsigned int attributes, bool isInnerType)
1378 {
1379     switch (mt->kind_) {
1380         case TypeKind::Float:
1381             enteredVector_ = false;
1382             if (attributes & ATTR_IN) {
1383                 return "float";
1384             } else {
1385                 return "float&";
1386             }
1387         case TypeKind::Double:
1388             enteredVector_ = false;
1389             if (attributes & ATTR_IN) {
1390                 return "double";
1391             } else {
1392                 return "double&";
1393             }
1394         case TypeKind::Void:
1395             enteredVector_ = false;
1396             return "void";
1397         default:
1398             return EmitComplexType(mt, attributes, isInnerType);
1399     }
1400 }
1401 
EmitComplexType(MetaType * mt,unsigned int attributes,bool isInnerType)1402 String CppCodeEmitter::EmitComplexType(MetaType* mt, unsigned int attributes, bool isInnerType)
1403 {
1404     switch (mt->kind_) {
1405         case TypeKind::String:
1406             enteredVector_ = false;
1407             if (attributes & ATTR_IN) {
1408                 if (!isInnerType) {
1409                     return "const std::string&";
1410                 } else {
1411                     return "std::string";
1412                 }
1413             } else {
1414                 return "std::string&";
1415             }
1416         case TypeKind::Map: {
1417             MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1418             MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
1419             if (attributes & ATTR_OUT) {
1420                 return String::Format("std::unordered_map<%s, %s>&",
1421                     EmitType(keyType, ATTR_IN, true).string(), EmitType(valueType, ATTR_IN, true).string());
1422             } else {
1423                 if (!isInnerType) {
1424                     return String::Format("const std::unordered_map<%s, %s>&",
1425                         EmitType(keyType, ATTR_IN, true).string(), EmitType(valueType, ATTR_IN, true).string());
1426                 } else {
1427                     return String::Format("std::unordered_map<%s, %s>",
1428                         EmitType(keyType, ATTR_IN, true).string(), EmitType(valueType, ATTR_IN, true).string());
1429                 }
1430             }
1431             break;
1432         }
1433         default:
1434             return EmitListType(mt, attributes, isInnerType);
1435     }
1436 }
1437 
EmitListType(MetaType * mt,unsigned int attributes,bool isInnerType)1438 String CppCodeEmitter::EmitListType(MetaType* mt, unsigned int attributes, bool isInnerType)
1439 {
1440     switch (mt->kind_) {
1441         case TypeKind::Array:
1442         case TypeKind::List: {
1443             enteredVector_ = true;
1444             MetaType* elementType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1445             if (attributes & ATTR_OUT) {
1446                 return String::Format("std::vector<%s>&",
1447                                       EmitType(elementType, ATTR_IN, true).string());
1448             } else {
1449                 if (!isInnerType) {
1450                     return String::Format("const std::vector<%s>&",
1451                                           EmitType(elementType, ATTR_IN, true).string());
1452                 } else {
1453                     return String::Format("std::vector<%s>",
1454                                           EmitType(elementType, ATTR_IN, true).string());
1455                 }
1456             }
1457         }
1458         default:
1459             return EmitObjectType(mt, attributes, isInnerType);
1460     }
1461 }
1462 
EmitObjectType(MetaType * mt,unsigned int attributes,bool isInnerType)1463 String CppCodeEmitter::EmitObjectType(MetaType* mt, unsigned int attributes, bool isInnerType)
1464 {
1465     switch (mt->kind_) {
1466         case TypeKind::Sequenceable: {
1467             MetaSequenceable* mp = metaComponent_->sequenceables_[mt->index_];
1468             if (mp == nullptr) {
1469                 return "unknown type";
1470             }
1471             if (enteredVector_) {
1472                 enteredVector_ = false;
1473                 return String::Format("%s", mp->name_);
1474             }
1475             if (readSequenceable_) {
1476                 readSequenceable_ = false;
1477                 return String::Format("%s", mp->name_);
1478             }
1479             if (createSequenceableForOut_) {
1480                 createSequenceableForOut_ = false;
1481                 return String::Format("%s", mp->name_);
1482             }
1483             if ((attributes & ATTR_MASK) == (ATTR_IN | ATTR_OUT)) {
1484                 return String::Format("%s*", mp->name_);
1485             } else if (attributes & ATTR_IN) {
1486                 return String::Format("const %s&", mp->name_);
1487             } else {
1488                 return String::Format("%s&", mp->name_);
1489             }
1490         }
1491         case TypeKind::Interface: {
1492             MetaInterface* mi = metaComponent_->interfaces_[mt->index_];
1493             if (mi == nullptr) {
1494                 return "unknown type";
1495             }
1496             if (attributes & ATTR_IN) {
1497                 if (!isInnerType) {
1498                     return String::Format("const sptr<%s>&", mi->name_);
1499                 } else {
1500                     return String::Format("sptr<%s>", mi->name_);
1501                 }
1502             } else {
1503                 return String::Format("sptr<%s>&", mi->name_);
1504             }
1505         }
1506         default:
1507             return "unknown type";
1508     }
1509 }
1510 
CppFullName(const String & name)1511 String CppCodeEmitter::CppFullName(const String& name)
1512 {
1513     if (name.IsEmpty()) {
1514         return name;
1515     }
1516 
1517     return name.Replace(".", "::");
1518 }
1519 
FileName(const String & name)1520 String CppCodeEmitter::FileName(const String& name)
1521 {
1522     if (name.IsEmpty()) {
1523         return name;
1524     }
1525 
1526     StringBuilder sb;
1527 
1528     for (int i = 0; i < name.GetLength(); i++) {
1529         char c = name[i];
1530         if (isupper(c) != 0) {
1531             // 2->Index of the last char array.
1532             if (i > 1 && name[i - 1] != '.' && name[i - 2] != '.') {
1533                 sb.Append('_');
1534             }
1535             sb.Append(tolower(c));
1536         } else {
1537             sb.Append(c);
1538         }
1539     }
1540 
1541     return sb.ToString().Replace('.', '/');
1542 }
1543 
MacroName(const String & name)1544 String CppCodeEmitter::MacroName(const String& name)
1545 {
1546     if (name.IsEmpty()) {
1547         return name;
1548     }
1549 
1550     String macro = name.Replace('.', '_').ToUpperCase() + "_H";
1551     return macro;
1552 }
1553 
ConstantName(const String & name)1554 String CppCodeEmitter::ConstantName(const String& name)
1555 {
1556     if (name.IsEmpty()) {
1557         return name;
1558     }
1559 
1560     StringBuilder sb;
1561 
1562     for (int i = 0; i < name.GetLength(); i++) {
1563         char c = name[i];
1564         if (isupper(c) != 0) {
1565             if (i > 1) {
1566                 sb.Append('_');
1567             }
1568             sb.Append(c);
1569         } else {
1570             sb.Append(toupper(c));
1571         }
1572     }
1573 
1574     return sb.ToString();
1575 }
1576 
UnderlineAdded(const String & originName)1577 const std::string CppCodeEmitter::UnderlineAdded(const String& originName)
1578 {
1579     std::string underline("_");
1580     return underline + std::string(originName.string());
1581 }
1582 } // namespace Idl
1583 } // namespace OHOS