Class<?> fieldClass = fieldInfo.getFieldClass();
Method method = fieldInfo.getMethod();
String className = getGenFieldDeserializer(clazz, fieldInfo);
ClassWriter cw = new ClassWriter();
Class<?> superClass;
if (fieldClass == int.class) {
superClass = IntegerFieldDeserializer.class;
} else if (fieldClass == long.class) {
superClass = LongFieldDeserializer.class;
} else {
superClass = StringFieldDeserializer.class;
}
int INVAKE_TYPE;
if (clazz.isInterface()) {
INVAKE_TYPE = INVOKEINTERFACE;
} else {
INVAKE_TYPE = INVOKEVIRTUAL;
}
cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, className, getType(superClass), null);
{
MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "(" + getDesc(PBDeserializer.class)
+ getDesc(Class.class) + getDesc(FieldInfo.class)
+ ")V", null, null);
mw.visitVarInsn(ALOAD, 0);
mw.visitVarInsn(ALOAD, 1);
mw.visitVarInsn(ALOAD, 2);
mw.visitVarInsn(ALOAD, 3);
mw.visitMethodInsn(INVOKESPECIAL, getType(superClass), "<init>", "(" + getDesc(PBDeserializer.class)
+ getDesc(Class.class)
+ getDesc(FieldInfo.class) + ")V");
mw.visitInsn(RETURN);
mw.visitMaxs(4, 6);
mw.visitEnd();
}
if (method != null) {
if (fieldClass == int.class) {
MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "setValue", "(" + getDesc(Object.class) + "I)V", null,
null);
mw.visitVarInsn(ALOAD, 1);
mw.visitTypeInsn(CHECKCAST, getType(method.getDeclaringClass())); // cast
mw.visitVarInsn(ILOAD, 2);
mw.visitMethodInsn(INVAKE_TYPE, getType(method.getDeclaringClass()), method.getName(), ASMUtils.getDesc(method));
mw.visitInsn(RETURN);
mw.visitMaxs(3, 3);
mw.visitEnd();
} else if (fieldClass == long.class) {
MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "setValue", "(" + getDesc(Object.class) + "J)V", null,
null);
mw.visitVarInsn(ALOAD, 1);
mw.visitTypeInsn(CHECKCAST, getType(method.getDeclaringClass())); // cast
mw.visitVarInsn(LLOAD, 2);
mw.visitMethodInsn(INVAKE_TYPE, getType(method.getDeclaringClass()), method.getName(), ASMUtils.getDesc(method));
mw.visitInsn(RETURN);
mw.visitMaxs(3, 4);
mw.visitEnd();
} else {
// public void setValue(Object object, Object value)
MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "setValue", "(" + getDesc(Object.class)
+ getDesc(Object.class) + ")V", null, null);
mw.visitVarInsn(ALOAD, 1);
mw.visitTypeInsn(CHECKCAST, getType(method.getDeclaringClass())); // cast
mw.visitVarInsn(ALOAD, 2);
mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast
mw.visitMethodInsn(INVAKE_TYPE, getType(method.getDeclaringClass()), method.getName(),
ASMUtils.getDesc(method));
mw.visitInsn(RETURN);
mw.visitMaxs(3, 3);
mw.visitEnd();
}
}
byte[] code = cw.toByteArray();
Class<?> exampleClass = classLoader.defineClassPublic(className, code, 0, code.length);
Constructor<?> constructor = exampleClass.getConstructor(PBDeserializer.class, Class.class, FieldInfo.class);
Object instance = constructor.newInstance(mapping, clazz, fieldInfo);