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 dataSequence = rpc.MessageSequence.create();\n");
316 stringBuilder.Append(prefix).Append(TAB).Append("let replySequence = rpc.MessageSequence.create();\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, "dataSequence", 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, dataSequence, replySequence, option).",
329 THIS_PROXY.c_str(), proxyName_.string(), ConstantName(metaMethod->name_).string());
330 stringBuilder.Append("then((result: rpc.RequestResult) => {\n");
331 EmitInterfaceMethodCallback(metaMethod, methodIndex, stringBuilder, prefix, haveOutPara);
332 stringBuilder.Append(prefix).Append(TAB).Append("}).catch((e: Error) => ").Append("{\n");
333 stringBuilder.Append(prefix).Append(TAB).Append(TAB)
334 .Append("console.log(\'sendMessageRequest failed, message: \' + e.message);\n");
335 stringBuilder.Append(prefix).Append(TAB).Append("}).finally(() => ").Append("{\n");
336 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("dataSequence.reclaim();").Append("\n");
337 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("replySequence.reclaim();").Append("\n");
338 stringBuilder.Append(prefix).Append(TAB).Append("});").Append("\n");
339 stringBuilder.Append(prefix).Append("}\n");
340 }
341
EmitInterfaceMethodCallback(MetaMethod * metaMethod,int methodIndex,StringBuilder & stringBuilder,const String & prefix,bool haveOutPara)342 void TsCodeEmitter::EmitInterfaceMethodCallback(MetaMethod* metaMethod, int methodIndex, StringBuilder& stringBuilder,
343 const String& prefix, bool haveOutPara)
344 {
345 stringBuilder.Append(prefix).Append(TAB).Append(TAB).AppendFormat("if (result.errCode === 0) {\n");
346 MetaType* returnType = metaComponent_->types_[metaMethod->returnTypeIndex_];
347 // emit errCode
348 MetaType errCode;
349 errCode.kind_ = TypeKind::Integer;
350 EmitReadOutVariable("result.reply", SuffixAdded(ERR_CODE).c_str(), &errCode, stringBuilder,
351 prefix + TAB + TAB + TAB);
352
353 if (returnType->kind_ != TypeKind::Void || haveOutPara) {
354 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).AppendFormat(
355 "if (%s != 0) {\n", SuffixAdded(ERR_CODE).c_str());
356 for (size_t index = 0; index < methods_[methodIndex].parameters_.size(); index++) {
357 if ((methods_[methodIndex].parameters_[index].attr_ & ATTR_OUT) != 0) {
358 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(TAB).AppendFormat(
359 "let %s = undefined;\n", SuffixAdded(
360 methods_[methodIndex].parameters_[index].name_.c_str()).c_str());
361 }
362 }
363 if (returnType->kind_ != TypeKind::Void) {
364 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(TAB).AppendFormat(
365 "let %s = undefined;\n", SuffixAdded(RETURN_VALUE).c_str());
366 }
367 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(TAB).AppendFormat("callback(");
368 stringBuilder.AppendFormat("%s", SuffixAdded(ERR_CODE).c_str());
369 if (methods_[methodIndex].retParameter_.name_.size() > 0) {
370 if (haveOutPara) {
371 stringBuilder.AppendFormat(", %s, ", SuffixAdded(RETURN_VALUE).c_str());
372 } else {
373 stringBuilder.AppendFormat(", %s", SuffixAdded(RETURN_VALUE).c_str());
374 }
375 } else {
376 if (haveOutPara) {
377 stringBuilder.Append(",");
378 }
379 }
380 for (size_t index = 0; index < methods_[methodIndex].parameters_.size(); index++) {
381 if ((methods_[methodIndex].parameters_[index].attr_ & ATTR_OUT) != 0) {
382 stringBuilder.AppendFormat("%s",
383 SuffixAdded(methods_[methodIndex].parameters_[index].name_.c_str()).c_str());
384 if (index != methods_[methodIndex].parameters_.size() - 1) {
385 stringBuilder.Append(", ");
386 }
387 }
388 }
389 stringBuilder.Append(");\n");
390 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(TAB).Append("return;\n");
391 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append("}\n");
392 }
393 EmitInterfaceMethodCallbackInner(returnType, metaMethod, methodIndex, stringBuilder, prefix, haveOutPara);
394 }
395
EmitInterfaceMethodCallbackInner(MetaType * returnType,MetaMethod * metaMethod,int methodIndex,StringBuilder & stringBuilder,const String & prefix,bool haveOutPara)396 void TsCodeEmitter::EmitInterfaceMethodCallbackInner(MetaType* returnType, MetaMethod* metaMethod,
397 int methodIndex, StringBuilder& stringBuilder, const String& prefix, bool haveOutPara)
398 {
399 // emit return
400 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
401 MetaParameter* mp = metaMethod->parameters_[index];
402 if ((mp->attributes_ & ATTR_OUT) != 0) {
403 EmitReadMethodParameter(mp, "result.reply", stringBuilder, prefix + TAB + TAB + TAB);
404 }
405 }
406 if (returnType->kind_ != TypeKind::Void) {
407 String parcelName = "result.reply";
408 EmitReadOutVariable(parcelName, SuffixAdded(RETURN_VALUE), returnType, stringBuilder,
409 prefix + TAB + TAB + TAB);
410 }
411 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).AppendFormat("callback(");
412 stringBuilder.AppendFormat("%s", SuffixAdded(ERR_CODE).c_str());
413 if (methods_[methodIndex].retParameter_.name_.size() > 0) {
414 if (haveOutPara) {
415 stringBuilder.AppendFormat(", %s, ", SuffixAdded(RETURN_VALUE).c_str());
416 } else {
417 stringBuilder.AppendFormat(", %s", SuffixAdded(RETURN_VALUE).c_str());
418 }
419 } else {
420 if (haveOutPara) {
421 stringBuilder.Append(",");
422 }
423 }
424 for (size_t index = 0; index < methods_[methodIndex].parameters_.size(); index++) {
425 if ((methods_[methodIndex].parameters_[index].attr_ & ATTR_OUT) != 0) {
426 stringBuilder.AppendFormat("%s",
427 SuffixAdded(methods_[methodIndex].parameters_[index].name_.c_str()).c_str());
428 if (index != methods_[methodIndex].parameters_.size() - 1) {
429 stringBuilder.Append(", ");
430 }
431 }
432 }
433 stringBuilder.Append(");\n");
434 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("} else {\n");
435 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(
436 "console.log(\"sendMessageRequest failed, errCode: \" + result.errCode);\n");
437 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("}\n");
438 }
439
EmitWriteMethodParameter(MetaParameter * mp,const String & parcelName,StringBuilder & stringBuilder,const String & prefix)440 void TsCodeEmitter::EmitWriteMethodParameter(MetaParameter* mp, const String& parcelName, StringBuilder& stringBuilder,
441 const String& prefix)
442 {
443 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
444 std::string name = mp->name_;
445 EmitWriteVariable(parcelName, name, mt, stringBuilder, prefix);
446 }
447
EmitReadMethodParameter(MetaParameter * mp,const String & parcelName,StringBuilder & stringBuilder,const String & prefix)448 void TsCodeEmitter::EmitReadMethodParameter(MetaParameter* mp, const String& parcelName, StringBuilder& stringBuilder,
449 const String& prefix)
450 {
451 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
452 std::string name = SuffixAdded(mp->name_);
453 EmitReadOutVariable(parcelName, name, mt, stringBuilder, prefix);
454 }
455
EmitInterfaceStub()456 void TsCodeEmitter::EmitInterfaceStub()
457 {
458 if (!CheckInterfaceType()) {
459 return;
460 }
461 String filePath = String::Format("%s/%s.ts", directory_.string(), FileName(stubName_).string());
462 File file(filePath, File::WRITE);
463
464 StringBuilder stringBuilder;
465 EmitLicense(stringBuilder);
466 stringBuilder.Append(NEWLINE);
467 EmitInterfaceImports(stringBuilder);
468 stringBuilder.Append(NEWLINE);
469 EmitInterfaceStubImpl(stringBuilder);
470 stringBuilder.Append(NEWLINE);
471
472 String data = stringBuilder.ToString();
473 file.WriteData(data.string(), data.GetLength());
474 file.Flush();
475 file.Close();
476 }
477
EmitInterfaceStubImpl(StringBuilder & stringBuilder)478 void TsCodeEmitter::EmitInterfaceStubImpl(StringBuilder& stringBuilder)
479 {
480 stringBuilder.AppendFormat("export default class %s extends rpc.RemoteObject implements %s {\n",
481 stubName_.string(), interfaceName_.string());
482 EmitInterfaceStubMethodImpls(stringBuilder, TAB);
483 stringBuilder.Append(NEWLINE);
484 EmitInterfaceMethodCommands(stringBuilder);
485 stringBuilder.Append("}\n");
486 }
487
EmitInterfaceStubConstructor(StringBuilder & stringBuilder,const String & prefix)488 void TsCodeEmitter::EmitInterfaceStubConstructor(StringBuilder& stringBuilder, const String& prefix)
489 {
490 stringBuilder.Append(prefix).Append("constructor(des: string) {\n");
491 stringBuilder.Append(prefix).Append(TAB).Append("super(des);\n");
492 stringBuilder.Append(prefix).Append("}\n");
493 }
494
EmitInterfaceStubMethodImpls(StringBuilder & stringBuilder,const String & prefix)495 void TsCodeEmitter::EmitInterfaceStubMethodImpls(StringBuilder& stringBuilder, const String& prefix)
496 {
497 EmitInterfaceStubConstructor(stringBuilder, prefix);
498 stringBuilder.Append(prefix).Append(NEWLINE);
499 stringBuilder.Append(prefix).Append("async onRemoteMessageRequest(code: number, data:rpc.MessageSequence,");
500 stringBuilder.Append(" reply:rpc.MessageSequence, option:rpc.MessageOption): Promise<boolean> {\n");
501 stringBuilder.Append(prefix).Append(TAB).Append(
502 "console.log(\"onRemoteMessageRequest called, code = \" + code);\n");
503 stringBuilder.Append(prefix).Append(TAB).Append("switch(code) {\n");
504 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
505 MetaMethod* metaMethod = metaInterface_->methods_[index];
506 EmitInterfaceStubMethodImpl(metaMethod, index, stringBuilder, prefix + TAB + TAB);
507 }
508 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("default: {\n");
509 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(
510 "console.log(\"invalid request code\" + code);\n");
511 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append("break;\n");
512 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("}\n");
513 stringBuilder.Append(prefix).Append(TAB).Append("}\n");
514 stringBuilder.Append(prefix).Append(TAB).Append("return false;\n");
515 stringBuilder.Append(prefix).Append("}\n");
516 stringBuilder.Append(prefix).Append(NEWLINE);
517
518 // emit empty method
519 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
520 bool isLastParaTypeIn = false;
521 MetaMethod* metaMethod = metaInterface_->methods_[index];
522 stringBuilder.Append(prefix).AppendFormat("%s(", MethodName(metaMethod->name_).string());
523 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
524 MetaParameter* mp = metaMethod->parameters_[index];
525 if ((mp->attributes_ & ATTR_IN) != 0) {
526 EmitInterfaceMethodParameter(mp, stringBuilder, prefix + TAB);
527 if (index != metaMethod->parameterNumber_ - 1) {
528 stringBuilder.Append(", ");
529 } else {
530 isLastParaTypeIn = true;
531 }
532 }
533 }
534 if (!isLastParaTypeIn) {
535 stringBuilder.AppendFormat("callback: %s", methods_[index].callbackName_.c_str());
536 } else {
537 stringBuilder.AppendFormat(", callback: %s", methods_[index].callbackName_.c_str());
538 }
539 stringBuilder.Append("): void{}\n");
540 }
541 }
542
EmitInterfaceStubMethodImpl(MetaMethod * metaMethod,int methodIndex,StringBuilder & stringBuilder,const String & prefix)543 void TsCodeEmitter::EmitInterfaceStubMethodImpl(MetaMethod* metaMethod, int methodIndex, StringBuilder& stringBuilder,
544 const String& prefix)
545 {
546 bool haveOutPara = false;
547 stringBuilder.Append(prefix).AppendFormat("case %s.COMMAND_%s: {\n", stubName_.string(),
548 ConstantName(metaMethod->name_).string());
549 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
550 MetaParameter* mp = metaMethod->parameters_[index];
551 if ((mp->attributes_ & ATTR_IN) != 0) {
552 MetaType* mt = metaComponent_->types_[mp->typeIndex_];
553 EmitReadVariable("data", SuffixAdded(mp->name_), mt, ATTR_IN, stringBuilder, prefix + TAB);
554 }
555 if ((mp->attributes_ & ATTR_OUT) != 0) {
556 haveOutPara = true;
557 }
558 }
559 stringBuilder.Append(prefix).Append(TAB).Append("let promise = new Promise<void>((resolve,reject) => { \n");
560 stringBuilder.Append(prefix).Append(TAB).Append(TAB)
561 .AppendFormat("this.%s(", MethodName(metaMethod->name_).string());
562 bool isLastParaTypeIn = false;
563 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
564 MetaParameter* mp = metaMethod->parameters_[index];
565 if ((mp->attributes_ & ATTR_IN) != 0) {
566 stringBuilder.Append(SuffixAdded(mp->name_).c_str());
567 if (index != metaMethod->parameterNumber_ - 1) {
568 stringBuilder.Append(", ");
569 } else {
570 isLastParaTypeIn = true;
571 }
572 }
573 }
574 if (!isLastParaTypeIn) {
575 stringBuilder.Append("(");
576 } else {
577 stringBuilder.Append(", (");
578 }
579 EmitInterfaceStubMethodPromiseImpl(metaMethod, methodIndex, stringBuilder, prefix, haveOutPara);
580 stringBuilder.Append(prefix).Append(TAB).Append("}").Append(");\n");
581 stringBuilder.Append(prefix).Append(TAB).Append("await promise;\n");
582 stringBuilder.Append(prefix).Append(TAB).Append("return true;\n");
583 stringBuilder.Append(prefix).Append("}\n");
584 }
585
EmitInterfaceStubMethodPromiseImpl(MetaMethod * metaMethod,int methodIndex,StringBuilder & stringBuilder,const String & prefix,bool haveOutPara)586 void TsCodeEmitter::EmitInterfaceStubMethodPromiseImpl(
587 MetaMethod* metaMethod, int methodIndex, StringBuilder& stringBuilder, const String& prefix, bool haveOutPara)
588 {
589 stringBuilder.Append(ERR_CODE);
590 if (methods_[methodIndex].retParameter_.name_.size() > 0) {
591 if (!haveOutPara) {
592 stringBuilder.AppendFormat(", %s", RETURN_VALUE.string());
593 } else {
594 stringBuilder.AppendFormat(", %s", RETURN_VALUE.string()).Append(", ");
595 }
596 } else {
597 if (haveOutPara) {
598 stringBuilder.Append(", ");
599 }
600 }
601 for (size_t index = 0; index < methods_[methodIndex].parameters_.size(); index++) {
602 if ((methods_[methodIndex].parameters_[index].attr_ & ATTR_OUT) != 0) {
603 stringBuilder.Append(methods_[methodIndex].parameters_[index].name_.c_str());
604 if (index != methods_[methodIndex].parameters_.size() - 1) {
605 stringBuilder.Append(", ");
606 }
607 }
608 }
609 stringBuilder.Append(") => {\n");
610 MetaType errCode;
611 errCode.kind_ = TypeKind::Integer;
612 EmitWriteVariable("reply", ERR_CODE.string(), &errCode, stringBuilder, prefix + TAB + TAB + TAB);
613 MetaType* returnType = metaComponent_->types_[metaMethod->returnTypeIndex_];
614
615 if (returnType->kind_ != TypeKind::Void || haveOutPara) {
616 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB)
617 .AppendFormat("if (%s == 0) {\n", ERR_CODE.string());
618 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
619 MetaParameter* mp = metaMethod->parameters_[index];
620 if ((mp->attributes_ & ATTR_OUT) != 0) {
621 EmitWriteMethodParameter(mp, "reply", stringBuilder, prefix + TAB + TAB + TAB + TAB);
622 }
623 }
624 if (returnType->kind_ != TypeKind::Void) {
625 EmitWriteVariable("reply", RETURN_VALUE.string(), returnType,
626 stringBuilder, prefix + TAB + TAB + TAB + TAB);
627 }
628 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append("}\n");
629 }
630 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append("resolve();\n");
631 stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("}");
632 stringBuilder.Append(");\n");
633 }
634
EmitInterfaceMethodCommands(StringBuilder & stringBuilder)635 void TsCodeEmitter::EmitInterfaceMethodCommands(StringBuilder& stringBuilder)
636 {
637 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
638 MetaMethod* metaMethod = metaInterface_->methods_[index];
639 stringBuilder.Append(TAB).AppendFormat("static readonly COMMAND_%s = %d;\n",
640 ConstantName(metaMethod->name_).string(), index + 1);
641 }
642 }
643
EmitLicense(StringBuilder & stringBuilder)644 void TsCodeEmitter::EmitLicense(StringBuilder& stringBuilder)
645 {
646 stringBuilder.Append(metaInterface_->license_).Append(NEWLINE);
647 }
648
EmitWriteVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)649 void TsCodeEmitter::EmitWriteVariable(const String& parcelName, const std::string& name, MetaType* mt,
650 StringBuilder& stringBuilder,
651 const String& prefix)
652 {
653 switch (mt->kind_) {
654 case TypeKind::Boolean:
655 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s ? 1 : 0);\n", parcelName.string(), name.c_str());
656 break;
657 case TypeKind::Char:
658 case TypeKind::Byte:
659 case TypeKind::Short:
660 case TypeKind::Integer:
661 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s);\n", parcelName.string(), name.c_str());
662 break;
663 case TypeKind::Long:
664 stringBuilder.Append(prefix).AppendFormat("%s.writeLong(%s);\n", parcelName.string(), name.c_str());
665 break;
666 case TypeKind::Float:
667 stringBuilder.Append(prefix).AppendFormat("%s.writeFloat(%s);\n", parcelName.string(), name.c_str());
668 break;
669 case TypeKind::Double:
670 stringBuilder.Append(prefix).AppendFormat("%s.writeDouble(%s);\n", parcelName.string(), name.c_str());
671 break;
672 case TypeKind::String:
673 stringBuilder.Append(prefix).AppendFormat("%s.writeString(%s);\n", parcelName.string(), name.c_str());
674 break;
675 case TypeKind::Sequenceable:
676 if (EmitType(mt).Equals("IRemoteObject")) {
677 stringBuilder.Append(prefix).AppendFormat("%s.writeRemoteObject(%s);\n", parcelName.string(),
678 name.c_str());
679 break;
680 }
681 stringBuilder.Append(prefix).AppendFormat("%s.writeParcelable(%s);\n", parcelName.string(),
682 name.c_str());
683 break;
684 case TypeKind::Interface:
685 stringBuilder.Append(prefix).AppendFormat("%s.writeRemoteObject(%s as %s);\n", parcelName.string(),
686 name.c_str(), StubName(EmitType(mt)).string());
687 break;
688 case TypeKind::List: {
689 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
690 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s.size());\n", parcelName.string(), name.c_str());
691 stringBuilder.Append(prefix).AppendFormat("for (%s element : %s) {\n",
692 EmitType(innerType).string(), name.c_str());
693 EmitWriteVariable(parcelName, "element", innerType, stringBuilder, prefix + TAB);
694 stringBuilder.Append(prefix).Append("}\n");
695 break;
696 }
697 case TypeKind::Map: {
698 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
699 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
700 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s.size);\n", parcelName.string(), name.c_str());
701 stringBuilder.Append(prefix).AppendFormat("for (let [key, value] of %s) {\n", name.c_str());
702 EmitWriteVariable(parcelName, "key", keyType, stringBuilder, prefix + TAB);
703 EmitWriteVariable(parcelName, "value", valueType, stringBuilder, prefix + TAB);
704 stringBuilder.Append(prefix).Append("}\n");
705 break;
706 }
707 case TypeKind::Array: {
708 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
709 EmitWriteArrayVariable(parcelName, name, innerType, stringBuilder, prefix);
710 break;
711 }
712 default:
713 break;
714 }
715 }
716
EmitWriteArrayVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)717 void TsCodeEmitter::EmitWriteArrayVariable(const String& parcelName, const std::string& name, MetaType* mt,
718 StringBuilder& stringBuilder,
719 const String& prefix)
720 {
721 switch (mt->kind_) {
722 case TypeKind::Boolean:
723 stringBuilder.Append(prefix).AppendFormat("%s.writeBooleanArray(%s);\n", parcelName.string(),
724 name.c_str());
725 break;
726 case TypeKind::Char:
727 stringBuilder.Append(prefix).AppendFormat("%s.writeCharArray(%s);\n", parcelName.string(), name.c_str());
728 break;
729 case TypeKind::Byte:
730 stringBuilder.Append(prefix).AppendFormat("%s.writeByteArray(%s);\n",
731 parcelName.string(), name.c_str());
732 break;
733 case TypeKind::Short:
734 stringBuilder.Append(prefix).AppendFormat("%s.writeShortArray(%s);\n", parcelName.string(), name.c_str());
735 break;
736 case TypeKind::Integer:
737 stringBuilder.Append(prefix).AppendFormat("%s.writeIntArray(%s);\n", parcelName.string(), name.c_str());
738 break;
739 case TypeKind::Long:
740 stringBuilder.Append(prefix).AppendFormat("%s.writeLongArray(%s);\n", parcelName.string(), name.c_str());
741 break;
742 case TypeKind::Float:
743 stringBuilder.Append(prefix).AppendFormat("%s.writeFloatArray(%s);\n", parcelName.string(), name.c_str());
744 break;
745 case TypeKind::Double:
746 stringBuilder.Append(prefix).AppendFormat("%s.writeDoubleArray(%s);\n", parcelName.string(), name.c_str());
747 break;
748 case TypeKind::String:
749 stringBuilder.Append(prefix).AppendFormat("%s.writeStringArray(%s);\n", parcelName.string(), name.c_str());
750 break;
751 case TypeKind::Sequenceable: {
752 String typeName = EmitType(mt).EndsWith("]") ?
753 (EmitType(mt).Substring(0, EmitType(mt).GetLength() - 2)) : EmitType(mt);
754 stringBuilder.Append(prefix).AppendFormat("let %sArray:Array<%s> = %s;\n", name.c_str(), typeName.string(),
755 name.c_str());
756 stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%sArray.length);\n", parcelName.string(),
757 name.c_str());
758 stringBuilder.Append(prefix).AppendFormat("for (let index = 0; index < %sArray.length; index++) {\n",
759 name.c_str());
760 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.writeSequenceable(%s[index]);\n",
761 parcelName.string(), name.c_str());
762 stringBuilder.Append(prefix).AppendFormat("}\n");
763 }
764 break;
765 default:
766 break;
767 }
768 }
769
EmitReadVariable(const String & parcelName,const std::string & name,MetaType * mt,unsigned int attributes,StringBuilder & stringBuilder,const String & prefix)770 void TsCodeEmitter::EmitReadVariable(const String& parcelName, const std::string& name, MetaType* mt,
771 unsigned int attributes,
772 StringBuilder& stringBuilder,
773 const String& prefix)
774 {
775 switch (mt->kind_) {
776 case TypeKind::Boolean:
777 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt() == 1 ? true : false;\n", name.c_str(),
778 parcelName.string());
779 break;
780 case TypeKind::Char:
781 case TypeKind::Byte:
782 case TypeKind::Short:
783 case TypeKind::Integer:
784 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt();\n", name.c_str(), parcelName.string());
785 break;
786 case TypeKind::Long:
787 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLong();\n", name.c_str(), parcelName.string());
788 break;
789 case TypeKind::Float:
790 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloat();\n", name.c_str(), parcelName.string());
791 break;
792 case TypeKind::Double:
793 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDouble();\n", name.c_str(), parcelName.string());
794 break;
795 case TypeKind::String:
796 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readString();\n", name.c_str(), parcelName.string());
797 break;
798 case TypeKind::Sequenceable:
799 if ((attributes & ATTR_OUT) == 0 && EmitType(mt).Equals("IRemoteObject")) {
800 stringBuilder.Append(prefix).AppendFormat("IRemoteObject %s = %s.readRemoteObject();\n",
801 name.c_str(), parcelName.string());
802 break;
803 }
804 if ((attributes & ATTR_OUT) == 0) {
805 stringBuilder.Append(prefix).AppendFormat("let %s = new %s();\n", name.c_str(), EmitType(mt).string());
806 }
807 stringBuilder.Append(prefix).AppendFormat("%s.readParcelable(%s);\n", parcelName.string(), name.c_str());
808
809 break;
810 case TypeKind::Interface:
811 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readRemoteObject();\n", name.c_str(),
812 parcelName.string());
813 break;
814
815 case TypeKind::Map: {
816 stringBuilder.Append(prefix).AppendFormat("let %s = new Map();\n", name.c_str());
817 stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
818 parcelName.string());
819 stringBuilder.Append(prefix).AppendFormat("for (let i = 0; i < %sSize; ++i) {\n", name.c_str());
820 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
821 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
822 EmitReadVariable(parcelName, "key", keyType, ATTR_IN, stringBuilder, prefix + TAB);
823 EmitReadVariable(parcelName, "value", valueType, ATTR_IN, stringBuilder, prefix + TAB);
824 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.set(key, value);\n", name.c_str());
825 stringBuilder.Append(prefix).Append("}\n");
826 break;
827 }
828 case TypeKind::Array: {
829 if ((attributes & ATTR_MASK) == ATTR_OUT) {
830 EmitReadOutArrayVariable(parcelName, name, mt, stringBuilder, prefix);
831 } else {
832 EmitReadArrayVariable(parcelName, name, mt, attributes, stringBuilder, prefix);
833 }
834 break;
835 }
836 default:
837 break;
838 }
839 }
840
EmitReadArrayVariable(const String & parcelName,const std::string & name,MetaType * mt,unsigned int attributes,StringBuilder & stringBuilder,const String & prefix)841 void TsCodeEmitter::EmitReadArrayVariable(const String& parcelName, const std::string& name, MetaType* mt,
842 unsigned int attributes, StringBuilder& stringBuilder, const String& prefix)
843 {
844 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
845 switch (innerType->kind_) {
846 case TypeKind::Boolean:
847 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readBooleanArray();\n", name.c_str(),
848 parcelName.string());
849 break;
850 case TypeKind::Char:
851 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readCharArray();\n", name.c_str(),
852 parcelName.string());
853 break;
854 case TypeKind::Byte:
855 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readByteArray();\n", name.c_str(),
856 parcelName.string());
857 break;
858 case TypeKind::Short:
859 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readShortArray();\n", name.c_str(),
860 parcelName.string());
861 break;
862 case TypeKind::Integer:
863 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readIntArray();\n", name.c_str(),
864 parcelName.string());
865 break;
866 case TypeKind::Long:
867 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLongArray();\n", name.c_str(),
868 parcelName.string());
869 break;
870 case TypeKind::Float:
871 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloatArray();\n", name.c_str(),
872 parcelName.string());
873 break;
874 case TypeKind::Double:
875 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDoubleArray();\n", name.c_str(),
876 parcelName.string());
877 break;
878 case TypeKind::String:
879 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readStringArray();\n", name.c_str(),
880 parcelName.string());
881 break;
882 case TypeKind::Sequenceable: {
883 String typeName = EmitType(mt).EndsWith("]") ?
884 (EmitType(mt).Substring(0, EmitType(mt).GetLength() - 2)) : EmitType(mt);
885 stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
886 parcelName.string());
887 stringBuilder.Append(prefix).AppendFormat("let %s:Array<%s> = [];\n", name.c_str(), typeName.string());
888 stringBuilder.Append(prefix).AppendFormat("for (let index = 0; index < %sSize; index++) {\n",
889 name.c_str());
890 stringBuilder.Append(prefix).Append(TAB).AppendFormat("let %sValue = new %s();\n",
891 name.c_str(), typeName.string());
892 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.readSequenceable(%sValue);\n",
893 parcelName.string(), name.c_str());
894 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.push(%sValue);\n", name.c_str(),
895 name.c_str());
896 stringBuilder.Append(prefix).AppendFormat("}\n");
897 }
898 break;
899 default:
900 break;
901 }
902 }
903
EmitReadOutArrayVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)904 void TsCodeEmitter::EmitReadOutArrayVariable(const String& parcelName, const std::string& name, MetaType* mt,
905 StringBuilder& stringBuilder,
906 const String& prefix)
907 {
908 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
909 switch (innerType->kind_) {
910 case TypeKind::Boolean:
911 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readBooleanArray();\n", name.c_str(),
912 parcelName.string());
913 break;
914 case TypeKind::Char:
915 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readCharArray();\n", name.c_str(),
916 parcelName.string());
917 break;
918 case TypeKind::Byte:
919 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readByteArray();\n", name.c_str(),
920 parcelName.string());
921 break;
922 case TypeKind::Short:
923 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readShortArray();\n", name.c_str(),
924 parcelName.string());
925 break;
926 case TypeKind::Integer:
927 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readIntArray();\n", name.c_str(),
928 parcelName.string());
929 break;
930 case TypeKind::Long:
931 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLongArray();\n", name.c_str(),
932 parcelName.string());
933 break;
934 case TypeKind::Float:
935 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloatArray();\n", name.c_str(),
936 parcelName.string());
937 break;
938 case TypeKind::Double:
939 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDoubleArray();\n", name.c_str(),
940 parcelName.string());
941 break;
942 case TypeKind::String:
943 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readStringArray();\n", name.c_str(),
944 parcelName.string());
945 break;
946 case TypeKind::Sequenceable: {
947 stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
948 parcelName.string());
949 String typeName = EmitType(mt).EndsWith("]") ?
950 (EmitType(mt).Substring(0, EmitType(mt).GetLength() - 2)) : EmitType(mt);
951 stringBuilder.Append(prefix).AppendFormat("let %s:Array<%s> = [];\n", name.c_str(), typeName.string());
952 stringBuilder.Append(prefix).AppendFormat("for (let index = 0; index < %sSize; index++) {\n",
953 name.c_str());
954 stringBuilder.Append(prefix).Append(TAB).AppendFormat("let %sValue = new %s();\n",
955 name.c_str(), typeName.string());
956 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.readSequenceable(%sValue);\n",
957 parcelName.string(), name.c_str());
958 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.push(%sValue);\n", name.c_str(),
959 name.c_str());
960 stringBuilder.Append(prefix).AppendFormat("}\n");
961 }
962 break;
963 default:
964 break;
965 }
966 }
967
EmitReadOutVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)968 void TsCodeEmitter::EmitReadOutVariable(const String& parcelName, const std::string& name, MetaType* mt,
969 StringBuilder& stringBuilder,
970 const String& prefix)
971 {
972 switch (mt->kind_) {
973 case TypeKind::Boolean:
974 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt() == 1 ? true : false;\n",
975 name.c_str(), parcelName.string());
976 break;
977 case TypeKind::Char:
978 case TypeKind::Byte:
979 case TypeKind::Short:
980 case TypeKind::Integer:
981 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt();\n", name.c_str(), parcelName.string());
982 break;
983 case TypeKind::Long:
984 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLong();\n", name.c_str(), parcelName.string());
985 break;
986 case TypeKind::Float:
987 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloat();\n", name.c_str(), parcelName.string());
988 break;
989 case TypeKind::Double:
990 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDouble();\n", name.c_str(), parcelName.string());
991 break;
992 case TypeKind::String:
993 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readString();\n", name.c_str(), parcelName.string());
994 break;
995 case TypeKind::Sequenceable:
996 if (EmitType(mt).Equals("IRemoteObject")) {
997 stringBuilder.Append(prefix).AppendFormat("%s = %s.readRemoteObject();\n", name.c_str(),
998 parcelName.string());
999 break;
1000 }
1001 stringBuilder.Append(prefix).AppendFormat("let %s = new %s();\n", name.c_str(), EmitType(mt).string());
1002 stringBuilder.Append(prefix).AppendFormat("%s.readSequenceable(%s);\n", parcelName.string(), name.c_str());
1003 break;
1004 case TypeKind::Interface:
1005 stringBuilder.Append(prefix).AppendFormat("let %s = %s.readRemoteObject();\n", name.c_str(),
1006 parcelName.string());
1007 break;
1008 case TypeKind::List: {
1009 stringBuilder.Append(prefix).AppendFormat("int %sSize = %s.readInt();\n", name.c_str(),
1010 parcelName.string());
1011 stringBuilder.Append(prefix).AppendFormat("for (int i = 0; i < %sSize; ++i) {\n", name.c_str());
1012 MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1013 EmitReadVariable(parcelName, "value", innerType, ATTR_IN, stringBuilder, prefix + TAB);
1014 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.add(value);\n", name.c_str());
1015 stringBuilder.Append(prefix).Append("}\n");
1016 break;
1017 }
1018 case TypeKind::Map: {
1019 stringBuilder.Append(prefix).AppendFormat("let %s = new Map();\n", name.c_str());
1020 stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
1021 parcelName.string());
1022 stringBuilder.Append(prefix).AppendFormat("for (let i = 0; i < %sSize; ++i) {\n", name.c_str());
1023 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1024 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
1025 EmitReadVariable(parcelName, "key", keyType, ATTR_IN, stringBuilder, prefix + TAB);
1026 EmitReadVariable(parcelName, "value", valueType, ATTR_IN, stringBuilder, prefix + TAB);
1027 stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.set(key, value);\n", name.c_str());
1028 stringBuilder.Append(prefix).Append("}\n");
1029 break;
1030 }
1031 case TypeKind::Array: {
1032 EmitReadOutArrayVariable(parcelName, name, mt, stringBuilder, prefix);
1033 break;
1034 }
1035 default:
1036 break;
1037 }
1038 }
1039
EmitType(MetaType * mt)1040 String TsCodeEmitter::EmitType(MetaType* mt)
1041 {
1042 switch (mt->kind_) {
1043 case TypeKind::Boolean:
1044 return "boolean";
1045 case TypeKind::Byte:
1046 return "number";
1047 case TypeKind::Short:
1048 return "number";
1049 case TypeKind::Integer:
1050 return "number";
1051 case TypeKind::Long:
1052 return "number";
1053 case TypeKind::Float:
1054 return "number";
1055 case TypeKind::Double:
1056 return "number";
1057 case TypeKind::String:
1058 return "string";
1059 case TypeKind::Void:
1060 return "void";
1061 case TypeKind::Sequenceable: {
1062 MetaSequenceable* mp = metaComponent_->sequenceables_[mt->index_];
1063 return mp->name_;
1064 }
1065 case TypeKind::Interface: {
1066 MetaInterface* mi = metaComponent_->interfaces_[mt->index_];
1067 return mi->name_;
1068 }
1069 case TypeKind::Map: {
1070 MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1071 MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
1072 if (EmitType(keyType).string() == UNKNOWN_TYPE || EmitType(valueType).string() == UNKNOWN_TYPE) {
1073 return String(UNKNOWN_TYPE.c_str());
1074 }
1075 return String::Format("Map<%s, %s>", EmitType(keyType).string(), EmitType(valueType).string());
1076 }
1077 case TypeKind::Array: {
1078 MetaType* elementType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1079 if (EmitType(elementType).string() == UNKNOWN_TYPE) {
1080 return String(UNKNOWN_TYPE.c_str());
1081 }
1082 return String::Format("%s[]", EmitType(elementType).string());
1083 }
1084 default:
1085 return String(UNKNOWN_TYPE.c_str());
1086 }
1087 }
1088
FileName(const String & name)1089 String TsCodeEmitter::FileName(const String& name)
1090 {
1091 if (name.IsEmpty()) {
1092 return name;
1093 }
1094
1095 StringBuilder stringBuilder;
1096 for (int index = 0; index < name.GetLength(); index++) {
1097 char c = name[index];
1098 if (isupper(c) != 0) {
1099 if (index > 0) {
1100 stringBuilder.Append('_');
1101 }
1102 stringBuilder.Append(tolower(c));
1103 } else {
1104 stringBuilder.Append(c);
1105 }
1106 }
1107 return stringBuilder.ToString().Replace('.', '/');
1108 }
1109
MethodName(const String & name)1110 String TsCodeEmitter::MethodName(const String& name)
1111 {
1112 if (name.IsEmpty() || islower(name[0])) {
1113 return name;
1114 }
1115 return String::Format("%c%s", tolower(name[0]), name.Substring(1).string());
1116 }
1117
ConstantName(const String & name)1118 String TsCodeEmitter::ConstantName(const String& name)
1119 {
1120 if (name.IsEmpty()) {
1121 return name;
1122 }
1123
1124 StringBuilder stringBuilder;
1125
1126 for (int index = 0; index < name.GetLength(); index++) {
1127 char c = name[index];
1128 if (isupper(c) != 0) {
1129 if (index > 1) {
1130 stringBuilder.Append('_');
1131 }
1132 stringBuilder.Append(c);
1133 } else {
1134 stringBuilder.Append(toupper(c));
1135 }
1136 }
1137
1138 return stringBuilder.ToString();
1139 }
1140
StubName(const String & name)1141 String TsCodeEmitter::StubName(const String& name)
1142 {
1143 return name.StartsWith("I") ? (name.Substring(1) + "Stub") : (name + "Stub");
1144 }
1145
UnderlineAdded(const String & originName)1146 const std::string TsCodeEmitter::UnderlineAdded(const String& originName)
1147 {
1148 std::string underline("_");
1149 return underline + std::string(originName.string());
1150 }
1151
SuffixAdded(const String & originName)1152 const std::string TsCodeEmitter::SuffixAdded(const String& originName)
1153 {
1154 std::string varSuffix("Var");
1155 return std::string(originName.string()) + varSuffix;
1156 }
1157
CheckInterfaceType()1158 bool TsCodeEmitter::CheckInterfaceType()
1159 {
1160 for (int index = 0; index < metaInterface_->methodNumber_; index++) {
1161 MetaMethod* metaMethod = metaInterface_->methods_[index];
1162 MetaType* returnType = metaComponent_->types_[metaMethod->returnTypeIndex_];
1163 std::string returnTypeStr = EmitType(returnType).string();
1164 if (returnTypeStr == UNKNOWN_TYPE) {
1165 Logger::E(TAG, "unsupported type in .idl file");
1166 return false;
1167 }
1168 for (int index = 0; index < metaMethod->parameterNumber_; index++) {
1169 MetaParameter* mp = metaMethod->parameters_[index];
1170 MetaType* paraType = metaComponent_->types_[mp->typeIndex_];
1171 std::string paraTypeStr = EmitType(paraType).string();
1172 if (paraTypeStr == UNKNOWN_TYPE) {
1173 Logger::E(TAG, "unsupported type in .idl file");
1174 return false;
1175 }
1176 }
1177 }
1178 return true;
1179 }
1180 } // namespace Idl
1181 } // namespace OHOS
1182