/src/test/java/com/alibaba/fastjson/codegen/DeserializerGen.java

https://github.com/alibaba/fastjson · Java · 648 lines · 540 code · 104 blank · 4 comment · 91 complexity · b96068975dc2f3afd611ab26109266de MD5 · raw file

  1. package com.alibaba.fastjson.codegen;
  2. import java.io.IOException;
  3. import java.lang.reflect.Constructor;
  4. import java.lang.reflect.Modifier;
  5. import java.lang.reflect.ParameterizedType;
  6. import java.lang.reflect.Type;
  7. import java.util.ArrayList;
  8. import java.util.Collection;
  9. import java.util.Collections;
  10. import java.util.HashSet;
  11. import java.util.LinkedList;
  12. import java.util.List;
  13. import java.util.TreeSet;
  14. import com.alibaba.fastjson.util.JavaBeanInfo;
  15. import com.alibaba.fastjson.util.FieldInfo;
  16. import com.alibaba.fastjson.util.TypeUtils;
  17. public class DeserializerGen extends ClassGen {
  18. private JavaBeanInfo beanInfo;
  19. private String genClassName;
  20. public DeserializerGen(Class<?> clazz, Appendable out){
  21. super(clazz, out);
  22. }
  23. @Override
  24. public void gen() throws IOException {
  25. beanInfo = JavaBeanInfo.build(clazz, type, null);
  26. genClassName = clazz.getSimpleName() + "GenDecoder";
  27. print("package ");
  28. print(clazz.getPackage().getName());
  29. println(";");
  30. println();
  31. println("import java.lang.reflect.Type;");
  32. println();
  33. println("import com.alibaba.fastjson.parser.DefaultJSONParser;");
  34. println("import com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask;");
  35. println("import com.alibaba.fastjson.parser.ParserConfig;");
  36. println("import com.alibaba.fastjson.parser.Feature;");
  37. println("import com.alibaba.fastjson.parser.JSONLexerBase;");
  38. println("import com.alibaba.fastjson.parser.JSONToken;");
  39. println("import com.alibaba.fastjson.parser.ParseContext;");
  40. println("import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer;");
  41. println("import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;");
  42. println();
  43. print("public class ");
  44. print(genClassName);
  45. print(" extends ASMJavaBeanDeserializer implements ObjectDeserializer {");
  46. incrementIndent();
  47. println();
  48. genConstructor();
  49. genCreateInstance();
  50. genDeserialze();
  51. endClass();
  52. }
  53. protected void genCreateInstance() throws IOException {
  54. println();
  55. print("public Object createInstance(DefaultJSONParser parser, Type type) {");
  56. incrementIndent();
  57. println();
  58. print("return new ");
  59. print(clazz.getSimpleName());
  60. print("();");
  61. println();
  62. decrementIndent();
  63. println();
  64. print("}");
  65. }
  66. protected void genDeserialze() throws IOException {
  67. if (beanInfo.fields.length == 0) {
  68. return;
  69. }
  70. for (FieldInfo fieldInfo : beanInfo.fields) {
  71. Class<?> fieldClass = fieldInfo.fieldClass;
  72. Type fieldType = fieldInfo.fieldType;
  73. if (fieldClass == char.class) {
  74. return;
  75. }
  76. if (Collection.class.isAssignableFrom(fieldClass)) {
  77. if (fieldType instanceof ParameterizedType) {
  78. Type itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
  79. if (itemType instanceof Class) {
  80. continue;
  81. } else {
  82. return;
  83. }
  84. } else {
  85. return;
  86. }
  87. }
  88. }
  89. FieldInfo[] fieldList = beanInfo.sortedFields;
  90. println();
  91. print("public Object deserialze(DefaultJSONParser parser, Type type, Object fieldName) {");
  92. incrementIndent();
  93. println();
  94. println("JSONLexerBase lexer = (JSONLexerBase) parser.getLexer();");
  95. println();
  96. println("if (!lexer.isEnabled(Feature.SortFeidFastMatch)) {");
  97. println("\treturn super.deserialze(parser, type, fieldName);");
  98. println("}");
  99. println();
  100. println("if (isSupportArrayToBean(lexer)) {");
  101. println("\t// deserialzeArrayMapping");
  102. println("}");
  103. println();
  104. println("if (lexer.scanType(\"Department\") == JSONLexerBase.NOT_MATCH) {");
  105. println("\treturn super.deserialze(parser, type, fieldName);");
  106. println("}");
  107. println();
  108. println("ParseContext mark_context = parser.getContext();");
  109. println("int matchedCount = 0;");
  110. print(clazz.getSimpleName());
  111. print(" instance = ");
  112. Constructor<?> defaultConstructor = beanInfo.defaultConstructor;
  113. if (Modifier.isPublic(defaultConstructor.getModifiers())) {
  114. print("new ");
  115. print(clazz.getSimpleName());
  116. println("();");
  117. } else {
  118. print("(");
  119. print(clazz.getSimpleName());
  120. print(") createInstance(parser);");
  121. }
  122. println();
  123. println("ParseContext context = parser.getContext();");
  124. println("ParseContext childContext = parser.setContext(context, instance, fieldName);");
  125. println();
  126. println("if (lexer.matchStat == JSONLexerBase.END) {");
  127. println("\treturn instance;");
  128. println("}");
  129. println();
  130. println("int matchStat = 0;");
  131. int fieldListSize = fieldList.length;
  132. for (int i = 0; i < fieldListSize; i += 32) {
  133. print("int _asm_flag_");
  134. print(Integer.toString(i / 32));
  135. println(" = 0;");
  136. }
  137. for (int i = 0; i < fieldListSize; ++i) {
  138. FieldInfo fieldInfo = fieldList[i];
  139. Class<?> fieldClass = fieldInfo.fieldClass;
  140. if (fieldClass == boolean.class) {
  141. print("boolean ");
  142. printFieldVarName(fieldInfo);
  143. println(" = false;");
  144. } else if (fieldClass == byte.class //
  145. || fieldClass == short.class //
  146. || fieldClass == int.class //
  147. || fieldClass == long.class //
  148. || fieldClass == float.class //
  149. || fieldClass == double.class //
  150. ) {
  151. print(fieldClass.getSimpleName());
  152. print(" ");
  153. printFieldVarName(fieldInfo);
  154. println(" = 0;");
  155. } else {
  156. if (fieldClass == String.class) {
  157. print("String ");
  158. printFieldVarName(fieldInfo);
  159. println(";");
  160. println("if (lexer.isEnabled(Feature.InitStringFieldAsEmpty)) {");
  161. print("\t");
  162. printFieldVarName(fieldInfo);
  163. println(" = lexer.stringDefaultValue();");
  164. print("\t");
  165. genSetFlag(i);
  166. println("} else {");
  167. print("\t");
  168. printFieldVarName(fieldInfo);
  169. println(" = null;");
  170. println("}");
  171. } else {
  172. printClassName(fieldClass);
  173. print(" ");
  174. printFieldVarName(fieldInfo);
  175. print(" = null;");
  176. println();
  177. }
  178. }
  179. }
  180. println("boolean endFlag = false, restFlag = false;");
  181. println();
  182. for (int i = 0; i < fieldListSize; ++i) {
  183. print("if ((!endFlag) && (!restFlag)) {");
  184. incrementIndent();
  185. println();
  186. FieldInfo fieldInfo = fieldList[i];
  187. Class<?> fieldClass = fieldInfo.fieldClass;
  188. Type fieldType = fieldInfo.fieldType;
  189. if (fieldClass == boolean.class) {
  190. printFieldVarName(fieldInfo);
  191. print(" = lexer.scanFieldBoolean(");
  192. printFieldPrefix(fieldInfo);
  193. println(");");
  194. } else if (fieldClass == byte.class || fieldClass == short.class || fieldClass == int.class) {
  195. printFieldVarName(fieldInfo);
  196. print(" = lexer.scanFieldInt(");
  197. printFieldPrefix(fieldInfo);
  198. println(");");
  199. } else if (fieldClass == long.class) {
  200. printFieldVarName(fieldInfo);
  201. print(" = lexer.scanFieldLong(");
  202. printFieldPrefix(fieldInfo);
  203. println(");");
  204. } else if (fieldClass == float.class) {
  205. printFieldVarName(fieldInfo);
  206. print(" = lexer.scanFieldFloat(");
  207. printFieldPrefix(fieldInfo);
  208. println(");");
  209. } else if (fieldClass == double.class) {
  210. printFieldVarName(fieldInfo);
  211. print(" = lexer.scanFieldDouble(");
  212. printFieldPrefix(fieldInfo);
  213. println(");");
  214. } else if (fieldClass == String.class) {
  215. printFieldVarName(fieldInfo);
  216. print(" = lexer.scanFieldString(");
  217. printFieldPrefix(fieldInfo);
  218. println(");");
  219. } else if (fieldClass.isEnum()) {
  220. print("String ");
  221. printFieldVarEnumName(fieldInfo);
  222. print(" = lexer.scanFieldSymbol(");
  223. printFieldPrefix(fieldInfo);
  224. println(", parser.getSymbolTable());");
  225. print("if (");
  226. printFieldVarEnumName(fieldInfo);
  227. println(" == null) {");
  228. print("\t");
  229. printFieldVarName(fieldInfo);
  230. print(" = ");
  231. printClassName(fieldClass);
  232. print(".valueOf(");
  233. printFieldVarEnumName(fieldInfo);
  234. println(");");
  235. println("}");
  236. } else if (Collection.class.isAssignableFrom(fieldClass)) {
  237. Class<?> itemClass = TypeUtils.getCollectionItemClass(fieldType);
  238. if (itemClass == String.class) {
  239. printFieldVarName(fieldInfo);
  240. print(" = (");
  241. printClassName(fieldClass);
  242. print(") lexer.scanFieldStringArray(");
  243. printFieldPrefix(fieldInfo);
  244. print(", ");
  245. printClassName(fieldClass);
  246. print(".class);");
  247. println();
  248. } else {
  249. genDeserialzeList(fieldInfo, i, itemClass);
  250. if (i == fieldListSize - 1) {
  251. genEndCheck();
  252. }
  253. }
  254. } else {
  255. genDeserialzeObject(fieldInfo, i);
  256. if (i == fieldListSize - 1) {
  257. genEndCheck();
  258. }
  259. }
  260. println("if(lexer.matchStat > 0) {");
  261. print("\t");
  262. genSetFlag(i);
  263. println("\tmatchedCount++;");
  264. println("}");
  265. println("if(lexer.matchStat == JSONLexerBase.NOT_MATCH) {");
  266. println("\trestFlag = true;");
  267. println("}");
  268. println("if(lexer.matchStat != JSONLexerBase.END) {");
  269. println("\tendFlag = true;");
  270. println("}");
  271. decrementIndent();
  272. println();
  273. println("}");
  274. }
  275. genBatchSet(fieldList, true);
  276. println();
  277. println("if (restFlag) {");
  278. println("\treturn super.parseRest(parser, type, fieldName, instance);");
  279. println("}");
  280. println();
  281. print("return instance;");
  282. println();
  283. decrementIndent();
  284. println();
  285. print("}");
  286. }
  287. private void genBatchSet(FieldInfo[] fieldList, boolean flag) throws IOException {
  288. for (int i = 0, size = fieldList.length; i < size; ++i) {
  289. FieldInfo fieldInfo = fieldList[i];
  290. String varName = "_asm_flag_" + (i / 32);
  291. if (flag) {
  292. print("if ((");
  293. print(varName);
  294. print(" & ");
  295. print(Integer.toString(1 << i));
  296. print(") != 0) {");
  297. println();
  298. incrementIndent();
  299. }
  300. if (fieldInfo.method != null) {
  301. print("\tinstance.");
  302. print(fieldInfo.method.getName());
  303. print("(");
  304. printFieldVarName(fieldInfo);
  305. println(");");
  306. } else {
  307. print("\tinstance.");
  308. print(fieldInfo.field.getName());
  309. print(" = ");
  310. printFieldVarName(fieldInfo);
  311. println(";");
  312. }
  313. if (flag) {
  314. decrementIndent();
  315. println();
  316. println("}");
  317. }
  318. }
  319. }
  320. private void genEndCheck() throws IOException {
  321. println("if (matchedCount <= 0 || lexer.token() != JSONToken.RBRACE) {");
  322. println("\trestFlag = true;");
  323. println("} else if (lexer.token() == JSONToken.COMMA) {");
  324. println("\tlexer.nextToken();");
  325. println("}");
  326. }
  327. protected void genDeserialzeList(FieldInfo fieldInfo, int i, Class<?> itemClass) throws IOException {
  328. print("if (lexer.matchField(");
  329. printFieldPrefix(fieldInfo);
  330. print(")) {");
  331. println();
  332. print("\t");
  333. genSetFlag(i);
  334. println("\tif (lexer.token() == JSONToken.NULL) {");
  335. println("\t\tlexer.nextToken(JSONToken.COMMA);");
  336. println("\t} else {");
  337. println("\t\tif (lexer.token() == JSONToken.LBRACKET) {");
  338. print("\t\t\tif(");
  339. printListFieldItemDeser(fieldInfo);
  340. print(" == null) {");
  341. println();
  342. print("\t\t\t\t");
  343. printListFieldItemDeser(fieldInfo);
  344. print(" = parser.getConfig().getDeserializer(");
  345. printClassName(itemClass);
  346. print(".class);");
  347. println();
  348. print("\t\t\t}");
  349. println();
  350. print("\t\t\tfinal int fastMatchToken = ");
  351. printListFieldItemDeser(fieldInfo);
  352. print(".getFastMatchToken();");
  353. println();
  354. println("\t\t\tlexer.nextToken(fastMatchToken);");
  355. // _newCollection
  356. print("\t\t\t");
  357. printFieldVarName(fieldInfo);
  358. print(" = ");
  359. Class<?> fieldClass = fieldInfo.fieldClass;
  360. if (fieldClass.isAssignableFrom(ArrayList.class)) {
  361. print("new java.util.ArrayList();");
  362. } else if (fieldClass.isAssignableFrom(LinkedList.class)) {
  363. print("new java.util.LinkedList();");
  364. } else if (fieldClass.isAssignableFrom(HashSet.class)) {
  365. print("new java.util.HashSet();");
  366. } else if (fieldClass.isAssignableFrom(TreeSet.class)) {
  367. print("new java.util.TreeSet();");
  368. } else {
  369. print("new ");
  370. printClassName(fieldClass);
  371. print("();");
  372. }
  373. println();
  374. println("\t\t\tParseContext listContext = parser.getContext();");
  375. print("\t\t\tparser.setContext(");
  376. printFieldVarName(fieldInfo);
  377. print(", \"");
  378. print(fieldInfo.name);
  379. print("\");");
  380. println();
  381. println();
  382. println("\t\t\tfor(int i = 0; ;++i) {");
  383. println("\t\t\t\tif (lexer.token() == JSONToken.RBRACKET) {");
  384. println("\t\t\t\t\tbreak;");
  385. println("\t\t\t\t}");
  386. print("\t\t\t\t");
  387. printClassName(itemClass);
  388. print(" itemValue = ");
  389. printListFieldItemDeser(fieldInfo);
  390. print(".deserialze(parser, ");
  391. printListFieldItemType(fieldInfo);
  392. println(", i);");
  393. print("\t\t\t\t");
  394. printFieldVarName(fieldInfo);
  395. println(".add(itemValue);");
  396. print("\t\t\t\tparser.checkListResolve(");
  397. printFieldVarName(fieldInfo);
  398. println(");");
  399. println("\t\t\t\tif (lexer.token() == JSONToken.COMMA) {");
  400. println("\t\t\t\t\tlexer.nextToken(fastMatchToken);");
  401. println("\t\t\t\t}");
  402. // end for
  403. println("\t\t\t}");
  404. println("\t\t\tparser.setContext(listContext);");
  405. println("\t\t\tif (lexer.token() != JSONToken.RBRACKET) {");
  406. println("\t\t\t\trestFlag = true;");
  407. println("\t\t\t}");
  408. println("\t\t\tlexer.nextToken(JSONToken.COMMA);");
  409. println();
  410. println("\t\t} else {");
  411. println("\t\t\trestFlag = true;");
  412. println("\t\t}");
  413. println("\t}");
  414. println("}");
  415. }
  416. protected void genDeserialzeObject(FieldInfo fieldInfo, int i) throws IOException {
  417. print("if (lexer.matchField(");
  418. printFieldPrefix(fieldInfo);
  419. print(")) {");
  420. println();
  421. print("\t");
  422. genSetFlag(i);
  423. println("\tmatchedCount++;");
  424. // _deserObject
  425. print("if (");
  426. printFieldDeser(fieldInfo);
  427. print(" == null) {");
  428. println();
  429. print("\t");
  430. printFieldDeser(fieldInfo);
  431. print(" = parser.getConfig().getDeserializer(");
  432. printClassName(fieldInfo.fieldClass);
  433. println(".class);");
  434. println("}");
  435. print("\t");
  436. printFieldDeser(fieldInfo);
  437. print(".deserialze(parser, ");
  438. if (fieldInfo.fieldType instanceof Class) {
  439. printClassName(fieldInfo.fieldClass);
  440. print(".class");
  441. } else {
  442. print("getFieldType(\"");
  443. println(fieldInfo.name);
  444. print("\")");
  445. }
  446. print(",\"");
  447. print(fieldInfo.name);
  448. println("\");");
  449. println("\tif(parser.getResolveStatus() == DefaultJSONParser.NeedToResolve) {");
  450. println("\t\tResolveTask resolveTask = parser.getLastResolveTask();");
  451. println("\t\tresolveTask.setOwnerContext(parser.getContext());");
  452. print("\t\tresolveTask.setFieldDeserializer(this.getFieldDeserializer(\"");
  453. print(fieldInfo.name);
  454. println("\"));");
  455. println("\t\tparser.setResolveStatus(DefaultJSONParser.NONE);");
  456. println("\t}");
  457. println("}");
  458. }
  459. private void printFieldVarName(FieldInfo fieldInfo) throws IOException {
  460. print(fieldInfo.name);
  461. print("_gen");
  462. }
  463. private void printFieldVarEnumName(FieldInfo fieldInfo) throws IOException {
  464. print(fieldInfo.name);
  465. print("_gen_enum_name");
  466. }
  467. private void printFieldPrefix(FieldInfo fieldInfo) throws IOException {
  468. print(fieldInfo.name);
  469. print("_gen_prefix__");
  470. }
  471. private void printListFieldItemDeser(FieldInfo fieldInfo) throws IOException {
  472. print(fieldInfo.name);
  473. print("_gen_list_item_deser__");
  474. }
  475. private void printFieldDeser(FieldInfo fieldInfo) throws IOException {
  476. print(fieldInfo.name);
  477. print("_gen_deser__");
  478. }
  479. private void printListFieldItemType(FieldInfo fieldInfo) throws IOException {
  480. print(fieldInfo.name);
  481. print("_gen_list_item_type__");
  482. }
  483. private void genSetFlag(int flag) throws IOException {
  484. String varName = "_asm_flag_" + (flag / 32);
  485. print(varName);
  486. print(" |= ");
  487. print(Integer.toString(1 << flag));
  488. print(";");
  489. println();
  490. }
  491. protected void genConstructor() throws IOException {
  492. for (int i = 0, size = beanInfo.fields.length; i < size; ++i) {
  493. FieldInfo fieldInfo = beanInfo.fields[i];
  494. print("private char[] ");
  495. printFieldPrefix(fieldInfo);
  496. print(" = \"\\\"");
  497. print(fieldInfo.name);
  498. print("\\\":\".toCharArray();");
  499. println();
  500. }
  501. println();
  502. boolean fieldDeserFlag = false;
  503. for (int i = 0, size = beanInfo.fields.length; i < size; ++i) {
  504. FieldInfo fieldInfo = beanInfo.fields[i];
  505. Class<?> fieldClass = fieldInfo.fieldClass;
  506. if (fieldClass.isPrimitive()) {
  507. continue;
  508. }
  509. if (fieldClass.isEnum()) {
  510. continue;
  511. }
  512. print("private ObjectDeserializer ");
  513. if (Collection.class.isAssignableFrom(fieldClass)) {
  514. printListFieldItemDeser(fieldInfo);
  515. } else {
  516. printFieldDeser(fieldInfo);
  517. }
  518. println(";");
  519. fieldDeserFlag = true;
  520. if (Collection.class.isAssignableFrom(fieldClass)) {
  521. print("private Type ");
  522. printListFieldItemType(fieldInfo);
  523. print(" = ");
  524. Class<?> fieldItemClass = TypeUtils.getCollectionItemClass(fieldInfo.fieldType);
  525. printClassName(fieldItemClass);
  526. println(".class;");
  527. }
  528. }
  529. if (fieldDeserFlag) {
  530. println();
  531. }
  532. // constructor
  533. print("public ");
  534. print(genClassName);
  535. print(" (ParserConfig config, Class clazz) {");
  536. incrementIndent();
  537. println();
  538. println("super(config, clazz);");
  539. decrementIndent();
  540. println();
  541. print("}");
  542. println();
  543. }
  544. }