/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
- package com.alibaba.fastjson.codegen;
- import java.io.IOException;
- import java.lang.reflect.Constructor;
- import java.lang.reflect.Modifier;
- import java.lang.reflect.ParameterizedType;
- import java.lang.reflect.Type;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.HashSet;
- import java.util.LinkedList;
- import java.util.List;
- import java.util.TreeSet;
- import com.alibaba.fastjson.util.JavaBeanInfo;
- import com.alibaba.fastjson.util.FieldInfo;
- import com.alibaba.fastjson.util.TypeUtils;
- public class DeserializerGen extends ClassGen {
- private JavaBeanInfo beanInfo;
- private String genClassName;
- public DeserializerGen(Class<?> clazz, Appendable out){
- super(clazz, out);
- }
- @Override
- public void gen() throws IOException {
- beanInfo = JavaBeanInfo.build(clazz, type, null);
- genClassName = clazz.getSimpleName() + "GenDecoder";
- print("package ");
- print(clazz.getPackage().getName());
- println(";");
- println();
- println("import java.lang.reflect.Type;");
- println();
- println("import com.alibaba.fastjson.parser.DefaultJSONParser;");
- println("import com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask;");
- println("import com.alibaba.fastjson.parser.ParserConfig;");
- println("import com.alibaba.fastjson.parser.Feature;");
- println("import com.alibaba.fastjson.parser.JSONLexerBase;");
- println("import com.alibaba.fastjson.parser.JSONToken;");
- println("import com.alibaba.fastjson.parser.ParseContext;");
- println("import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer;");
- println("import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;");
- println();
- print("public class ");
- print(genClassName);
- print(" extends ASMJavaBeanDeserializer implements ObjectDeserializer {");
- incrementIndent();
- println();
- genConstructor();
- genCreateInstance();
- genDeserialze();
- endClass();
- }
- protected void genCreateInstance() throws IOException {
- println();
- print("public Object createInstance(DefaultJSONParser parser, Type type) {");
- incrementIndent();
- println();
- print("return new ");
- print(clazz.getSimpleName());
- print("();");
- println();
- decrementIndent();
- println();
- print("}");
- }
- protected void genDeserialze() throws IOException {
- if (beanInfo.fields.length == 0) {
- return;
- }
- for (FieldInfo fieldInfo : beanInfo.fields) {
- Class<?> fieldClass = fieldInfo.fieldClass;
- Type fieldType = fieldInfo.fieldType;
- if (fieldClass == char.class) {
- return;
- }
- if (Collection.class.isAssignableFrom(fieldClass)) {
- if (fieldType instanceof ParameterizedType) {
- Type itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
- if (itemType instanceof Class) {
- continue;
- } else {
- return;
- }
- } else {
- return;
- }
- }
- }
- FieldInfo[] fieldList = beanInfo.sortedFields;
- println();
- print("public Object deserialze(DefaultJSONParser parser, Type type, Object fieldName) {");
- incrementIndent();
- println();
- println("JSONLexerBase lexer = (JSONLexerBase) parser.getLexer();");
- println();
- println("if (!lexer.isEnabled(Feature.SortFeidFastMatch)) {");
- println("\treturn super.deserialze(parser, type, fieldName);");
- println("}");
- println();
- println("if (isSupportArrayToBean(lexer)) {");
- println("\t// deserialzeArrayMapping");
- println("}");
- println();
- println("if (lexer.scanType(\"Department\") == JSONLexerBase.NOT_MATCH) {");
- println("\treturn super.deserialze(parser, type, fieldName);");
- println("}");
- println();
- println("ParseContext mark_context = parser.getContext();");
- println("int matchedCount = 0;");
- print(clazz.getSimpleName());
- print(" instance = ");
- Constructor<?> defaultConstructor = beanInfo.defaultConstructor;
- if (Modifier.isPublic(defaultConstructor.getModifiers())) {
- print("new ");
- print(clazz.getSimpleName());
- println("();");
- } else {
- print("(");
- print(clazz.getSimpleName());
- print(") createInstance(parser);");
- }
- println();
- println("ParseContext context = parser.getContext();");
- println("ParseContext childContext = parser.setContext(context, instance, fieldName);");
- println();
- println("if (lexer.matchStat == JSONLexerBase.END) {");
- println("\treturn instance;");
- println("}");
- println();
- println("int matchStat = 0;");
- int fieldListSize = fieldList.length;
- for (int i = 0; i < fieldListSize; i += 32) {
- print("int _asm_flag_");
- print(Integer.toString(i / 32));
- println(" = 0;");
- }
- for (int i = 0; i < fieldListSize; ++i) {
- FieldInfo fieldInfo = fieldList[i];
- Class<?> fieldClass = fieldInfo.fieldClass;
- if (fieldClass == boolean.class) {
- print("boolean ");
- printFieldVarName(fieldInfo);
- println(" = false;");
- } else if (fieldClass == byte.class //
- || fieldClass == short.class //
- || fieldClass == int.class //
- || fieldClass == long.class //
- || fieldClass == float.class //
- || fieldClass == double.class //
- ) {
- print(fieldClass.getSimpleName());
- print(" ");
- printFieldVarName(fieldInfo);
- println(" = 0;");
- } else {
- if (fieldClass == String.class) {
- print("String ");
- printFieldVarName(fieldInfo);
- println(";");
- println("if (lexer.isEnabled(Feature.InitStringFieldAsEmpty)) {");
- print("\t");
- printFieldVarName(fieldInfo);
- println(" = lexer.stringDefaultValue();");
- print("\t");
- genSetFlag(i);
- println("} else {");
- print("\t");
- printFieldVarName(fieldInfo);
- println(" = null;");
- println("}");
- } else {
- printClassName(fieldClass);
- print(" ");
- printFieldVarName(fieldInfo);
- print(" = null;");
- println();
- }
- }
- }
- println("boolean endFlag = false, restFlag = false;");
- println();
- for (int i = 0; i < fieldListSize; ++i) {
- print("if ((!endFlag) && (!restFlag)) {");
- incrementIndent();
- println();
- FieldInfo fieldInfo = fieldList[i];
- Class<?> fieldClass = fieldInfo.fieldClass;
- Type fieldType = fieldInfo.fieldType;
- if (fieldClass == boolean.class) {
- printFieldVarName(fieldInfo);
- print(" = lexer.scanFieldBoolean(");
- printFieldPrefix(fieldInfo);
- println(");");
- } else if (fieldClass == byte.class || fieldClass == short.class || fieldClass == int.class) {
- printFieldVarName(fieldInfo);
- print(" = lexer.scanFieldInt(");
- printFieldPrefix(fieldInfo);
- println(");");
- } else if (fieldClass == long.class) {
- printFieldVarName(fieldInfo);
- print(" = lexer.scanFieldLong(");
- printFieldPrefix(fieldInfo);
- println(");");
- } else if (fieldClass == float.class) {
- printFieldVarName(fieldInfo);
- print(" = lexer.scanFieldFloat(");
- printFieldPrefix(fieldInfo);
- println(");");
- } else if (fieldClass == double.class) {
- printFieldVarName(fieldInfo);
- print(" = lexer.scanFieldDouble(");
- printFieldPrefix(fieldInfo);
- println(");");
- } else if (fieldClass == String.class) {
- printFieldVarName(fieldInfo);
- print(" = lexer.scanFieldString(");
- printFieldPrefix(fieldInfo);
- println(");");
- } else if (fieldClass.isEnum()) {
- print("String ");
- printFieldVarEnumName(fieldInfo);
- print(" = lexer.scanFieldSymbol(");
- printFieldPrefix(fieldInfo);
- println(", parser.getSymbolTable());");
- print("if (");
- printFieldVarEnumName(fieldInfo);
- println(" == null) {");
- print("\t");
- printFieldVarName(fieldInfo);
- print(" = ");
- printClassName(fieldClass);
- print(".valueOf(");
- printFieldVarEnumName(fieldInfo);
- println(");");
- println("}");
- } else if (Collection.class.isAssignableFrom(fieldClass)) {
- Class<?> itemClass = TypeUtils.getCollectionItemClass(fieldType);
- if (itemClass == String.class) {
- printFieldVarName(fieldInfo);
- print(" = (");
- printClassName(fieldClass);
- print(") lexer.scanFieldStringArray(");
- printFieldPrefix(fieldInfo);
- print(", ");
- printClassName(fieldClass);
- print(".class);");
- println();
- } else {
- genDeserialzeList(fieldInfo, i, itemClass);
- if (i == fieldListSize - 1) {
- genEndCheck();
- }
- }
- } else {
- genDeserialzeObject(fieldInfo, i);
- if (i == fieldListSize - 1) {
- genEndCheck();
- }
- }
- println("if(lexer.matchStat > 0) {");
- print("\t");
- genSetFlag(i);
- println("\tmatchedCount++;");
- println("}");
- println("if(lexer.matchStat == JSONLexerBase.NOT_MATCH) {");
- println("\trestFlag = true;");
- println("}");
-
- println("if(lexer.matchStat != JSONLexerBase.END) {");
- println("\tendFlag = true;");
- println("}");
-
- decrementIndent();
- println();
- println("}");
- }
- genBatchSet(fieldList, true);
- println();
- println("if (restFlag) {");
- println("\treturn super.parseRest(parser, type, fieldName, instance);");
- println("}");
- println();
- print("return instance;");
- println();
- decrementIndent();
- println();
- print("}");
- }
- private void genBatchSet(FieldInfo[] fieldList, boolean flag) throws IOException {
- for (int i = 0, size = fieldList.length; i < size; ++i) {
- FieldInfo fieldInfo = fieldList[i];
-
- String varName = "_asm_flag_" + (i / 32);
- if (flag) {
- print("if ((");
- print(varName);
- print(" & ");
- print(Integer.toString(1 << i));
- print(") != 0) {");
- println();
- incrementIndent();
- }
-
- if (fieldInfo.method != null) {
- print("\tinstance.");
- print(fieldInfo.method.getName());
- print("(");
- printFieldVarName(fieldInfo);
- println(");");
- } else {
- print("\tinstance.");
- print(fieldInfo.field.getName());
- print(" = ");
- printFieldVarName(fieldInfo);
- println(";");
- }
- if (flag) {
- decrementIndent();
- println();
- println("}");
- }
- }
- }
- private void genEndCheck() throws IOException {
- println("if (matchedCount <= 0 || lexer.token() != JSONToken.RBRACE) {");
- println("\trestFlag = true;");
- println("} else if (lexer.token() == JSONToken.COMMA) {");
- println("\tlexer.nextToken();");
- println("}");
- }
- protected void genDeserialzeList(FieldInfo fieldInfo, int i, Class<?> itemClass) throws IOException {
- print("if (lexer.matchField(");
- printFieldPrefix(fieldInfo);
- print(")) {");
- println();
- print("\t");
- genSetFlag(i);
- println("\tif (lexer.token() == JSONToken.NULL) {");
- println("\t\tlexer.nextToken(JSONToken.COMMA);");
- println("\t} else {");
- println("\t\tif (lexer.token() == JSONToken.LBRACKET) {");
- print("\t\t\tif(");
- printListFieldItemDeser(fieldInfo);
- print(" == null) {");
- println();
- print("\t\t\t\t");
- printListFieldItemDeser(fieldInfo);
- print(" = parser.getConfig().getDeserializer(");
- printClassName(itemClass);
- print(".class);");
- println();
- print("\t\t\t}");
- println();
- print("\t\t\tfinal int fastMatchToken = ");
- printListFieldItemDeser(fieldInfo);
- print(".getFastMatchToken();");
- println();
- println("\t\t\tlexer.nextToken(fastMatchToken);");
- // _newCollection
- print("\t\t\t");
- printFieldVarName(fieldInfo);
- print(" = ");
- Class<?> fieldClass = fieldInfo.fieldClass;
- if (fieldClass.isAssignableFrom(ArrayList.class)) {
- print("new java.util.ArrayList();");
- } else if (fieldClass.isAssignableFrom(LinkedList.class)) {
- print("new java.util.LinkedList();");
- } else if (fieldClass.isAssignableFrom(HashSet.class)) {
- print("new java.util.HashSet();");
- } else if (fieldClass.isAssignableFrom(TreeSet.class)) {
- print("new java.util.TreeSet();");
- } else {
- print("new ");
- printClassName(fieldClass);
- print("();");
- }
- println();
- println("\t\t\tParseContext listContext = parser.getContext();");
- print("\t\t\tparser.setContext(");
- printFieldVarName(fieldInfo);
- print(", \"");
- print(fieldInfo.name);
- print("\");");
- println();
- println();
- println("\t\t\tfor(int i = 0; ;++i) {");
- println("\t\t\t\tif (lexer.token() == JSONToken.RBRACKET) {");
- println("\t\t\t\t\tbreak;");
- println("\t\t\t\t}");
- print("\t\t\t\t");
- printClassName(itemClass);
- print(" itemValue = ");
- printListFieldItemDeser(fieldInfo);
- print(".deserialze(parser, ");
- printListFieldItemType(fieldInfo);
- println(", i);");
- print("\t\t\t\t");
- printFieldVarName(fieldInfo);
- println(".add(itemValue);");
- print("\t\t\t\tparser.checkListResolve(");
- printFieldVarName(fieldInfo);
- println(");");
- println("\t\t\t\tif (lexer.token() == JSONToken.COMMA) {");
- println("\t\t\t\t\tlexer.nextToken(fastMatchToken);");
- println("\t\t\t\t}");
- // end for
- println("\t\t\t}");
- println("\t\t\tparser.setContext(listContext);");
- println("\t\t\tif (lexer.token() != JSONToken.RBRACKET) {");
- println("\t\t\t\trestFlag = true;");
- println("\t\t\t}");
- println("\t\t\tlexer.nextToken(JSONToken.COMMA);");
- println();
- println("\t\t} else {");
- println("\t\t\trestFlag = true;");
- println("\t\t}");
- println("\t}");
- println("}");
- }
- protected void genDeserialzeObject(FieldInfo fieldInfo, int i) throws IOException {
- print("if (lexer.matchField(");
- printFieldPrefix(fieldInfo);
- print(")) {");
- println();
- print("\t");
- genSetFlag(i);
- println("\tmatchedCount++;");
- // _deserObject
- print("if (");
- printFieldDeser(fieldInfo);
- print(" == null) {");
- println();
- print("\t");
- printFieldDeser(fieldInfo);
- print(" = parser.getConfig().getDeserializer(");
- printClassName(fieldInfo.fieldClass);
- println(".class);");
- println("}");
- print("\t");
- printFieldDeser(fieldInfo);
- print(".deserialze(parser, ");
- if (fieldInfo.fieldType instanceof Class) {
- printClassName(fieldInfo.fieldClass);
- print(".class");
- } else {
- print("getFieldType(\"");
- println(fieldInfo.name);
- print("\")");
- }
- print(",\"");
- print(fieldInfo.name);
- println("\");");
- println("\tif(parser.getResolveStatus() == DefaultJSONParser.NeedToResolve) {");
- println("\t\tResolveTask resolveTask = parser.getLastResolveTask();");
- println("\t\tresolveTask.setOwnerContext(parser.getContext());");
- print("\t\tresolveTask.setFieldDeserializer(this.getFieldDeserializer(\"");
- print(fieldInfo.name);
- println("\"));");
- println("\t\tparser.setResolveStatus(DefaultJSONParser.NONE);");
- println("\t}");
- println("}");
- }
- private void printFieldVarName(FieldInfo fieldInfo) throws IOException {
- print(fieldInfo.name);
- print("_gen");
- }
- private void printFieldVarEnumName(FieldInfo fieldInfo) throws IOException {
- print(fieldInfo.name);
- print("_gen_enum_name");
- }
- private void printFieldPrefix(FieldInfo fieldInfo) throws IOException {
- print(fieldInfo.name);
- print("_gen_prefix__");
- }
- private void printListFieldItemDeser(FieldInfo fieldInfo) throws IOException {
- print(fieldInfo.name);
- print("_gen_list_item_deser__");
- }
- private void printFieldDeser(FieldInfo fieldInfo) throws IOException {
- print(fieldInfo.name);
- print("_gen_deser__");
- }
- private void printListFieldItemType(FieldInfo fieldInfo) throws IOException {
- print(fieldInfo.name);
- print("_gen_list_item_type__");
- }
- private void genSetFlag(int flag) throws IOException {
- String varName = "_asm_flag_" + (flag / 32);
- print(varName);
- print(" |= ");
- print(Integer.toString(1 << flag));
- print(";");
- println();
- }
- protected void genConstructor() throws IOException {
- for (int i = 0, size = beanInfo.fields.length; i < size; ++i) {
- FieldInfo fieldInfo = beanInfo.fields[i];
- print("private char[] ");
- printFieldPrefix(fieldInfo);
- print(" = \"\\\"");
- print(fieldInfo.name);
- print("\\\":\".toCharArray();");
- println();
- }
- println();
- boolean fieldDeserFlag = false;
- for (int i = 0, size = beanInfo.fields.length; i < size; ++i) {
- FieldInfo fieldInfo = beanInfo.fields[i];
- Class<?> fieldClass = fieldInfo.fieldClass;
- if (fieldClass.isPrimitive()) {
- continue;
- }
- if (fieldClass.isEnum()) {
- continue;
- }
- print("private ObjectDeserializer ");
- if (Collection.class.isAssignableFrom(fieldClass)) {
- printListFieldItemDeser(fieldInfo);
- } else {
- printFieldDeser(fieldInfo);
- }
- println(";");
- fieldDeserFlag = true;
- if (Collection.class.isAssignableFrom(fieldClass)) {
- print("private Type ");
- printListFieldItemType(fieldInfo);
- print(" = ");
- Class<?> fieldItemClass = TypeUtils.getCollectionItemClass(fieldInfo.fieldType);
- printClassName(fieldItemClass);
- println(".class;");
- }
- }
- if (fieldDeserFlag) {
- println();
- }
- // constructor
- print("public ");
- print(genClassName);
- print(" (ParserConfig config, Class clazz) {");
- incrementIndent();
- println();
- println("super(config, clazz);");
- decrementIndent();
- println();
- print("}");
- println();
- }
- }