• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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};