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