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