@@ -41,7 +41,7 @@ class Codegen {
41
41
add (Vector .class );
42
42
}};
43
43
static volatile Map <String , Decoder > cache = new HashMap <String , Decoder >();
44
- static List <Extension > fieldDecoderFactories = new ArrayList <Extension >();
44
+ static List <Extension > extensions = new ArrayList <Extension >();
45
45
static ClassPool pool = ClassPool .getDefault ();
46
46
47
47
static Decoder getDecoder (String cacheKey , Type type , Type ... typeArgs ) {
@@ -164,10 +164,51 @@ public static void addNewDecoder(String cacheKey, Decoder decoder) {
164
164
}
165
165
166
166
private static String genObject (Class clazz , String cacheKey ) {
167
- Map <Integer , Object > map = new HashMap <Integer , Object >();
167
+ Map <Integer , Object > trieTree = buildTriTree (clazz );
168
+ String newInstanceCode = null ;
169
+ for (Extension extension : extensions ) {
170
+ newInstanceCode = extension .codegenNewInstance (clazz );
171
+ if (newInstanceCode != null ) {
172
+ break ;
173
+ }
174
+ }
175
+ if (newInstanceCode == null ) {
176
+ newInstanceCode = "new " + clazz .getCanonicalName () + "()" ;
177
+ }
178
+ if (trieTree .isEmpty ()) {
179
+ StringBuilder lines = new StringBuilder ();
180
+ append (lines , "public Object decode(com.jsoniter.Jsoniter iter) {" );
181
+ append (lines , "{{clazz}} obj = {{newInst}};" );
182
+ append (lines , "iter.skip();" );
183
+ append (lines , "return obj;" );
184
+ append (lines , "}" );
185
+ return lines .toString ().replace ("{{clazz}}" , clazz .getName ()).replace ("{{newInst}}" , newInstanceCode );
186
+ }
187
+ StringBuilder lines = new StringBuilder ();
188
+ append (lines , "public Object decode(com.jsoniter.Jsoniter iter) {" );
189
+ append (lines , "{{clazz}} obj = {{newInst}};" );
190
+ append (lines , "for (com.jsoniter.Slice field = iter.readObjectAsSlice(); field != null; field = iter.readObjectAsSlice()) {" );
191
+ append (lines , "switch (field.len) {" );
192
+ for (Map .Entry <Integer , Object > entry : trieTree .entrySet ()) {
193
+ Integer len = entry .getKey ();
194
+ append (lines , "case " + len + ": " );
195
+ Map <Byte , Object > current = (Map <Byte , Object >) entry .getValue ();
196
+ addFieldDispatch (lines , len , 0 , current , cacheKey );
197
+ append (lines , "break;" );
198
+ }
199
+ append (lines , "}" );
200
+ append (lines , "iter.skip();" );
201
+ append (lines , "}" );
202
+ append (lines , "return obj;" );
203
+ append (lines , "}" );
204
+ return lines .toString ().replace ("{{clazz}}" , clazz .getName ()).replace ("{{newInst}}" , newInstanceCode );
205
+ }
206
+
207
+ private static Map <Integer , Object > buildTriTree (Class clazz ) {
208
+ Map <Integer , Object > trieTree = new HashMap <Integer , Object >();
168
209
for (Field field : clazz .getFields ()) {
169
210
String [] alternativeFieldNames = null ;
170
- for (Extension extension : fieldDecoderFactories ) {
211
+ for (Extension extension : extensions ) {
171
212
alternativeFieldNames = extension .getAlternativeFieldNames (field );
172
213
if (alternativeFieldNames != null ) {
173
214
break ;
@@ -178,10 +219,10 @@ private static String genObject(Class clazz, String cacheKey) {
178
219
}
179
220
for (String alternativeFieldName : alternativeFieldNames ) {
180
221
byte [] fieldName = alternativeFieldName .getBytes ();
181
- Map <Byte , Object > current = (Map <Byte , Object >) map .get (fieldName .length );
222
+ Map <Byte , Object > current = (Map <Byte , Object >) trieTree .get (fieldName .length );
182
223
if (current == null ) {
183
224
current = new HashMap <Byte , Object >();
184
- map .put (fieldName .length , current );
225
+ trieTree .put (fieldName .length , current );
185
226
}
186
227
for (int i = 0 ; i < fieldName .length - 1 ; i ++) {
187
228
byte b = fieldName [i ];
@@ -195,37 +236,11 @@ private static String genObject(Class clazz, String cacheKey) {
195
236
current .put (fieldName [fieldName .length - 1 ], field );
196
237
}
197
238
}
198
- if (map .isEmpty ()) {
199
- StringBuilder lines = new StringBuilder ();
200
- append (lines , "public Object decode(com.jsoniter.Jsoniter iter) {" );
201
- append (lines , "{{clazz}} obj = new {{clazz}}();" );
202
- append (lines , "iter.skip();" );
203
- append (lines , "return obj;" );
204
- append (lines , "}" );
205
- return lines .toString ().replace ("{{clazz}}" , clazz .getName ());
206
- }
207
- StringBuilder lines = new StringBuilder ();
208
- append (lines , "public Object decode(com.jsoniter.Jsoniter iter) {" );
209
- append (lines , "{{clazz}} obj = new {{clazz}}();" );
210
- append (lines , "for (com.jsoniter.Slice field = iter.readObjectAsSlice(); field != null; field = iter.readObjectAsSlice()) {" );
211
- append (lines , "switch (field.len) {" );
212
- for (Map .Entry <Integer , Object > entry : map .entrySet ()) {
213
- Integer len = entry .getKey ();
214
- append (lines , "case " + len + ": " );
215
- Map <Byte , Object > current = (Map <Byte , Object >) entry .getValue ();
216
- addFieldDispatch (lines , len , 0 , current , cacheKey );
217
- append (lines , "break;" );
218
- }
219
- append (lines , "}" );
220
- append (lines , "iter.skip();" );
221
- append (lines , "}" );
222
- append (lines , "return obj;" );
223
- append (lines , "}" );
224
- return lines .toString ().replace ("{{clazz}}" , clazz .getName ());
239
+ return trieTree ;
225
240
}
226
241
227
242
private static Decoder createFieldDecoder (String fieldCacheKey , Field field ) {
228
- for (Extension extension : fieldDecoderFactories ) {
243
+ for (Extension extension : extensions ) {
229
244
Decoder decoder = extension .createDecoder (field );
230
245
if (decoder != null ) {
231
246
addNewDecoder (fieldCacheKey , decoder );
@@ -480,8 +495,8 @@ private static void append(StringBuilder lines, String str) {
480
495
lines .append ("\n " );
481
496
}
482
497
483
- public static void addFieldDecoderFactory (Extension extension ) {
484
- fieldDecoderFactories .add (extension );
498
+ public static void registerExtension (Extension extension ) {
499
+ extensions .add (extension );
485
500
}
486
501
487
502
public static Decoder .IntDecoder getIntDecoder (String cacheKey ) {
0 commit comments