Skip to content

Commit adf4faa

Browse files
committed
support TypeDecoder and FieldDecoder
1 parent a1e6af2 commit adf4faa

File tree

6 files changed

+174
-75
lines changed

6 files changed

+174
-75
lines changed

src/main/java/com/github/jsoniter/Codegen.java

Lines changed: 52 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@
88
import java.lang.reflect.Field;
99
import java.lang.reflect.ParameterizedType;
1010
import java.lang.reflect.Type;
11-
import java.util.ArrayList;
12-
import java.util.HashMap;
13-
import java.util.List;
14-
import java.util.Map;
11+
import java.util.*;
1512

1613
class Codegen {
1714
final static Map<String, String> NATIVE_READS = new HashMap<String, String>() {{
@@ -55,34 +52,40 @@ private synchronized static Decoder gen(String cacheKey, Type type, Type[] typeA
5552
} else {
5653
clazz = (Class) type;
5754
}
55+
String source;
56+
if (clazz.isArray()) {
57+
source = genArray(clazz);
58+
} else if (List.class.isAssignableFrom(clazz)) {
59+
Class compType = (Class) typeArgs[0];
60+
if (clazz == List.class) {
61+
clazz = ArrayList.class;
62+
}
63+
source = genList(clazz, compType);
64+
} else {
65+
source = genObject(clazz, cacheKey);
66+
}
5867
try {
5968
CtClass ctClass = pool.makeClass(cacheKey);
6069
ctClass.setInterfaces(new CtClass[]{pool.get(Decoder.class.getName())});
61-
String source;
62-
if (clazz.isArray()) {
63-
source = genArray(clazz);
64-
} else if (List.class.isAssignableFrom(clazz)) {
65-
Class compType = (Class) typeArgs[0];
66-
if (clazz == List.class) {
67-
clazz = ArrayList.class;
68-
}
69-
source = genList(clazz, compType);
70-
} else {
71-
source = genObject(clazz);
72-
}
7370
CtMethod method = CtNewMethod.make(source, ctClass);
7471
ctClass.addMethod(method);
7572
decoder = (Decoder) ctClass.toClass().newInstance();
76-
HashMap<String, Decoder> newCache = new HashMap<>(cache);
77-
newCache.put(cacheKey, decoder);
78-
cache = newCache;
73+
addNewDecoder(cacheKey, decoder);
7974
return decoder;
8075
} catch (Exception e) {
76+
System.err.println("failed to generate encoder for: " + type + " with " + Arrays.toString(typeArgs));
77+
System.err.println(source);
8178
throw new RuntimeException(e);
8279
}
8380
}
8481

85-
private static String genObject(Class clazz) {
82+
public static void addNewDecoder(String cacheKey, Decoder decoder) {
83+
HashMap<String, Decoder> newCache = new HashMap<>(cache);
84+
newCache.put(cacheKey, decoder);
85+
cache = newCache;
86+
}
87+
88+
private static String genObject(Class clazz, String cacheKey) {
8689
Map<Integer, Object> map = new HashMap<>();
8790
for (Field field : clazz.getFields()) {
8891
byte[] fieldName = field.getName().getBytes();
@@ -120,7 +123,7 @@ private static String genObject(Class clazz) {
120123
Integer len = entry.getKey();
121124
append(lines, "case " + len + ": ");
122125
Map<Byte, Object> current = (Map<Byte, Object>) entry.getValue();
123-
addFieldDispatch(lines, len, 0, current);
126+
addFieldDispatch(lines, len, 0, current, cacheKey);
124127
append(lines, "break;");
125128
}
126129
append(lines, "}");
@@ -131,36 +134,45 @@ private static String genObject(Class clazz) {
131134
return lines.toString().replace("{{clazz}}", clazz.getName());
132135
}
133136

134-
private static void addFieldDispatch(StringBuilder lines, int len, int i, Map<Byte, Object> current) {
137+
private static void addFieldDispatch(StringBuilder lines, int len, int i, Map<Byte, Object> current, String cacheKey) {
135138
for (Map.Entry<Byte, Object> entry : current.entrySet()) {
136139
Byte b = entry.getKey();
137140
append(lines, String.format("if (field.at(%d)==%s) {", i, b));
138141
if (i == len - 1) {
139-
Field field = (Field) entry.getValue();
140-
String fieldTypeName = field.getType().getCanonicalName();
141-
String nativeRead = NATIVE_READS.get(fieldTypeName);
142-
if (nativeRead == null) {
143-
if (field.getGenericType() instanceof ParameterizedType) {
144-
ParameterizedType pType = (ParameterizedType) field.getGenericType();
145-
Class arg1 = (Class) pType.getActualTypeArguments()[0];
146-
append(lines, String.format("obj.%s = (%s)iter.read(\"%s\", %s.class, %s.class);",
147-
field.getName(), fieldTypeName, TypeLiteral.generateCacheKey(field.getGenericType()),
148-
fieldTypeName, arg1.getName()));
149-
} else {
150-
append(lines, String.format("obj.%s = (%s)iter.read(%s.class);",
151-
field.getName(), fieldTypeName, fieldTypeName));
152-
}
153-
} else {
154-
append(lines, String.format("obj.%s = %s;", field.getName(), nativeRead));
155-
}
142+
genField(lines, (Field) entry.getValue(), cacheKey);
156143
append(lines, "continue;");
157144
} else {
158-
addFieldDispatch(lines, len, i + 1, (Map<Byte, Object>) entry.getValue());
145+
addFieldDispatch(lines, len, i + 1, (Map<Byte, Object>) entry.getValue(), cacheKey);
159146
}
160147
append(lines, "}");
161148
}
162149
}
163150

151+
private static void genField(StringBuilder lines, Field field, String cacheKey) {
152+
String fieldCacheKey = field.getName() + "@" + cacheKey;
153+
String fieldTypeName = field.getType().getCanonicalName();
154+
String nativeRead = NATIVE_READS.get(fieldTypeName);
155+
if (cache.containsKey(fieldCacheKey)) {
156+
append(lines, String.format("obj.%s = (%s)iter.read(\"%s\", %s.class);",
157+
field.getName(), fieldTypeName, fieldCacheKey, fieldTypeName));
158+
return;
159+
}
160+
if (nativeRead == null) {
161+
if (field.getGenericType() instanceof ParameterizedType) {
162+
ParameterizedType pType = (ParameterizedType) field.getGenericType();
163+
Class arg1 = (Class) pType.getActualTypeArguments()[0];
164+
append(lines, String.format("obj.%s = (%s)iter.read(\"%s\", %s.class, %s.class);",
165+
field.getName(), fieldTypeName, TypeLiteral.generateCacheKey(field.getGenericType()),
166+
fieldTypeName, arg1.getName()));
167+
} else {
168+
append(lines, String.format("obj.%s = (%s)iter.read(%s.class);",
169+
field.getName(), fieldTypeName, fieldTypeName));
170+
}
171+
} else {
172+
append(lines, String.format("obj.%s = %s;", field.getName(), nativeRead));
173+
}
174+
}
175+
164176
private static String genArray(Class clazz) {
165177
Class compType = clazz.getComponentType();
166178
if (compType.isArray()) {

0 commit comments

Comments
 (0)