1 2/* 3* Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd. 4* Licensed under the Apache License, Version 2.0 (the "License"); 5* you may not use this file except in compliance with the License. 6* You may obtain a copy of the License at 7* 8* http://www.apache.org/licenses/LICENSE-2.0 9* 10* Unless required by applicable law or agreed to in writing, software 11* distributed under the License is distributed on an "AS IS" BASIS, 12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13* See the License for the specific language governing permissions and 14* limitations under the License. 15*/ 16const { NapiLog } = require('../tools/napi_log'); 17const { replaceAll, getTab } = require('../tools/tool'); 18const re = require('../tools/re'); 19const { iServiceHTemplate, proxyHTemplate, stubHTemplate, serviceHTemplate, proxyCppTemplate, proxyFuncTemplate, 20 stubCppTemplate, stubInnerFuncTemplate, serviceCppTemplate, serviceFuncImplTemplate, clientCppTemplate, buildGnTemplate, 21 buildGnTemplate41, bundleJsonTemplate, bundleJsonTemplate41, profileGnTemplate, profileGnTemplate41, profileJsonTemplate, 22 profileXmlTemplate, serviceCfgTemplate, serviceCfgTemplate41, serviceCfgGnTemplate, iServiceCppTemplate } = require('./file_template'); 23const { DATA_W_MAP, DATA_R_MAP, VECTOR_W_MAP, VECTOR_R_MAP, getParcelType, AllParseFileList, MarshallInfo, 24 ProcessingClassList } = require('../tools/common'); 25const numericTypes = ['short', 'int', 'long', 'long long', 'float', 'double']; 26const boolType = ['bool']; 27const charType = ['char', 'string']; 28let rootHFileSrc = ''; // .h文件的源码 29let dependSrcList = []; //在.h文件中定义并被接口使用到的class/struct类定义源码集合(接口没用到的class定义就不需要了) 30let marshallFuncList = []; // class类的消息序列化方法代码集合 31 32let fileContent = { 33 'iServiceHFile': {}, 34 'proxyHFile': {}, 35 'stubHFile': {}, 36 'serviceHFile': {}, 37 'proxyCppFile': {}, 38 'stubCppFile': {}, 39 'serviceCppFile': {}, 40 'clientCppFile': {}, 41 'buildGnFile': {}, 42 'bundleJsonFile': {}, 43 'profileGnFile': {}, 44 'profileXmlFile': {}, 45 'profileJsonFile': {}, 46 'serviceCfgFile': {}, 47 'serviceCfgGnFile': {}, 48 'iServiceCppFile': {}, 49}; 50 51function getIncludeStr(includeList) { 52 let includeStr = ''; 53 for (let i = 0; i < includeList.length; ++i) { 54 includeStr += '#include ' + includeList[i] + '\n'; 55 } 56 return includeStr; 57} 58 59function getUsingStr(usingList) { 60 let usingStr = ''; 61 for (usingName in usingList) { 62 usingStr += '\nusing ' + usingList[usingName].raw_type + ';'; 63 } 64 return usingStr; 65} 66 67function getFuncParamStr(params) { 68 let paramStr = ''; 69 for (let i = 0; i < params.length; ++i) { 70 paramStr += (i === 0) ? '' : ', '; 71 paramStr += params[i].type + ' ' + params[i].name; 72 } 73 return paramStr; 74} 75 76function getClientFuncParamStr(params) { 77 let paramStr = ''; 78 for (let i = 0; i < params.length; ++i) { 79 paramStr += (i === 0) ? '' : ', '; 80 paramStr += params[i].name; 81 } 82 return paramStr; 83} 84 85function genClientMsgFunc(funcList) { 86 let initParavalue = ''; 87 let initParamessage = ''; 88 for (let n = 0; n < funcList.params.length; ++n) { 89 if (numericTypes.includes(funcList.params[n].type)) { 90 // 数值类型初始化为0 91 initParavalue = '1'; 92 initParamessage += ' int ' + funcList.params[n].name + ' = ' + initParavalue + ';\r\n'; 93 funcList.params[n].name; 94 } else if (boolType.includes(funcList.params[n].type)) { 95 // 布尔类型初始化为true 96 initParavalue = 'true'; 97 initParamessage += ' bool ' + funcList.params[n].name + ' = ' + initParavalue + ';\r\n'; 98 } else if (charType.includes(funcList.params[n].type)) { 99 // 字符类型初始化为空字符'' 100 initParavalue = ''; 101 initParamessage += ' string ' + funcList.params[n].name + ' = ' + initParavalue + ';\r\n'; 102 } else { 103 // 对于其他类型,这里可以根据需要进行处理 104 initRetvalue = 'nullptr'; // 假设是指针类型或其他复杂类型 105 } 106 } 107 return initParamessage; 108} 109 110function genClientLogFunc(funcList) { 111 let initParaLog = ''; 112 for (let n = 0; n < funcList.params.length; ++n) { 113 if (numericTypes.includes(funcList.params[n].type)) { 114 // 数值类型初始化为0 115 initParaLog += ' printf("client %s = %i",%s);\r\n'.format(funcList.params[n].name, funcList.params[n].name); 116 } else { 117 // 对于其他类型,这里可以根据需要进行处理 118 } 119 } 120 return initParaLog; 121} 122 123 124/** 125 * 获取class类型在原始.h文件中的定义源码段 126 * @param className 待查找的class名称(可以是struct) 127 * @param rawContent .h文件源码 128 * @returns class类型在原始.h文件中的定义源码段 129 */ 130function getClassSrc(className, rawContent) { 131 let beginPos = rawContent.indexOf(className); 132 if (beginPos < 0) { 133 NapiLog.logError('Warning: Can not find definition of ' + className); 134 return null; 135 } 136 137 let firstBracesPos = rawContent.indexOf('{', beginPos); // class后面第一个{的位置 138 let firstSemiPos = rawContent.indexOf(';', beginPos); // class后面第一个分号的位置 139 if ((firstBracesPos < 0) || (firstSemiPos < firstBracesPos)) { 140 // class定义后面找不到{},或先找到了结束符分号,视为该class没有相关的实现代码 141 NapiLog.logError('Warning: Can not find implementation of ' + className); 142 return null; 143 } 144 145 let endPos = firstBracesPos + 1; 146 let bracesCount = 1; 147 for (; (endPos < rawContent.length) && (bracesCount !== 0); ++endPos) { 148 if (rawContent.charAt(endPos) === '{') { 149 ++bracesCount; 150 } 151 if (rawContent.charAt(endPos) === '}') { 152 --bracesCount; 153 } 154 } 155 156 if (bracesCount !== 0) { 157 // 左右括号不匹配 158 NapiLog.logError('Warning: The braces of %s do not match.'.format(className)); 159 return null; 160 } 161 162 let classSrc = rawContent.substring(beginPos, endPos); 163 return classSrc; 164} 165 166/** 167 * 查看变量类型是否为class/struct类型,是否已生成指定的打包函数 168 * @param vType 变量类型 169 * @returns [class对应的打包函数(没有为null), class结构信息(没找到为null)] 170 */ 171function findClassGenInfo(vType) { 172 let marshallInfo = null; 173 for (let i = 0; i < marshallFuncList.length; ++i) { 174 if (marshallFuncList[i].className === vType) { 175 marshallInfo = marshallFuncList[i].marshallFuncs; 176 } 177 } 178 179 if (marshallInfo) { 180 // 该class已经有生成好的包装代码,就不用再到原始代码结构体AllParseFileList中去查找了。 181 return [marshallInfo, null]; 182 } 183 let classInfo = AllParseFileList.findClassByName(vType); 184 return [null, classInfo]; 185} 186 187function findGetSet(propName, classInfo) { 188 let upperName = propName.replace(propName[0], propName[0].toUpperCase()); 189 let getName = 'get' + upperName; 190 let setName = 'set' + upperName; 191 let findGet = false; 192 let findSet = false; 193 let result = null; 194 for (let i = 0; i < classInfo.methods.public.length; ++i) { 195 if (getName === classInfo.methods.public[i].name) { 196 findGet = true; 197 } 198 if (setName === classInfo.methods.public[i].name) { 199 findSet = true; 200 } 201 } 202 if (findGet && findSet) { 203 // get和set方法必须同时具备,成员对象属性才能序列化/反序列化,缺一不可。 204 result = { 'name': propName, 'getName': getName, 'setName': setName }; 205 } 206 return result; 207} 208 209function privatePropMashall(parcelName, objName, classInfo, marshallInfo) { 210 let properties = classInfo.properties.protected.concat(classInfo.properties.private); 211 let propFuncs = []; // 保存成员属性对应的get/set方法 212 for (let i = 0; i < properties.length; ++i) { 213 let getSetInfo = findGetSet(properties[i].name, classInfo); 214 if (getSetInfo !== null && getSetInfo !== undefined) { 215 getSetInfo.type = properties[i].type; 216 propFuncs.push(getSetInfo); 217 } else { 218 NapiLog.logError( 219 'Warning: Can not find get/set method of %s.%s, the property will be ignored in remote request.' 220 .format(classInfo.name, properties[i].name)); 221 } 222 } 223 let writePropStr = ''; 224 let readPropStr = ''; 225 let tab = getTab(1); 226 for (let i = 0; i < propFuncs.length; ++i) { 227 writePropStr += '\n' + tab; 228 writePropStr += genWrite(objName + '.' + propFuncs[i].getName + '()', parcelName, propFuncs[i].type); 229 230 readPropStr += '\n' + tab; 231 let destObj = { 232 'name': objName + '.' + propFuncs[i].name, 233 'setFunc': objName + '.' + propFuncs[i].setName, 234 'type': propFuncs[i].type 235 }; 236 readPropStr += genRead(parcelName, destObj); 237 } 238 marshallInfo.marshallFuncH = marshallInfo.marshallFuncH.replace('[privateMarshall]', writePropStr); 239 marshallInfo.unmarshallFuncH = marshallInfo.unmarshallFuncH.replace('[privateUnmarshall]', readPropStr); 240} 241 242function publicPropMashall(parcelName, objName, classInfo, marshallInfo) { 243 let properties = classInfo.properties.public; 244 let writePropStr = ''; 245 let readPropStr = ''; 246 let tab = getTab(1); 247 for (let i = 0; i < properties.length; ++i) { 248 writePropStr += '\n' + tab; 249 writePropStr += genWrite(objName + '.' + properties[i].name, parcelName, properties[i].type); 250 251 readPropStr += '\n' + tab; 252 let destObj = { 253 'name': objName + '.' + properties[i].name, 254 'setFunc': null, 255 'type': properties[i].type 256 }; 257 readPropStr += genRead(parcelName, destObj); 258 } 259 marshallInfo.marshallFuncH = marshallInfo.marshallFuncH.replace('[publicMarshall]', writePropStr); 260 marshallInfo.unmarshallFuncH = marshallInfo.unmarshallFuncH.replace('[publicUnmarshall]', readPropStr); 261} 262 263/** 264 * 保存远程接口用到的相关class/struct定义代码,以便后面写入到生成的iservice.h接口文件中 265 * @param classInfo 接口使用到的class信息 266 */ 267function saveClassSrc(classInfo) { 268 if (classInfo.isInclude) { 269 // 只有service class所在的主.h文件中定义的class/struct需要保存其源码 270 // 定义在其它include文件中的类,不需要保存定义源码。 271 return; 272 } 273 for (let i = 0; i < dependSrcList.length; ++i) { 274 if (dependSrcList[i].name === classInfo.name) { 275 // 该class的定义源码已经保存过了。 276 return; 277 } 278 } 279 280 let srcObj = {}; 281 srcObj.name = classInfo.name; 282 let className = classInfo.declaration_method + ' ' + classInfo.name; 283 284 // 从.h源码中获取该class定义的源码段 285 srcObj.srcCode = getClassSrc(className, rootHFileSrc); 286 if (srcObj.srcCode !== null && srcObj.srcCode !== undefined) { 287 dependSrcList.push(srcObj); 288 } 289} 290 291/** 292 * 创建class对象序列化/反序列化代码数据结构 293 * @param classInfo class类信息 294 */ 295function createMarshallInfo(classInfo) { 296 saveClassSrc(classInfo); 297 let newMarshall = new MarshallInfo(classInfo.name); 298 let objName = classInfo.name.toLowerCase(); 299 newMarshall.marshallFuncName = 'marshalling' + classInfo.name; 300 newMarshall.unmarshallFuncName = 'unmarshalling' + classInfo.name; 301 // 为了marshall方法的入参能同时支持左值引用marshall(xx.obj)和右值引用marshall(xx.getObj()),这里采用万能引用模板来实现 302 newMarshall.marshallFuncH = replaceAll( 303 '\ntemplate<typename T> // T should be [className]& or [className]&&', '[className]', classInfo.name); 304 newMarshall.marshallFuncH += 305 '\n%s bool %s(MessageParcel& data, T&& %s) {[publicMarshall][privateMarshall]\n return true;\n}\n' 306 .format('__attribute__((unused)) static', newMarshall.marshallFuncName, objName); 307 newMarshall.unmarshallFuncH = 308 '\n%s bool %s(MessageParcel& data, %s& %s) {[publicUnmarshall][privateUnmarshall]\n return true;\n}\n' 309 .format('__attribute__((unused)) static', newMarshall.unmarshallFuncName, classInfo.name, objName); 310 311 let marshallInfo = { 312 'className': classInfo.name, 313 'marshallFuncs': newMarshall 314 }; 315 // 这里必须先将class放入处理列表中,以免后续的属性代码生成过程中再次遇到该class类型造成无限循环嵌套。 316 ProcessingClassList.push(marshallInfo); 317 318 // 继续生成属性代码 319 publicPropMashall('data', objName, classInfo, newMarshall); 320 privatePropMashall('data', objName, classInfo, newMarshall); 321 322 marshallFuncList.push(marshallInfo); 323 return newMarshall; 324} 325 326/** 327 * 生成class对象转换remote消息buffer(parcel data)的代码段 328 * @param objName 待写入的class对象名 329 * @param parcelName 写入目标(parcel data)变量的名称 330 * @param marshallInfo class对应的打包函数(没有为null) 331 * @param classInfo class结构信息 332 */ 333function genClassWriteString(objName, parcelName, marshallInfo, classInfo) { 334 let marshall = marshallInfo; 335 if (!marshall) { 336 // class的序列化代码还未生成,查看是否已在待处理列表中 337 let ProcessingClass = ProcessingClassList.findByName(classInfo.name); 338 if (ProcessingClass === null || ProcessingClass === undefined) { 339 // 待处理列表中没有,则创建该class的读写代码数据。 340 marshall = createMarshallInfo(classInfo); 341 } else { 342 // 待处理列表中存在(说明该class已经在递归生成代码的执行路径中),直接使用即将生成的marshalling方法名 343 marshall = ProcessingClass.marshallFuncs; 344 } 345 } 346 return '%s(%s, %s);'.format(marshall.marshallFuncName, parcelName, objName); 347} 348 349/** 350 * 生成从remote消息buffer(parcel data)中读取class对象的代码段 351 * @param destObj 待读取的class对象信息 352 * @param parcelName 待读取的(parcel data)变量的名称 353 * @param marshallInfo class对应的打包函数(没有为null) 354 * @param classInfo class结构信息 355 */ 356function genClassReadString(destObj, parcelName, marshallInfo, classInfo) { 357 let marshall = marshallInfo; 358 if (!marshall) { 359 marshall = createMarshallInfo(classInfo); 360 } 361 let readStr = ''; 362 if (destObj.setFunc) { // 有set方法的是私有成员,需要生成set代码 363 let className = destObj.type; 364 readStr = '%s tmp%s;\n %s(%s, tmp%s);\n %s(tmp%s);'.format(className, className, 365 marshall.unmarshallFuncName, parcelName, className, destObj.setFunc, className); 366 } else { 367 readStr = '%s(%s, %s);'.format(marshall.unmarshallFuncName, parcelName, destObj.name); 368 } 369 return readStr; 370} 371 372/** 373 * 生成vector集合写入remote消息buffer(parcel data)的代码段 374 * 375 * @param vectorName 待写入的vector变量名 376 * @param parcelName 写入目标(parcel data)变量的名称 377 * @param vecType vector变量类型 378 * @param matchs vector类型的正则匹配结果 379 * @returns 生成的vector变量序列化打包代码段 380 */ 381function genVectorWrite(vectorName, parcelName, vecType, matchs) { 382 let rawType = re.getReg(vecType, matchs.regs[2]); 383 let parcelType = getParcelType(rawType); 384 let wFunc = VECTOR_W_MAP.get(parcelType); 385 if (!wFunc) { 386 NapiLog.logError('Unsupport writing with type: ' + vecType); 387 return ''; 388 } 389 return '%s.%s(%s);'.format(parcelName, wFunc, vectorName); 390} 391 392/** 393 * 生成c参数写入remote消息buffer(parcel data)的代码段 394 * @param srcName 待写入的c变量名 395 * @param parcelName 写入目标(parcel data)变量的名称 396 * @param vType c变量类型 397 * @returns 生成的代码段 398 */ 399function genWrite(srcName, parcelName, vType) { 400 let matchs = re.match('(std::)?vector<([\x21-\x7e]+)[ ]?>', vType); 401 if (matchs) { 402 // vector类型变量包装成parcel data 403 return genVectorWrite(srcName, parcelName, vType, matchs); 404 } 405 406 let parcelType = getParcelType(vType); 407 let wFunc = DATA_W_MAP.get(parcelType); 408 if (!wFunc) { 409 let result = findClassGenInfo(vType); 410 if (!result[0] && !result[1]) { 411 NapiLog.logError('Unsupport writing with type: ' + vType); 412 return ''; 413 } 414 415 // class与struct类型变量包装成parcel data 416 return genClassWriteString(srcName, parcelName, result[0], result[1]); 417 } 418 419 // 基本类型变量包装成parcel data 420 return '%s.%s(%s);'.format(parcelName, wFunc, srcName); 421} 422 423/** 424 * 生成从remote消息buffer(parcel data)中读取vector集合的代码段 425 * 426 * @param parcelName 待读取的消息buffer(parcel data)变量的名称 427 * @param vectorName 待写入的vector变量名 428 * @param vecType vector变量类型 429 * @param matchs vector类型的正则匹配结果 430 * @returns 生成的vector变量反序列化读取码段 431 */ 432function genVectorRead(parcelName, vectorName, vecType, matchs) { 433 let rawType = re.getReg(vecType, matchs.regs[2]); 434 let parcelType = getParcelType(rawType); 435 let rFunc = VECTOR_R_MAP.get(parcelType); 436 if (!rFunc) { 437 NapiLog.logError('Unsupport reading with type: ' + vecType); 438 return ''; 439 } 440 return '%s.%s(&(%s));'.format(parcelName, rFunc, vectorName); 441} 442 443/** 444 * 生成从remote消息buffer(parcel data)读取c参数的代码段 445 * @param parcelName 待读取的parcel data变量名称 446 * @param destObj 读取出的内容写入的c变量信息 447 * @returns 生成的代码段 448 */ 449function genRead(parcelName, destObj) { 450 let matchs = re.match('(std::)?vector<([\x21-\x7e]+)[ ]?>', destObj.type); 451 if (matchs) { 452 // 从parcel data中读取vector类型变量 453 return genVectorRead(parcelName, destObj.name, destObj.type, matchs); 454 } 455 456 let parcelType = getParcelType(destObj.type); 457 let rFunc = DATA_R_MAP.get(parcelType); 458 if (!rFunc) { 459 let result = findClassGenInfo(destObj.type); 460 if (!result[0] && !result[1]) { 461 NapiLog.logError('Unsupport reading with type: ' + destObj.type); 462 return ''; 463 } 464 465 // 从parcel data中读取class与struct类型变量 466 return genClassReadString(destObj, parcelName, result[0], result[1]); 467 } 468 469 // 从parcel data中读取基本类型变量 470 let result = destObj.setFunc ? '%s(%s.%s());'.format(destObj.setFunc, parcelName, rFunc) 471 : '%s = %s.%s();'.format(destObj.name, parcelName, rFunc); 472 return result; 473} 474 475function genProxyFunc(funcInfo, className, paramStr) { 476 let proxyFunc = replaceAll(proxyFuncTemplate, '[className]', className); 477 proxyFunc = replaceAll(proxyFunc, '[funcName]', funcInfo.name); 478 proxyFunc = replaceAll(proxyFunc, '[params]', paramStr); 479 proxyFunc = replaceAll(proxyFunc, '[retType]', funcInfo.retType); 480 proxyFunc = replaceAll(proxyFunc, '[funcEnum]', funcInfo.funcEnum); 481 482 // 入参处理 483 let writeDataStr = ''; 484 let tab = getTab(1); 485 for (let i = 0; i < funcInfo.params.length; ++i) { 486 let param = funcInfo.params[i]; 487 writeDataStr += (i === 0) ? '' : '\n' + tab; 488 writeDataStr += genWrite(param.name, 'data', param.type); 489 } 490 proxyFunc = replaceAll(proxyFunc, '[writeData]', writeDataStr); 491 492 // 返回值处理 493 let readReplyStr = ''; 494 if (funcInfo.retType !== 'void') { 495 readReplyStr = '%s result;'.format(funcInfo.retType); 496 let destObj = { 497 'name': 'result', 498 'setFunc': null, 499 'type': funcInfo.retType 500 }; 501 readReplyStr += '\n' + tab + genRead('reply', destObj); 502 readReplyStr += '\n' + tab + 'return result;'; 503 } 504 proxyFunc = replaceAll(proxyFunc, '[readReply]', readReplyStr); 505 506 return proxyFunc; 507} 508 509function genStubInnerFunc(funcInfo, className) { 510 let innerFunc = replaceAll(stubInnerFuncTemplate, '[className]', className); 511 innerFunc = replaceAll(innerFunc, '[funcName]', funcInfo.name); 512 513 // 入参处理 514 let readDataStr = ''; // 生成服务端读取客户端传参的代码段 515 let tab = getTab(1); 516 let innerParamStr = ''; // 调用业务方法时传入的入参列表 517 for (let i = 0; i < funcInfo.params.length; ++i) { 518 let param = funcInfo.params[i]; 519 let innerParamName = param.name + 'Val'; 520 if (i > 0) { 521 readDataStr += '\n' + tab; 522 innerParamStr += ' ,'; 523 } 524 525 //将remote请求中的参数值读取到内部参数变量中 526 readDataStr += '%s %s;'.format(param.type, innerParamName); // 定义内部参数变量 527 let destObj = { 528 'name': param.name + 'Val', 529 'setFunc': null, 530 'type': param.type 531 }; 532 readDataStr += '\n' + tab + genRead('data', destObj); 533 innerParamStr += innerParamName; 534 } 535 innerFunc = replaceAll(innerFunc, '[readData]', readDataStr); 536 537 // 调用service的实际业务逻辑实现方法 538 let writeReplyStr = ''; // 生成调用服务端实现并返回结果的代码段 539 if (funcInfo.retType === 'void') { 540 writeReplyStr += '%s(%s); // call business implementation'.format(funcInfo.name, innerParamStr); 541 writeReplyStr += '\n' + tab + 'reply.WriteInt32(retCode);'; 542 } else { 543 writeReplyStr += '%s retVal = %s(%s); // call business implementation'.format( 544 funcInfo.retType, funcInfo.name, innerParamStr); 545 writeReplyStr += '\n' + tab + 'reply.WriteInt32(retCode);'; 546 writeReplyStr += '\n' + tab + genWrite('retVal', 'reply', funcInfo.retType); 547 } 548 innerFunc = replaceAll(innerFunc, '[writeReply]', writeReplyStr); 549 return innerFunc; 550} 551 552function genServiceFunc(funcInfo, className, paramStr) { 553 let serviceFunc = replaceAll(serviceFuncImplTemplate, '[retType]', funcInfo.retType); 554 // 根据类型初始化返回值 555 let initRetvalue; 556 let paramsName = ''; 557 if (numericTypes.includes(funcInfo.retType)) { 558 // 数值类型初始化为0 559 initRetvalue = '0'; 560 } else if (boolType.includes(funcInfo.retType)) { 561 // 布尔类型初始化为true 562 initRetvalue = 'true'; 563 } else if (charType.includes(funcInfo.retType)) { 564 // 字符类型初始化为空字符'' 565 initRetvalue = ''; 566 } else { 567 // 对于其他类型,这里可以根据需要进行处理 568 initRetvalue = 'nullptr'; // 假设是指针类型或其他复杂类型 569 } 570 571 for (let n = 0; n < funcInfo.params.length; ++n) { 572 if (numericTypes.includes(funcInfo.params[n].type)) { 573 // 数值添加 574 paramsName += (n === 0) ? '' : '+ '; 575 paramsName += funcInfo.params[n].name + ' '; 576 } else { 577 // 对于其他类型,这里可以根据需要进行处理 578 } 579 } 580 serviceFunc = replaceAll(serviceFunc, '[initRetvalue]', initRetvalue); 581 serviceFunc = replaceAll(serviceFunc, '[className]', className); 582 serviceFunc = replaceAll(serviceFunc, '[funcName]', funcInfo.name); 583 serviceFunc = replaceAll(serviceFunc, '[params]', paramStr); 584 serviceFunc = replaceAll(serviceFunc, '[paramsName]', paramsName); 585 return serviceFunc; 586} 587 588function genFunctions(classInfo, files) { 589 let res = genFunctionCode(classInfo); 590 files.iServiceH = replaceAll(files.iServiceH, '[funcEnum]', res.funcEnumStr); 591 files.iServiceH = replaceAll(files.iServiceH, '[functions]', res.iServiceFuncH); 592 files.proxyH = replaceAll(files.proxyH, '[functions]', res.proxyFuncH); 593 files.stubH = replaceAll(files.stubH, '[innerFuncDef]', res.stubInnerFuncH); 594 files.serviceH = replaceAll(files.serviceH, '[functions]', res.proxyFuncH); 595 files.proxyCpp = replaceAll(files.proxyCpp, '[remoteFuncImpl]', res.proxyFuncCpp); 596 files.stubCpp = replaceAll(files.stubCpp, '[innerFuncMap]', res.stubInnerFuncMap); 597 files.stubCpp = replaceAll(files.stubCpp, '[innerFuncImpl]', res.stubInnerFuncCpp); 598 files.serviceCpp = replaceAll(files.serviceCpp, '[serviceFuncImpl]', res.serviceFuncCpp); 599 files.clientCpp = replaceAll(files.clientCpp, '[clientFuncInvoke]', res.clientFuncCpp); 600 files.clientCpp = replaceAll(files.clientCpp, '[clientFuncParaMessage]', res.clientFuncMessage); 601 files.clientCpp = replaceAll(files.clientCpp, '[clientFuncParaLogMessage]', res.clientFuncLogMessage); 602} 603 604function genFilesByTemplate(upperServiceName, lowServiceName, rootInfo) { 605 let files = {}; 606 // 按模板生成.h和.cpp文件内容框架 607 files.iServiceH = replaceAll(iServiceHTemplate, '[marcoName]', upperServiceName); 608 files.proxyH = replaceAll(proxyHTemplate, '[marcoName]', upperServiceName); 609 files.stubH = replaceAll(stubHTemplate, '[marcoName]', upperServiceName); 610 files.serviceH = replaceAll(serviceHTemplate, '[marcoName]', upperServiceName); 611 files.proxyCpp = proxyCppTemplate; 612 files.stubCpp = stubCppTemplate; 613 files.serviceCpp = replaceAll(serviceCppTemplate, '[marcoName]', upperServiceName); 614 files.clientCpp = replaceAll(clientCppTemplate, '[marcoName]', upperServiceName); 615 files.iServiceCpp = iServiceCppTemplate; 616 617 // 按模板生成资源配置文件内容框架 618 if (rootInfo.versionTag === '4.1') { 619 files.buildGn = replaceAll(buildGnTemplate41, '[lowServiceName]', lowServiceName); 620 files.bundleJson = replaceAll(bundleJsonTemplate41, '[lowServiceName]', lowServiceName); 621 files.profileJson = replaceAll(profileJsonTemplate, '[lowServiceName]', lowServiceName); 622 files.profileJson = replaceAll(files.profileJson, '[serviceId]', rootInfo.serviceId); 623 files.profileGn = replaceAll(profileGnTemplate41, '[lowServiceName]', lowServiceName); 624 files.serviceCfg = replaceAll(serviceCfgTemplate41, '[lowServiceName]', lowServiceName); 625 } else { 626 files.buildGn = replaceAll(buildGnTemplate, '[lowServiceName]', lowServiceName); 627 files.bundleJson = replaceAll(bundleJsonTemplate, '[lowServiceName]', lowServiceName); 628 files.profileXml = replaceAll(profileXmlTemplate, '[lowServiceName]', lowServiceName); 629 files.profileXml = replaceAll(files.profileXml, '[serviceId]', rootInfo.serviceId); 630 files.profileGn = replaceAll(profileGnTemplate, '[lowServiceName]', lowServiceName); 631 files.serviceCfg = replaceAll(serviceCfgTemplate, '[lowServiceName]', lowServiceName); 632 } 633 files.buildGn = replaceAll(files.buildGn, '[stubCppFile]', fileContent.stubCppFile.name); 634 files.buildGn = replaceAll(files.buildGn, '[serviceCppFile]', fileContent.serviceCppFile.name); 635 files.buildGn = replaceAll(files.buildGn, '[proxyCppFile]', fileContent.proxyCppFile.name); 636 files.buildGn = replaceAll(files.buildGn, '[clientCppFile]', fileContent.clientCppFile.name); 637 files.buildGn = replaceAll(files.buildGn, '[iServiceCppFile]', fileContent.iServiceCppFile.name); 638 files.profileGn = replaceAll(files.profileGn, '[serviceId]', rootInfo.serviceId); 639 files.serviceGnCfg = replaceAll(serviceCfgGnTemplate, '[lowServiceName]', lowServiceName); 640 return files; 641} 642 643function replaceClassName(files, classInfo) { 644 files.iServiceH = replaceAll(files.iServiceH, '[className]', classInfo.name); 645 files.proxyH = replaceAll(files.proxyH, '[className]', classInfo.name); 646 files.stubH = replaceAll(files.stubH, '[className]', classInfo.name); 647 files.serviceH = replaceAll(files.serviceH, '[className]', classInfo.name); 648 files.proxyCpp = replaceAll(files.proxyCpp, '[className]', classInfo.name); 649 files.stubCpp = replaceAll(files.stubCpp, '[className]', classInfo.name); 650 files.serviceCpp = replaceAll(files.serviceCpp, '[className]', classInfo.name); 651 files.clientCpp = replaceAll(files.clientCpp, '[className]', classInfo.name); 652} 653 654function replaceServiceName(files, rootInfo) { 655 files.iServiceH = replaceAll(files.iServiceH, '[serviceName]', rootInfo.serviceName); 656 files.proxyH = replaceAll(files.proxyH, '[serviceName]', rootInfo.serviceName); 657 files.stubH = replaceAll(files.stubH, '[serviceName]', rootInfo.serviceName); 658 files.serviceH = replaceAll(files.serviceH, '[serviceName]', rootInfo.serviceName); 659 files.proxyCpp = replaceAll(files.proxyCpp, '[serviceName]', rootInfo.serviceName); 660 files.stubCpp = replaceAll(files.stubCpp, '[serviceName]', rootInfo.serviceName); 661 files.serviceCpp = replaceAll(files.serviceCpp, '[serviceName]', rootInfo.serviceName); 662 files.clientCpp = replaceAll(files.clientCpp, '[serviceName]', rootInfo.serviceName); 663} 664 665function replaceIncludes(files, rootInfo) { 666 files.iServiceH = replaceAll(files.iServiceH, '[includes]', getIncludeStr(rootInfo.includes)); 667 files.proxyH = replaceAll(files.proxyH, '[iServiceHInclude]', fileContent.iServiceHFile.name); 668 files.stubH = replaceAll(files.stubH, '[iServiceHInclude]', fileContent.iServiceHFile.name); 669 files.serviceH = replaceAll(files.serviceH, '[stubHInclude]', fileContent.stubHFile.name); 670 files.proxyCpp = replaceAll(files.proxyCpp, '[proxyHInclude]', fileContent.proxyHFile.name); 671 files.stubCpp = replaceAll(files.stubCpp, '[stubHInclude]', fileContent.stubHFile.name); 672 files.serviceCpp = replaceAll(files.serviceCpp, '[serviceHInclude]', fileContent.serviceHFile.name); 673 files.clientCpp = replaceAll(files.clientCpp, '[proxyHInclude]', fileContent.proxyHFile.name); 674 files.iServiceCpp = replaceAll(files.iServiceCpp, '[iServiceHInclude]', fileContent.iServiceHFile.name); 675} 676 677function replaceUsing(files, rootInfo) { 678 files.iServiceH = replaceAll(files.iServiceH, '[using]', getUsingStr(rootInfo.using)); 679} 680 681function genFileNames(lowServiceName, rootInfo) { 682 fileContent.iServiceHFile.name = 'i_%s_service.h'.format(lowServiceName); 683 fileContent.proxyHFile.name = '%s_service_proxy.h'.format(lowServiceName); 684 fileContent.stubHFile.name = '%s_service_stub.h'.format(lowServiceName); 685 fileContent.serviceHFile.name = '%s_service.h'.format(lowServiceName); 686 fileContent.proxyCppFile.name = '%s_service_proxy.cpp'.format(lowServiceName); 687 fileContent.stubCppFile.name = '%s_service_stub.cpp'.format(lowServiceName); 688 fileContent.serviceCppFile.name = '%s_service.cpp'.format(lowServiceName); 689 fileContent.clientCppFile.name = '%s_client.cpp'.format(lowServiceName); 690 fileContent.buildGnFile.name = 'BUILD.gn'; 691 fileContent.bundleJsonFile.name = 'bundle.json'; 692 fileContent.profileGnFile.name = 'BUILD.gn'; 693 if (rootInfo.versionTag === '4.1') { 694 fileContent.profileJsonFile.name = rootInfo.serviceId + '.json'; 695 } else { 696 fileContent.profileXmlFile.name = rootInfo.serviceId + '.xml'; 697 } 698 fileContent.serviceCfgFile.name = '%s_service.cfg'.format(lowServiceName); 699 fileContent.serviceCfgGnFile.name = 'BUILD.gn'; 700 fileContent.iServiceCppFile.name = 'i_%s_service.cpp'.format(lowServiceName); 701} 702 703function genFunctionCode(classInfo) { 704 let funcList = classInfo.functions; 705 let genResult = {}; 706 genResult.funcEnumStr = ''; 707 genResult.iServiceFuncH = ''; //i_service.h 方法定义 708 genResult.proxyFuncH = ''; //proxy.h 方法定义 709 genResult.stubInnerFuncH = ''; // stub.h 的inner方法定义 710 genResult.proxyFuncCpp = ''; //proxy.cpp 方法实现 711 genResult.stubInnerFuncMap = ''; // stub.cpp 的inner方法映射表 712 genResult.stubInnerFuncCpp = ''; // stub.cpp 的inner方法实现 713 genResult.serviceFuncCpp = ''; // service.cpp的方法实现 714 genResult.clientFuncCpp = ''; // client.cpp 的inner方法定义 715 genResult.clientFuncParaLen = ''; // client.cpp中参数的个数 716 genResult.clientFuncMessage = ''; // client.cpp中参数的初始化 717 genResult.clientFuncLogMessage = ''; //client.cpp 中的打印信息 718 let enumTab = getTab(2); 719 let funcTab = getTab(1); 720 for (let i = 0; i < funcList.length; ++i) { 721 funcList[i].funcEnum = funcList[i].name.toUpperCase(); // remote方法的枚举值 722 genResult.funcEnumStr += (i === 0) ? '' : ',\n' + enumTab; 723 genResult.funcEnumStr += funcList[i].funcEnum; 724 725 let paramStr = getFuncParamStr(funcList[i].params); 726 let clientParamStr = getClientFuncParamStr(funcList[i].params); 727 genResult.iServiceFuncH += (i === 0) ? '' : '\n' + funcTab; 728 genResult.iServiceFuncH += 'virtual %s %s(%s) = 0;'.format(funcList[i].retType, funcList[i].name, paramStr); 729 730 genResult.proxyFuncH += (i === 0) ? '' : '\n' + funcTab; 731 genResult.proxyFuncH += '%s %s(%s) override;'.format(funcList[i].retType, funcList[i].name, paramStr); 732 733 genResult.stubInnerFuncH += (i === 0) ? '' : '\n' + funcTab; 734 genResult.stubInnerFuncH += 735 'ErrCode %sInner(MessageParcel &data, MessageParcel &reply);'.format(funcList[i].name); 736 737 genResult.proxyFuncCpp += genProxyFunc(funcList[i], classInfo.name, paramStr); 738 739 genResult.stubInnerFuncMap += (i === 0) ? '' : '\n' + funcTab; 740 genResult.stubInnerFuncMap += 'innerFuncs_[%s] = &%sStub::%sInner;'.format( 741 funcList[i].funcEnum, classInfo.name, funcList[i].name); 742 743 genResult.stubInnerFuncCpp += genStubInnerFunc(funcList[i], classInfo.name); 744 genResult.serviceFuncCpp += genServiceFunc(funcList[i], classInfo.name, paramStr); 745 746 genResult.clientFuncParaLen += '%s'.format(funcList[i].params.length); 747 748 genResult.clientFuncMessage += genClientMsgFunc(funcList[i]); 749 genResult.clientFuncLogMessage += genClientLogFunc(funcList[i]); 750 genResult.clientFuncCpp += (i === 0) ? '' : '\n' + funcTab; 751 genResult.clientFuncCpp += 'res = proxy->%s(%s);'.format(funcList[i].name, clientParamStr); 752 } 753 return genResult; 754} 755 756function genMarshallFuncs(files) { 757 let marshallFuncH = ''; 758 for (let i = 0; i < marshallFuncList.length; ++i) { 759 marshallFuncH += marshallFuncList[i].marshallFuncs.marshallFuncH; 760 marshallFuncH += marshallFuncList[i].marshallFuncs.unmarshallFuncH; 761 } 762 files.iServiceH = files.iServiceH.replace('[marshallFunctions]', marshallFuncH); 763} 764 765function genDependClasses(files) { 766 let dependSrc = ''; 767 for (let i = 0; i < dependSrcList.length; ++i) { 768 dependSrc += dependSrcList[i].srcCode + ';\n\n'; 769 } 770 files.iServiceH = files.iServiceH.replace('[dependClasses]', dependSrc); 771} 772 773function doGenerate(rootInfo) { 774 rootHFileSrc = rootInfo.rawContent; 775 let lowServiceName = rootInfo.serviceName.toLowerCase(); 776 let upperServiceName = rootInfo.serviceName.toUpperCase(); 777 778 // 生成文件名 779 genFileNames(lowServiceName, rootInfo); 780 781 // 按模板生成.h和.cpp文件内容框架 782 let files = genFilesByTemplate(upperServiceName, lowServiceName, rootInfo); 783 784 // 替换文件includes 785 replaceIncludes(files, rootInfo); 786 787 // 替换文件using 788 replaceUsing(files, rootInfo); 789 790 // 替换namespace 791 replaceServiceName(files, rootInfo); 792 793 // 替换类名 794 let classInfo = rootInfo.class[0]; 795 replaceClassName(files, classInfo); 796 797 // 生成函数定义与实现 798 genFunctions(classInfo, files); 799 800 // 生成复合对象的序列化反序列化方法 801 genMarshallFuncs(files); 802 803 // 生成依赖的class定义代码 804 genDependClasses(files); 805 806 // 文件内容汇总 807 fileContent.iServiceHFile.content = files.iServiceH; 808 fileContent.proxyHFile.content = files.proxyH; 809 fileContent.stubHFile.content = files.stubH; 810 fileContent.serviceHFile.content = files.serviceH; 811 fileContent.proxyCppFile.content = files.proxyCpp; 812 fileContent.stubCppFile.content = files.stubCpp; 813 fileContent.serviceCppFile.content = files.serviceCpp; 814 fileContent.clientCppFile.content = files.clientCpp; 815 fileContent.buildGnFile.content = files.buildGn; 816 fileContent.bundleJsonFile.content = files.bundleJson; 817 fileContent.profileGnFile.content = files.profileGn; 818 if (rootInfo.versionTag === '4.1') { 819 fileContent.profileJsonFile.content = files.profileJson; 820 } else { 821 fileContent.profileXmlFile.content = files.profileXml; 822 } 823 fileContent.serviceCfgFile.content = files.serviceCfg; 824 fileContent.serviceCfgGnFile.content = files.serviceGnCfg; 825 fileContent.iServiceCppFile.content = files.iServiceCpp; 826 return fileContent; 827} 828 829module.exports = { 830 doGenerate 831};