// Copyright 2009 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.protobuf;

import com.google.gwtorm.client.Column;
import com.google.gwtorm.schema.ColumnModel;
import com.google.gwtorm.schema.Util;
import com.google.gwtorm.schema.java.JavaColumnModel;
import com.google.gwtorm.server.CodeGenSupport;
import com.google.gwtorm.server.GeneratedClassLoader;
import com.google.gwtorm.server.OrmException;
import com.google.protobuf.ByteString;
import com.google.protobuf.CodedInputStream;
import com.google.protobuf.CodedOutputStream;
import com.google.protobuf.WireFormat;

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;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.TreeSet;

/** Generates {@link ProtobufCodec} implementations. */
class CodecGen<T> implements Opcodes {
  private static final Type illegalStateException =
      Type.getType(IllegalStateException.class);
  private static final Type collection =
      Type.getType(java.util.Collection.class);
  private static final Type iterator = Type.getType(java.util.Iterator.class);
  private static final Type string = Type.getType(String.class);
  private static final Type enumType = Type.getType(Enum.class);
  private static final Type byteString = Type.getType(ByteString.class);
  private static final Type object = Type.getType(Object.class);
  private static final Type codedOutputStream =
      Type.getType(CodedOutputStream.class);
  private static final Type codedInputStream =
      Type.getType(CodedInputStream.class);
  private final GeneratedClassLoader classLoader;
  private final Class<T> pojo;
  private final Type pojoType;

  private ClassWriter cw;
  private JavaColumnModel[] myFields;
  private String superTypeName;
  private String implClassName;
  private String implTypeName;

  private Map<Class<?>, NestedCodec> nestedCodecs;

  public CodecGen(final GeneratedClassLoader loader, final Class<T> t) {
    classLoader = loader;
    pojo = t;
    pojoType = Type.getType(pojo);
    nestedCodecs = new HashMap<Class<?>, NestedCodec>();
  }

  public ProtobufCodec<T> create() throws OrmException {
    myFields = scanFields(pojo);

    init();
    implementNewInstanceObject();
    implementNewInstanceSelf();

    implementSizeofObject();
    implementSizeofSelf();

    implementEncodeObject();
    implementEncodeSelf();

    implementMergeFromObject();
    implementMergeFromSelf();

    implementCodecFields();
    implementStaticInit();
    implementConstructor();
    cw.visitEnd();
    classLoader.defineClass(implClassName, cw.toByteArray());

    try {
      final Class<?> c = Class.forName(implClassName, true, classLoader);
      return cast(c.newInstance());
    } catch (InstantiationException e) {
      throw new OrmException("Cannot create new encoder", e);
    } catch (IllegalAccessException e) {
      throw new OrmException("Cannot create new encoder", e);
    } catch (ClassNotFoundException e) {
      throw new OrmException("Cannot create new encoder", e);
    }
  }

  private static JavaColumnModel[] scanFields(Class<?> in) throws OrmException {
    final Collection<JavaColumnModel> col = new ArrayList<JavaColumnModel>();
    while (in != null) {
      for (final Field f : JavaColumnModel.getDeclaredFields(in)) {
        if (f.getAnnotation(Column.class) != null) {
          col.add(new JavaColumnModel(f));
        }
      }
      in = in.getSuperclass();
    }
    if (col.isEmpty()) {
      throw new OrmException(
          "Cannot create new encoder, no @Column fields found");
    }
    return sort(col);
  }

  private static JavaColumnModel[] sort(
      final Collection<? extends ColumnModel> col) {
    JavaColumnModel[] out = col.toArray(new JavaColumnModel[col.size()]);
    Arrays.sort(out, new Comparator<JavaColumnModel>() {
      @Override
      public int compare(JavaColumnModel o1, JavaColumnModel o2) {
        return o1.getColumnID() - o2.getColumnID();
      }
    });
    return out;
  }

  @SuppressWarnings("unchecked")
  private static <T> ProtobufCodec<T> cast(final Object c) {
    return (ProtobufCodec<T>) c;
  }

  private void init() {
    superTypeName = Type.getInternalName(ProtobufCodec.class);
    implClassName = pojo.getName() + "_protobuf_" + 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[] {});
  }

  private void implementCodecFields() {
    for (NestedCodec other : nestedCodecs.values()) {
      cw.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, other.field,
          other.codecType.getDescriptor(), null, null).visitEnd();
    }
  }

  private void implementStaticInit() {
    final MethodVisitor mv =
        cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", Type
            .getMethodDescriptor(Type.VOID_TYPE, new Type[] {}), null, null);
    mv.visitCode();

    for (NestedCodec other : nestedCodecs.values()) {
      mv.visitTypeInsn(NEW, other.codecType.getInternalName());
      mv.visitInsn(DUP);
      mv.visitMethodInsn(INVOKESPECIAL, other.codecType.getInternalName(),
          "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
      mv.visitFieldInsn(PUTSTATIC, implTypeName, other.field, other.codecType
          .getDescriptor());
    }

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

  private void implementConstructor() {
    final String consName = "<init>";
    final String consDesc =
        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {});
    final MethodVisitor mv =
        cw.visitMethod(ACC_PUBLIC, consName, consDesc, null, null);
    mv.visitCode();

    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, superTypeName, consName, consDesc);

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

  private void implementNewInstanceObject() {
    final MethodVisitor mv =
        cw.visitMethod(ACC_PUBLIC, "newInstance", Type.getMethodDescriptor(
            object, new Type[] {}), null, new String[] {});
    mv.visitCode();

    mv.visitTypeInsn(NEW, pojoType.getInternalName());
    mv.visitInsn(DUP);
    mv.visitMethodInsn(INVOKESPECIAL, pojoType.getInternalName(), "<init>",
        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));

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

  private void implementNewInstanceSelf() {
    final MethodVisitor mv =
        cw.visitMethod(ACC_PUBLIC, "newInstance", Type.getMethodDescriptor(
            pojoType, new Type[] {}), null, new String[] {});
    mv.visitCode();

    mv.visitTypeInsn(NEW, pojoType.getInternalName());
    mv.visitInsn(DUP);
    mv.visitMethodInsn(INVOKESPECIAL, pojoType.getInternalName(), "<init>",
        Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));

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

  private void implementSizeofObject() {
    final MethodVisitor mv =
        cw.visitMethod(ACC_PUBLIC, "sizeof", Type.getMethodDescriptor(
            Type.INT_TYPE, new Type[] {object}), null, new String[] {});
    mv.visitCode();
    final SizeofCGS cgs = new SizeofCGS(mv);
    cgs.sizeVar = cgs.newLocal();
    cgs.setEntityType(pojoType);

    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(CHECKCAST, pojoType.getInternalName());
    mv.visitMethodInsn(INVOKEVIRTUAL, implTypeName, "sizeof", Type
        .getMethodDescriptor(Type.INT_TYPE, new Type[] {pojoType}));

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

  private void implementSizeofSelf() throws OrmException {
    final MethodVisitor mv =
        cw.visitMethod(ACC_PUBLIC, "sizeof", Type.getMethodDescriptor(
            Type.INT_TYPE, new Type[] {pojoType}), null, new String[] {});
    mv.visitCode();
    final SizeofCGS cgs = new SizeofCGS(mv);
    cgs.sizeVar = cgs.newLocal();
    cgs.setEntityType(pojoType);

    cgs.push(0);
    mv.visitVarInsn(ISTORE, cgs.sizeVar);
    sizeofMessage(myFields, mv, cgs);

    mv.visitVarInsn(ILOAD, cgs.sizeVar);
    mv.visitInsn(IRETURN);
    mv.visitMaxs(-1, -1);
    mv.visitEnd();
  }

  private void sizeofMessage(final JavaColumnModel[] myFields,
      final MethodVisitor mv, final SizeofCGS cgs) throws OrmException {
    for (final JavaColumnModel f : myFields) {
      if (f.isNested()) {
        final NestedCodec n = nestedFor(f);
        final Label end = new Label();
        cgs.setFieldReference(f);
        cgs.pushFieldValue();
        mv.visitJumpInsn(IFNULL, end);

        final int msgSizeVar = cgs.newLocal();
        mv.visitFieldInsn(GETSTATIC, implTypeName, n.field, n.codecType
            .getDescriptor());
        cgs.pushFieldValue();
        mv.visitMethodInsn(INVOKEVIRTUAL, n.codecType.getInternalName(),
            "sizeof", Type.getMethodDescriptor(Type.INT_TYPE,
                new Type[] {n.pojoType}));
        mv.visitVarInsn(ISTORE, msgSizeVar);

        cgs.preinc();
        cgs.push(f.getColumnID());
        cgs.doinc("computeTagSize", Type.INT_TYPE);

        cgs.preinc();
        mv.visitVarInsn(ILOAD, msgSizeVar);
        cgs.doinc("computeRawVarint32Size", Type.INT_TYPE);

        cgs.preinc();
        mv.visitVarInsn(ILOAD, msgSizeVar);
        cgs.doinc();

        cgs.freeLocal(msgSizeVar);
        mv.visitLabel(end);

      } else if (f.isCollection()) {
        sizeofCollection(f, mv, cgs);

      } else {
        sizeofScalar(mv, cgs, f);
      }
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private NestedCodec nestedFor(JavaColumnModel f) {
    Class clazz = f.getNestedClass();
    NestedCodec n = nestedCodecs.get(clazz);
    if (n == null) {
      Class<? extends ProtobufCodec> codec = null;
      Type type = Type.getType(clazz);
      if (f.getField() != null) {
        final CustomCodec cc = f.getField().getAnnotation(CustomCodec.class);
        if (cc != null) {
          codec = cc.value();
          type = object;
        }
      }
      if (codec == null) {
        codec = CodecFactory.encoder(clazz).getClass();
      }

      n = new NestedCodec("codec" + f.getColumnID(), codec, type);
      nestedCodecs.put(clazz, n);
    }
    return n;
  }

  private void sizeofCollection(final JavaColumnModel f,
      final MethodVisitor mv, final SizeofCGS cgs) throws OrmException {
    final int itr = cgs.newLocal();
    final int val = cgs.newLocal();
    final Class<?> valClazz = (Class<?>) f.getArgumentTypes()[0];
    final Type valType = Type.getType(valClazz);
    final JavaColumnModel col = collectionColumn(f, valClazz);
    final SizeofCGS ng = new SizeofCGS(mv) {
      {
        sizeVar = cgs.sizeVar;
        setEntityType(valType);
      }

      @Override
      public void pushEntity() {
        mv.visitVarInsn(ALOAD, val);
      }

      @Override
      protected void appendGetField(final ColumnModel c) {
        if (c != col) {
          super.appendGetField(c);
        }
      }

      @Override
      public int newLocal() {
        return cgs.newLocal();
      }

      @Override
      public void freeLocal(int index) {
        cgs.freeLocal(index);
      }
    };

    final Label end = new Label();
    cgs.setFieldReference(f);
    cgs.pushFieldValue();
    mv.visitJumpInsn(IFNULL, end);

    cgs.setFieldReference(f);
    cgs.pushFieldValue();
    mv.visitMethodInsn(INVOKEINTERFACE, collection.getInternalName(),
        "iterator", Type.getMethodDescriptor(iterator, new Type[] {}));
    mv.visitVarInsn(ASTORE, itr);

    final Label doloop = new Label();
    mv.visitLabel(doloop);
    mv.visitVarInsn(ALOAD, itr);
    mv.visitMethodInsn(INVOKEINTERFACE, iterator.getInternalName(), "hasNext",
        Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[] {}));
    mv.visitJumpInsn(IFEQ, end);

    mv.visitVarInsn(ALOAD, itr);
    mv.visitMethodInsn(INVOKEINTERFACE, iterator.getInternalName(), "next",
        Type.getMethodDescriptor(object, new Type[] {}));
    mv.visitTypeInsn(CHECKCAST, valType.getInternalName());
    mv.visitVarInsn(ASTORE, val);

    sizeofMessage(new JavaColumnModel[] {col}, mv, ng);
    mv.visitJumpInsn(GOTO, doloop);

    mv.visitLabel(end);
    cgs.freeLocal(itr);
    cgs.freeLocal(val);
  }

  private JavaColumnModel collectionColumn(final JavaColumnModel f,
      final Class<?> valClazz) throws OrmException {
    return new JavaColumnModel( //
        f.getField(), //
        f.getPathToFieldName(), //
        f.getColumnID(), //
        valClazz);
  }

  private void sizeofScalar(final MethodVisitor mv, final SizeofCGS cgs,
      final JavaColumnModel f) throws OrmException {
    cgs.setFieldReference(f);

    switch (Type.getType(f.getPrimitiveType()).getSort()) {
      case Type.BOOLEAN:
        cgs.preinc();
        cgs.push(f.getColumnID());
        cgs.pushFieldValue();
        cgs.doinc("computeBoolSize", Type.INT_TYPE, Type.BOOLEAN_TYPE);
        break;

      case Type.CHAR:
        cgs.preinc();
        cgs.push(f.getColumnID());
        cgs.pushFieldValue();
        cgs.doinc("computeUInt32Size", Type.INT_TYPE, Type.INT_TYPE);
        break;

      case Type.BYTE:
      case Type.SHORT:
      case Type.INT:
        cgs.preinc();
        cgs.push(f.getColumnID());
        cgs.pushFieldValue();
        cgs.doinc("computeInt32Size", Type.INT_TYPE, Type.INT_TYPE);
        break;

      case Type.FLOAT:
        cgs.preinc();
        cgs.push(f.getColumnID());
        cgs.pushFieldValue();
        cgs.doinc("computeFloatSize", Type.INT_TYPE, Type.FLOAT_TYPE);
        break;

      case Type.DOUBLE:
        cgs.preinc();
        cgs.push(f.getColumnID());
        cgs.pushFieldValue();
        cgs.doinc("computeDoubleSize", Type.INT_TYPE, Type.DOUBLE_TYPE);
        break;

      case Type.LONG:
        cgs.preinc();
        cgs.push(f.getColumnID());
        cgs.pushFieldValue();
        cgs.doinc("computeInt64Size", Type.INT_TYPE, Type.LONG_TYPE);
        break;

      case Type.ARRAY:
      case Type.OBJECT: {
        final Label end = new Label();
        cgs.pushFieldValue();
        mv.visitJumpInsn(IFNULL, end);

        if (f.getPrimitiveType() == byte[].class) {
          cgs.preinc();
          cgs.push(f.getColumnID());
          cgs.doinc("computeTagSize", Type.INT_TYPE);

          cgs.preinc();
          cgs.pushFieldValue();
          mv.visitInsn(ARRAYLENGTH);
          cgs.doinc("computeRawVarint32Size", Type.INT_TYPE);

          cgs.preinc();
          cgs.pushFieldValue();
          mv.visitInsn(ARRAYLENGTH);
          cgs.doinc();

        } else if (f.getPrimitiveType() == String.class) {
          cgs.preinc();
          cgs.push(f.getColumnID());
          cgs.pushFieldValue();
          cgs.doinc("computeStringSize", Type.INT_TYPE, string);

        } else if (f.getPrimitiveType() == java.sql.Timestamp.class
            || f.getPrimitiveType() == java.util.Date.class
            || f.getPrimitiveType() == java.sql.Date.class) {
          cgs.preinc();
          cgs.push(f.getColumnID());
          cgs.pushFieldValue();
          String tsType = Type.getType(f.getPrimitiveType()).getInternalName();
          mv.visitMethodInsn(INVOKEVIRTUAL, tsType, "getTime", Type
              .getMethodDescriptor(Type.LONG_TYPE, new Type[] {}));
          cgs.doinc("computeFixed64Size", Type.INT_TYPE, Type.LONG_TYPE);

        } else if (f.getPrimitiveType().isEnum()) {
          cgs.preinc();
          cgs.push(f.getColumnID());
          cgs.pushFieldValue();
          mv.visitMethodInsn(INVOKEVIRTUAL, enumType.getInternalName(),
              "ordinal", //
              Type.getMethodDescriptor(Type.INT_TYPE, new Type[] {}));
          cgs.doinc("computeEnumSize", Type.INT_TYPE, Type.INT_TYPE);

        } else {
          throw new OrmException("Type " + f.getPrimitiveType()
              + " not supported for field " + f.getPathToFieldName());
        }
        mv.visitLabel(end);
        break;
      }

      default:
        throw new OrmException("Type " + f.getPrimitiveType()
            + " not supported for field " + f.getPathToFieldName());
    }
  }

  private void implementEncodeObject() {
    final MethodVisitor mv =
        cw.visitMethod(ACC_PUBLIC, "encode", Type.getMethodDescriptor(
            Type.VOID_TYPE, new Type[] {object, codedOutputStream}), null,
            new String[] {});
    mv.visitCode();
    final EncodeCGS cgs = new EncodeCGS(mv);
    cgs.setEntityType(pojoType);

    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitTypeInsn(CHECKCAST, pojoType.getInternalName());
    mv.visitVarInsn(ALOAD, 2);
    mv.visitMethodInsn(INVOKEVIRTUAL, implTypeName, "encode", Type
        .getMethodDescriptor(Type.VOID_TYPE, new Type[] {pojoType,
            codedOutputStream}));

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

  private void implementEncodeSelf() throws OrmException {
    final MethodVisitor mv =
        cw.visitMethod(ACC_PUBLIC, "encode", Type.getMethodDescriptor(
            Type.VOID_TYPE, new Type[] {pojoType, codedOutputStream}), null,
            new String[] {});
    mv.visitCode();
    final EncodeCGS cgs = new EncodeCGS(mv);
    cgs.setEntityType(pojoType);

    encodeMessage(myFields, mv, cgs);

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

  private void encodeMessage(final JavaColumnModel[] myFields,
      final MethodVisitor mv, final EncodeCGS cgs) throws OrmException {
    for (final JavaColumnModel f : myFields) {
      if (f.isNested()) {
        final NestedCodec n = nestedFor(f);

        final Label end = new Label();
        cgs.setFieldReference(f);
        cgs.pushFieldValue();
        mv.visitJumpInsn(IFNULL, end);

        final int msgSizeVar = cgs.newLocal();
        mv.visitFieldInsn(GETSTATIC, implTypeName, n.field, n.codecType
            .getDescriptor());
        cgs.pushFieldValue();
        mv.visitMethodInsn(INVOKEVIRTUAL, n.codecType.getInternalName(),
            "sizeof", Type.getMethodDescriptor(Type.INT_TYPE,
                new Type[] {n.pojoType}));
        mv.visitVarInsn(ISTORE, msgSizeVar);

        cgs.pushCodedOutputStream();
        cgs.push(f.getColumnID());
        cgs.push(WireFormat.FieldType.MESSAGE.getWireType());
        mv.visitMethodInsn(INVOKEVIRTUAL, codedOutputStream.getInternalName(),
            "writeTag", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {
                Type.INT_TYPE, Type.INT_TYPE}));

        cgs.pushCodedOutputStream();
        mv.visitVarInsn(ILOAD, msgSizeVar);
        mv.visitMethodInsn(INVOKEVIRTUAL, codedOutputStream.getInternalName(),
            "writeRawVarint32", Type.getMethodDescriptor(Type.VOID_TYPE,
                new Type[] {Type.INT_TYPE}));

        mv.visitFieldInsn(GETSTATIC, implTypeName, n.field, n.codecType
            .getDescriptor());
        cgs.pushFieldValue();
        cgs.pushCodedOutputStream();
        mv.visitMethodInsn(INVOKEVIRTUAL, n.codecType.getInternalName(),
            "encode", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {
                n.pojoType, codedOutputStream}));

        cgs.freeLocal(msgSizeVar);
        mv.visitLabel(end);

      } else if (f.isCollection()) {
        encodeCollection(f, mv, cgs);

      } else {
        encodeScalar(mv, cgs, f);
      }
    }
  }

  private void encodeCollection(final JavaColumnModel f,
      final MethodVisitor mv, final EncodeCGS cgs) throws OrmException {
    final int itr = cgs.newLocal();
    final int val = cgs.newLocal();
    final Class<?> valClazz = (Class<?>) f.getArgumentTypes()[0];
    final Type valType = Type.getType(valClazz);
    final JavaColumnModel col = collectionColumn(f, valClazz);
    final EncodeCGS ng = new EncodeCGS(mv) {
      {
        sizeVar = cgs.sizeVar;
        setEntityType(valType);
      }

      @Override
      public void pushEntity() {
        mv.visitVarInsn(ALOAD, val);
      }

      @Override
      protected void appendGetField(final ColumnModel c) {
        if (c != col) {
          super.appendGetField(c);
        }
      }

      @Override
      public int newLocal() {
        return cgs.newLocal();
      }

      @Override
      public void freeLocal(int index) {
        cgs.freeLocal(index);
      }
    };

    final Label end = new Label();
    cgs.setFieldReference(f);
    cgs.pushFieldValue();
    mv.visitJumpInsn(IFNULL, end);

    cgs.setFieldReference(f);
    cgs.pushFieldValue();
    mv.visitMethodInsn(INVOKEINTERFACE, collection.getInternalName(),
        "iterator", Type.getMethodDescriptor(iterator, new Type[] {}));
    mv.visitVarInsn(ASTORE, itr);

    final Label doloop = new Label();
    mv.visitLabel(doloop);
    mv.visitVarInsn(ALOAD, itr);
    mv.visitMethodInsn(INVOKEINTERFACE, iterator.getInternalName(), "hasNext",
        Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[] {}));
    mv.visitJumpInsn(IFEQ, end);

    mv.visitVarInsn(ALOAD, itr);
    mv.visitMethodInsn(INVOKEINTERFACE, iterator.getInternalName(), "next",
        Type.getMethodDescriptor(object, new Type[] {}));
    mv.visitTypeInsn(CHECKCAST, valType.getInternalName());
    mv.visitVarInsn(ASTORE, val);

    encodeMessage(new JavaColumnModel[] {col}, mv, ng);
    mv.visitJumpInsn(GOTO, doloop);

    mv.visitLabel(end);
    cgs.freeLocal(itr);
    cgs.freeLocal(val);
  }

  private void encodeScalar(final MethodVisitor mv, final EncodeCGS cgs,
      final JavaColumnModel f) throws OrmException {
    cgs.setFieldReference(f);

    switch (Type.getType(f.getPrimitiveType()).getSort()) {
      case Type.BOOLEAN:
        cgs.pushCodedOutputStream();
        cgs.push(f.getColumnID());
        cgs.pushFieldValue();
        cgs.write("writeBool", Type.BOOLEAN_TYPE);
        break;

      case Type.CHAR:
        cgs.pushCodedOutputStream();
        cgs.push(f.getColumnID());
        cgs.pushFieldValue();
        cgs.write("writeUInt32", Type.INT_TYPE);
        break;

      case Type.BYTE:
      case Type.SHORT:
      case Type.INT:
        cgs.pushCodedOutputStream();
        cgs.push(f.getColumnID());
        cgs.pushFieldValue();
        cgs.write("writeInt32", Type.INT_TYPE);
        break;

      case Type.FLOAT:
        cgs.pushCodedOutputStream();
        cgs.push(f.getColumnID());
        cgs.pushFieldValue();
        cgs.write("writeFloat", Type.FLOAT_TYPE);
        break;

      case Type.DOUBLE:
        cgs.pushCodedOutputStream();
        cgs.push(f.getColumnID());
        cgs.pushFieldValue();
        cgs.write("writeDouble", Type.DOUBLE_TYPE);
        break;

      case Type.LONG:
        cgs.pushCodedOutputStream();
        cgs.push(f.getColumnID());
        cgs.pushFieldValue();
        cgs.write("writeInt64", Type.LONG_TYPE);
        break;

      case Type.ARRAY:
      case Type.OBJECT: {
        final Label end = new Label();
        cgs.pushFieldValue();
        mv.visitJumpInsn(IFNULL, end);

        if (f.getPrimitiveType() == byte[].class) {
          cgs.pushCodedOutputStream();
          cgs.push(f.getColumnID());
          cgs.push(WireFormat.FieldType.BYTES.getWireType());
          mv.visitMethodInsn(INVOKEVIRTUAL,
              codedOutputStream.getInternalName(), "writeTag", Type
                  .getMethodDescriptor(Type.VOID_TYPE, new Type[] {
                      Type.INT_TYPE, Type.INT_TYPE}));

          cgs.pushCodedOutputStream();
          cgs.pushFieldValue();
          mv.visitInsn(ARRAYLENGTH);
          mv.visitMethodInsn(INVOKEVIRTUAL,
              codedOutputStream.getInternalName(), "writeRawVarint32", Type
                  .getMethodDescriptor(Type.VOID_TYPE,
                      new Type[] {Type.INT_TYPE}));

          cgs.pushCodedOutputStream();
          cgs.pushFieldValue();
          mv.visitMethodInsn(INVOKEVIRTUAL,
              codedOutputStream.getInternalName(), "writeRawBytes", Type
                  .getMethodDescriptor(Type.VOID_TYPE, new Type[] {Type
                      .getType(byte[].class)}));

        } else {
          cgs.pushCodedOutputStream();
          cgs.push(f.getColumnID());
          cgs.pushFieldValue();

          if (f.getPrimitiveType() == String.class) {
            cgs.write("writeString", string);

          } else if (f.getPrimitiveType() == java.sql.Timestamp.class
              || f.getPrimitiveType() == java.util.Date.class
              || f.getPrimitiveType() == java.sql.Date.class) {
            String tsType =
                Type.getType(f.getPrimitiveType()).getInternalName();
            mv.visitMethodInsn(INVOKEVIRTUAL, tsType, "getTime", Type
                .getMethodDescriptor(Type.LONG_TYPE, new Type[] {}));
            cgs.write("writeFixed64", Type.LONG_TYPE);

          } else if (f.getPrimitiveType().isEnum()) {
            mv.visitMethodInsn(INVOKEVIRTUAL, enumType.getInternalName(),
                "ordinal", //
                Type.getMethodDescriptor(Type.INT_TYPE, new Type[] {}));
            cgs.write("writeEnum", Type.INT_TYPE);

          } else {
            throw new OrmException("Type " + f.getPrimitiveType()
                + " not supported for field " + f.getPathToFieldName());
          }
        }
        mv.visitLabel(end);
        break;
      }

      default:
        throw new OrmException("Type " + f.getPrimitiveType()
            + " not supported for field " + f.getPathToFieldName());
    }
  }

  private void implementMergeFromObject() {
    final MethodVisitor mv =
        cw.visitMethod(ACC_PUBLIC, "mergeFrom", Type.getMethodDescriptor(
            Type.VOID_TYPE, new Type[] {codedInputStream, object}), null,
            new String[] {});
    mv.visitCode();

    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ALOAD, 1);
    mv.visitVarInsn(ALOAD, 2);
    mv.visitTypeInsn(CHECKCAST, pojoType.getInternalName());
    mv.visitMethodInsn(INVOKEVIRTUAL, implTypeName, "mergeFrom", Type
        .getMethodDescriptor(Type.VOID_TYPE, new Type[] {codedInputStream,
            pojoType}));

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

  private void implementMergeFromSelf() throws OrmException {
    final MethodVisitor mv =
        cw.visitMethod(ACC_PUBLIC, "mergeFrom", Type.getMethodDescriptor(
            Type.VOID_TYPE, new Type[] {codedInputStream, pojoType}), null,
            new String[] {});
    mv.visitCode();
    final DecodeCGS cgs = new DecodeCGS(mv);
    cgs.objVar = 2;
    cgs.tagVar = cgs.newLocal();
    cgs.setEntityType(pojoType);

    decodeMessage(myFields, mv, cgs);

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

  private void decodeMessage(final JavaColumnModel[] myFields,
      final MethodVisitor mv, final DecodeCGS cgs) throws OrmException {
    final Label nextField = new Label();
    final Label end = new Label();
    mv.visitLabel(nextField);

    // while (!ci.isAtEnd) { ...
    cgs.call("readTag", Type.INT_TYPE);
    mv.visitInsn(DUP);
    mv.visitVarInsn(ISTORE, cgs.tagVar);

    cgs.push(3);
    mv.visitInsn(IUSHR);

    final Label badField = new Label();
    final int[] caseTags = new int[1 + myFields.length];
    final Label[] caseLabels = new Label[caseTags.length];

    caseTags[0] = 0;
    caseLabels[0] = new Label();

    int gaps = 0;
    for (int i = 1; i < caseTags.length; i++) {
      caseTags[i] = myFields[i - 1].getColumnID();
      caseLabels[i] = new Label();
      gaps += caseTags[i] - (caseTags[i - 1] + 1);
    }

    if (2 * gaps / 3 <= myFields.length) {
      final int min = 0;
      final int max = caseTags[caseTags.length - 1];
      final Label[] table = new Label[max + 1];
      Arrays.fill(table, badField);
      for (int idx = 0; idx < caseTags.length; idx++) {
        table[caseTags[idx]] = caseLabels[idx];
      }
      mv.visitTableSwitchInsn(min, max, badField, table);
    } else {
      mv.visitLookupSwitchInsn(badField, caseTags, caseLabels);
    }

    mv.visitLabel(caseLabels[0]);
    mv.visitJumpInsn(GOTO, end);

    for (int idx = 1; idx < caseTags.length; idx++) {
      final JavaColumnModel f = myFields[idx - 1];
      mv.visitLabel(caseLabels[idx]);
      decodeField(mv, cgs, f);
      mv.visitJumpInsn(GOTO, nextField);
    }

    // default:
    mv.visitLabel(badField);
    cgs.pushCodedInputStream();
    mv.visitVarInsn(ILOAD, cgs.tagVar);
    cgs.ncallInt("skipField", Type.BOOLEAN_TYPE);
    mv.visitInsn(POP);
    mv.visitJumpInsn(GOTO, nextField);

    mv.visitLabel(end);
    cgs.pushCodedInputStream();
    cgs.push(0);
    cgs.ncallInt("checkLastTagWas", Type.VOID_TYPE);
  }

  private void decodeField(final MethodVisitor mv, final DecodeCGS cgs,
      final JavaColumnModel f) throws OrmException {
    if (f.isNested()) {
      final NestedCodec n = nestedFor(f);
      final Label load = new Label();
      cgs.setFieldReference(f);
      cgs.pushFieldValue();
      mv.visitJumpInsn(IFNONNULL, load);

      // Since the field isn't initialized, construct it
      //
      cgs.fieldSetBegin();
      mv.visitFieldInsn(GETSTATIC, implTypeName, n.field, n.codecType
          .getDescriptor());
      mv.visitMethodInsn(INVOKEVIRTUAL, n.codecType.getInternalName(),
          "newInstance", Type.getMethodDescriptor(n.pojoType, new Type[] {}));
      if (object.equals(n.pojoType)) {
        mv.visitTypeInsn(CHECKCAST, Type.getType(f.getNestedClass())
            .getInternalName());
      }
      cgs.fieldSetEnd();

      // read the length, set a new limit, decode the message, validate
      // we stopped at the end of it as expected.
      //
      mv.visitLabel(load);
      final int limitVar = cgs.newLocal();
      cgs.pushCodedInputStream();
      cgs.call("readRawVarint32", Type.INT_TYPE);
      cgs.ncallInt("pushLimit", Type.INT_TYPE);
      mv.visitVarInsn(ISTORE, limitVar);

      mv.visitFieldInsn(GETSTATIC, implTypeName, n.field, n.codecType
          .getDescriptor());
      cgs.pushCodedInputStream();
      cgs.pushFieldValue();
      mv.visitMethodInsn(INVOKEVIRTUAL, n.codecType.getInternalName(),
          "mergeFrom", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {
              codedInputStream, n.pojoType}));

      cgs.pushCodedInputStream();
      mv.visitVarInsn(ILOAD, limitVar);
      cgs.ncallInt("popLimit", Type.VOID_TYPE);
      cgs.freeLocal(limitVar);

    } else if (f.isCollection()) {
      decodeCollection(mv, cgs, f);

    } else {
      decodeScalar(mv, cgs, f);
    }
  }

  private void decodeCollection(final MethodVisitor mv, final DecodeCGS cgs,
      final JavaColumnModel f) throws OrmException {
    final Class<?> valClazz = (Class<?>) f.getArgumentTypes()[0];
    final Type valType = Type.getType(valClazz);
    final JavaColumnModel col = collectionColumn(f, valClazz);
    final DecodeCGS ng = new DecodeCGS(mv) {
      {
        tagVar = cgs.tagVar;
        setEntityType(valType);
      }

      @Override
      public int newLocal() {
        return cgs.newLocal();
      }

      @Override
      public void freeLocal(int index) {
        cgs.freeLocal(index);
      }

      @Override
      protected void appendGetField(final ColumnModel c) {
        if (c != col) {
          super.appendGetField(c);
        }
      }

      @Override
      public void fieldSetBegin() {
        if (col.isNested()) {
          super.fieldSetBegin();
        } else {
          cgs.pushFieldValue();
        }
      }

      @Override
      public void fieldSetEnd() {
        if (col.isNested()) {
          super.fieldSetEnd();
        } else {
          mv.visitMethodInsn(INVOKEINTERFACE, collection.getInternalName(),
              "add", Type.getMethodDescriptor(Type.BOOLEAN_TYPE,
                  new Type[] {object}));
          mv.visitInsn(POP);
        }
      }
    };

    final Label notnull = new Label();
    cgs.setFieldReference(f);
    cgs.pushFieldValue();
    mv.visitJumpInsn(IFNONNULL, notnull);

    // If the field is null, try to initialize it based on its declared type.
    // If we don't know what that is, we have to throw an exception instead.
    //
    final Type concreteType;
    if (!f.getNestedClass().isInterface()
        && (f.getNestedClass().getModifiers() & Modifier.ABSTRACT) == 0) {
      concreteType = Type.getType(f.getNestedClass());

    } else if (f.getNestedClass().isAssignableFrom(ArrayList.class)) {
      concreteType = Type.getType(ArrayList.class);

    } else if (f.getNestedClass().isAssignableFrom(HashSet.class)) {
      concreteType = Type.getType(HashSet.class);

    } else if (f.getNestedClass().isAssignableFrom(TreeSet.class)) {
      concreteType = Type.getType(TreeSet.class);

    } else {
      mv.visitTypeInsn(NEW, illegalStateException.getInternalName());
      mv.visitInsn(DUP);
      mv.visitLdcInsn("Field " + f.getPathToFieldName() + " not initialized");
      mv.visitMethodInsn(INVOKESPECIAL,
          illegalStateException.getInternalName(), "<init>", Type
              .getMethodDescriptor(Type.VOID_TYPE, new Type[] {string}));
      mv.visitInsn(ATHROW);
      concreteType = null;
    }
    if (concreteType != null) {
      cgs.fieldSetBegin();
      mv.visitTypeInsn(NEW, concreteType.getInternalName());
      mv.visitInsn(DUP);
      mv.visitMethodInsn(INVOKESPECIAL, concreteType.getInternalName(),
          "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {}));
      cgs.fieldSetEnd();
    }
    mv.visitLabel(notnull);

    if (col.isNested()) {
      // If its nested, we have to build the object instance.
      //
      final NestedCodec n = nestedFor(col);
      ng.objVar = cgs.newLocal();
      mv.visitFieldInsn(GETSTATIC, implTypeName, n.field, n.codecType
          .getDescriptor());
      mv.visitMethodInsn(INVOKEVIRTUAL, n.codecType.getInternalName(),
          "newInstance", Type.getMethodDescriptor(n.pojoType, new Type[] {}));
      mv.visitVarInsn(ASTORE, ng.objVar);

      // read the length, set a new limit, decode the message, validate
      // we stopped at the end of it as expected.
      //
      final int limitVar = cgs.newLocal();
      cgs.pushCodedInputStream();
      cgs.call("readRawVarint32", Type.INT_TYPE);
      cgs.ncallInt("pushLimit", Type.INT_TYPE);
      mv.visitVarInsn(ISTORE, limitVar);

      mv.visitFieldInsn(GETSTATIC, implTypeName, n.field, n.codecType
          .getDescriptor());
      cgs.pushCodedInputStream();
      mv.visitVarInsn(ALOAD, ng.objVar);
      mv.visitMethodInsn(INVOKEVIRTUAL, n.codecType.getInternalName(),
          "mergeFrom", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {
              codedInputStream, n.pojoType}));

      cgs.pushCodedInputStream();
      mv.visitVarInsn(ILOAD, limitVar);
      cgs.ncallInt("popLimit", Type.VOID_TYPE);
      cgs.freeLocal(limitVar);
      cgs.pushFieldValue();

      mv.visitVarInsn(ALOAD, ng.objVar);
      mv.visitMethodInsn(INVOKEINTERFACE, collection.getInternalName(), "add",
          Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[] {object}));
      mv.visitInsn(POP);
      cgs.freeLocal(ng.objVar);

    } else if (col.isCollection()) {
      throw new OrmException("Cannot nest collection as member of another"
          + " collection: " + f.getPathToFieldName());

    } else {
      decodeScalar(mv, ng, col);
    }
  }

  private static void decodeScalar(final MethodVisitor mv, final DecodeCGS cgs,
      final JavaColumnModel f) throws OrmException {
    cgs.setFieldReference(f);
    cgs.fieldSetBegin();
    switch (Type.getType(f.getPrimitiveType()).getSort()) {
      case Type.BOOLEAN:
        cgs.call("readBool", Type.BOOLEAN_TYPE);
        break;

      case Type.CHAR:
        cgs.call("readUInt32", Type.INT_TYPE);
        break;

      case Type.BYTE:
      case Type.SHORT:
      case Type.INT:
        cgs.call("readInt32", Type.INT_TYPE);
        break;

      case Type.FLOAT:
        cgs.call("readFloat", Type.FLOAT_TYPE);
        break;

      case Type.DOUBLE:
        cgs.call("readDouble", Type.DOUBLE_TYPE);
        break;

      case Type.LONG:
        cgs.call("readInt64", Type.LONG_TYPE);
        break;

      default:
        if (f.getPrimitiveType() == byte[].class) {
          cgs.call("readBytes", byteString);
          mv.visitMethodInsn(INVOKEVIRTUAL, byteString.getInternalName(),
              "toByteArray", Type.getMethodDescriptor(Type
                  .getType(byte[].class), new Type[] {}));

        } else if (f.getPrimitiveType() == String.class) {
          cgs.call("readString", string);

        } else if (f.getPrimitiveType() == java.sql.Timestamp.class
            || f.getPrimitiveType() == java.util.Date.class
            || f.getPrimitiveType() == java.sql.Date.class) {
          String tsType = Type.getType(f.getPrimitiveType()).getInternalName();
          mv.visitTypeInsn(NEW, tsType);
          mv.visitInsn(DUP);
          cgs.call("readFixed64", Type.LONG_TYPE);
          mv.visitMethodInsn(INVOKESPECIAL, tsType, "<init>", //
              Type.getMethodDescriptor(Type.VOID_TYPE,
                  new Type[] {Type.LONG_TYPE}));

        } else if (f.getPrimitiveType().isEnum()) {
          Type et = Type.getType(f.getPrimitiveType());
          mv.visitMethodInsn(INVOKESTATIC, et.getInternalName(), "values", Type
              .getMethodDescriptor(Type.getType("[" + et.getDescriptor()),
                  new Type[] {}));
          cgs.call("readEnum", Type.INT_TYPE);
          mv.visitInsn(AALOAD);

        } else {
          throw new OrmException("Type " + f.getPrimitiveType()
              + " not supported for field " + f.getPathToFieldName());
        }
        break;
    }
    cgs.fieldSetEnd();
  }

  private static class SizeofCGS extends CodeGenSupport {
    int sizeVar;

    SizeofCGS(MethodVisitor method) {
      super(method);
    }

    void doinc(String name, Type... args) {
      mv.visitMethodInsn(INVOKESTATIC, codedOutputStream.getInternalName(),
          name, Type.getMethodDescriptor(Type.INT_TYPE, args));
      doinc();
    }

    void preinc() {
      mv.visitVarInsn(ILOAD, sizeVar);
    }

    void doinc() {
      mv.visitInsn(IADD);
      mv.visitVarInsn(ISTORE, sizeVar);
    }

    @Override
    public void pushEntity() {
      mv.visitVarInsn(ALOAD, 1);
    }
  }

  private static class EncodeCGS extends SizeofCGS {
    private EncodeCGS(MethodVisitor method) {
      super(method);
    }

    void pushCodedOutputStream() {
      mv.visitVarInsn(ALOAD, 2);
    }

    void write(String name, Type arg) {
      mv.visitMethodInsn(INVOKEVIRTUAL, codedOutputStream.getInternalName(),
          name, Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] {
              Type.INT_TYPE, arg}));
    }
  }

  private static class DecodeCGS extends CodeGenSupport {
    final int codedInputStreamVar = 1;
    int objVar;
    int tagVar;

    DecodeCGS(MethodVisitor method) {
      super(method);
    }

    void pushCodedInputStream() {
      mv.visitVarInsn(ALOAD, codedInputStreamVar);
    }

    void call(String name, Type ret) {
      pushCodedInputStream();
      mv.visitMethodInsn(INVOKEVIRTUAL, codedInputStream.getInternalName(),
          name, Type.getMethodDescriptor(ret, new Type[] {}));
    }

    void ncallInt(String name, Type ret) {
      mv.visitMethodInsn(INVOKEVIRTUAL, codedInputStream.getInternalName(),
          name, Type.getMethodDescriptor(ret, new Type[] {Type.INT_TYPE}));
    }

    @Override
    public void pushEntity() {
      mv.visitVarInsn(ALOAD, objVar);
    }
  }

  private static class NestedCodec {
    final String field;
    final Type codecType;
    final Type pojoType;

    NestedCodec(String field, Class<?> impl, Type pojoType) {
      this.field = field;
      this.codecType = Type.getType(impl);
      this.pojoType = pojoType;
    }
  }
}
