1 /*
2 * Copyright (c) 2022 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/ts_code_emitter.h"
17
18 #include <cctype>
19 #include <cstdio>
20 #include <algorithm>
21
22 #include "securec.h"
23 #include "util/file.h"
24 #include "util/logger.h"
25
26 namespace OHOS {
27 namespace Idl {
28 namespace {
29 const std::string PROXY = "proxy";
30 const std::string THIS_PROXY = "this.proxy";
31 static const char* TAG = "TsCodeEmitter";
32 const std::string UNKNOWN_TYPE = "unknown type";
33 const String NEWLINE = "\n";
34 const String RETURN_VALUE = "returnValue";
35 const std::string ERR_CODE_TYPE = "errCode: number";
36 const String ERR_CODE = "errCode";
37 }
38
EmitInterface()39 void TsCodeEmitter::EmitInterface()
40 {
41 if (!CheckInterfaceType()) {
42 return;
43 }
44 String filePath = String::Format("%s/%s.ts", directory_.string(), FileName(interfaceName_).string());
45 File file(filePath, File::WRITE);
46
47 StringBuilder stringBuilder;
48
49 EmitLicense(stringBuilder);
50 stringBuilder.Append(NEWLINE);
51 EmitInterfaceSelfDefinedTypeImports(stringBuilder);
52 stringBuilder.Append(NEWLINE);
53 EmitInterfaceDefinition(stringBuilder);
54 stringBuilder.Append(NEWLINE);
55
56 String data = stringBuilder.ToString();
57 file.WriteData(data.string(), data.GetLength());
58 file.Flush();
59 file.Close();
60 }
61
EmitInterfaceImports(StringBuilder & stringBuilder)62 void TsCodeEmitter::EmitInterfaceImports(StringBuilder& stringBuilder)
63 {
64 for (const auto &item : methods_) {
65 if (item.callbackName_.size() > 0) {
66 stringBuilder.AppendFormat("import {%s} from \"./%s\";\n",
67 item.callbackName_.c_str(), FileName(interfaceName_).string());
68 }
69 }
70 stringBuilder.AppendFormat("import %s from \"./%s\";\n", metaInterface_->name_, FileName(interfaceName_).string());
71 stringBuilder.Append("import rpc from \"@ohos.rpc\";\n");
72 EmitInterfaceSelfDefinedTypeImports(stringBuilder);
73
74 for (int index = 0; index < metaComponent_->interfaceNumber_; index++) {
75 MetaInterface* mi = metaComponent_->interfaces_[index];
76 if (!interfaceName_.Equals(mi->name_)) {
77 String dependInterface = mi->name_;
78 String dependStubName = dependInterface.StartsWith("I") ?
79 dependInterface.Substring(1) + "Stub" : dependInterface + "Stub";
80 stringBuilder.AppendFormat("import %s from \"./%s\";\n", dependStubName.string(),
81 FileName(dependStubName).string());
82 }
83 }
84 }
85
EmitInterfaceSelfDefinedTypeImports(StringBuilder & stringBuilder)86 void TsCodeEmitter::EmitInterfaceSelfDefinedTypeImports(StringBuilder& stringBuilder)
87 {
88 for (int index = 0; index < metaComponent_->sequenceableNumber_; index++) {
89 MetaSequenceable* mp = metaComponent_->sequenceables_[index];
90 stringBuilder.AppendFormat("import %s from \"./%s\";\n", mp->name_, FileName(mp->name_).string());
91 }
92
93 for (int index = 0; index < metaComponent_->interfaceNumber_; index++) {
94 MetaInterface* mi = metaComponent_->interfaces_[index];
95 if (mi->external_) {
96 stringBuilder.AppendFormat("import %s from \"./%s\";\n", mi->name_, FileName(mi->name_).string());
97 }
98 }
99 }
100
EmitInterfaceDefinition(StringBuilder & stringBuilder)101 void TsCodeEmitter::EmitInterfaceDefinition(StringBuilder& stringBuilder)
102 {
103 stringBuilder.AppendFormat("export default interface %s {\n", metaInterface_->name_);
104 EmitInterfaceMethods(stringBuilder, TAB);
105 stringBuilder.Append("}\n");
106
107 for (const auto &item : methods_) {
108 if (item.callbackName_.size() > 0) {
109 stringBuilder.AppendFormat("%s\n", item.exportFunction_.c_str());
110 }
111 }
112 }
113
EmitInterfaceMethods(StringBuilder & stringBuilder,const String & prefix)114 void TsCodeEmitter::EmitInterfaceMethods(StringBuilder& stringBuilder, const String& prefix)
115 {
116 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
117 MetaMethod* metaMethod = metaInterface_->methods_[index];
118 EmitInterfaceMethod(metaMethod, stringBuilder, prefix);
119 }
120 }
121
EmitInterfaceMethod(MetaMethod * metaMethod,StringBuilder & stringBuilder,const String & prefix)122 void TsCodeEmitter::EmitInterfaceMethod(MetaMethod* metaMethod, StringBuilder& stringBuilder, const String& prefix)
123 {
124 MetaType* returnType = metaComponent_->types_[metaMethod->returnTypeIndex_];
125 Method method;
126 method.properties_ = metaMethod->properties_;
127 StringBuilder callbackName;
128 callbackName.AppendFormat("%sCallback", MethodName(metaMethod->name_).string());
129 method.callbackName_ = callbackName.ToString();
130 method.exportFunction_ = "export type " + callbackName.ToString() + " = (" + ERR_CODE_TYPE.c_str();
131
132 bool haveOutPara = false;
133 StringBuilder methodStr;
134 if (returnType->kind_ != TypeKind::Void) {
135 method.retParameter_.name_ = RETURN_VALUE.string();
136 method.retParameter_.type_ = EmitType(returnType).string();
137 }
138 methodStr.Append(prefix).AppendFormat("%s(", MethodName(metaMethod->name_).string());
139 method.name_ = MethodName(metaMethod->name_).string();
140
141 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
142 MetaParameter* mp = metaMethod->parameters_[index];
143 MetaType* paraType = metaComponent_->types_[mp->typeIndex_];
144 Parameter para;
145 para.attr_ = mp->attributes_;
146 para.name_ = mp->name_;
147 para.type_ = EmitType(paraType).string();
148 if ((mp->attributes_ & ATTR_OUT) != 0) {
149 haveOutPara = true;
150 }
151 method.parameters_.emplace_back(para);
152 }
153
154 bool isLastParaTypeIn = false;
155 for (size_t index = 0; index < method.parameters_.size(); index++) {
156 if ((method.parameters_[index].attr_ & ATTR_IN) != 0) {
157 EmitMethodInParameter(methodStr, method.parameters_[index].name_, method.parameters_[index].type_,
158 prefix + TAB);
159 if (index != method.parameters_.size() - 1) {
160 methodStr.Append(", ");
161 } else {
162 isLastParaTypeIn = true;
163 }
164 }
165 }
166 std::sort(method.parameters_.begin(), method.parameters_.end());
167 if (method.callbackName_.size() > 0) {
168 if (!isLastParaTypeIn) {
169 methodStr.AppendFormat("callback: %s", method.callbackName_.c_str());
170 } else {
171 methodStr.AppendFormat(", callback: %s", method.callbackName_.c_str());
172 }
173 if (method.retParameter_.name_.size() > 0) {
174 if (!haveOutPara) {
175 method.exportFunction_ +=
176 (", " + method.retParameter_.name_ + ": " + method.retParameter_.type_ + ") => void;");
177 } else {
178 method.exportFunction_ +=
179 (", " + method.retParameter_.name_ + ": " + method.retParameter_.type_ + ", ");
180 }
181 } else {
182 if (!haveOutPara) {
183 method.exportFunction_ += ") => void;";
184 } else {
185 method.exportFunction_ += ", ";
186 }
187 }
188 for (size_t index = 0; index < method.parameters_.size(); index++) {
189 bool isLast = (index == method.parameters_.size() - 1) ? true : false;
190 if ((method.parameters_[index].attr_ & ATTR_OUT) != 0) {
191 EmitInterfaceMethodExportCallback(method, method.parameters_[index], isLast);
192 }
193 }
194 }
195 methodStr.Append("): void;\n");
196 stringBuilder.Append(methodStr.ToString());
197 methods_.emplace_back(method);
198 }
199
EmitInterfaceMethodParameter(MetaParameter * mp,StringBuilder & stringBuilder,const String & prefix)200 void TsCodeEmitter::EmitInterfaceMethodParameter(MetaParameter* mp, StringBuilder& stringBuilder, const String& prefix)
201 {
202 MetaType* paraType = metaComponent_->types_[mp->typeIndex_];
203 stringBuilder.AppendFormat("%s: %s", mp->name_, EmitType(paraType).string());
204 }
205
EmitMethodInParameter(StringBuilder & stringBuilder,const std::string & name,const std::string & type,const String & prefix)206 void TsCodeEmitter::EmitMethodInParameter(StringBuilder& stringBuilder, const std::string& name,
207 const std::string& type, const String& prefix)
208 {
209 stringBuilder.AppendFormat("%s: %s", name.c_str(), type.c_str());
210 }
211
EmitInterfaceMethodExportCallback(Method & m,const Parameter & para,bool isLast)212 void TsCodeEmitter::EmitInterfaceMethodExportCallback(Method& m, const Parameter& para, bool isLast)
213 {
214 StringBuilder exportCallback;
215 exportCallback.Append(m.exportFunction_.c_str());
216 if (isLast) {
217 exportCallback.AppendFormat("%s: %s) => void;", para.name_.c_str(), para.type_.c_str());
218 } else {
219 exportCallback.AppendFormat("%s: %s, ", para.name_.c_str(), para.type_.c_str());
220 }
221 m.exportFunction_ = exportCallback.ToString();
222 }
223
EmitInterfaceProxy()224 void TsCodeEmitter::EmitInterfaceProxy()
225 {
226 if (!CheckInterfaceType()) {
227 return;
228 }
229 String filePath = String::Format("%s/%s.ts", directory_.string(), FileName(proxyName_).string());
230 File file(filePath, File::WRITE);
231
232 StringBuilder stringBuilder;
233
234 EmitLicense(stringBuilder);
235 stringBuilder.Append(NEWLINE);
236 EmitInterfaceImports(stringBuilder);
237 stringBuilder.Append(NEWLINE);
238 EmitInterfaceProxyImpl(stringBuilder);
239 stringBuilder.Append(NEWLINE);
240
241 String data = stringBuilder.ToString();
242 file.WriteData(data.string(), data.GetLength());
243 file.Flush();
244 file.Close();
245 }
246
EmitInterfaceProxyImpl(StringBuilder & stringBuilder)247 void TsCodeEmitter::EmitInterfaceProxyImpl(StringBuilder& stringBuilder)
248 {
249 stringBuilder.AppendFormat("export default class %s implements %s {\n", proxyName_.string(),
250 interfaceName_.string());
251 EmitInterfaceProxyConstructor(stringBuilder, TAB);
252 stringBuilder.Append(NEWLINE);
253 EmitInterfaceProxyMethodImpls(stringBuilder, TAB);
254 stringBuilder.Append(NEWLINE);
255 EmitInterfaceMethodCommands(stringBuilder);
256 stringBuilder.Append(TAB).AppendFormat("private %s", PROXY.c_str());
257 stringBuilder.Append(NEWLINE);
258 stringBuilder.Append("}\n");
259 }
260
EmitInterfaceProxyConstructor(StringBuilder & stringBuilder,const String & prefix)261 void TsCodeEmitter::EmitInterfaceProxyConstructor(StringBuilder& stringBuilder, const String& prefix)
262 {
263 stringBuilder.Append(prefix).AppendFormat("constructor(%s) {\n", PROXY.c_str());
264 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s = %s;\n", THIS_PROXY.c_str(), PROXY.c_str());
265 stringBuilder.Append(prefix).Append("}\n");
266 }
267
EmitInterfaceProxyMethodImpls(StringBuilder & stringBuilder,const String & prefix)268 void TsCodeEmitter::EmitInterfaceProxyMethodImpls(StringBuilder& stringBuilder, const String& prefix)
269 {
270 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
271 MetaMethod* metaMethod = metaInterface_->methods_[index];
272 EmitInterfaceProxyMethodImpl(metaMethod, index, stringBuilder, prefix);
273 if (index != metaInterface_->methodNumber_ - 1) {
274 stringBuilder.Append(NEWLINE);
275 }
276 }
277 }
278
EmitInterfaceProxyMethodImpl(MetaMethod * metaMethod,int methodIndex,StringBuilder & stringBuilder,const String & prefix)279 void TsCodeEmitter::EmitInterfaceProxyMethodImpl(MetaMethod* metaMethod, int methodIndex, StringBuilder& stringBuilder,
280 const String& prefix)
281 {
282 stringBuilder.Append(prefix).AppendFormat("%s(", MethodName(metaMethod->name_).string());
283 bool isLastParaTypeIn = false;
284 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
285 MetaParameter* mp = metaMethod->parameters_[index];
286 if ((mp->attributes_ & ATTR_IN) != 0) {
287 EmitInterfaceMethodParameter(mp, stringBuilder, prefix + TAB);
288 if (index != metaMethod->parameterNumber_ - 1) {
289 stringBuilder.Append(", ");
290 } else {
291 isLastParaTypeIn = true;
292 }
293 }
294 }
295 if (methods_[methodIndex].callbackName_.size() > 0) {
296 if (!isLastParaTypeIn) {
297 stringBuilder.AppendFormat("callback: %s", methods_[methodIndex].callbackName_.c_str());
298 } else {
299 stringBuilder.AppendFormat(", callback: %s", methods_[methodIndex].callbackName_.c_str());
300 }
301 }
302 stringBuilder.Append("): void\n");
303 EmitInterfaceProxyMethodBody(metaMethod, methodIndex, stringBuilder, prefix);
304 }
305
EmitInterfaceProxyMethodBody(MetaMethod * metaMethod,int methodIndex,StringBuilder & stringBuilder,const String & prefix)306 void TsCodeEmitter::EmitInterfaceProxyMethodBody(MetaMethod* metaMethod, int methodIndex, StringBuilder& stringBuilder,
307 const String& prefix)
308 {
309 bool haveOutPara = false;
310 stringBuilder.Append(prefix).Append("{\n");
311 stringBuilder.Append(prefix).Append(TAB).AppendFormat("let _option = new rpc.MessageOption();\n");
312 if ((metaMethod->properties_ & METHOD_PROPERTY_ONEWAY) || (metaInterface_->properties_ & METHOD_PROPERTY_ONEWAY)) {
313 stringBuilder.Append(prefix).Append(TAB).AppendFormat("_option.setFlags(_option.TF_ASYNC);\n");
314 }
315 stringBuilder.Append(prefix).Append(TAB).Append("let _data = new rpc.MessageParcel();\n");
316 stringBuilder.Append(prefix).Append(TAB).Append("let _reply = new rpc.MessageParcel();\n");
317
318 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
319 MetaParameter* mp = metaMethod->parameters_[index];
320 if ((mp->attributes_ & ATTR_IN) != 0) {
321 EmitWriteMethodParameter(mp, "_data", stringBuilder, prefix + TAB);
322 }
323 if ((mp->attributes_ & ATTR_OUT) != 0) {
324 haveOutPara = true;
325 }
326 }
327 stringBuilder.Append(prefix).Append(TAB).AppendFormat(
328 "%s.sendMessageRequest(%s.COMMAND_%s, _data, _reply, _option).then(function(result) {\n", THIS_PROXY.c_str(),
329 proxyName_.string(), ConstantName(metaMethod->name_).string());
330 stringBuilder.Append(prefix).Append(TAB).Append(TAB).AppendFormat("if (result.errCode === 0) {\n");
331 MetaType* returnType = metaComponent_->types_[metaMethod->returnTypeIndex_];
332 // emit errCode
333 MetaType errCode;
334 errCode.kind_ = TypeKind::Integer;
335 EmitReadOutVariable("result.reply", UnderlineAdded(ERR_CODE).c_str(), &errCode, stringBuilder,
336 prefix + TAB + TAB + TAB);
337
338 if (returnType->kind_ != TypeKind::Void || haveOutPara) {
339 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).AppendFormat(
340 "if (%s != 0) {\n", UnderlineAdded(ERR_CODE).c_str());
341 for (size_t index = 0; index < methods_[methodIndex].parameters_.size(); index++) {
342 if ((methods_[methodIndex].parameters_[index].attr_ & ATTR_OUT) != 0) {
343 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(TAB).AppendFormat(
344 "let %s = undefined;\n", UnderlineAdded(
345 methods_[methodIndex].parameters_[index].name_.c_str()).c_str());
346 }
347 }
348 if (returnType->kind_ != TypeKind::Void) {
349 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(TAB).AppendFormat(
350 "let %s = undefined;\n", UnderlineAdded(RETURN_VALUE).c_str());
351 }
352 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(TAB).AppendFormat("callback(");
353 stringBuilder.AppendFormat("%s", UnderlineAdded(ERR_CODE).c_str());
354 if (methods_[methodIndex].retParameter_.name_.size() > 0) {
355 if (haveOutPara) {
356 stringBuilder.AppendFormat(", %s, ", UnderlineAdded(RETURN_VALUE).c_str());
357 } else {
358 stringBuilder.AppendFormat(", %s", UnderlineAdded(RETURN_VALUE).c_str());
359 }
360 } else {
361 if (haveOutPara) {
362 stringBuilder.Append(",");
363 }
364 }
365 for (size_t index = 0; index < methods_[methodIndex].parameters_.size(); index++) {
366 if ((methods_[methodIndex].parameters_[index].attr_ & ATTR_OUT) != 0) {
367 stringBuilder.AppendFormat("%s",
368 UnderlineAdded(methods_[methodIndex].parameters_[index].name_.c_str()).c_str());
369 if (index != methods_[methodIndex].parameters_.size() - 1) {
370 stringBuilder.Append(", ");
371 }
372 }
373 }
374 stringBuilder.Append(");\n");
375 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(TAB).Append("return;\n");
376 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append("}\n");
377 }
378 // emit return
379 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
380 MetaParameter* mp = metaMethod->parameters_[index];
381 if ((mp->attributes_ & ATTR_OUT) != 0) {
382 EmitReadMethodParameter(mp, "result.reply", stringBuilder, prefix + TAB + TAB + TAB);
383 }
384 }
385 if (returnType->kind_ != TypeKind::Void) {
386 String parcelName = "result.reply";
387 EmitReadOutVariable(parcelName, UnderlineAdded(RETURN_VALUE), returnType, stringBuilder,
388 prefix + TAB + TAB + TAB);
389 }
390 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).AppendFormat("callback(");
391 stringBuilder.AppendFormat("%s", UnderlineAdded(ERR_CODE).c_str());
392 if (methods_[methodIndex].retParameter_.name_.size() > 0) {
393 if (haveOutPara) {
394 stringBuilder.AppendFormat(", %s, ", UnderlineAdded(RETURN_VALUE).c_str());
395 } else {
396 stringBuilder.AppendFormat(", %s", UnderlineAdded(RETURN_VALUE).c_str());
397 }
398 } else {
399 if (haveOutPara) {
400 stringBuilder.Append(",");
401 }
402 }
403 for (size_t index = 0; index < methods_[methodIndex].parameters_.size(); index++) {
404 if ((methods_[methodIndex].parameters_[index].attr_ & ATTR_OUT) != 0) {
405 stringBuilder.AppendFormat("%s",
406 UnderlineAdded(methods_[methodIndex].parameters_[index].name_.c_str()).c_str());
407 if (index != methods_[methodIndex].parameters_.size() - 1) {
408 stringBuilder.Append(", ");
409 }
410 }
411 }
412 stringBuilder.Append(");\n");
413 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("} else {\n");
414 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(
415 "console.log(\"sendMessageRequest failed, errCode: \" + result.errCode);\n");
416 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("}\n");
417 stringBuilder.Append(prefix).Append(TAB).Append("})\n");
418 stringBuilder.Append(prefix).Append("}\n");
419 }
420
EmitWriteMethodParameter(MetaParameter * mp,const String & parcelName,StringBuilder & stringBuilder,const String & prefix)421 void TsCodeEmitter::EmitWriteMethodParameter(MetaParameter* mp, const String& parcelName, StringBuilder& stringBuilder,
422 const String& prefix)
423 {
424 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
425 std::string name = mp->name_;
426 EmitWriteVariable(parcelName, name, mt, stringBuilder, prefix);
427 }
428
EmitReadMethodParameter(MetaParameter * mp,const String & parcelName,StringBuilder & stringBuilder,const String & prefix)429 void TsCodeEmitter::EmitReadMethodParameter(MetaParameter* mp, const String& parcelName, StringBuilder& stringBuilder,
430 const String& prefix)
431 {
432 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
433 std::string name = UnderlineAdded(mp->name_);
434 EmitReadOutVariable(parcelName, name, mt, stringBuilder, prefix);
435 }
436
EmitInterfaceStub()437 void TsCodeEmitter::EmitInterfaceStub()
438 {
439 if (!CheckInterfaceType()) {
440 return;
441 }
442 String filePath = String::Format("%s/%s.ts", directory_.string(), FileName(stubName_).string());
443 File file(filePath, File::WRITE);
444
445 StringBuilder stringBuilder;
446 EmitLicense(stringBuilder);
447 stringBuilder.Append(NEWLINE);
448 EmitInterfaceImports(stringBuilder);
449 stringBuilder.Append(NEWLINE);
450 EmitInterfaceStubImpl(stringBuilder);
451 stringBuilder.Append(NEWLINE);
452
453 String data = stringBuilder.ToString();
454 file.WriteData(data.string(), data.GetLength());
455 file.Flush();
456 file.Close();
457 }
458
EmitInterfaceStubImpl(StringBuilder & stringBuilder)459 void TsCodeEmitter::EmitInterfaceStubImpl(StringBuilder& stringBuilder)
460 {
461 stringBuilder.AppendFormat("export default class %s extends rpc.RemoteObject implements %s {\n",
462 stubName_.string(), interfaceName_.string());
463 EmitInterfaceStubMethodImpls(stringBuilder, TAB);
464 stringBuilder.Append(NEWLINE);
465 EmitInterfaceMethodCommands(stringBuilder);
466 stringBuilder.Append("}\n");
467 }
468
EmitInterfaceStubConstructor(StringBuilder & stringBuilder,const String & prefix)469 void TsCodeEmitter::EmitInterfaceStubConstructor(StringBuilder& stringBuilder, const String& prefix)
470 {
471 stringBuilder.Append(prefix).Append("constructor(des: string) {\n");
472 stringBuilder.Append(prefix).Append(TAB).Append("super(des);\n");
473 stringBuilder.Append(prefix).Append("}\n");
474 }
475
EmitInterfaceStubMethodImpls(StringBuilder & stringBuilder,const String & prefix)476 void TsCodeEmitter::EmitInterfaceStubMethodImpls(StringBuilder& stringBuilder, const String& prefix)
477 {
478 EmitInterfaceStubConstructor(stringBuilder, prefix);
479 stringBuilder.Append(prefix).Append(NEWLINE);
480 stringBuilder.Append(prefix).AppendFormat(
481 "async onRemoteMessageRequest(code: number, data, reply, option): Promise<boolean> {\n");
482 stringBuilder.Append(prefix).Append(TAB).Append(
483 "console.log(\"onRemoteMessageRequest called, code = \" + code);\n");
484 stringBuilder.Append(prefix).Append(TAB).Append("switch(code) {\n");
485 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
486 MetaMethod* metaMethod = metaInterface_->methods_[index];
487 EmitInterfaceStubMethodImpl(metaMethod, index, stringBuilder, prefix + TAB + TAB);
488 }
489 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("default: {\n");
490 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(
491 "console.log(\"invalid request code\" + code);\n");
492 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append("break;\n");
493 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("}\n");
494 stringBuilder.Append(prefix).Append(TAB).Append("}\n");
495 stringBuilder.Append(prefix).Append(TAB).Append("return false;\n");
496 stringBuilder.Append(prefix).Append("}\n");
497 stringBuilder.Append(prefix).Append(NEWLINE);
498
499 // emit empty method
500 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
501 bool isLastParaTypeIn = false;
502 MetaMethod* metaMethod = metaInterface_->methods_[index];
503 stringBuilder.Append(prefix).AppendFormat("%s(", MethodName(metaMethod->name_).string());
504 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
505 MetaParameter* mp = metaMethod->parameters_[index];
506 if ((mp->attributes_ & ATTR_IN) != 0) {
507 EmitInterfaceMethodParameter(mp, stringBuilder, prefix + TAB);
508 if (index != metaMethod->parameterNumber_ - 1) {
509 stringBuilder.Append(", ");
510 } else {
511 isLastParaTypeIn = true;
512 }
513 }
514 }
515 if (!isLastParaTypeIn) {
516 stringBuilder.AppendFormat("callback: %s", methods_[index].callbackName_.c_str());
517 } else {
518 stringBuilder.AppendFormat(", callback: %s", methods_[index].callbackName_.c_str());
519 }
520 stringBuilder.Append("): void{}\n");
521 }
522 }
523
EmitInterfaceStubMethodImpl(MetaMethod * metaMethod,int methodIndex,StringBuilder & stringBuilder,const String & prefix)524 void TsCodeEmitter::EmitInterfaceStubMethodImpl(MetaMethod* metaMethod, int methodIndex, StringBuilder& stringBuilder,
525 const String& prefix)
526 {
527 bool haveOutPara = false;
528 stringBuilder.Append(prefix).AppendFormat("case %s.COMMAND_%s: {\n", stubName_.string(),
529 ConstantName(metaMethod->name_).string());
530 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
531 MetaParameter* mp = metaMethod->parameters_[index];
532 if ((mp->attributes_ & ATTR_IN) != 0) {
533 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
534 EmitReadVariable("data", UnderlineAdded(mp->name_), mt, ATTR_IN, stringBuilder, prefix + TAB);
535 }
536 if ((mp->attributes_ & ATTR_OUT) != 0) {
537 haveOutPara = true;
538 }
539 }
540 stringBuilder.Append(prefix).Append(TAB).AppendFormat("this.%s(", MethodName(metaMethod->name_).string());
541 bool isLastParaTypeIn = false;
542 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
543 MetaParameter* mp = metaMethod->parameters_[index];
544 if ((mp->attributes_ & ATTR_IN) != 0) {
545 stringBuilder.Append(UnderlineAdded(mp->name_).c_str());
546 if (index != metaMethod->parameterNumber_ - 1) {
547 stringBuilder.Append(", ");
548 } else {
549 isLastParaTypeIn = true;
550 }
551 }
552 }
553 if (!isLastParaTypeIn) {
554 stringBuilder.Append("(");
555 } else {
556 stringBuilder.Append(", (");
557 }
558 stringBuilder.Append(ERR_CODE);
559 if (methods_[methodIndex].retParameter_.name_.size() > 0) {
560 if (!haveOutPara) {
561 stringBuilder.AppendFormat(", %s", RETURN_VALUE.string());
562 } else {
563 stringBuilder.AppendFormat(", %s", RETURN_VALUE.string()).Append(", ");
564 }
565 } else {
566 if (haveOutPara) {
567 stringBuilder.Append(", ");
568 }
569 }
570 for (size_t index = 0; index < methods_[methodIndex].parameters_.size(); index++) {
571 if ((methods_[methodIndex].parameters_[index].attr_ & ATTR_OUT) != 0) {
572 stringBuilder.Append(methods_[methodIndex].parameters_[index].name_.c_str());
573 if (index != methods_[methodIndex].parameters_.size() - 1) {
574 stringBuilder.Append(", ");
575 }
576 }
577 }
578
579 stringBuilder.Append(") => {\n");
580 MetaType errCode;
581 errCode.kind_ = TypeKind::Integer;
582 EmitWriteVariable("reply", ERR_CODE.string(), &errCode, stringBuilder, prefix + TAB + TAB);
583 MetaType* returnType = metaComponent_->types_[metaMethod->returnTypeIndex_];
584
585 if (returnType->kind_ != TypeKind::Void || haveOutPara) {
586 stringBuilder.Append(prefix).Append(TAB).Append(TAB).AppendFormat("if (%s == 0) {\n", ERR_CODE.string());
587 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
588 MetaParameter* mp = metaMethod->parameters_[index];
589 if ((mp->attributes_ & ATTR_OUT) != 0) {
590 EmitWriteMethodParameter(mp, "reply", stringBuilder, prefix + TAB + TAB + TAB);
591 }
592 }
593 if (returnType->kind_ != TypeKind::Void) {
594 EmitWriteVariable("reply", RETURN_VALUE.string(), returnType, stringBuilder, prefix + TAB + TAB + TAB);
595 }
596 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("}\n");
597 }
598 stringBuilder.Append(prefix).Append(TAB).Append("}");
599 stringBuilder.Append(");\n");
600 stringBuilder.Append(prefix).Append(TAB).Append("return true;\n");
601 stringBuilder.Append(prefix).Append("}\n");
602 }
603
EmitInterfaceMethodCommands(StringBuilder & stringBuilder)604 void TsCodeEmitter::EmitInterfaceMethodCommands(StringBuilder& stringBuilder)
605 {
606 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
607 MetaMethod* metaMethod = metaInterface_->methods_[index];
608 stringBuilder.Append(TAB).AppendFormat("static readonly COMMAND_%s = %d;\n",
609 ConstantName(metaMethod->name_).string(), index + 1);
610 }
611 }
612
EmitLicense(StringBuilder & stringBuilder)613 void TsCodeEmitter::EmitLicense(StringBuilder& stringBuilder)
614 {
615 stringBuilder.Append(metaInterface_->license_).Append(NEWLINE);
616 }
617
EmitWriteVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)618 void TsCodeEmitter::EmitWriteVariable(const String& parcelName, const std::string& name, MetaType* mt,
619 StringBuilder& stringBuilder,
620 const String& prefix)
621 {
622 switch (mt->kind_) {
623 case TypeKind::Boolean:
624 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s ? 1 : 0);\n", parcelName.string(), name.c_str());
625 break;
626 case TypeKind::Char:
627 case TypeKind::Byte:
628 case TypeKind::Short:
629 case TypeKind::Integer:
630 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s);\n", parcelName.string(), name.c_str());
631 break;
632 case TypeKind::Long:
633 stringBuilder.Append(prefix).AppendFormat("%s.writeLong(%s);\n", parcelName.string(), name.c_str());
634 break;
635 case TypeKind::Float:
636 stringBuilder.Append(prefix).AppendFormat("%s.writeFloat(%s);\n", parcelName.string(), name.c_str());
637 break;
638 case TypeKind::Double:
639 stringBuilder.Append(prefix).AppendFormat("%s.writeDouble(%s);\n", parcelName.string(), name.c_str());
640 break;
641 case TypeKind::String:
642 stringBuilder.Append(prefix).AppendFormat("%s.writeString(%s);\n", parcelName.string(), name.c_str());
643 break;
644 case TypeKind::Sequenceable:
645 if (EmitType(mt).Equals("IRemoteObject")) {
646 stringBuilder.Append(prefix).AppendFormat("%s.writeRemoteObject(%s);\n", parcelName.string(),
647 name.c_str());
648 break;
649 }
650 stringBuilder.Append(prefix).AppendFormat("%s.writeSequenceable(%s);\n", parcelName.string(),
651 name.c_str());
652 break;
653 case TypeKind::Interface:
654 stringBuilder.Append(prefix).AppendFormat("%s.writeRemoteObject(%s as %s);\n", parcelName.string(),
655 name.c_str(), StubName(EmitType(mt)).string());
656 break;
657 case TypeKind::List: {
658 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
659 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s.size());\n", parcelName.string(), name.c_str());
660 stringBuilder.Append(prefix).AppendFormat("for (%s element : %s) {\n",
661 EmitType(innerType).string(), name.c_str());
662 EmitWriteVariable(parcelName, "element", innerType, stringBuilder, prefix + TAB);
663 stringBuilder.Append(prefix).Append("}\n");
664 break;
665 }
666 case TypeKind::Map: {
667 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
668 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
669 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s.size);\n", parcelName.string(), name.c_str());
670 stringBuilder.Append(prefix).AppendFormat("for (let [key, value] of %s) {\n", name.c_str());
671 EmitWriteVariable(parcelName, "key", keyType, stringBuilder, prefix + TAB);
672 EmitWriteVariable(parcelName, "value", valueType, stringBuilder, prefix + TAB);
673 stringBuilder.Append(prefix).Append("}\n");
674 break;
675 }
676 case TypeKind::Array: {
677 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
678 EmitWriteArrayVariable(parcelName, name, innerType, stringBuilder, prefix);
679 break;
680 }
681 default:
682 break;
683 }
684 }
685
EmitWriteArrayVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)686 void TsCodeEmitter::EmitWriteArrayVariable(const String& parcelName, const std::string& name, MetaType* mt,
687 StringBuilder& stringBuilder,
688 const String& prefix)
689 {
690 switch (mt->kind_) {
691 case TypeKind::Boolean:
692 stringBuilder.Append(prefix).AppendFormat("%s.writeBooleanArray(%s);\n", parcelName.string(),
693 name.c_str());
694 break;
695 case TypeKind::Char:
696 stringBuilder.Append(prefix).AppendFormat("%s.writeCharArray(%s);\n", parcelName.string(), name.c_str());
697 break;
698 case TypeKind::Byte:
699 stringBuilder.Append(prefix).AppendFormat("%s.writeByteArray(%s);\n",
700 parcelName.string(), name.c_str());
701 break;
702 case TypeKind::Short:
703 stringBuilder.Append(prefix).AppendFormat("%s.writeShortArray(%s);\n", parcelName.string(), name.c_str());
704 break;
705 case TypeKind::Integer:
706 stringBuilder.Append(prefix).AppendFormat("%s.writeIntArray(%s);\n", parcelName.string(), name.c_str());
707 break;
708 case TypeKind::Long:
709 stringBuilder.Append(prefix).AppendFormat("%s.writeLongArray(%s);\n", parcelName.string(), name.c_str());
710 break;
711 case TypeKind::Float:
712 stringBuilder.Append(prefix).AppendFormat("%s.writeFloatArray(%s);\n", parcelName.string(), name.c_str());
713 break;
714 case TypeKind::Double:
715 stringBuilder.Append(prefix).AppendFormat("%s.writeDoubleArray(%s);\n", parcelName.string(), name.c_str());
716 break;
717 case TypeKind::String:
718 stringBuilder.Append(prefix).AppendFormat("%s.writeStringArray(%s);\n", parcelName.string(), name.c_str());
719 break;
720 case TypeKind::Sequenceable: {
721 String typeName = EmitType(mt).EndsWith("]") ?
722 (EmitType(mt).Substring(0, EmitType(mt).GetLength() - 2)) : EmitType(mt);
723 stringBuilder.Append(prefix).AppendFormat("let %sArray:Array<%s> = %s;\n", name.c_str(), typeName.string(),
724 name.c_str());
725 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%sArray.length);\n", parcelName.string(),
726 name.c_str());
727 stringBuilder.Append(prefix).AppendFormat("for (let index = 0; index < %sArray.length; index++) {\n",
728 name.c_str());
729 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.writeSequenceable(%s[index]);\n",
730 parcelName.string(), name.c_str());
731 stringBuilder.Append(prefix).AppendFormat("}\n");
732 }
733 break;
734 default:
735 break;
736 }
737 }
738
EmitReadVariable(const String & parcelName,const std::string & name,MetaType * mt,unsigned int attributes,StringBuilder & stringBuilder,const String & prefix)739 void TsCodeEmitter::EmitReadVariable(const String& parcelName, const std::string& name, MetaType* mt,
740 unsigned int attributes,
741 StringBuilder& stringBuilder,
742 const String& prefix)
743 {
744 switch (mt->kind_) {
745 case TypeKind::Boolean:
746 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt() == 1 ? true : false;\n", name.c_str(),
747 parcelName.string());
748 break;
749 case TypeKind::Char:
750 case TypeKind::Byte:
751 case TypeKind::Short:
752 case TypeKind::Integer:
753 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt();\n", name.c_str(), parcelName.string());
754 break;
755 case TypeKind::Long:
756 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLong();\n", name.c_str(), parcelName.string());
757 break;
758 case TypeKind::Float:
759 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloat();\n", name.c_str(), parcelName.string());
760 break;
761 case TypeKind::Double:
762 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDouble();\n", name.c_str(), parcelName.string());
763 break;
764 case TypeKind::String:
765 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readString();\n", name.c_str(), parcelName.string());
766 break;
767 case TypeKind::Sequenceable:
768 if ((attributes & ATTR_OUT) == 0 && EmitType(mt).Equals("IRemoteObject")) {
769 stringBuilder.Append(prefix).AppendFormat("IRemoteObject %s = %s.readRemoteObject();\n",
770 name.c_str(), parcelName.string());
771 break;
772 }
773 if ((attributes & ATTR_OUT) == 0) {
774 stringBuilder.Append(prefix).AppendFormat("let %s = new %s();\n", name.c_str(), EmitType(mt).string());
775 }
776 stringBuilder.Append(prefix).AppendFormat("%s.readSequenceable(%s);\n", parcelName.string(), name.c_str());
777
778 break;
779 case TypeKind::Interface:
780 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readRemoteObject();\n", name.c_str(),
781 parcelName.string());
782 break;
783
784 case TypeKind::Map: {
785 stringBuilder.Append(prefix).AppendFormat("let %s = new Map();\n", name.c_str());
786 stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
787 parcelName.string());
788 stringBuilder.Append(prefix).AppendFormat("for (let i = 0; i < %sSize; ++i) {\n", name.c_str());
789 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
790 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
791 EmitReadVariable(parcelName, "key", keyType, ATTR_IN, stringBuilder, prefix + TAB);
792 EmitReadVariable(parcelName, "value", valueType, ATTR_IN, stringBuilder, prefix + TAB);
793 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.set(key, value);\n", name.c_str());
794 stringBuilder.Append(prefix).Append("}\n");
795 break;
796 }
797 case TypeKind::Array: {
798 if ((attributes & ATTR_MASK) == ATTR_OUT) {
799 EmitReadOutArrayVariable(parcelName, name, mt, stringBuilder, prefix);
800 } else {
801 EmitReadArrayVariable(parcelName, name, mt, attributes, stringBuilder, prefix);
802 }
803 break;
804 }
805 default:
806 break;
807 }
808 }
809
EmitReadArrayVariable(const String & parcelName,const std::string & name,MetaType * mt,unsigned int attributes,StringBuilder & stringBuilder,const String & prefix)810 void TsCodeEmitter::EmitReadArrayVariable(const String& parcelName, const std::string& name, MetaType* mt,
811 unsigned int attributes, StringBuilder& stringBuilder, const String& prefix)
812 {
813 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
814 switch (innerType->kind_) {
815 case TypeKind::Boolean:
816 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readBooleanArray();\n", name.c_str(),
817 parcelName.string());
818 break;
819 case TypeKind::Char:
820 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readCharArray();\n", name.c_str(),
821 parcelName.string());
822 break;
823 case TypeKind::Byte:
824 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readByteArray();\n", name.c_str(),
825 parcelName.string());
826 break;
827 case TypeKind::Short:
828 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readShortArray();\n", name.c_str(),
829 parcelName.string());
830 break;
831 case TypeKind::Integer:
832 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readIntArray();\n", name.c_str(),
833 parcelName.string());
834 break;
835 case TypeKind::Long:
836 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLongArray();\n", name.c_str(),
837 parcelName.string());
838 break;
839 case TypeKind::Float:
840 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloatArray();\n", name.c_str(),
841 parcelName.string());
842 break;
843 case TypeKind::Double:
844 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDoubleArray();\n", name.c_str(),
845 parcelName.string());
846 break;
847 case TypeKind::String:
848 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readStringArray();\n", name.c_str(),
849 parcelName.string());
850 break;
851 case TypeKind::Sequenceable: {
852 String typeName = EmitType(mt).EndsWith("]") ?
853 (EmitType(mt).Substring(0, EmitType(mt).GetLength() - 2)) : EmitType(mt);
854 stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
855 parcelName.string());
856 stringBuilder.Append(prefix).AppendFormat("let %s:Array<%s> = [];\n", name.c_str(), typeName.string());
857 stringBuilder.Append(prefix).AppendFormat("for (let index = 0; index < %sSize; index++) {\n",
858 name.c_str());
859 stringBuilder.Append(prefix).Append(TAB).AppendFormat("let %sValue = new %s();\n",
860 name.c_str(), typeName.string());
861 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.readSequenceable(%sValue);\n",
862 parcelName.string(), name.c_str());
863 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.push(%sValue);\n", name.c_str(),
864 name.c_str());
865 stringBuilder.Append(prefix).AppendFormat("}\n");
866 }
867 break;
868 default:
869 break;
870 }
871 }
872
EmitReadOutArrayVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)873 void TsCodeEmitter::EmitReadOutArrayVariable(const String& parcelName, const std::string& name, MetaType* mt,
874 StringBuilder& stringBuilder,
875 const String& prefix)
876 {
877 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
878 switch (innerType->kind_) {
879 case TypeKind::Boolean:
880 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readBooleanArray();\n", name.c_str(),
881 parcelName.string());
882 break;
883 case TypeKind::Char:
884 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readCharArray();\n", name.c_str(),
885 parcelName.string());
886 break;
887 case TypeKind::Byte:
888 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readByteArray();\n", name.c_str(),
889 parcelName.string());
890 break;
891 case TypeKind::Short:
892 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readShortArray();\n", name.c_str(),
893 parcelName.string());
894 break;
895 case TypeKind::Integer:
896 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readIntArray();\n", name.c_str(),
897 parcelName.string());
898 break;
899 case TypeKind::Long:
900 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLongArray();\n", name.c_str(),
901 parcelName.string());
902 break;
903 case TypeKind::Float:
904 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloatArray();\n", name.c_str(),
905 parcelName.string());
906 break;
907 case TypeKind::Double:
908 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDoubleArray();\n", name.c_str(),
909 parcelName.string());
910 break;
911 case TypeKind::String:
912 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readStringArray();\n", name.c_str(),
913 parcelName.string());
914 break;
915 case TypeKind::Sequenceable: {
916 stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
917 parcelName.string());
918 String typeName = EmitType(mt).EndsWith("]") ?
919 (EmitType(mt).Substring(0, EmitType(mt).GetLength() - 2)) : EmitType(mt);
920 stringBuilder.Append(prefix).AppendFormat("let %s:Array<%s> = [];\n", name.c_str(), typeName.string());
921 stringBuilder.Append(prefix).AppendFormat("for (let index = 0; index < %sSize; index++) {\n",
922 name.c_str());
923 stringBuilder.Append(prefix).Append(TAB).AppendFormat("let %sValue = new %s();\n",
924 name.c_str(), typeName.string());
925 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.readSequenceable(%sValue);\n",
926 parcelName.string(), name.c_str());
927 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.push(%sValue);\n", name.c_str(),
928 name.c_str());
929 stringBuilder.Append(prefix).AppendFormat("}\n");
930 }
931 break;
932 default:
933 break;
934 }
935 }
936
EmitReadOutVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)937 void TsCodeEmitter::EmitReadOutVariable(const String& parcelName, const std::string& name, MetaType* mt,
938 StringBuilder& stringBuilder,
939 const String& prefix)
940 {
941 switch (mt->kind_) {
942 case TypeKind::Boolean:
943 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt() == 1 ? true : false;\n",
944 name.c_str(), parcelName.string());
945 break;
946 case TypeKind::Char:
947 case TypeKind::Byte:
948 case TypeKind::Short:
949 case TypeKind::Integer:
950 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt();\n", name.c_str(), parcelName.string());
951 break;
952 case TypeKind::Long:
953 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLong();\n", name.c_str(), parcelName.string());
954 break;
955 case TypeKind::Float:
956 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloat();\n", name.c_str(), parcelName.string());
957 break;
958 case TypeKind::Double:
959 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDouble();\n", name.c_str(), parcelName.string());
960 break;
961 case TypeKind::String:
962 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readString();\n", name.c_str(), parcelName.string());
963 break;
964 case TypeKind::Sequenceable:
965 if (EmitType(mt).Equals("IRemoteObject")) {
966 stringBuilder.Append(prefix).AppendFormat("%s = %s.readRemoteObject();\n", name.c_str(),
967 parcelName.string());
968 break;
969 }
970 stringBuilder.Append(prefix).AppendFormat("let %s = new %s();\n", name.c_str(), EmitType(mt).string());
971 stringBuilder.Append(prefix).AppendFormat("%s.readSequenceable(%s);\n", parcelName.string(), name.c_str());
972 break;
973 case TypeKind::Interface:
974 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readRemoteObject();\n", name.c_str(),
975 parcelName.string());
976 break;
977 case TypeKind::List: {
978 stringBuilder.Append(prefix).AppendFormat("int %sSize = %s.readInt();\n", name.c_str(),
979 parcelName.string());
980 stringBuilder.Append(prefix).AppendFormat("for (int i = 0; i < %sSize; ++i) {\n", name.c_str());
981 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
982 EmitReadVariable(parcelName, "value", innerType, ATTR_IN, stringBuilder, prefix + TAB);
983 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.add(value);\n", name.c_str());
984 stringBuilder.Append(prefix).Append("}\n");
985 break;
986 }
987 case TypeKind::Map: {
988 stringBuilder.Append(prefix).AppendFormat("let %s = new Map();\n", name.c_str());
989 stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
990 parcelName.string());
991 stringBuilder.Append(prefix).AppendFormat("for (let i = 0; i < %sSize; ++i) {\n", name.c_str());
992 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
993 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
994 EmitReadVariable(parcelName, "key", keyType, ATTR_IN, stringBuilder, prefix + TAB);
995 EmitReadVariable(parcelName, "value", valueType, ATTR_IN, stringBuilder, prefix + TAB);
996 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.set(key, value);\n", name.c_str());
997 stringBuilder.Append(prefix).Append("}\n");
998 break;
999 }
1000 case TypeKind::Array: {
1001 EmitReadOutArrayVariable(parcelName, name, mt, stringBuilder, prefix);
1002 break;
1003 }
1004 default:
1005 break;
1006 }
1007 }
1008
EmitType(MetaType * mt)1009 String TsCodeEmitter::EmitType(MetaType* mt)
1010 {
1011 switch (mt->kind_) {
1012 case TypeKind::Boolean:
1013 return "boolean";
1014 case TypeKind::Byte:
1015 return "number";
1016 case TypeKind::Short:
1017 return "number";
1018 case TypeKind::Integer:
1019 return "number";
1020 case TypeKind::Long:
1021 return "number";
1022 case TypeKind::Float:
1023 return "number";
1024 case TypeKind::Double:
1025 return "number";
1026 case TypeKind::String:
1027 return "string";
1028 case TypeKind::Void:
1029 return "void";
1030 case TypeKind::Sequenceable: {
1031 MetaSequenceable* mp = metaComponent_->sequenceables_[mt->index_];
1032 return mp->name_;
1033 }
1034 case TypeKind::Interface: {
1035 MetaInterface* mi = metaComponent_->interfaces_[mt->index_];
1036 return mi->name_;
1037 }
1038 case TypeKind::Map: {
1039 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1040 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
1041 if (EmitType(keyType).string() == UNKNOWN_TYPE || EmitType(valueType).string() == UNKNOWN_TYPE) {
1042 return String(UNKNOWN_TYPE.c_str());
1043 }
1044 return String::Format("Map<%s, %s>", EmitType(keyType).string(), EmitType(valueType).string());
1045 }
1046 case TypeKind::Array: {
1047 MetaType* elementType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1048 if (EmitType(elementType).string() == UNKNOWN_TYPE) {
1049 return String(UNKNOWN_TYPE.c_str());
1050 }
1051 return String::Format("%s[]", EmitType(elementType).string());
1052 }
1053 default:
1054 return String(UNKNOWN_TYPE.c_str());
1055 }
1056 }
1057
FileName(const String & name)1058 String TsCodeEmitter::FileName(const String& name)
1059 {
1060 if (name.IsEmpty()) {
1061 return name;
1062 }
1063
1064 StringBuilder stringBuilder;
1065 for (int index = 0; index < name.GetLength(); index++) {
1066 char c = name[index];
1067 if (isupper(c) != 0) {
1068 if (index > 0) {
1069 stringBuilder.Append('_');
1070 }
1071 stringBuilder.Append(tolower(c));
1072 } else {
1073 stringBuilder.Append(c);
1074 }
1075 }
1076 return stringBuilder.ToString().Replace('.', '/');
1077 }
1078
MethodName(const String & name)1079 String TsCodeEmitter::MethodName(const String& name)
1080 {
1081 if (name.IsEmpty() || islower(name[0])) {
1082 return name;
1083 }
1084 return String::Format("%c%s", tolower(name[0]), name.Substring(1).string());
1085 }
1086
ConstantName(const String & name)1087 String TsCodeEmitter::ConstantName(const String& name)
1088 {
1089 if (name.IsEmpty()) {
1090 return name;
1091 }
1092
1093 StringBuilder stringBuilder;
1094
1095 for (int index = 0; index < name.GetLength(); index++) {
1096 char c = name[index];
1097 if (isupper(c) != 0) {
1098 if (index > 1) {
1099 stringBuilder.Append('_');
1100 }
1101 stringBuilder.Append(c);
1102 } else {
1103 stringBuilder.Append(toupper(c));
1104 }
1105 }
1106
1107 return stringBuilder.ToString();
1108 }
1109
StubName(const String & name)1110 String TsCodeEmitter::StubName(const String& name)
1111 {
1112 return name.StartsWith("I") ? (name.Substring(1) + "Stub") : (name + "Stub");
1113 }
1114
UnderlineAdded(const String & originName)1115 const std::string TsCodeEmitter::UnderlineAdded(const String& originName)
1116 {
1117 std::string underline("_");
1118 return underline + std::string(originName.string());
1119 }
1120
CheckInterfaceType()1121 bool TsCodeEmitter::CheckInterfaceType()
1122 {
1123 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
1124 MetaMethod* metaMethod = metaInterface_->methods_[index];
1125 MetaType* returnType = metaComponent_->types_[metaMethod->returnTypeIndex_];
1126 std::string returnTypeStr = EmitType(returnType).string();
1127 if (returnTypeStr == UNKNOWN_TYPE) {
1128 Logger::E(TAG, "unsupported type in .idl file");
1129 return false;
1130 }
1131 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
1132 MetaParameter* mp = metaMethod->parameters_[index];
1133 MetaType* paraType = metaComponent_->types_[mp->typeIndex_];
1134 std::string paraTypeStr = EmitType(paraType).string();
1135 if (paraTypeStr == UNKNOWN_TYPE) {
1136 Logger::E(TAG, "unsupported type in .idl file");
1137 return false;
1138 }
1139 }
1140 }
1141 return true;
1142 }
1143 } // namespace Idl
1144 } // namespace OHOS
1145