// Copyright 2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.gwtorm.jdbc;

import com.google.gwtorm.client.Key;
import com.google.gwtorm.schema.ColumnModel;
import com.google.gwtorm.schema.KeyModel;
import com.google.gwtorm.schema.QueryModel;
import com.google.gwtorm.schema.RelationModel;
import com.google.gwtorm.schema.Util;
import com.google.gwtorm.schema.sql.SqlDialect;
import com.google.gwtorm.server.Access;
import com.google.gwtorm.server.CodeGenSupport;
import com.google.gwtorm.server.GeneratedClassLoader;
import com.google.gwtorm.server.OrmException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

/** Generates a concrete implementation of an {@link Access} extension. */
class AccessGen implements Opcodes {
  private static final String REL_ALIAS = "T";

  private static enum DmlType {
    INSERT("bindOneInsert"),

    UPDATE("bindOneUpdate"),

    DELETE("bindOneDelete");

    final String methodName;

    DmlType(final String m) {
      methodName = m;
    }
  }

  private final GeneratedClassLoader classLoader;
  private final RelationModel model;
  private final SqlDialect dialect;

  private ClassWriter cw;
  private String superTypeName;
  private String implClassName;
  private String implTypeName;
  private Type entityType;

  AccessGen(final GeneratedClassLoader loader, final RelationModel rm, final SqlDialect sd) {
    classLoader = loader;
    model = rm;
    dialect = sd;
    entityType = Type.getObjectType(model.getEntityTypeClassName().replace('.', '/'));
  }

  public Class<?> create() throws OrmException {
    init();
    implementConstructor();
    implementGetString("getRelationName", model.getRelationName());
    implementGetString("getInsertOneSql", model.getInsertOneSql(dialect));
    implementGetRelationID();

    if (model.getPrimaryKey() != null) {
      if (model.getDependentColumns().isEmpty()) {
        implementMissingGetString("getUpdateOneSql", "update");
      } else {
        implementGetString("getUpdateOneSql", model.getUpdateOneSql(dialect));
      }
      implementGetString("getDeleteOneSql", model.getDeleteOneSql(dialect));
    } else {
      implementMissingGetString("getUpdateOneSql", "update");
      implementMissingGetString("getDeleteOneSql", "delete");
    }

    implementPrimaryKey();
    implementGetOne();
    implementNewEntityInstance();
    implementBindOne(DmlType.INSERT);
    implementBindOne(DmlType.UPDATE);
    implementBindOne(DmlType.DELETE);
    implementBindOneFetch();

    if (model.getPrimaryKey() != null) {
      implementKeyQuery(model.getPrimaryKey());
      if ((model.getPrimaryKey().getField().isNested()
              || !model.getPrimaryKey().getField().getPrimitiveType().isPrimitive())
          && model.getPrimaryKey().getAllLeafColumns().size() == 1) {
        overrideGetMany();
      }
    }

    for (final QueryModel q : model.getQueries()) {
      implementQuery(q);
    }
    implementQuery(new QueryModel(model, "iterateAllEntities", ""));

    cw.visitEnd();
    classLoader.defineClass(implClassName, cw.toByteArray());
    return loadClass();
  }

  private Class<?> loadClass() throws OrmException {
    try {
      return Class.forName(implClassName, false, classLoader);
    } catch (ClassNotFoundException err) {
      throw new OrmException("Cannot load generated class", err);
    }
  }

  private void init() {
    superTypeName = Type.getInternalName(JdbcAccess.class);
    implClassName =
        model.getEntityTypeClassName()
            + "_Access_"
            + model.getMethodName()
            + "_"
            + Util.createRandomName();
    implTypeName = implClassName.replace('.', '/');

    cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    cw.visit(
        V1_3,
        ACC_PUBLIC | ACC_FINAL | ACC_SUPER,
        implTypeName,
        null,
        superTypeName,
        new String[] {model.getAccessInterfaceName().replace('.', '/')});
  }

  private void implementConstructor() {
    final String consName = "<init>";
    final String consDesc =
        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {Type.getType(JdbcSchema.class)});
    final MethodVisitor mv;
    mv = cw.visitMethod(ACC_PUBLIC, consName, consDesc, null, null);
    mv.visitCode();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKESPECIAL, superTypeName, consName, consDesc);
    mv.visitInsn(RETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
  }

  private void implementGetString(final String methodName, final String returnValue) {
    final MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC | ACC_FINAL,
            methodName,
            Type.getMethodDescriptor(Type.getType(String.class), new Type[] {}),
            null,
            null);
    mv.visitCode();
    mv.visitLdcInsn(returnValue);
    mv.visitInsn(ARETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
  }

  private void implementGetRelationID() {
    final MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC | ACC_FINAL,
            "getRelationID",
            Type.getMethodDescriptor(Type.INT_TYPE, new Type[] {}),
            null,
            null);
    mv.visitCode();
    new CodeGenSupport(mv).push(model.getRelationID());
    mv.visitInsn(IRETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
  }

  private void implementMissingGetString(final String methodName, final String why) {
    final MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC | ACC_FINAL,
            methodName,
            Type.getMethodDescriptor(Type.getType(String.class), new Type[] {}),
            null,
            null);
    mv.visitCode();
    throwUnsupported(mv, model.getMethodName() + " does not support " + why);
    mv.visitInsn(RETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
  }

  private void throwUnsupported(final MethodVisitor mv, final String message) {
    final Type eType = Type.getType(UnsupportedOperationException.class);
    mv.visitTypeInsn(NEW, eType.getInternalName());
    mv.visitInsn(DUP);
    mv.visitLdcInsn(message);
    mv.visitMethodInsn(
        INVOKESPECIAL,
        eType.getInternalName(),
        "<init>",
        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {Type.getType(String.class)}));
    mv.visitInsn(ATHROW);
  }

  private void implementPrimaryKey() {
    final KeyModel pk = model.getPrimaryKey();
    final MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC | ACC_FINAL,
            "primaryKey",
            Type.getMethodDescriptor(
                Type.getType(Key.class), new Type[] {Type.getType(Object.class)}),
            null,
            null);
    mv.visitCode();
    if (pk != null && pk.getField().isNested()) {
      final ColumnModel pkf = pk.getField();
      mv.visitVarInsn(ALOAD, 1);
      mv.visitTypeInsn(CHECKCAST, entityType.getInternalName());
      mv.visitFieldInsn(
          GETFIELD,
          entityType.getInternalName(),
          pkf.getFieldName(),
          CodeGenSupport.toType(pkf).getDescriptor());
    } else {
      mv.visitInsn(ACONST_NULL);
    }
    mv.visitInsn(ARETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
  }

  private void implementGetOne() {
    final KeyModel pk = model.getPrimaryKey();

    final MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC | ACC_FINAL,
            "get",
            Type.getMethodDescriptor(
                Type.getType(Object.class), new Type[] {Type.getType(Key.class)}),
            null,
            new String[] {Type.getType(OrmException.class).getInternalName()});
    mv.visitCode();
    if (pk != null && pk.getField().isNested()) {
      final Type keyType = CodeGenSupport.toType(pk.getField());
      mv.visitVarInsn(ALOAD, 0);
      mv.visitVarInsn(ALOAD, 1);
      mv.visitTypeInsn(CHECKCAST, keyType.getInternalName());
      mv.visitMethodInsn(
          INVOKEVIRTUAL,
          implTypeName,
          pk.getName(),
          Type.getMethodDescriptor(entityType, new Type[] {keyType}));
      mv.visitInsn(ARETURN);
    } else {
      throwUnsupported(mv, model.getMethodName() + " does not support get(Key)");
    }
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
  }

  private void implementNewEntityInstance() {
    final MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC | ACC_FINAL,
            "newEntityInstance",
            Type.getMethodDescriptor(Type.getType(Object.class), new Type[] {}),
            null,
            null);
    mv.visitCode();
    mv.visitTypeInsn(NEW, entityType.getInternalName());
    mv.visitInsn(DUP);
    mv.visitMethodInsn(
        INVOKESPECIAL,
        entityType.getInternalName(),
        "<init>",
        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
    mv.visitInsn(ARETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
  }

  private void implementBindOne(final DmlType type) {
    final MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC | ACC_FINAL,
            type.methodName,
            Type.getMethodDescriptor(
                Type.VOID_TYPE,
                new Type[] {Type.getType(PreparedStatement.class), Type.getType(Object.class)}),
            null,
            new String[] {Type.getType(SQLException.class).getInternalName()});
    mv.visitCode();

    if (type != DmlType.INSERT && model.getPrimaryKey() == null) {
      throwUnsupported(mv, model.getMethodName() + " has no primary key");
      mv.visitInsn(RETURN);
      mv.visitMaxs(-1, -1);
      mv.visitEnd();
    }

    mv.visitVarInsn(ALOAD, 2);
    mv.visitTypeInsn(CHECKCAST, entityType.getInternalName());
    mv.visitVarInsn(ASTORE, 2);

    final CodeGenSupport cgs = new CodeGenSupport(mv);
    cgs.setEntityType(entityType);

    for (final ColumnModel col : model.getRowVersionColumns()) {
      cgs.setFieldReference(col);
      cgs.fieldSetBegin();
      cgs.pushFieldValue();
      mv.visitInsn(ICONST_1);
      mv.visitInsn(IADD);
      cgs.fieldSetEnd();
    }
    cgs.resetColumnIndex(0);

    if (type != DmlType.DELETE) {
      final List<ColumnModel> cols = new ArrayList<>();
      cols.addAll(model.getDependentFields());
      cols.addAll(model.getRowVersionFields());
      for (final ColumnModel field : cols) {
        doBindOne(mv, cgs, field);
      }
    }

    for (final ColumnModel col : model.getPrimaryKeyColumns()) {
      cgs.setFieldReference(col);
      dialect.getSqlTypeInfo(col).generatePreparedStatementSet(cgs);
    }
    if (type != DmlType.INSERT) {
      for (final ColumnModel col : model.getRowVersionColumns()) {
        cgs.setFieldReference(col);
        cgs.pushSqlHandle();
        cgs.pushColumnIndex();
        cgs.pushFieldValue();
        mv.visitInsn(ICONST_1);
        mv.visitInsn(ISUB);
        cgs.invokePreparedStatementSet("Int");
      }
    }

    mv.visitInsn(RETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
  }

  private void doBindOne(
      final MethodVisitor mv, final CodeGenSupport cgs, final ColumnModel field) {
    if (field.isNested() && field.isNotNull()) {
      for (final ColumnModel c : field.getAllLeafColumns()) {
        doBindOne(mv, cgs, c);
      }

    } else if (field.isNested()) {
      final int colIdx = cgs.getColumnIndex();
      final Label isnull = new Label();
      final Label end = new Label();

      cgs.setFieldReference(field);
      cgs.pushFieldValue();
      mv.visitJumpInsn(IFNULL, isnull);
      cgs.resetColumnIndex(colIdx);
      for (final ColumnModel c : field.getNestedColumns()) {
        doBindOne(mv, cgs, c);
      }
      mv.visitJumpInsn(GOTO, end);

      mv.visitLabel(isnull);
      cgs.resetColumnIndex(colIdx);
      for (final ColumnModel c : field.getAllLeafColumns()) {
        cgs.setFieldReference(c);
        dialect.getSqlTypeInfo(c).generatePreparedStatementNull(cgs);
      }

      mv.visitLabel(end);
    } else {
      cgs.setFieldReference(field);
      dialect.getSqlTypeInfo(field).generatePreparedStatementSet(cgs);
    }
  }

  private void implementBindOneFetch() {
    final MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC | ACC_FINAL,
            "bindOneFetch",
            Type.getMethodDescriptor(
                Type.VOID_TYPE,
                new Type[] {Type.getType(ResultSet.class), Type.getType(Object.class)}),
            null,
            new String[] {Type.getType(SQLException.class).getInternalName()});
    mv.visitCode();

    mv.visitVarInsn(ALOAD, 2);
    mv.visitTypeInsn(CHECKCAST, entityType.getInternalName());
    mv.visitVarInsn(ASTORE, 2);

    final CodeGenSupport cgs = new CodeGenSupport(mv);
    cgs.setEntityType(entityType);

    if (model.getPrimaryKey() != null && model.getPrimaryKey().getField().isNested()) {
      final ColumnModel pkf = model.getPrimaryKey().getField();
      final Type vType = CodeGenSupport.toType(pkf);
      final int oldIdx = cgs.getColumnIndex();
      cgs.setFieldReference(pkf);
      cgs.fieldSetBegin();
      mv.visitTypeInsn(NEW, vType.getInternalName());
      mv.visitInsn(DUP);
      mv.visitMethodInsn(
          INVOKESPECIAL,
          vType.getInternalName(),
          "<init>",
          Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
      cgs.fieldSetEnd();
      cgs.resetColumnIndex(oldIdx);
    }

    final List<ColumnModel> cols = new ArrayList<>();
    cols.addAll(model.getDependentFields());
    cols.addAll(model.getRowVersionFields());
    cols.addAll(model.getPrimaryKeyColumns());
    for (final ColumnModel field : cols) {
      doFetchOne(mv, cgs, field, -1);
    }

    mv.visitInsn(RETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
  }

  private void doFetchOne(
      final MethodVisitor mv,
      final CodeGenSupport cgs,
      final ColumnModel field,
      final int reportLiveInto) {
    if (field.isNested()) {
      int oldIdx = cgs.getColumnIndex();
      final Type vType = CodeGenSupport.toType(field);
      final int livecnt;

      if (field.isNotNull()) {
        livecnt = -1;
      } else {
        livecnt = cgs.newLocal();
        cgs.push(0);
        mv.visitVarInsn(ISTORE, livecnt);
      }

      cgs.setFieldReference(field);
      cgs.fieldSetBegin();
      mv.visitTypeInsn(NEW, vType.getInternalName());
      mv.visitInsn(DUP);
      mv.visitMethodInsn(
          INVOKESPECIAL,
          vType.getInternalName(),
          "<init>",
          Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
      cgs.fieldSetEnd();

      cgs.resetColumnIndex(oldIdx);
      for (final ColumnModel c : field.getNestedColumns()) {
        doFetchOne(mv, cgs, c, livecnt);
      }

      if (livecnt >= 0) {
        oldIdx = cgs.getColumnIndex();

        final Label islive = new Label();
        mv.visitVarInsn(ILOAD, livecnt);
        mv.visitJumpInsn(IFNE, islive);
        cgs.setFieldReference(field);
        cgs.fieldSetBegin();
        mv.visitInsn(ACONST_NULL);
        cgs.fieldSetEnd();

        if (reportLiveInto >= 0) {
          final Label end = new Label();
          mv.visitJumpInsn(GOTO, end);
          mv.visitLabel(islive);
          mv.visitIincInsn(reportLiveInto, 1);
          mv.visitLabel(end);
        } else {
          mv.visitLabel(islive);
        }

        cgs.resetColumnIndex(oldIdx);
        cgs.freeLocal(livecnt);
      }

    } else {
      final int dupTo;
      if (reportLiveInto >= 0 && CodeGenSupport.toType(field).getSort() == Type.OBJECT) {
        dupTo = cgs.newLocal();
      } else {
        dupTo = -1;
      }

      cgs.setFieldReference(field);
      cgs.setDupOnFieldSetEnd(dupTo);
      dialect.getSqlTypeInfo(field).generateResultSetGet(cgs);

      if (reportLiveInto >= 0) {
        final Label wasnull = new Label();
        if (dupTo >= 0) {
          mv.visitVarInsn(ALOAD, dupTo);
          mv.visitJumpInsn(IFNULL, wasnull);
          cgs.freeLocal(dupTo);
        } else {
          cgs.pushSqlHandle();
          mv.visitMethodInsn(
              INVOKEINTERFACE,
              Type.getType(ResultSet.class).getInternalName(),
              "wasNull",
              Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[] {}));
          mv.visitJumpInsn(IFNE, wasnull);
        }
        mv.visitIincInsn(reportLiveInto, 1);
        mv.visitLabel(wasnull);
      }
    }
  }

  private void implementKeyQuery(final KeyModel info) {
    final Type keyType = CodeGenSupport.toType(info.getField());
    final StringBuilder query = new StringBuilder();
    query.append(model.getSelectSql(dialect, REL_ALIAS));
    query.append(" WHERE ");
    int nth = 1;
    for (final Iterator<ColumnModel> i = info.getAllLeafColumns().iterator(); i.hasNext(); ) {
      final ColumnModel c = i.next();
      query.append(REL_ALIAS);
      query.append('.');
      query.append(c.getColumnName());
      query.append('=');
      query.append(dialect.getParameterPlaceHolder(nth++));
      if (i.hasNext()) {
        query.append(" AND ");
      }
    }

    final MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC | ACC_FINAL,
            info.getName(),
            Type.getMethodDescriptor(entityType, new Type[] {keyType}),
            null,
            new String[] {Type.getType(OrmException.class).getInternalName()});
    mv.visitCode();

    final int keyvar = 1, psvar = keyvar + keyType.getSize();
    mv.visitVarInsn(ALOAD, 0);
    mv.visitLdcInsn(query.toString());
    mv.visitMethodInsn(
        INVOKEVIRTUAL,
        superTypeName,
        "prepareStatement",
        Type.getMethodDescriptor(
            Type.getType(PreparedStatement.class), new Type[] {Type.getType(String.class)}));
    mv.visitVarInsn(ASTORE, psvar);

    final CodeGenSupport cgs =
        new CodeGenSupport(mv) {
          @Override
          public void pushSqlHandle() {
            mv.visitVarInsn(ALOAD, psvar);
          }

          @Override
          public void pushFieldValue() {
            appendGetField(getFieldReference());
          }

          @Override
          protected void appendGetField(final ColumnModel c) {
            if (c.getParent() == null) {
              loadVar(keyType, keyvar);
            } else {
              super.appendGetField(c);
            }
          }
        };
    for (final ColumnModel c : info.getAllLeafColumns()) {
      cgs.setFieldReference(c);
      dialect.getSqlTypeInfo(c).generatePreparedStatementSet(cgs);
    }

    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, psvar);
    mv.visitMethodInsn(
        INVOKEVIRTUAL,
        superTypeName,
        "queryOne",
        Type.getMethodDescriptor(
            Type.getType(Object.class), new Type[] {Type.getType(PreparedStatement.class)}));
    mv.visitTypeInsn(CHECKCAST, entityType.getInternalName());
    mv.visitInsn(ARETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
  }

  private void overrideGetMany() {
    final KeyModel pk = model.getPrimaryKey();
    final StringBuilder query = new StringBuilder();
    query.append(model.getSelectSql(dialect, REL_ALIAS));
    query.append(" WHERE ");
    final ColumnModel pkcol = pk.getAllLeafColumns().iterator().next();
    query.append(REL_ALIAS);
    query.append('.');
    query.append(pkcol.getColumnName());
    query.append(" IN");

    final MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC | ACC_FINAL,
            "getBySqlIn",
            Type.getMethodDescriptor(
                Type.getType(com.google.gwtorm.server.ResultSet.class),
                new Type[] {Type.getType(Collection.class)}),
            null,
            new String[] {Type.getType(OrmException.class).getInternalName()});
    mv.visitCode();

    final int keyset = 1;
    final int psvar = 2;
    final int itrvar = 3;
    final int colvar = 4;
    final int keyvar = 5;

    mv.visitVarInsn(ALOAD, 0);
    mv.visitLdcInsn(query.toString());
    mv.visitVarInsn(ALOAD, keyset);
    mv.visitMethodInsn(
        INVOKEVIRTUAL,
        superTypeName,
        "prepareBySqlIn",
        Type.getMethodDescriptor(
            Type.getType(PreparedStatement.class),
            new Type[] {Type.getType(String.class), Type.getType(Collection.class)}));
    mv.visitVarInsn(ASTORE, psvar);

    mv.visitVarInsn(ALOAD, keyset);
    mv.visitMethodInsn(
        INVOKEINTERFACE,
        Type.getInternalName(Collection.class),
        "iterator",
        Type.getMethodDescriptor(Type.getType(Iterator.class), new Type[] {}));
    mv.visitVarInsn(ASTORE, itrvar);

    mv.visitInsn(ICONST_1);
    mv.visitVarInsn(ISTORE, colvar);

    final Label endbind = new Label();
    final Label again = new Label();
    mv.visitLabel(again);
    mv.visitVarInsn(ALOAD, itrvar);
    mv.visitMethodInsn(
        INVOKEINTERFACE,
        Type.getInternalName(Iterator.class),
        "hasNext",
        Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[] {}));
    mv.visitJumpInsn(IFEQ, endbind);

    mv.visitVarInsn(ALOAD, itrvar);
    mv.visitMethodInsn(
        INVOKEINTERFACE,
        Type.getInternalName(Iterator.class),
        "next",
        Type.getMethodDescriptor(Type.getType(Object.class), new Type[] {}));
    mv.visitTypeInsn(CHECKCAST, CodeGenSupport.toType(pk.getField()).getInternalName());
    mv.visitVarInsn(ASTORE, keyvar);

    final CodeGenSupport cgs =
        new CodeGenSupport(mv) {
          @Override
          public void pushSqlHandle() {
            mv.visitVarInsn(ALOAD, psvar);
          }

          @Override
          public void pushFieldValue() {
            appendGetField(getFieldReference());
          }

          @Override
          public void pushColumnIndex() {
            mv.visitVarInsn(ILOAD, colvar);
          }

          @Override
          protected void appendGetField(final ColumnModel c) {
            if (c.getParent() == null) {
              mv.visitVarInsn(ALOAD, keyvar);
            } else {
              super.appendGetField(c);
            }
          }
        };

    cgs.setFieldReference(pkcol);
    dialect.getSqlTypeInfo(pkcol).generatePreparedStatementSet(cgs);
    mv.visitIincInsn(colvar, 1);
    mv.visitJumpInsn(GOTO, again);

    mv.visitLabel(endbind);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, psvar);
    mv.visitMethodInsn(
        INVOKEVIRTUAL,
        superTypeName,
        "queryList",
        Type.getMethodDescriptor(
            Type.getType(com.google.gwtorm.server.ResultSet.class),
            new Type[] {Type.getType(PreparedStatement.class)}));
    mv.visitInsn(ARETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
  }

  private void implementQuery(final QueryModel info) {
    final List<ColumnModel> pCols = info.getParameters();
    final boolean hasLimitParam = info.hasLimitParameter();
    final Type[] pTypes = new Type[pCols.size() + (hasLimitParam ? 1 : 0)];
    final int[] pVars = new int[pTypes.length];
    int nextVar = 1;
    for (int i = 0; i < pCols.size(); i++) {
      pTypes[i] = CodeGenSupport.toType(pCols.get(i));
      pVars[i] = nextVar;
      nextVar += pTypes[i].getSize();
    }
    if (hasLimitParam) {
      pTypes[pTypes.length - 1] = Type.INT_TYPE;
      pVars[pTypes.length - 1] = nextVar;
      nextVar += Type.INT_TYPE.getSize();
    }

    final int psvar = nextVar++;
    final MethodVisitor mv =
        cw.visitMethod(
            ACC_PUBLIC | ACC_FINAL,
            info.getName(),
            Type.getMethodDescriptor(
                Type.getType(com.google.gwtorm.server.ResultSet.class), pTypes),
            null,
            new String[] {Type.getType(OrmException.class).getInternalName()});
    mv.visitCode();

    mv.visitVarInsn(ALOAD, 0);
    mv.visitLdcInsn(info.getSelectSql(dialect, REL_ALIAS));
    mv.visitMethodInsn(
        INVOKEVIRTUAL,
        superTypeName,
        "prepareStatement",
        Type.getMethodDescriptor(
            Type.getType(PreparedStatement.class), new Type[] {Type.getType(String.class)}));
    mv.visitVarInsn(ASTORE, psvar);

    final int argIdx[] = new int[] {0};
    final CodeGenSupport cgs =
        new CodeGenSupport(mv) {
          @Override
          public void pushSqlHandle() {
            mv.visitVarInsn(ALOAD, psvar);
          }

          @Override
          public void pushFieldValue() {
            appendGetField(getFieldReference());
          }

          @Override
          protected void appendGetField(final ColumnModel c) {
            final int n = argIdx[0];
            if (c == pCols.get(n)) {
              loadVar(pTypes[n], pVars[n]);
            } else {
              super.appendGetField(c);
            }
          }
        };
    for (final ColumnModel c : pCols) {
      if (c.isNested()) {
        for (final ColumnModel n : c.getAllLeafColumns()) {
          cgs.setFieldReference(n);
          dialect.getSqlTypeInfo(n).generatePreparedStatementSet(cgs);
        }
      } else {
        cgs.setFieldReference(c);
        dialect.getSqlTypeInfo(c).generatePreparedStatementSet(cgs);
      }
      argIdx[0]++;
    }

    if (info.hasLimit()) {
      if (hasLimitParam || !dialect.selectHasLimit()) {
        mv.visitVarInsn(ALOAD, psvar);
        if (hasLimitParam) {
          if (dialect.selectHasLimit()) {
            CodeGenSupport cgs2 =
                new CodeGenSupport(mv) {
                  @Override
                  public void pushSqlHandle() {
                    mv.visitVarInsn(ALOAD, psvar);
                  }

                  @Override
                  public void pushFieldValue() {
                    final int n = argIdx[0];
                    loadVar(pTypes[n], pVars[n]);
                  }
                };
            cgs2.resetColumnIndex(cgs.getColumnIndex() + 1);
            dialect.getSqlTypeInfo(Integer.TYPE).generatePreparedStatementSet(cgs2);
          }
          mv.visitVarInsn(ILOAD, pVars[pTypes.length - 1]);
        } else {
          cgs.push(info.getStaticLimit());
        }
        mv.visitMethodInsn(
            INVOKEINTERFACE,
            Type.getType(PreparedStatement.class).getInternalName(),
            "setMaxRows",
            Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {Type.INT_TYPE}));
      }
    }

    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, psvar);
    mv.visitMethodInsn(
        INVOKEVIRTUAL,
        superTypeName,
        "queryList",
        Type.getMethodDescriptor(
            Type.getType(com.google.gwtorm.server.ResultSet.class),
            new Type[] {Type.getType(PreparedStatement.class)}));
    mv.visitInsn(ARETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
  }
}
