123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- const fs = require('fs');
- const path = require('fire-path');
- const util = require('util');
- const codeBodyFormat =
- `/**
- * 此文件为协议自动生成文件,不可手动编辑
- * 如协议有变动,只需执行【扩展/proto/create-message】即可
- */
- // proto插件proto-processor.js 12行可以修改
- import { CMessageBase, MessageRegister } from "./network/Message";
- /**协议文件 */
- export let ProtoFile = [
- %s];
- %s
- `;
- const fileListFormat =
- ` "%s",
- `;
- const classFormat =
- `
- /**%s */
- export class %s extends CMessageBase {
- constructor (databuff = null) {
- super();
- this.protocolType = %d;
- this.messageName = '%s';
- this.initMsgObj(databuff);
- }%s
- }
- MessageRegister.registerClass(%d, %s);
- `;
- const accessFormat =
- `
- /**%s */
- set %s (param : %s) {
- this.msgObj.%s = param;
- }
- get %s () : %s {
- return this.msgObj.%s;
- }`;
- // proto类型转换跟js类型的映射关系
- const TYPE = {
- "int32": "number",
- "int64": "number",
- "string": "string",
- "bool": "boolean",
- }
- // proto关键字
- const KEY_WORD = ['required', 'optional', 'repeated'];
- /**去除所有空格 */
- var trimAll = function (str) {
- return str.replace(/\s|\xA0/g, "");
- }
- var formatNum = function (str) {
- str = str.trim();
- return parseInt(str);
- }
- /**首字母大写 */
- var firstCharUpper = function (str) {
- str = str.substring(0, 1).toUpperCase() + str.substring(1);
- return str;
- }
- module.exports = {
- outputData: {},
- /**
- * 传入文件列表,返回最终的数据
- * @param {*} fileDataList
- */
- deal(fileDataList) {
- this.outputData = {};
- for (let i = 0; i < fileDataList.length; i++) {
- let data = fileDataList[i];
- if (!data.isUse) {
- continue;
- }
- let fileName = path.basenameNoExt(data.name);
- let str = fs.readFileSync(data.fullPath, 'utf-8').toString();
- this._dealProtoFile(fileName, str);
- }
- return this._formatOutput();
- },
- _dealProtoFile(fileName, str) {
- this.outputData[fileName] = {};
- let messageName;
- let bDealProperty = false;
- let tProperty = {};
- // 每个message之间用'}'分割
- let tMsg = str.trim().split('}');
- let self = this;
- tMsg.forEach(function (msg, mindex) {
- // 该段消息体如果没有 comment 或者 msgtype 标注,则不处理
- if (msg.indexOf('//@comment') == -1 && msg.indexOf('//@msgtype') == -1) {
- return;
- }
- msg.split('\n').forEach(function (v, index) {
- // 处理@comment
- if (v.indexOf('//@comment') != -1) {
- let tCommentRet = self._dealComment(v);
- let comment = tCommentRet[0];
- let protocolType = tCommentRet[1];
- messageName = tCommentRet[2];
- if (messageName && !self.outputData[fileName].hasOwnProperty(messageName)) {
- self.outputData[fileName][messageName] = {}
- }
- self.outputData[fileName][messageName] = {
- "comment": comment,
- "protocolType": protocolType,
- "messageName": messageName,
- "property": [],
- }
- return;
- }
- // 处理@msgtype
- if (v.indexOf('//@msgtype') != -1) {
- let tCommentRet = self._dealMsgType(v);
- let comment = tCommentRet[0];
- messageName = tCommentRet[1];
- if (messageName && !self.outputData[fileName].hasOwnProperty(messageName)) {
- self.outputData[fileName][messageName] = {}
- }
- self.outputData[fileName][messageName] = {
- "comment": comment,
- "protocolType": -1,
- "messageName": messageName,
- "property": [],
- }
- return;
- }
- // 只在message和}之间才能解析属性
- if (!bDealProperty && v.indexOf('message') != -1) {
- bDealProperty = true;
- tProperty = {};
- return;
- }
- if (bDealProperty && v.indexOf('}') != -1) {
- bDealProperty = false;
- return
- }
- if (!bDealProperty) {
- return;
- }
- // 处理属性注释
- if (v.indexOf("//") != -1) {
- let comment = v.trim().substring(2).trim();
- tProperty["comment"] = comment;
- return;
- }
- // 处理属性
- if (v.indexOf('=') != -1) {
- let info = self._getProperty(v);
- let type = info[0];
- let name = info[1];
- tProperty["type"] = type;
- tProperty["name"] = name;
- self.outputData[fileName][messageName]["property"].push(tProperty);
- tProperty = {}
- return;
- }
- });
- });
- },
- // 处理comment注释获得注释、协议号、消息名
- _dealComment(str) {
- str = trimAll(str);
- let pattern = /@comment\(\"(\S*)\",(\S*),\"(\S*)\"\)/;
- let values = str.match(pattern);
- let comment = values[1];
- let protocolType = formatNum(values[2]);
- let messageName = values[3];
- return [comment, protocolType, messageName];
- },
- // 处理property获得注释、消息名
- _dealMsgType(str) {
- str = trimAll(str);
- let pattern = /@msgtype\(\"(\S*)\",\"(\S*)\"\)/;
- let values = str.match(pattern);
- let comment = values[1];
- let messageName = values[2];
- return [comment, messageName];
- },
- // 处理属性,格式:关键字(可选) 类型 名字 = 索引;
- _getProperty(str) {
- let t = str.trim().split(/\s+/);
- // 第一个为关键字,忽略
- if (KEY_WORD.indexOf(t[0]) != -1) {
- t.splice(0, 1);
- }
- let type = t[0];
- if (TYPE[type]) {
- type = TYPE[type];
- }
- let name = t[1];
- // map类型解析
- if (type.indexOf('map<') != -1) {
- let startIdx = type.indexOf('<');
- let endIdx = type.indexOf('>');
- type = type.substring(startIdx + 1, endIdx);
- let arr = type.split(',');
- type = 'map<';
- for (let i = 0; i < arr.length; i++) {
- if (TYPE[arr[i]]) {
- type += TYPE[arr[i]];
- } else {
- type += arr[i];
- }
- if (i != arr.length - 1) {
- type += ',';
- }
- }
- type += '>';
- type = firstCharUpper(type);
- }
- // 如果是repeated则为数组类型
- if (str.indexOf("repeated") != -1) {
- type = util.format("Array<%s>", type);
- }
- return [type, name];
- },
- _formatOutput() {
- let exportFileStr = '';
- let exportClassStr = '';
- for (let fileName in this.outputData) {
- exportFileStr += util.format(fileListFormat, fileName);
- let fileInfo = this.outputData[fileName];
- for (let msgName in fileInfo) {
- let msgInfo = fileInfo[msgName];
- let accessStr = "";
- for (let idx in msgInfo.property) {
- let info = msgInfo.property[idx];
- accessStr += util.format(accessFormat, info.comment, info.name, info.type, info.name, info.name, info.type, info.name);
- }
- exportClassStr += util.format(classFormat, msgInfo.comment, msgInfo.messageName, msgInfo.protocolType, msgInfo.messageName, accessStr, msgInfo.protocolType, msgInfo.messageName);
- }
- }
- let outputStr = util.format(codeBodyFormat, exportFileStr, exportClassStr);
- return outputStr;
- }
- }
|