• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.sendRequest(%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(\"sendRequest 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("onRemoteRequest(code: number, data, reply, option): boolean {\n");
481     stringBuilder.Append(prefix).Append(TAB).Append("console.log(\"onRemoteRequest called, code = \" + code);\n");
482     stringBuilder.Append(prefix).Append(TAB).Append("switch(code) {\n");
483     for (int index = 0; index < metaInterface_->methodNumber_; index++) {
484         MetaMethod* metaMethod = metaInterface_->methods_[index];
485         EmitInterfaceStubMethodImpl(metaMethod, index, stringBuilder, prefix + TAB + TAB);
486     }
487     stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("default: {\n");
488     stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append(
489         "console.log(\"invalid request code\" + code);\n");
490     stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append(TAB).Append("break;\n");
491     stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("}\n");
492     stringBuilder.Append(prefix).Append(TAB).Append("}\n");
493     stringBuilder.Append(prefix).Append(TAB).Append("return false;\n");
494     stringBuilder.Append(prefix).Append("}\n");
495     stringBuilder.Append(prefix).Append(NEWLINE);
496 
497     // emit empty method
498     for (int index = 0; index < metaInterface_->methodNumber_; index++) {
499         bool isLastParaTypeIn = false;
500         MetaMethod* metaMethod = metaInterface_->methods_[index];
501         stringBuilder.Append(prefix).AppendFormat("%s(", MethodName(metaMethod->name_).string());
502         for (int index = 0; index < metaMethod->parameterNumber_; index++) {
503             MetaParameter* mp = metaMethod->parameters_[index];
504             if ((mp->attributes_ & ATTR_IN) != 0) {
505                 EmitInterfaceMethodParameter(mp, stringBuilder, prefix + TAB);
506                 if (index != metaMethod->parameterNumber_ - 1) {
507                     stringBuilder.Append(", ");
508                 } else {
509                     isLastParaTypeIn = true;
510                 }
511             }
512         }
513         if (!isLastParaTypeIn) {
514             stringBuilder.AppendFormat("callback: %s", methods_[index].callbackName_.c_str());
515         } else {
516             stringBuilder.AppendFormat(", callback: %s", methods_[index].callbackName_.c_str());
517         }
518         stringBuilder.Append("): void{}\n");
519     }
520 }
521 
EmitInterfaceStubMethodImpl(MetaMethod * metaMethod,int methodIndex,StringBuilder & stringBuilder,const String & prefix)522 void TsCodeEmitter::EmitInterfaceStubMethodImpl(MetaMethod* metaMethod, int methodIndex, StringBuilder& stringBuilder,
523     const String& prefix)
524 {
525     bool haveOutPara = false;
526     stringBuilder.Append(prefix).AppendFormat("case %s.COMMAND_%s: {\n", stubName_.string(),
527         ConstantName(metaMethod->name_).string());
528     for (int index = 0; index < metaMethod->parameterNumber_; index++) {
529         MetaParameter* mp = metaMethod->parameters_[index];
530         if ((mp->attributes_ & ATTR_IN) != 0) {
531             MetaType* mt = metaComponent_->types_[mp->typeIndex_];
532             EmitReadVariable("data", UnderlineAdded(mp->name_), mt, ATTR_IN, stringBuilder, prefix + TAB);
533         }
534         if ((mp->attributes_ & ATTR_OUT) != 0) {
535             haveOutPara = true;
536         }
537     }
538     stringBuilder.Append(prefix).Append(TAB).AppendFormat("this.%s(", MethodName(metaMethod->name_).string());
539     bool isLastParaTypeIn = false;
540     for (int index = 0; index < metaMethod->parameterNumber_; index++) {
541         MetaParameter* mp = metaMethod->parameters_[index];
542         if ((mp->attributes_ & ATTR_IN) != 0) {
543             stringBuilder.Append(UnderlineAdded(mp->name_).c_str());
544             if (index != metaMethod->parameterNumber_ - 1) {
545                 stringBuilder.Append(", ");
546             } else {
547                 isLastParaTypeIn = true;
548             }
549         }
550     }
551     if (!isLastParaTypeIn) {
552         stringBuilder.Append("(");
553     } else {
554         stringBuilder.Append(", (");
555     }
556     stringBuilder.Append(ERR_CODE);
557     if (methods_[methodIndex].retParameter_.name_.size() > 0) {
558         if (!haveOutPara) {
559             stringBuilder.AppendFormat(", %s", RETURN_VALUE.string());
560         } else {
561             stringBuilder.AppendFormat(", %s", RETURN_VALUE.string()).Append(", ");
562         }
563     } else {
564         if (haveOutPara) {
565             stringBuilder.Append(", ");
566         }
567     }
568     for (size_t index = 0; index < methods_[methodIndex].parameters_.size(); index++) {
569         if ((methods_[methodIndex].parameters_[index].attr_ & ATTR_OUT) != 0) {
570             stringBuilder.Append(methods_[methodIndex].parameters_[index].name_.c_str());
571             if (index != methods_[methodIndex].parameters_.size() - 1) {
572                 stringBuilder.Append(", ");
573             }
574         }
575     }
576 
577     stringBuilder.Append(") => {\n");
578     MetaType errCode;
579     errCode.kind_ = TypeKind::Integer;
580     EmitWriteVariable("reply", ERR_CODE.string(), &errCode, stringBuilder, prefix + TAB + TAB);
581     MetaType* returnType = metaComponent_->types_[metaMethod->returnTypeIndex_];
582 
583     if (returnType->kind_ != TypeKind::Void || haveOutPara) {
584         stringBuilder.Append(prefix).Append(TAB).Append(TAB).AppendFormat("if (%s == 0) {\n", ERR_CODE.string());
585         for (int index = 0; index < metaMethod->parameterNumber_; index++) {
586             MetaParameter* mp = metaMethod->parameters_[index];
587             if ((mp->attributes_ & ATTR_OUT) != 0) {
588                 EmitWriteMethodParameter(mp, "reply", stringBuilder, prefix + TAB + TAB + TAB);
589             }
590         }
591         if (returnType->kind_ != TypeKind::Void) {
592             EmitWriteVariable("reply", RETURN_VALUE.string(), returnType, stringBuilder, prefix + TAB + TAB + TAB);
593         }
594         stringBuilder.Append(prefix).Append(TAB).Append(TAB).Append("}\n");
595     }
596     stringBuilder.Append(prefix).Append(TAB).Append("}");
597     stringBuilder.Append(");\n");
598     stringBuilder.Append(prefix).Append(TAB).Append("return true;\n");
599     stringBuilder.Append(prefix).Append("}\n");
600 }
601 
EmitInterfaceMethodCommands(StringBuilder & stringBuilder)602 void TsCodeEmitter::EmitInterfaceMethodCommands(StringBuilder& stringBuilder)
603 {
604     for (int index = 0; index < metaInterface_->methodNumber_; index++) {
605         MetaMethod* metaMethod = metaInterface_->methods_[index];
606         stringBuilder.Append(TAB).AppendFormat("static readonly COMMAND_%s = %d;\n",
607             ConstantName(metaMethod->name_).string(), index + 1);
608     }
609 }
610 
EmitLicense(StringBuilder & stringBuilder)611 void TsCodeEmitter::EmitLicense(StringBuilder& stringBuilder)
612 {
613     stringBuilder.Append(metaInterface_->license_).Append(NEWLINE);
614 }
615 
EmitWriteVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)616 void TsCodeEmitter::EmitWriteVariable(const String& parcelName, const std::string& name, MetaType* mt,
617     StringBuilder& stringBuilder,
618     const String& prefix)
619 {
620     switch (mt->kind_) {
621         case TypeKind::Boolean:
622             stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s ? 1 : 0);\n", parcelName.string(), name.c_str());
623             break;
624         case TypeKind::Char:
625         case TypeKind::Byte:
626         case TypeKind::Short:
627         case TypeKind::Integer:
628             stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s);\n", parcelName.string(), name.c_str());
629             break;
630         case TypeKind::Long:
631             stringBuilder.Append(prefix).AppendFormat("%s.writeLong(%s);\n", parcelName.string(), name.c_str());
632             break;
633         case TypeKind::Float:
634             stringBuilder.Append(prefix).AppendFormat("%s.writeFloat(%s);\n", parcelName.string(), name.c_str());
635             break;
636         case TypeKind::Double:
637             stringBuilder.Append(prefix).AppendFormat("%s.writeDouble(%s);\n", parcelName.string(), name.c_str());
638             break;
639         case TypeKind::String:
640             stringBuilder.Append(prefix).AppendFormat("%s.writeString(%s);\n", parcelName.string(), name.c_str());
641             break;
642         case TypeKind::Sequenceable:
643             if (EmitType(mt).Equals("IRemoteObject")) {
644                 stringBuilder.Append(prefix).AppendFormat("%s.writeRemoteObject(%s);\n", parcelName.string(),
645                     name.c_str());
646                 break;
647             }
648             stringBuilder.Append(prefix).AppendFormat("%s.writeSequenceable(%s);\n", parcelName.string(),
649                 name.c_str());
650             break;
651         case TypeKind::Interface:
652             stringBuilder.Append(prefix).AppendFormat("%s.writeRemoteObject(%s as %s);\n", parcelName.string(),
653                 name.c_str(), StubName(EmitType(mt)).string());
654             break;
655         case TypeKind::List: {
656             MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
657             stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s.size());\n", parcelName.string(), name.c_str());
658             stringBuilder.Append(prefix).AppendFormat("for (%s element : %s) {\n",
659                 EmitType(innerType).string(), name.c_str());
660             EmitWriteVariable(parcelName, "element", innerType, stringBuilder, prefix + TAB);
661             stringBuilder.Append(prefix).Append("}\n");
662             break;
663         }
664         case TypeKind::Map: {
665             MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
666             MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
667             stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%s.size);\n", parcelName.string(), name.c_str());
668             stringBuilder.Append(prefix).AppendFormat("for (let [key, value] of %s) {\n", name.c_str());
669             EmitWriteVariable(parcelName, "key", keyType, stringBuilder, prefix + TAB);
670             EmitWriteVariable(parcelName, "value", valueType, stringBuilder, prefix + TAB);
671             stringBuilder.Append(prefix).Append("}\n");
672             break;
673         }
674         case TypeKind::Array: {
675             MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
676             EmitWriteArrayVariable(parcelName, name, innerType, stringBuilder, prefix);
677             break;
678         }
679         default:
680             break;
681     }
682 }
683 
EmitWriteArrayVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)684 void TsCodeEmitter::EmitWriteArrayVariable(const String& parcelName, const std::string& name, MetaType* mt,
685     StringBuilder& stringBuilder,
686     const String& prefix)
687 {
688     switch (mt->kind_) {
689         case TypeKind::Boolean:
690             stringBuilder.Append(prefix).AppendFormat("%s.writeBooleanArray(%s);\n", parcelName.string(),
691                 name.c_str());
692             break;
693         case TypeKind::Char:
694             stringBuilder.Append(prefix).AppendFormat("%s.writeCharArray(%s);\n", parcelName.string(), name.c_str());
695             break;
696         case TypeKind::Byte:
697             stringBuilder.Append(prefix).AppendFormat("%s.writeByteArray(%s);\n",
698                 parcelName.string(), name.c_str());
699             break;
700         case TypeKind::Short:
701             stringBuilder.Append(prefix).AppendFormat("%s.writeShortArray(%s);\n", parcelName.string(), name.c_str());
702             break;
703         case TypeKind::Integer:
704             stringBuilder.Append(prefix).AppendFormat("%s.writeIntArray(%s);\n", parcelName.string(), name.c_str());
705             break;
706         case TypeKind::Long:
707             stringBuilder.Append(prefix).AppendFormat("%s.writeLongArray(%s);\n", parcelName.string(), name.c_str());
708             break;
709         case TypeKind::Float:
710             stringBuilder.Append(prefix).AppendFormat("%s.writeFloatArray(%s);\n", parcelName.string(), name.c_str());
711             break;
712         case TypeKind::Double:
713             stringBuilder.Append(prefix).AppendFormat("%s.writeDoubleArray(%s);\n", parcelName.string(), name.c_str());
714             break;
715         case TypeKind::String:
716             stringBuilder.Append(prefix).AppendFormat("%s.writeStringArray(%s);\n", parcelName.string(), name.c_str());
717             break;
718         case TypeKind::Sequenceable: {
719             String typeName = EmitType(mt).EndsWith("]") ?
720                 (EmitType(mt).Substring(0, EmitType(mt).GetLength() - 2)) : EmitType(mt);
721             stringBuilder.Append(prefix).AppendFormat("let %sArray:Array<%s> = %s;\n", name.c_str(), typeName.string(),
722                 name.c_str());
723             stringBuilder.Append(prefix).AppendFormat("%s.writeInt(%sArray.length);\n", parcelName.string(),
724                 name.c_str());
725             stringBuilder.Append(prefix).AppendFormat("for (let index = 0; index < %sArray.length; index++) {\n",
726                 name.c_str());
727             stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.writeSequenceable(%s[index]);\n",
728                 parcelName.string(), name.c_str());
729             stringBuilder.Append(prefix).AppendFormat("}\n");
730         }
731             break;
732         default:
733             break;
734     }
735 }
736 
EmitReadVariable(const String & parcelName,const std::string & name,MetaType * mt,unsigned int attributes,StringBuilder & stringBuilder,const String & prefix)737 void TsCodeEmitter::EmitReadVariable(const String& parcelName, const std::string& name, MetaType* mt,
738     unsigned int attributes,
739     StringBuilder& stringBuilder,
740     const String& prefix)
741 {
742     switch (mt->kind_) {
743         case TypeKind::Boolean:
744             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt() == 1 ? true : false;\n", name.c_str(),
745                 parcelName.string());
746             break;
747         case TypeKind::Char:
748         case TypeKind::Byte:
749         case TypeKind::Short:
750         case TypeKind::Integer:
751             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt();\n", name.c_str(), parcelName.string());
752             break;
753         case TypeKind::Long:
754             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLong();\n", name.c_str(), parcelName.string());
755             break;
756         case TypeKind::Float:
757             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloat();\n", name.c_str(), parcelName.string());
758             break;
759         case TypeKind::Double:
760             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDouble();\n", name.c_str(), parcelName.string());
761             break;
762         case TypeKind::String:
763             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readString();\n", name.c_str(), parcelName.string());
764             break;
765         case TypeKind::Sequenceable:
766             if ((attributes & ATTR_OUT) == 0 && EmitType(mt).Equals("IRemoteObject")) {
767                 stringBuilder.Append(prefix).AppendFormat("IRemoteObject %s = %s.readRemoteObject();\n",
768                     name.c_str(), parcelName.string());
769                 break;
770             }
771             if ((attributes & ATTR_OUT) == 0) {
772                 stringBuilder.Append(prefix).AppendFormat("let %s = new %s();\n", name.c_str(), EmitType(mt).string());
773             }
774             stringBuilder.Append(prefix).AppendFormat("%s.readSequenceable(%s);\n", parcelName.string(), name.c_str());
775 
776             break;
777         case TypeKind::Interface:
778             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readRemoteObject();\n", name.c_str(),
779                 parcelName.string());
780             break;
781 
782         case TypeKind::Map: {
783             stringBuilder.Append(prefix).AppendFormat("let %s = new Map();\n", name.c_str());
784             stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
785                 parcelName.string());
786             stringBuilder.Append(prefix).AppendFormat("for (let i = 0; i < %sSize; ++i) {\n", name.c_str());
787             MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
788             MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
789             EmitReadVariable(parcelName, "key", keyType, ATTR_IN, stringBuilder, prefix + TAB);
790             EmitReadVariable(parcelName, "value", valueType, ATTR_IN, stringBuilder, prefix + TAB);
791             stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.set(key, value);\n", name.c_str());
792             stringBuilder.Append(prefix).Append("}\n");
793             break;
794         }
795         case TypeKind::Array: {
796             if ((attributes & ATTR_MASK) == ATTR_OUT) {
797                 EmitReadOutArrayVariable(parcelName, name, mt, stringBuilder, prefix);
798             } else {
799                 EmitReadArrayVariable(parcelName, name, mt, attributes, stringBuilder, prefix);
800             }
801             break;
802         }
803         default:
804             break;
805     }
806 }
807 
EmitReadArrayVariable(const String & parcelName,const std::string & name,MetaType * mt,unsigned int attributes,StringBuilder & stringBuilder,const String & prefix)808 void TsCodeEmitter::EmitReadArrayVariable(const String& parcelName, const std::string& name, MetaType* mt,
809     unsigned int attributes, StringBuilder& stringBuilder, const String& prefix)
810 {
811     MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
812     switch (innerType->kind_) {
813         case TypeKind::Boolean:
814             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readBooleanArray();\n", name.c_str(),
815                 parcelName.string());
816             break;
817         case TypeKind::Char:
818             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readCharArray();\n", name.c_str(),
819                 parcelName.string());
820             break;
821         case TypeKind::Byte:
822             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readByteArray();\n", name.c_str(),
823                 parcelName.string());
824             break;
825         case TypeKind::Short:
826             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readShortArray();\n", name.c_str(),
827                 parcelName.string());
828             break;
829         case TypeKind::Integer:
830             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readIntArray();\n", name.c_str(),
831                 parcelName.string());
832             break;
833         case TypeKind::Long:
834             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLongArray();\n", name.c_str(),
835                 parcelName.string());
836             break;
837         case TypeKind::Float:
838             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloatArray();\n", name.c_str(),
839                 parcelName.string());
840             break;
841         case TypeKind::Double:
842             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDoubleArray();\n", name.c_str(),
843                 parcelName.string());
844             break;
845         case TypeKind::String:
846             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readStringArray();\n", name.c_str(),
847                 parcelName.string());
848             break;
849         case TypeKind::Sequenceable: {
850             String typeName = EmitType(mt).EndsWith("]") ?
851                 (EmitType(mt).Substring(0, EmitType(mt).GetLength() - 2)) : EmitType(mt);
852             stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
853                 parcelName.string());
854             stringBuilder.Append(prefix).AppendFormat("let %s:Array<%s> = [];\n", name.c_str(), typeName.string());
855             stringBuilder.Append(prefix).AppendFormat("for (let index = 0; index < %sSize; index++) {\n",
856                 name.c_str());
857             stringBuilder.Append(prefix).Append(TAB).AppendFormat("let %sValue = new %s();\n",
858                 name.c_str(), typeName.string());
859             stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.readSequenceable(%sValue);\n",
860                 parcelName.string(), name.c_str());
861             stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.push(%sValue);\n", name.c_str(),
862                 name.c_str());
863             stringBuilder.Append(prefix).AppendFormat("}\n");
864         }
865             break;
866         default:
867             break;
868     }
869 }
870 
EmitReadOutArrayVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)871 void TsCodeEmitter::EmitReadOutArrayVariable(const String& parcelName, const std::string& name, MetaType* mt,
872     StringBuilder& stringBuilder,
873     const String& prefix)
874 {
875     MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
876     switch (innerType->kind_) {
877         case TypeKind::Boolean:
878             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readBooleanArray();\n", name.c_str(),
879                 parcelName.string());
880             break;
881         case TypeKind::Char:
882             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readCharArray();\n", name.c_str(),
883                 parcelName.string());
884             break;
885         case TypeKind::Byte:
886             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readByteArray();\n", name.c_str(),
887                 parcelName.string());
888             break;
889         case TypeKind::Short:
890             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readShortArray();\n", name.c_str(),
891                 parcelName.string());
892             break;
893         case TypeKind::Integer:
894             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readIntArray();\n", name.c_str(),
895                 parcelName.string());
896             break;
897         case TypeKind::Long:
898             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLongArray();\n", name.c_str(),
899                 parcelName.string());
900             break;
901         case TypeKind::Float:
902             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloatArray();\n", name.c_str(),
903                 parcelName.string());
904             break;
905         case TypeKind::Double:
906             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDoubleArray();\n", name.c_str(),
907                 parcelName.string());
908             break;
909         case TypeKind::String:
910             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readStringArray();\n", name.c_str(),
911                 parcelName.string());
912             break;
913         case TypeKind::Sequenceable: {
914             stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
915                 parcelName.string());
916             String typeName = EmitType(mt).EndsWith("]") ?
917                 (EmitType(mt).Substring(0, EmitType(mt).GetLength() - 2)) : EmitType(mt);
918             stringBuilder.Append(prefix).AppendFormat("let %s:Array<%s> = [];\n", name.c_str(), typeName.string());
919             stringBuilder.Append(prefix).AppendFormat("for (let index = 0; index < %sSize; index++) {\n",
920                 name.c_str());
921             stringBuilder.Append(prefix).Append(TAB).AppendFormat("let %sValue = new %s();\n",
922                 name.c_str(), typeName.string());
923             stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.readSequenceable(%sValue);\n",
924                 parcelName.string(), name.c_str());
925             stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.push(%sValue);\n", name.c_str(),
926                 name.c_str());
927             stringBuilder.Append(prefix).AppendFormat("}\n");
928         }
929             break;
930         default:
931             break;
932     }
933 }
934 
EmitReadOutVariable(const String & parcelName,const std::string & name,MetaType * mt,StringBuilder & stringBuilder,const String & prefix)935 void TsCodeEmitter::EmitReadOutVariable(const String& parcelName, const std::string& name, MetaType* mt,
936     StringBuilder& stringBuilder,
937     const String& prefix)
938 {
939     switch (mt->kind_) {
940         case TypeKind::Boolean:
941             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt() == 1 ? true : false;\n",
942                 name.c_str(), parcelName.string());
943             break;
944         case TypeKind::Char:
945         case TypeKind::Byte:
946         case TypeKind::Short:
947         case TypeKind::Integer:
948             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readInt();\n", name.c_str(), parcelName.string());
949             break;
950         case TypeKind::Long:
951             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readLong();\n", name.c_str(), parcelName.string());
952             break;
953         case TypeKind::Float:
954             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readFloat();\n", name.c_str(), parcelName.string());
955             break;
956         case TypeKind::Double:
957             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readDouble();\n", name.c_str(), parcelName.string());
958             break;
959         case TypeKind::String:
960             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readString();\n", name.c_str(), parcelName.string());
961             break;
962         case TypeKind::Sequenceable:
963             if (EmitType(mt).Equals("IRemoteObject")) {
964                 stringBuilder.Append(prefix).AppendFormat("%s = %s.readRemoteObject();\n", name.c_str(),
965                     parcelName.string());
966                 break;
967             }
968             stringBuilder.Append(prefix).AppendFormat("let %s = new %s();\n", name.c_str(), EmitType(mt).string());
969             stringBuilder.Append(prefix).AppendFormat("%s.readSequenceable(%s);\n", parcelName.string(), name.c_str());
970             break;
971         case TypeKind::Interface:
972             stringBuilder.Append(prefix).AppendFormat("let %s = %s.readRemoteObject();\n", name.c_str(),
973                 parcelName.string());
974             break;
975         case TypeKind::List: {
976             stringBuilder.Append(prefix).AppendFormat("int %sSize = %s.readInt();\n", name.c_str(),
977                 parcelName.string());
978             stringBuilder.Append(prefix).AppendFormat("for (int i = 0; i < %sSize; ++i) {\n", name.c_str());
979             MetaType* innerType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
980             EmitReadVariable(parcelName, "value", innerType, ATTR_IN, stringBuilder, prefix + TAB);
981             stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.add(value);\n", name.c_str());
982             stringBuilder.Append(prefix).Append("}\n");
983             break;
984         }
985         case TypeKind::Map: {
986             stringBuilder.Append(prefix).AppendFormat("let %s = new Map();\n", name.c_str());
987             stringBuilder.Append(prefix).AppendFormat("let %sSize = %s.readInt();\n", name.c_str(),
988                 parcelName.string());
989             stringBuilder.Append(prefix).AppendFormat("for (let i = 0; i < %sSize; ++i) {\n", name.c_str());
990             MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
991             MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
992             EmitReadVariable(parcelName, "key", keyType, ATTR_IN, stringBuilder, prefix + TAB);
993             EmitReadVariable(parcelName, "value", valueType, ATTR_IN, stringBuilder, prefix + TAB);
994             stringBuilder.Append(prefix).Append(TAB).AppendFormat("%s.set(key, value);\n", name.c_str());
995             stringBuilder.Append(prefix).Append("}\n");
996             break;
997         }
998         case TypeKind::Array: {
999             EmitReadOutArrayVariable(parcelName, name, mt, stringBuilder, prefix);
1000             break;
1001         }
1002         default:
1003             break;
1004     }
1005 }
1006 
EmitType(MetaType * mt)1007 String TsCodeEmitter::EmitType(MetaType* mt)
1008 {
1009     switch (mt->kind_) {
1010         case TypeKind::Boolean:
1011             return "boolean";
1012         case TypeKind::Byte:
1013             return "number";
1014         case TypeKind::Short:
1015             return "number";
1016         case TypeKind::Integer:
1017             return "number";
1018         case TypeKind::Long:
1019             return "number";
1020         case TypeKind::Float:
1021             return "number";
1022         case TypeKind::Double:
1023             return "number";
1024         case TypeKind::String:
1025             return "string";
1026         case TypeKind::Void:
1027             return "void";
1028         case TypeKind::Sequenceable: {
1029             MetaSequenceable* mp = metaComponent_->sequenceables_[mt->index_];
1030             return mp->name_;
1031         }
1032         case TypeKind::Interface: {
1033             MetaInterface* mi = metaComponent_->interfaces_[mt->index_];
1034             return mi->name_;
1035         }
1036         case TypeKind::Map: {
1037             MetaType* keyType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1038             MetaType* valueType = metaComponent_->types_[mt->nestedTypeIndexes_[1]];
1039             if (EmitType(keyType).string() == UNKNOWN_TYPE || EmitType(valueType).string() == UNKNOWN_TYPE) {
1040                 return String(UNKNOWN_TYPE.c_str());
1041             }
1042             return String::Format("Map<%s, %s>", EmitType(keyType).string(), EmitType(valueType).string());
1043         }
1044         case TypeKind::Array: {
1045             MetaType* elementType = metaComponent_->types_[mt->nestedTypeIndexes_[0]];
1046             if (EmitType(elementType).string() == UNKNOWN_TYPE) {
1047                 return String(UNKNOWN_TYPE.c_str());
1048             }
1049             return String::Format("%s[]", EmitType(elementType).string());
1050         }
1051         default:
1052             return String(UNKNOWN_TYPE.c_str());
1053     }
1054 }
1055 
FileName(const String & name)1056 String TsCodeEmitter::FileName(const String& name)
1057 {
1058     if (name.IsEmpty()) {
1059         return name;
1060     }
1061 
1062     StringBuilder stringBuilder;
1063     for (int index = 0; index < name.GetLength(); index++) {
1064         char c = name[index];
1065         if (isupper(c) != 0) {
1066             if (index > 0) {
1067                 stringBuilder.Append('_');
1068             }
1069             stringBuilder.Append(tolower(c));
1070         } else {
1071             stringBuilder.Append(c);
1072         }
1073     }
1074     return stringBuilder.ToString().Replace('.', '/');
1075 }
1076 
MethodName(const String & name)1077 String TsCodeEmitter::MethodName(const String& name)
1078 {
1079     if (name.IsEmpty() || islower(name[0])) {
1080         return name;
1081     }
1082     return String::Format("%c%s", tolower(name[0]), name.Substring(1).string());
1083 }
1084 
ConstantName(const String & name)1085 String TsCodeEmitter::ConstantName(const String& name)
1086 {
1087     if (name.IsEmpty()) {
1088         return name;
1089     }
1090 
1091     StringBuilder stringBuilder;
1092 
1093     for (int index = 0; index < name.GetLength(); index++) {
1094         char c = name[index];
1095         if (isupper(c) != 0) {
1096             if (index > 1) {
1097                 stringBuilder.Append('_');
1098             }
1099             stringBuilder.Append(c);
1100         } else {
1101             stringBuilder.Append(toupper(c));
1102         }
1103     }
1104 
1105     return stringBuilder.ToString();
1106 }
1107 
StubName(const String & name)1108 String TsCodeEmitter::StubName(const String& name)
1109 {
1110     return name.StartsWith("I") ? (name.Substring(1) + "Stub") : (name + "Stub");
1111 }
1112 
UnderlineAdded(const String & originName)1113 const std::string TsCodeEmitter::UnderlineAdded(const String& originName)
1114 {
1115     std::string underline("_");
1116     return underline + std::string(originName.string());
1117 }
1118 
CheckInterfaceType()1119 bool TsCodeEmitter::CheckInterfaceType()
1120 {
1121     for (int index = 0; index < metaInterface_->methodNumber_; index++) {
1122         MetaMethod* metaMethod = metaInterface_->methods_[index];
1123         MetaType* returnType = metaComponent_->types_[metaMethod->returnTypeIndex_];
1124         std::string returnTypeStr = EmitType(returnType).string();
1125         if (returnTypeStr == UNKNOWN_TYPE) {
1126             Logger::E(TAG, "unsupported type in .idl file");
1127             return false;
1128         }
1129         for (int index = 0; index < metaMethod->parameterNumber_; index++) {
1130             MetaParameter* mp = metaMethod->parameters_[index];
1131             MetaType* paraType = metaComponent_->types_[mp->typeIndex_];
1132             std::string paraTypeStr = EmitType(paraType).string();
1133             if (paraTypeStr == UNKNOWN_TYPE) {
1134                 Logger::E(TAG, "unsupported type in .idl file");
1135                 return false;
1136             }
1137         }
1138     }
1139     return true;
1140 }
1141 } // namespace Idl
1142 } // namespace OHOS
1143