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