perf[protocol]: 优化生成的生成协议文件的注释

This commit is contained in:
godotg committed 2022-07-29 22:16:47 +08:00
1 parent 59e149181e
commit 1dbae44e59
12 files changed
+231 -281

No files matched your search

@@ -1,102 +0,0 @@
/*
* Copyright (C) 2020 The zfoo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.generate;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.registration.IProtocolRegistration;
import com.zfoo.protocol.registration.ProtocolRegistration;
import com.zfoo.protocol.registration.anno.Note;
import com.zfoo.protocol.registration.anno.Protocol;
import com.zfoo.protocol.util.AssertionUtils;
import com.zfoo.protocol.util.StringUtils;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 生成协议的时候,协议的文档注释和字段注释会使用这个类
*
* @author jaysunxiao
* @version 3.0
*/
public abstract class GenerateProtocolDocument {
// 临时变量,启动完成就会销毁,协议的文档,外层map的key为协议类;pair的key为总的注释,value为属性字段的注释,value表示的map的key为属性名称
// 比如在Test中的ComplexObject生成的pari是如下格式
/**
* key docTitle:
* // 复杂的对象
* // 包括了各种复杂的结构,数组,List,Set,Map
* //
* // @author jaysunxiao
* // @version 1.0
* <p>
* value aa:
* // byte的包装类型
* // 优先使用基础类型,包装类型会有装箱拆箱
*/
private static Map<Short, Pair<String, Map<String, String>>> protocolDocumentMap = new HashMap<>();
public static void clear() {
protocolDocumentMap.clear();
protocolDocumentMap = null;
}
/**
* 此方法仅在生成协议的时候调用,一旦运行,不能调用
*/
public static Pair<String, Map<String, String>> getProtocolDocument(short protocolId) {
AssertionUtils.notNull(protocolDocumentMap, "[{}]已经初始完成,初始化完成过后不能调用getProtocolDocument", GenerateProtocolDocument.class.getSimpleName());
var protocolDocument = protocolDocumentMap.get(protocolId);
if (protocolDocument == null) {
return new Pair<>(StringUtils.EMPTY, Collections.emptyMap());
}
return protocolDocument;
}
public static void initProtocolDocument(List<IProtocolRegistration> protocolRegistrations) {
AssertionUtils.notNull(protocolDocumentMap, "[{}]已经初始完成,初始化完成过后不能调用initProtocolDocument", GenerateProtocolDocument.class.getSimpleName());
for (var protocolRegistration : protocolRegistrations) {
var protocolClazz = protocolRegistration.protocolConstructor().getDeclaringClass();
var docFieldMap = new HashMap<String, String>();
var docTitle = StringUtils.EMPTY;
var protocolClass = protocolClazz.getDeclaredAnnotation(Protocol.class);
if (protocolClass != null && StringUtils.isNotEmpty(protocolClass.note())) {
var docTitleBuilder = new StringBuilder().append("//").append(protocolClass.note());
docTitle = docTitleBuilder.toString();
}
var registration = (ProtocolRegistration) protocolRegistration;
for (var field : registration.getFields()) {
var noteDescription = field.getDeclaredAnnotation(Note.class);
if (noteDescription == null || StringUtils.isEmpty(noteDescription.value())) {
continue;
}
var docBuilder = new StringBuilder().append("//").append(noteDescription.value());
var fieldName = field.getName();
docFieldMap.put(fieldName, docBuilder.toString());
}
protocolDocumentMap.put(protocolRegistration.protocolId(), new Pair<>(docTitle, docFieldMap));
}
}
}
@@ -97,7 +97,7 @@ public abstract class GenerateProtocolFile {
.collect(Collectors.toList());
// 解析协议的文档注释
GenerateProtocolDocument.initProtocolDocument(allSortedGenerateProtocols);
GenerateProtocolNote.initProtocolNote(allSortedGenerateProtocols);
// 计算协议生成的路径
@@ -0,0 +1,143 @@
/*
* Copyright (C) 2020 The zfoo Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and limitations under the License.
*/
package com.zfoo.protocol.generate;
import com.zfoo.protocol.exception.RunException;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.registration.IProtocolRegistration;
import com.zfoo.protocol.registration.ProtocolRegistration;
import com.zfoo.protocol.registration.anno.Note;
import com.zfoo.protocol.registration.anno.Protocol;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.util.AssertionUtils;
import com.zfoo.protocol.util.StringUtils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 生成协议的时候,协议的文档注释和字段注释会使用这个类
*
* @author jaysunxiao
* @version 3.0
*/
public abstract class GenerateProtocolNote {
// 临时变量,启动完成就会销毁,协议的文档,外层map的key为协议类;pair的key为总的注释,value为属性字段的注释,value表示的map的key为属性名称
// 比如在Test中的ComplexObject生成的pari是如下格式
/**
* key docTitle:
* // 复杂的对象
* // 包括了各种复杂的结构,数组,List,Set,Map
* //
* // @author jaysunxiao
* // @version 1.0
* <p>
* value aa:
* // byte的包装类型
* // 优先使用基础类型,包装类型会有装箱拆箱
*/
private static Map<Short, Pair<String, Map<String, String>>> protocolNoteMap = new HashMap<>();
public static void clear() {
protocolNoteMap.clear();
protocolNoteMap = null;
}
public static String classNote(short protocolId, CodeLanguage language) {
var protocolNote = protocolNoteMap.get(protocolId);
var classNote = protocolNote.getKey();
if (StringUtils.isBlank(classNote)) {
return StringUtils.EMPTY;
}
switch (language) {
case Cpp:
case JavaScript:
case TypeScript:
case CSharp:
case Protobuf:
classNote = StringUtils.format("// {}", classNote);
break;
case Lua:
classNote = StringUtils.format("-- {}", classNote);
break;
case GdScript:
classNote = StringUtils.format("# {}", classNote);
break;
case Enhance:
default:
throw new RunException("无法识别的枚举类型[{}]", language);
}
return classNote;
}
public static String fieldNote(short protocolId, String fieldName, CodeLanguage language) {
var protocolNote = protocolNoteMap.get(protocolId);
var fieldNoteMap = protocolNote.getValue();
var fieldNote = fieldNoteMap.get(fieldName);
if (StringUtils.isBlank(fieldNote)) {
return StringUtils.EMPTY;
}
switch (language) {
case Cpp:
case JavaScript:
case TypeScript:
case CSharp:
case Protobuf:
fieldNote = StringUtils.format("// {}", fieldNote);
break;
case Lua:
fieldNote = StringUtils.format("-- {}", fieldNote);
break;
case GdScript:
fieldNote = StringUtils.format("# {}", fieldNote);
break;
case Enhance:
default:
throw new RunException("无法识别的枚举类型[{}]", language);
}
return fieldNote;
}
public static void initProtocolNote(List<IProtocolRegistration> protocolRegistrations) {
AssertionUtils.notNull(protocolNoteMap, "[{}]已经初始完成,初始化完成过后不能调用initProtocolDocument", GenerateProtocolNote.class.getSimpleName());
for (var protocolRegistration : protocolRegistrations) {
var protocolClazz = protocolRegistration.protocolConstructor().getDeclaringClass();
var classNote = StringUtils.EMPTY;
var protocolClass = protocolClazz.getDeclaredAnnotation(Protocol.class);
if (protocolClass != null && StringUtils.isNotEmpty(protocolClass.note())) {
classNote = StringUtils.trim(protocolClass.note());
}
var fieldNoteMap = new HashMap<String, String>();
var registration = (ProtocolRegistration) protocolRegistration;
for (var field : registration.getFields()) {
var noteDescription = field.getDeclaredAnnotation(Note.class);
if (noteDescription == null || StringUtils.isEmpty(noteDescription.value())) {
continue;
}
var fieldName = field.getName();
var fieldNote = noteDescription.value();
fieldNoteMap.put(fieldName, StringUtils.trim(fieldNote));
}
protocolNoteMap.put(protocolRegistration.protocolId(), new Pair<>(classNote, fieldNoteMap));
}
}
}
@@ -19,8 +19,8 @@ import com.zfoo.protocol.collection.CollectionUtils;
import com.zfoo.protocol.exception.RunException;
import com.zfoo.protocol.exception.UnknownException;
import com.zfoo.protocol.generate.GenerateOperation;
import com.zfoo.protocol.generate.GenerateProtocolDocument;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.generate.GenerateProtocolNote;
import com.zfoo.protocol.generate.GenerateProtocolPath;
import com.zfoo.protocol.registration.anno.Compatible;
import com.zfoo.protocol.registration.anno.Protocol;
@@ -214,7 +214,7 @@ public class ProtocolAnalysis {
return;
}
GenerateProtocolDocument.clear();
GenerateProtocolNote.clear();
GenerateProtocolPath.clear();
GenerateProtocolFile.clear();
GenerateCppUtils.clear();
@@ -16,8 +16,8 @@ package com.zfoo.protocol.serializer.cpp;
import com.zfoo.protocol.IPacket;
import com.zfoo.protocol.collection.CollectionUtils;
import com.zfoo.protocol.generate.GenerateOperation;
import com.zfoo.protocol.generate.GenerateProtocolDocument;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.generate.GenerateProtocolNote;
import com.zfoo.protocol.generate.GenerateProtocolPath;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.registration.IProtocolRegistration;
@@ -25,6 +25,7 @@ import com.zfoo.protocol.registration.ProtocolAnalysis;
import com.zfoo.protocol.registration.ProtocolRegistration;
import com.zfoo.protocol.registration.anno.Compatible;
import com.zfoo.protocol.registration.field.IFieldRegistration;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.enhance.EnhanceObjectProtocolSerializer;
import com.zfoo.protocol.serializer.reflect.*;
import com.zfoo.protocol.util.ClassUtils;
@@ -127,23 +128,21 @@ public abstract class GenerateCppUtils {
var protocolId = registration.protocolId();
var registrationConstructor = registration.getConstructor();
var fieldRegistrations = registration.getFieldRegistrations();
var protocolClazzName = registrationConstructor.getDeclaringClass().getSimpleName();
var protocolTemplate = StringUtils.bytesToString(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("cpp/ProtocolTemplate.h")));
// protocol object
var defineProtocolName = protocolClazzName.toUpperCase();
var includeHeaders = includeSubProtocol(registration);
var docTitle = docTitle(registration);
var classNote = GenerateProtocolNote.classNote(protocolId, CodeLanguage.Cpp);
var fieldDefinition = fieldDefinition(registration);
var valueOfMethod = valueOfMethod(registration);
var operator = operator(registration);
var writeObject = writeObject(registration);
var readObject = readObject(registration);
protocolTemplate = StringUtils.format(protocolTemplate, defineProtocolName, defineProtocolName, protocolOutputRootPath, includeHeaders, docTitle
protocolTemplate = StringUtils.format(protocolTemplate, defineProtocolName, defineProtocolName, protocolOutputRootPath, includeHeaders, classNote
, protocolClazzName, fieldDefinition, protocolClazzName, protocolClazzName, valueOfMethod.getKey(), protocolClazzName
, valueOfMethod.getValue().trim(), protocolId, protocolClazzName, operator.trim(),
protocolClazzName, protocolId, protocolClazzName, writeObject.trim(), protocolClazzName, readObject.trim());
@@ -177,41 +176,26 @@ public abstract class GenerateCppUtils {
return cppBuilder.toString();
}
private static String docTitle(ProtocolRegistration registration) {
var protocolId = registration.getId();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docTitle = protocolDocument.getKey();
var cppBuilder = new StringBuilder();
if (StringUtils.isNotBlank(docTitle)) {
Arrays.stream(docTitle.split(LS)).forEach(it -> cppBuilder.append(TAB).append(it).append(LS));
}
return cppBuilder.toString().trim();
}
private static String fieldDefinition(ProtocolRegistration registration) {
var protocolId = registration.getId();
var fields = registration.getFields();
var fieldRegistrations = registration.getFieldRegistrations();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docFieldMap = protocolDocument.getValue();
var cppBuilder = new StringBuilder();
// 协议的属性生成
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
IFieldRegistration fieldRegistration = fieldRegistrations[i];
var fieldName = field.getName();
var propertyTypeAndName = cppSerializer(fieldRegistration.serializer()).field(field, fieldRegistration);
var propertyType = propertyTypeAndName.getKey();
var propertyName = propertyTypeAndName.getValue();
var propertyFullName = StringUtils.format("{} {};", propertyType, propertyName);
// 生成注释
var doc = docFieldMap.get(propertyName);
if (StringUtils.isNotBlank(doc)) {
Arrays.stream(doc.split(LS)).forEach(it -> cppBuilder.append(TAB + TAB).append(it).append(LS));
var filedNote = GenerateProtocolNote.fieldNote(protocolId, fieldName, CodeLanguage.Cpp);
if (StringUtils.isNotBlank(filedNote)) {
cppBuilder.append(TAB + TAB).append(filedNote).append(LS);
}
cppBuilder.append(TAB + TAB).append(propertyFullName).append(LS);
}
@@ -14,12 +14,13 @@
package com.zfoo.protocol.serializer.csharp;
import com.zfoo.protocol.generate.GenerateOperation;
import com.zfoo.protocol.generate.GenerateProtocolDocument;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.generate.GenerateProtocolNote;
import com.zfoo.protocol.generate.GenerateProtocolPath;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.registration.ProtocolRegistration;
import com.zfoo.protocol.registration.anno.Compatible;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.reflect.*;
import com.zfoo.protocol.util.ClassUtils;
import com.zfoo.protocol.util.FileUtils;
@@ -28,7 +29,10 @@ import com.zfoo.protocol.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static com.zfoo.protocol.util.FileUtils.LS;
@@ -106,14 +110,14 @@ public abstract class GenerateCsUtils {
var protocolTemplate = StringUtils.bytesToString(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("csharp/ProtocolTemplate.cs")));
var docTitle = docTitle(registration);
var classNote = GenerateProtocolNote.classNote(protocolId, CodeLanguage.CSharp);
var fieldDefinition = fieldDefinition(registration);
var valueOfMethod = valueOfMethod(registration);
var writeObject = writeObject(registration);
var readObject = readObject(registration);
protocolTemplate = StringUtils.format(protocolTemplate, docTitle, protocolClazzName, fieldDefinition.trim()
protocolTemplate = StringUtils.format(protocolTemplate, classNote, protocolClazzName, fieldDefinition.trim()
, protocolClazzName, valueOfMethod.getKey().trim(), protocolClazzName, valueOfMethod.getValue().trim()
, protocolId, protocolClazzName, protocolId, protocolClazzName, protocolClazzName,writeObject.trim()
, protocolId, protocolClazzName, protocolId, protocolClazzName, protocolClazzName, writeObject.trim()
, protocolClazzName, protocolClazzName, readObject.trim());
var protocolOutputPath = StringUtils.format("{}/{}/{}.cs"
@@ -123,34 +127,19 @@ public abstract class GenerateCsUtils {
FileUtils.writeStringToFile(new File(protocolOutputPath), protocolTemplate, true);
}
private static String docTitle(ProtocolRegistration registration) {
var protocolId = registration.getId();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docTitle = protocolDocument.getKey();
var csBuilder = new StringBuilder();
if (StringUtils.isNotBlank(docTitle)) {
Arrays.stream(docTitle.split(LS)).forEach(it -> csBuilder.append(TAB).append(it).append(LS));
}
return csBuilder.toString().trim();
}
private static String fieldDefinition(ProtocolRegistration registration) {
var protocolId = registration.getId();
var protocolId = registration.protocolId();
var fields = registration.getFields();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docFieldMap = protocolDocument.getValue();
var csBuilder = new StringBuilder();
// 协议的属性生成
for (var field : fields) {
var fieldName = field.getName();
var propertyType = toCsClassName(field.getGenericType().getTypeName());
var propertyName = field.getName();
var propertyFullName = StringUtils.format("public {} {};", propertyType, propertyName);
var propertyFullName = StringUtils.format("public {} {};", propertyType, fieldName);
// 生成注释
var doc = docFieldMap.get(propertyName);
if (StringUtils.isNotBlank(doc)) {
Arrays.stream(doc.split(LS)).forEach(it -> csBuilder.append(TAB + TAB).append(it).append(LS));
var fieldNote = GenerateProtocolNote.fieldNote(protocolId, fieldName, CodeLanguage.CSharp);
if (StringUtils.isNotBlank(fieldNote)) {
csBuilder.append(TAB + TAB).append(fieldNote).append(LS);
}
csBuilder.append(TAB + TAB).append(propertyFullName).append(LS);
}
@@ -14,12 +14,13 @@
package com.zfoo.protocol.serializer.gdscript;
import com.zfoo.protocol.generate.GenerateOperation;
import com.zfoo.protocol.generate.GenerateProtocolDocument;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.generate.GenerateProtocolNote;
import com.zfoo.protocol.generate.GenerateProtocolPath;
import com.zfoo.protocol.registration.IProtocolRegistration;
import com.zfoo.protocol.registration.ProtocolRegistration;
import com.zfoo.protocol.registration.anno.Compatible;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.reflect.*;
import com.zfoo.protocol.util.ClassUtils;
import com.zfoo.protocol.util.FileUtils;
@@ -28,7 +29,6 @@ import com.zfoo.protocol.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -109,44 +109,31 @@ public abstract class GenerateGdUtils {
var registrationConstructor = registration.getConstructor();
var protocolClazzName = registrationConstructor.getDeclaringClass().getSimpleName();
var docTitle = docTitle(registration);
var classNote = GenerateProtocolNote.classNote(protocolId, CodeLanguage.GdScript);
var fieldDefinition = fieldDefinition(registration);
var writeObject = writeObject(registration);
var readObject = readObject(registration);
var protocolTemplate = StringUtils.bytesToString(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("gdscript/ProtocolTemplate.gd")));
protocolTemplate = StringUtils.format(protocolTemplate, docTitle, fieldDefinition.trim(), protocolId, writeObject.trim(), readObject.trim());
protocolTemplate = StringUtils.format(protocolTemplate, classNote, fieldDefinition.trim(), protocolId, writeObject.trim(), readObject.trim());
var protocolOutputPath = StringUtils.format("{}/{}/{}.gd", protocolOutputRootPath, GenerateProtocolPath.getProtocolPath(protocolId), protocolClazzName);
FileUtils.writeStringToFile(new File(protocolOutputPath), protocolTemplate, true);
}
private static String docTitle(ProtocolRegistration registration) {
var protocolId = registration.getId();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docTitle = protocolDocument.getKey();
var gdBuilder = new StringBuilder();
if (StringUtils.isNotBlank(docTitle)) {
gdBuilder.append(gdDocument(docTitle));
}
return gdBuilder.toString();
}
private static String fieldDefinition(ProtocolRegistration registration) {
var protocolId = registration.getId();
var fields = registration.getFields();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docFieldMap = protocolDocument.getValue();
var gdBuilder = new StringBuilder();
for (var field : fields) {
var propertyName = field.getName();
var fieldName = field.getName();
// 生成注释
var doc = docFieldMap.get(propertyName);
if (StringUtils.isNotBlank(doc)) {
Arrays.stream(doc.split(LS)).forEach(it -> gdBuilder.append(gdDocument(it)).append(LS));
var fieldNote = GenerateProtocolNote.fieldNote(protocolId, fieldName, CodeLanguage.GdScript);
if (StringUtils.isNotBlank(fieldNote)) {
gdBuilder.append(fieldNote).append(LS);
}
// 生成类型的注释
gdBuilder.append(StringUtils.format("var {} # ", propertyName)).append(field.getGenericType().getTypeName()).append(LS);
gdBuilder.append(StringUtils.format("var {} # ", fieldName)).append(field.getGenericType().getTypeName()).append(LS);
}
return gdBuilder.toString();
}
@@ -180,10 +167,6 @@ public abstract class GenerateGdUtils {
return gdBuilder.toString();
}
private static String gdDocument(String doc) {
return doc.replaceAll("//", "#");
}
public static StringBuilder addTab(StringBuilder builder, int deep) {
builder.append(TAB_ASCII.repeat(Math.max(0, deep)));
return builder;
@@ -14,13 +14,14 @@
package com.zfoo.protocol.serializer.javascript;
import com.zfoo.protocol.generate.GenerateOperation;
import com.zfoo.protocol.generate.GenerateProtocolDocument;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.generate.GenerateProtocolNote;
import com.zfoo.protocol.generate.GenerateProtocolPath;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.registration.IProtocolRegistration;
import com.zfoo.protocol.registration.ProtocolRegistration;
import com.zfoo.protocol.registration.anno.Compatible;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.reflect.*;
import com.zfoo.protocol.util.ClassUtils;
import com.zfoo.protocol.util.FileUtils;
@@ -121,12 +122,12 @@ public abstract class GenerateJsUtils {
var protocolTemplate = StringUtils.bytesToString(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("javascript/ProtocolTemplate.js")));
var docTitle = docTitle(registration);
var classNote = GenerateProtocolNote.classNote(protocolId, CodeLanguage.JavaScript);
var valueOfMethod = valueOfMethod(registration);
var writeObject = writeObject(registration);
var readObject = readObject(registration);
protocolTemplate = StringUtils.format(protocolTemplate, docTitle, protocolClazzName
protocolTemplate = StringUtils.format(protocolTemplate, classNote, protocolClazzName
, valueOfMethod.getKey().trim(), valueOfMethod.getValue().trim(), protocolClazzName, protocolId, protocolClazzName
, writeObject.trim(), protocolClazzName, protocolClazzName, readObject.trim(), protocolClazzName);
var protocolOutputPath = StringUtils.format("{}/{}/{}.js", protocolOutputRootPath
@@ -134,13 +135,6 @@ public abstract class GenerateJsUtils {
FileUtils.writeStringToFile(new File(protocolOutputPath), protocolTemplate, true);
}
private static String docTitle(ProtocolRegistration registration) {
var protocolId = registration.getId();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docTitle = protocolDocument.getKey();
return docTitle;
}
private static Pair<String, String> valueOfMethod(ProtocolRegistration registration) {
var protocolId = registration.getId();
var fields = registration.getFields();
@@ -148,18 +142,15 @@ public abstract class GenerateJsUtils {
var fieldValueOf = StringUtils.joinWith(", ", Arrays.stream(fields).map(it -> it.getName()).collect(Collectors.toList()).toArray());
var fieldDefinitionBuilder = new StringBuilder();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docFieldMap = protocolDocument.getValue();
for (var field : fields) {
var propertyName = field.getName();
var fieldName = field.getName();
// 生成注释
var doc = docFieldMap.get(propertyName);
if (StringUtils.isNotBlank(doc)) {
Arrays.stream(doc.split(LS)).forEach(it -> fieldDefinitionBuilder.append(TAB).append(it).append(LS));
var fileNote = GenerateProtocolNote.fieldNote(protocolId, fieldName, CodeLanguage.JavaScript);
if (StringUtils.isNotBlank(fileNote)) {
fieldDefinitionBuilder.append(TAB).append(fileNote).append(LS);
}
fieldDefinitionBuilder.append(TAB)
.append(StringUtils.format("this.{} = {};", propertyName, propertyName))
.append(StringUtils.format("this.{} = {};", fieldName, fieldName))
.append(" // ").append(field.getGenericType().getTypeName())// 生成类型的注释
.append(LS);
}
@@ -14,13 +14,14 @@
package com.zfoo.protocol.serializer.lua;
import com.zfoo.protocol.generate.GenerateOperation;
import com.zfoo.protocol.generate.GenerateProtocolDocument;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.generate.GenerateProtocolNote;
import com.zfoo.protocol.generate.GenerateProtocolPath;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.registration.IProtocolRegistration;
import com.zfoo.protocol.registration.ProtocolRegistration;
import com.zfoo.protocol.registration.anno.Compatible;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.reflect.*;
import com.zfoo.protocol.util.ClassUtils;
import com.zfoo.protocol.util.FileUtils;
@@ -118,12 +119,12 @@ public abstract class GenerateLuaUtils {
var protocolClazzName = registrationConstructor.getDeclaringClass().getSimpleName();
var protocolTemplate = StringUtils.bytesToString(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("lua/ProtocolTemplate.lua")));
var docTitle = docTitle(registration);
var classNote = GenerateProtocolNote.classNote(protocolId, CodeLanguage.Lua);
var valueOfMethod = valueOfMethod(registration);
var writePacket = writePacket(registration);
var readPacket = readPacket(registration);
protocolTemplate = StringUtils.format(protocolTemplate, docTitle, protocolClazzName, StringUtils.EMPTY_JSON, protocolClazzName
protocolTemplate = StringUtils.format(protocolTemplate, classNote, protocolClazzName, StringUtils.EMPTY_JSON, protocolClazzName
, valueOfMethod.getKey().trim(), valueOfMethod.getValue().trim(), protocolClazzName, protocolId
, protocolClazzName, writePacket.trim(), protocolClazzName, protocolClazzName, readPacket.trim(), protocolClazzName);
@@ -132,41 +133,26 @@ public abstract class GenerateLuaUtils {
FileUtils.writeStringToFile(new File(protocolOutputPath), protocolTemplate, true);
}
private static String docTitle(ProtocolRegistration registration) {
var protocolId = registration.protocolId();
var luaBuilder = new StringBuilder();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docTitle = protocolDocument.getKey();
if (StringUtils.isNotBlank(docTitle)) {
Arrays.stream(docTitle.split(LS)).forEach(it -> luaBuilder.append(docToLuaDoc(it)).append(LS));
}
return luaBuilder.toString();
}
private static Pair<String, String> valueOfMethod(ProtocolRegistration registration) {
var protocolId = registration.getId();
var fields = registration.getFields();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docFieldMap = protocolDocument.getValue();
var valueOfParams = StringUtils.joinWith(", ", Arrays.stream(fields).map(it -> it.getName()).collect(Collectors.toList()).toArray());
var luaBuilder = new StringBuilder();
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
var propertyName = field.getName();
var fieldName = field.getName();
// 生成注释
var doc = docFieldMap.get(propertyName);
if (StringUtils.isNotBlank(doc)) {
Arrays.stream(doc.split(LS)).forEach(it -> luaBuilder.append(TAB + TAB).append(docToLuaDoc(it)).append(LS));
var fieldNote = GenerateProtocolNote.fieldNote(protocolId, fieldName, CodeLanguage.Lua);
if (StringUtils.isNotBlank(fieldNote)) {
luaBuilder.append(TAB + TAB).append(fieldNote).append(LS);
}
if (i == fields.length - 1) {
luaBuilder.append(TAB + TAB).append(StringUtils.format("{} = {}", propertyName, propertyName));
luaBuilder.append(TAB + TAB).append(StringUtils.format("{} = {}", fieldName, fieldName));
} else {
luaBuilder.append(TAB + TAB).append(StringUtils.format("{} = {},", propertyName, propertyName));
luaBuilder.append(TAB + TAB).append(StringUtils.format("{} = {},", fieldName, fieldName));
}
// 生成类型的注释
luaBuilder.append(" -- ").append(field.getGenericType().getTypeName()).append(LS);
@@ -205,7 +191,4 @@ public abstract class GenerateLuaUtils {
return luaBuilder.toString();
}
private static String docToLuaDoc(String doc) {
return doc.replaceFirst("//", "--");
}
}
@@ -18,12 +18,13 @@ import com.zfoo.protocol.ProtocolManager;
import com.zfoo.protocol.collection.ArrayUtils;
import com.zfoo.protocol.exception.RunException;
import com.zfoo.protocol.generate.GenerateOperation;
import com.zfoo.protocol.generate.GenerateProtocolDocument;
import com.zfoo.protocol.generate.GenerateProtocolNote;
import com.zfoo.protocol.model.Pair;
import com.zfoo.protocol.registration.IProtocolRegistration;
import com.zfoo.protocol.registration.ProtocolAnalysis;
import com.zfoo.protocol.registration.ProtocolRegistration;
import com.zfoo.protocol.registration.field.*;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.reflect.*;
import com.zfoo.protocol.util.ClassUtils;
import com.zfoo.protocol.util.DomUtils;
@@ -193,16 +194,15 @@ public abstract class GenerateProtobufUtils {
var protocolId = ProtocolAnalysis.getProtocolIdByClass(protocolClass);
var protocolRegistration = ProtocolManager.getProtocol(protocolId);
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docTitle = protocolDocument.getKey();
builder.append("// id = ").append(protocolId).append(LS);
if (StringUtils.isNotBlank(docTitle)) {
Arrays.stream(docTitle.split(LS)).forEach(it -> builder.append(it).append(LS));
var classNote = GenerateProtocolNote.classNote(protocolId, CodeLanguage.Protobuf);
if (StringUtils.isNotBlank(classNote)) {
builder.append(classNote).append(LS);
}
builder.append("//id = ").append(protocolId).append(LS);
builder.append(StringUtils.format("message {} {", protocolClass.getSimpleName())).append(LS);
builder.append(protocolClass((ProtocolRegistration) protocolRegistration));
builder.append(protobufFiled((ProtocolRegistration) protocolRegistration));
builder.append("}").append(LS).append(LS);
}
@@ -213,16 +213,15 @@ public abstract class GenerateProtobufUtils {
/**
* 优化一下生成协议顺序
*
* @param registration
* @return
*/
private static String protocolClass(ProtocolRegistration registration) {
private static String protobufFiled(ProtocolRegistration registration) {
var protocolId = registration.getId();
var fields = registration.getFields();
var fieldRegistrations = registration.getFieldRegistrations();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docFieldMap = protocolDocument.getValue();
// 先检查注解id顺序是否有重复
var orderMap = new TreeMap<Integer, String>();
for (int i = 0, length = fields.length; i < length; i++) {
@@ -238,16 +237,16 @@ public abstract class GenerateProtobufUtils {
throw new RunException("protobuf协议类注解[{}],order的顺序重复[{}]", Protobuf.class.getSimpleName(), order);
}
var builder = new StringBuilder();
var propertyName = field.getName();
var fieldName = field.getName();
// 生成注释
var doc = docFieldMap.get(propertyName);
if (StringUtils.isNotBlank(doc)) {
Arrays.stream(doc.split(LS)).forEach(it -> builder.append(TAB).append(it).append(LS));
var fieldNote = GenerateProtocolNote.fieldNote(protocolId, fieldName, CodeLanguage.Protobuf);
if (StringUtils.isNotBlank(fieldNote)) {
builder.append(TAB).append(fieldNote).append(LS);
}
var singleFieldStr = toFieldTypeName(fieldRegistration);
if (StringUtils.isNotBlank(singleFieldStr)) {
builder.append(TAB).append(StringUtils.format("{} {} = {};", singleFieldStr, propertyName, order)).append(LS);
builder.append(TAB).append(StringUtils.format("{} {} = {};", singleFieldStr, fieldName, order)).append(LS);
orderMap.put(order, builder.toString());
continue;
}
@@ -255,20 +254,20 @@ public abstract class GenerateProtobufUtils {
if (fieldRegistration instanceof ArrayField) {
var arrayField = (ArrayField) fieldRegistration;
var arrayFieldStr = toFieldTypeName(arrayField.getArrayElementRegistration());
builder.append(TAB).append(StringUtils.format("repeated {} {} = {};", arrayFieldStr, propertyName, order)).append(LS);
builder.append(TAB).append(StringUtils.format("repeated {} {} = {};", arrayFieldStr, fieldName, order)).append(LS);
} else if (fieldRegistration instanceof ListField) {
var listField = (ListField) fieldRegistration;
var listFieldStr = toFieldTypeName(listField.getListElementRegistration());
builder.append(TAB).append(StringUtils.format("repeated {} {} = {};", listFieldStr, propertyName, order)).append(LS);
builder.append(TAB).append(StringUtils.format("repeated {} {} = {};", listFieldStr, fieldName, order)).append(LS);
} else if (fieldRegistration instanceof SetField) {
var setField = (SetField) fieldRegistration;
var setFieldStr = toFieldTypeName(setField.getSetElementRegistration());
builder.append(TAB).append(StringUtils.format("repeated {} {} = {};", setFieldStr, propertyName, order)).append(LS);
builder.append(TAB).append(StringUtils.format("repeated {} {} = {};", setFieldStr, fieldName, order)).append(LS);
} else if (fieldRegistration instanceof MapField) {
var mapField = (MapField) fieldRegistration;
var keyFieldStr = toFieldTypeName(mapField.getMapKeyRegistration());
var valueFieldStr = toFieldTypeName(mapField.getMapValueRegistration());
builder.append(TAB).append(StringUtils.format("map<{}, {}> {} = {};", keyFieldStr, valueFieldStr, propertyName, order)).append(LS);
builder.append(TAB).append(StringUtils.format("map<{}, {}> {} = {};", keyFieldStr, valueFieldStr, fieldName, order)).append(LS);
} else {
throw new RunException("无法识别的protobuf类型[{}]", field.getName());
}
@@ -15,13 +15,14 @@ package com.zfoo.protocol.serializer.typescript;
import com.zfoo.protocol.collection.CollectionUtils;
import com.zfoo.protocol.generate.GenerateOperation;
import com.zfoo.protocol.generate.GenerateProtocolDocument;
import com.zfoo.protocol.generate.GenerateProtocolFile;
import com.zfoo.protocol.generate.GenerateProtocolNote;
import com.zfoo.protocol.generate.GenerateProtocolPath;
import com.zfoo.protocol.registration.IProtocolRegistration;
import com.zfoo.protocol.registration.ProtocolAnalysis;
import com.zfoo.protocol.registration.ProtocolRegistration;
import com.zfoo.protocol.registration.anno.Compatible;
import com.zfoo.protocol.serializer.CodeLanguage;
import com.zfoo.protocol.serializer.enhance.EnhanceObjectProtocolSerializer;
import com.zfoo.protocol.serializer.reflect.*;
import com.zfoo.protocol.util.ClassUtils;
@@ -31,7 +32,6 @@ import com.zfoo.protocol.util.StringUtils;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -122,12 +122,12 @@ public abstract class GenerateTsUtils {
var protocolTemplate = StringUtils.bytesToString(IOUtils.toByteArray(ClassUtils.getFileFromClassPath("typescript/ProtocolTemplate.ts")));
var importSubProtocol = importSubProtocol(registration);
var docTitle = docTitle(registration);
var classNote = GenerateProtocolNote.classNote(protocolId, CodeLanguage.TypeScript);
var fieldDefinition = fieldDefinition(registration);
var writeObject = writeObject(registration);
var readObject = readObject(registration);
protocolTemplate = StringUtils.format(protocolTemplate, importSubProtocol, docTitle, protocolClazzName, fieldDefinition.trim()
protocolTemplate = StringUtils.format(protocolTemplate, importSubProtocol, classNote, protocolClazzName, fieldDefinition.trim()
, protocolId, protocolClazzName, writeObject.trim(), protocolClazzName, protocolClazzName, readObject.trim(), protocolClazzName);
var protocolOutputPath = StringUtils.format("{}/{}/{}.ts", protocolOutputRootPath
, GenerateProtocolPath.getProtocolPath(protocolId), protocolClazzName);
@@ -154,34 +154,21 @@ public abstract class GenerateTsUtils {
return importBuilder.toString();
}
private static String docTitle(ProtocolRegistration registration) {
var protocolId = registration.getId();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docTitle = protocolDocument.getKey();
return docTitle;
}
private static String fieldDefinition(ProtocolRegistration registration) {
var protocolId = registration.getId();
var protocolId = registration.protocolId();
var fields = registration.getFields();
var fieldRegistrations = registration.getFieldRegistrations();
var fieldDefinitionBuilder = new StringBuilder();
var protocolDocument = GenerateProtocolDocument.getProtocolDocument(protocolId);
var docFieldMap = protocolDocument.getValue();
for (var i = 0; i < fields.length; i++) {
var field = fields[i];
var fieldRegistration = fieldRegistrations[i];
var propertyName = field.getName();
var fieldName = field.getName();
// 生成注释
var doc = docFieldMap.get(propertyName);
if (StringUtils.isNotBlank(doc)) {
Arrays.stream(doc.split(LS)).forEach(it -> fieldDefinitionBuilder.append(TAB).append(it).append(LS));
var fieldNote = GenerateProtocolNote.fieldNote(protocolId, fieldName, CodeLanguage.TypeScript);
if (StringUtils.isNotBlank(fieldNote)) {
fieldDefinitionBuilder.append(TAB).append(fieldNote).append(LS);
}
var triple = tsSerializer(fieldRegistration.serializer()).field(field, fieldRegistration);
fieldDefinitionBuilder.append(TAB).append(StringUtils.format("{}{} = {};", triple.getMiddle(), triple.getLeft(), triple.getRight())).append(LS);
}
@@ -15,28 +15,21 @@ package com.zfoo.protocol.packet;
import com.zfoo.protocol.IPacket;
import com.zfoo.protocol.registration.anno.Compatible;
import com.zfoo.protocol.registration.anno.Note;
import com.zfoo.protocol.registration.anno.Protocol;
import java.util.*;
/**
* 复杂的对象
* 包括了各种复杂的结构,数组,List,Set,Map
*
* @author jaysunxiao
* @version 3.0
*/
@Protocol(note = "复杂的对象,包括了各种复杂的结构,数组,List,Set,Map")
public class ComplexObject implements IPacket {
public static final transient short PROTOCOL_ID = 100;
// byte类型,最简单的整形
@Note("byte类型,最简单的整形")
private byte a;
// byte的包装类型
// 优先使用基础类型,包装类型会有装箱拆箱
@Note("byte的包装类型,优先使用基础类型,包装类型会有装箱拆箱")
private Byte aa;
/**
* 数组类型
*/
@Note("数组类型")
private byte[] aaa;
private Byte[] aaaa;
@@ -100,7 +93,7 @@ public class ComplexObject implements IPacket {
private Set<String> ssss;
private Set<Map<Integer, String>> sssss;
// 如果要修改协议并且兼容老协议,需要加上Compatible注解,按照增加的顺序添加order
@Note("如果要修改协议并且兼容老协议,需要加上Compatible注解,按照增加的顺序添加order")
@Compatible(order = 1)
private int myCompatible;
@Compatible(order = 2)