mirror of
https://github.com/tiennm99/zfoo.git
synced 2026-05-19 17:29:39 +00:00
del[protobuf]: delete CodeBuilder of protobuf
This commit is contained in:
-225
@@ -1,225 +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.serializer.protobuf.builder;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* 简易的代码构建器,方便进行行内的占位符,占位符采用$key$的形式方便预生成代码的阅读.
|
||||
* 占位符采用下标的方式赋值$name$中间的字符会被忽略
|
||||
*/
|
||||
public class CodeBuilder {
|
||||
private final StringBuilder code;
|
||||
private static final String INDENT_CHARS = " ";
|
||||
private static final String SHORT_INDENT_CHARS = "\t";
|
||||
private static final String LINE_SPERATOR = "\n";
|
||||
private final BlockingQueue<String> prepares;
|
||||
private final BlockingQueue<String> args;
|
||||
|
||||
/**
|
||||
* 使用紧凑的缩进,紧凑缩进使用一个"\t"tab键缩进的方式
|
||||
*/
|
||||
private boolean compactIdentation;
|
||||
|
||||
public CodeBuilder() {
|
||||
code = new StringBuilder();
|
||||
prepares = new ArrayBlockingQueue<>(40);
|
||||
args = new ArrayBlockingQueue<>(40);
|
||||
compactIdentation = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 向现有代码中缩进指定的级别
|
||||
*
|
||||
* @param level 缩进的级别
|
||||
* @return
|
||||
*/
|
||||
public CodeBuilder t(int level) {
|
||||
flush();
|
||||
for (int i = 0; i < level; i++) {
|
||||
if (!isCompactIdentation()) {
|
||||
code.append(INDENT_CHARS);
|
||||
} else {
|
||||
code.append(SHORT_INDENT_CHARS);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为占位符的表达式中占位符进行赋值
|
||||
*
|
||||
* @param arg 占位符赋值的字符串数组
|
||||
* @return
|
||||
*/
|
||||
public CodeBuilder arg(String... arg) {
|
||||
if (prepares.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
for (String a : arg) {
|
||||
args.offer(a);
|
||||
}
|
||||
if (args.size() >= prepares.size() - 1) {
|
||||
flush();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 向代码中追加字符串
|
||||
*
|
||||
* @param str 需要追加的字符串
|
||||
* @return
|
||||
*/
|
||||
public CodeBuilder c(String str) {
|
||||
flush();
|
||||
code.append(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定需要替换占位符的字符串,占位符使用"$$"包含,"$"内部的字符不会输出一个"$$"作为一个
|
||||
* 占位符,如果需要输出"$"则使用"\"进行转义
|
||||
*
|
||||
* @param expression 需要替换占位符的表达式
|
||||
* @return
|
||||
*/
|
||||
public CodeBuilder e(String expression) {
|
||||
if (expression == null || expression.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
flush();
|
||||
char c;
|
||||
boolean isStarted = false;
|
||||
StringBuilder tmp = new StringBuilder();
|
||||
for (int i = 0; i < expression.length(); i++) {
|
||||
c = expression.charAt(i);
|
||||
if (c == '$') {
|
||||
isStarted = dealTmpData(tmp, c, isStarted);
|
||||
} else {
|
||||
tmp.append(c);
|
||||
}
|
||||
}
|
||||
prepares.offer(tmp.toString());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当出现$占位符时,判断解析状态并返回下一个字符的解析状态
|
||||
*
|
||||
* @param tmp 临时保存的数据
|
||||
* @param c 当前的字符
|
||||
* @param isStarted 当前解析的状态
|
||||
* @return
|
||||
*/
|
||||
private boolean dealTmpData(StringBuilder tmp, char c, final boolean isStarted) {
|
||||
boolean start = isStarted;
|
||||
if (tmp.length() == 0) {
|
||||
if (isStarted) {
|
||||
start = false;
|
||||
tmp.delete(0, tmp.length());
|
||||
} else {
|
||||
prepares.offer(tmp.toString());
|
||||
start = true;
|
||||
tmp.delete(0, tmp.length());
|
||||
}
|
||||
} else {
|
||||
if (tmp.charAt(tmp.length() - 1) != '\\') {
|
||||
if (isStarted) {
|
||||
start = false;
|
||||
tmp.delete(0, tmp.length());
|
||||
} else {
|
||||
prepares.offer(tmp.toString());
|
||||
start = true;
|
||||
tmp.delete(0, tmp.length());
|
||||
}
|
||||
} else {
|
||||
tmp.setCharAt(tmp.length() - 1, c);
|
||||
}
|
||||
}
|
||||
return start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
flush();
|
||||
return code.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新占位符替换后的字符串到现有代码中,当给定的变量个数多余占位符的个数时多余的变量
|
||||
* 不会被输出
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CodeBuilder flush() {
|
||||
if (prepares.isEmpty()) {
|
||||
args.clear();
|
||||
return this;
|
||||
}
|
||||
int count = prepares.size();
|
||||
String str;
|
||||
for (int i = 0; i < count - 1; i++) {
|
||||
str = prepares.poll();
|
||||
if (str != null) {
|
||||
code.append(str);
|
||||
}
|
||||
String val = args.poll();
|
||||
if (val != null) {
|
||||
code.append(val);
|
||||
}
|
||||
}
|
||||
str = prepares.poll();
|
||||
while (str != null) {
|
||||
code.append(str);
|
||||
str = prepares.poll();
|
||||
}
|
||||
args.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 向代码中追加指定个数的换行符
|
||||
*
|
||||
* @param rows 换行符的个数
|
||||
* @return
|
||||
*/
|
||||
public CodeBuilder ln(int rows) {
|
||||
flush();
|
||||
code.append(LINE_SPERATOR);
|
||||
if (rows > 1) {
|
||||
for (int i = 1; i < rows; i++) {
|
||||
code.append(LINE_SPERATOR);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 向代码中追加一个换行符,如果有没有输出的占位符的字符串则会先追加占位符的字符串
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public CodeBuilder ln() {
|
||||
return ln(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用紧凑的缩进,紧凑缩进使用一个"\t"tab键缩进的方式
|
||||
*/
|
||||
public boolean isCompactIdentation() {
|
||||
return compactIdentation;
|
||||
}
|
||||
|
||||
}
|
||||
+33
-71
@@ -14,14 +14,20 @@
|
||||
package com.zfoo.protocol.serializer.protobuf.builder;
|
||||
|
||||
import com.zfoo.protocol.collection.CollectionUtils;
|
||||
import com.zfoo.protocol.serializer.protobuf.parser.Proto;
|
||||
import com.zfoo.protocol.serializer.protobuf.parser.TypeJava;
|
||||
import com.zfoo.protocol.serializer.protobuf.parser.TypeProtobuf;
|
||||
import com.zfoo.protocol.serializer.protobuf.wire.*;
|
||||
import com.zfoo.protocol.serializer.protobuf.parser.Proto;
|
||||
import com.zfoo.protocol.serializer.protobuf.wire.MapField;
|
||||
import com.zfoo.protocol.serializer.protobuf.wire.Option;
|
||||
import com.zfoo.protocol.serializer.protobuf.wire.PbField;
|
||||
import com.zfoo.protocol.serializer.protobuf.wire.ProtoMessage;
|
||||
import com.zfoo.protocol.util.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.zfoo.protocol.util.FileUtils.LS;
|
||||
import static com.zfoo.protocol.util.StringUtils.TAB;
|
||||
|
||||
public class JavaBuilder {
|
||||
private static final List<String> BASE_TYPES;
|
||||
|
||||
@@ -64,15 +70,6 @@ public class JavaBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
public String getAnnotationType(PbField field) {
|
||||
String type = field.getTypeString();
|
||||
if (BASE_TYPES.contains(type.toLowerCase(Locale.ENGLISH))) {
|
||||
return "Type." + TypeProtobuf.valueOf(type.toUpperCase(Locale.ENGLISH));
|
||||
} else {
|
||||
return "Type." + TypeProtobuf.MESSAGE;
|
||||
}
|
||||
}
|
||||
|
||||
private void buildMsgImps(ProtoMessage msg, List<PbField> tmp, List<String> imps) {
|
||||
var fields = msg.getFields();
|
||||
if (CollectionUtils.isNotEmpty(fields)) {
|
||||
@@ -91,20 +88,20 @@ public class JavaBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private void buildDocComment(CodeBuilder cb, ProtoMessage msg) {
|
||||
private void buildDocComment(StringBuilder builder, ProtoMessage msg) {
|
||||
if (CollectionUtils.isEmpty(msg.getComments())) {
|
||||
return;
|
||||
}
|
||||
cb.t(0).c("/**").ln();
|
||||
msg.getComments().forEach(c -> cb.t(0).c(" * ").c(c).ln());
|
||||
cb.t(0).c(" */").ln();
|
||||
builder.append("/**").append(LS);
|
||||
msg.getComments().forEach(it -> builder.append(StringUtils.format(" * {}", it)).append(LS));
|
||||
builder.append(" */").append(LS);
|
||||
}
|
||||
|
||||
private void buildFieldComment(CodeBuilder cb, PbField pbField) {
|
||||
private void buildFieldComment(StringBuilder builder, PbField pbField) {
|
||||
if (CollectionUtils.isEmpty(pbField.getComments())) {
|
||||
return;
|
||||
}
|
||||
pbField.getComments().forEach(c -> cb.t(1).c("// ").c(c).ln());
|
||||
pbField.getComments().forEach(it -> builder.append(TAB).append(StringUtils.format("// {}", it)).append(LS));
|
||||
}
|
||||
|
||||
private String getJavaPackage(Proto proto) {
|
||||
@@ -125,41 +122,25 @@ public class JavaBuilder {
|
||||
var imps = new ArrayList<String>();
|
||||
var builder = new StringBuilder();
|
||||
|
||||
var cb = new CodeBuilder();
|
||||
|
||||
buildMsgImps(msg, tmp, imps);
|
||||
|
||||
List<PbField> fields = new ArrayList<>();
|
||||
tmp.stream().sorted(Comparator.comparingInt(PbField::getTag))
|
||||
.forEach(fields::add);
|
||||
|
||||
// not nested
|
||||
imps.stream().sorted(Comparator.naturalOrder())
|
||||
.forEach(e -> cb.t(level - 1).e("import $cls$;").arg(e).ln());
|
||||
.forEach(it -> builder.append(StringUtils.format("import {};", it)).append(LS));
|
||||
|
||||
cb.ln();
|
||||
buildDocComment(cb, msg);
|
||||
cb.t(level - 1).e("public class $name$ {").arg(msg.getName()).ln(2);
|
||||
|
||||
CodeBuilder getCode;
|
||||
CodeBuilder setCode;
|
||||
buildDocComment(builder, msg);
|
||||
builder.append(StringUtils.format("public class {} {", msg.getName())).append(LS);
|
||||
|
||||
int size = fields.size();
|
||||
|
||||
List<String> getCodes = new ArrayList<>(size);
|
||||
List<String> setCodes = new ArrayList<>(size);
|
||||
|
||||
CodeBuilder cons = new CodeBuilder();
|
||||
var builderMethod = new StringBuilder();
|
||||
for (int i = 0; i < size; i++) {
|
||||
PbField f = fields.get(i);
|
||||
getCode = new CodeBuilder();
|
||||
setCode = new CodeBuilder();
|
||||
|
||||
String typeName = getAnnotationType(f);
|
||||
if (msg.getName().equals("Type")) {
|
||||
typeName = Proto.class.getPackage().getName() + ".wire.Field." + typeName;
|
||||
}
|
||||
buildFieldComment(cb, f);
|
||||
buildFieldComment(builder, f);
|
||||
String type = getJavaType(f);
|
||||
String name = f.getName();
|
||||
if (f.getCardinality() == PbField.Cardinality.REPEATED) {
|
||||
@@ -167,47 +148,28 @@ public class JavaBuilder {
|
||||
type = "List<" + boxedTypeName + ">";
|
||||
}
|
||||
|
||||
cb.t(level).e("private $type$ $name$;")
|
||||
.arg(type, name).ln();
|
||||
builder.append(TAB).append(StringUtils.format("private {} {};", type, name)).append(LS);
|
||||
|
||||
String getMethod;
|
||||
if (!"bool".equalsIgnoreCase(f.getType())) {
|
||||
getMethod = "get" +
|
||||
f.getName().substring(0, 1).toUpperCase(Locale.ENGLISH) +
|
||||
f.getName().substring(1);
|
||||
getMethod = StringUtils.format("get{}", StringUtils.capitalize(f.getName()));
|
||||
} else {
|
||||
getMethod = "is" +
|
||||
f.getName().substring(0, 1).toUpperCase(Locale.ENGLISH) +
|
||||
f.getName().substring(1);
|
||||
getMethod = StringUtils.format("is{}", StringUtils.capitalize(f.getName()));
|
||||
}
|
||||
getCode.t(level).e("public $type$ $getMethod$() {")
|
||||
.arg(type, getMethod).ln();
|
||||
getCode.t(level + 1).e("return $name$;").arg(f.getName()).ln();
|
||||
getCode.t(level).c("}").ln();
|
||||
getCodes.add(getCode.toString());
|
||||
|
||||
String retType = "void";
|
||||
String setMethod = "set" +
|
||||
f.getName().substring(0, 1).toUpperCase(Locale.ENGLISH) +
|
||||
f.getName().substring(1);
|
||||
setCode.t(level).e("public $retType$ $setMethod$($type$ $name$) {")
|
||||
.arg(retType, setMethod, type, name).ln();
|
||||
setCode.t(level + 1).e("this.$name$ = $name$;")
|
||||
.arg(f.getName(), f.getName()).ln();
|
||||
setCode.t(level).c("}").ln();
|
||||
setCodes.add(setCode.toString());
|
||||
builderMethod.append(TAB).append(StringUtils.format("public {} {}() {", type, getMethod)).append(LS);
|
||||
builderMethod.append(TAB + TAB).append(StringUtils.format("return {};", f.getName())).append(LS);
|
||||
builderMethod.append(TAB).append("}").append(LS);
|
||||
|
||||
String setMethod = StringUtils.format("set{}", StringUtils.capitalize(f.getName()));
|
||||
builderMethod.append(TAB).append(StringUtils.format("public void {}({} {}) {", setMethod, type, f.getName())).append(LS);
|
||||
builderMethod.append(TAB + TAB).append(StringUtils.format("this.{} = {};", f.getName(), f.getName())).append(LS);
|
||||
builderMethod.append(TAB).append("}").append(LS);
|
||||
}
|
||||
|
||||
cb.ln().c(cons.toString());
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
cb.ln().c(getCodes.get(i));
|
||||
cb.ln().c(setCodes.get(i));
|
||||
}
|
||||
|
||||
|
||||
cb.t(level - 1).c("}");
|
||||
return cb.toString();
|
||||
builder.append(LS).append(builderMethod);
|
||||
builder.append("}");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private String getBoxedTypeName(PbField f) {
|
||||
|
||||
Reference in New Issue
Block a user