/*
 * ProGuard -- shrinking, optimization, obfuscation, and preverification
 *             of Java bytecode.
 *
 * Copyright (c) 2002-2011 Eric Lafortune (eric@graphics.cornell.edu)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package proguard.classfile.editor;

import proguard.classfile.*;
import proguard.classfile.attribute.*;
import proguard.classfile.attribute.annotation.*;
import proguard.classfile.attribute.annotation.visitor.*;
import proguard.classfile.attribute.preverification.*;
import proguard.classfile.attribute.preverification.visitor.*;
import proguard.classfile.attribute.visitor.*;
import proguard.classfile.constant.*;
import proguard.classfile.constant.visitor.ConstantVisitor;
import proguard.classfile.instruction.*;
import proguard.classfile.instruction.visitor.InstructionVisitor;
import proguard.classfile.util.SimplifiedVisitor;
import proguard.classfile.visitor.*;

/**
 * This ClassVisitor remaps all possible references to constant pool entries
 * of the classes that it visits, based on a given index map. It is assumed that
 * the constant pool entries themselves have already been remapped.
 *
 * @author Eric Lafortune
 */
public class ConstantPoolRemapper
extends      SimplifiedVisitor
implements   ClassVisitor,
             ConstantVisitor,
             MemberVisitor,
             AttributeVisitor,
             BootstrapMethodInfoVisitor,
             InnerClassesInfoVisitor,
             ExceptionInfoVisitor,
             InstructionVisitor,
             StackMapFrameVisitor,
             VerificationTypeVisitor,
             LocalVariableInfoVisitor,
             LocalVariableTypeInfoVisitor,
             AnnotationVisitor,
             ElementValueVisitor
{
    private final CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor(false);

    private int[] constantIndexMap;


    /**
     * Sets the given mapping of old constant pool entry indexes to their new
     * indexes.
     */
    public void setConstantIndexMap(int[] constantIndexMap)
    {
        this.constantIndexMap = constantIndexMap;
    }


    // Implementations for ClassVisitor.

    public void visitProgramClass(ProgramClass programClass)
    {
        // Remap the local constant pool references.
        programClass.u2thisClass  = remapConstantIndex(programClass.u2thisClass);
        programClass.u2superClass = remapConstantIndex(programClass.u2superClass);

        remapConstantIndexArray(programClass.u2interfaces,
                                programClass.u2interfacesCount);

        // Remap the references of the contant pool entries themselves.
        programClass.constantPoolEntriesAccept(this);

        // Remap the references in all fields, methods, and attributes.
        programClass.fieldsAccept(this);
        programClass.methodsAccept(this);
        programClass.attributesAccept(this);
    }


    public void visitLibraryClass(LibraryClass libraryClass)
    {
    }


    // Implementations for ConstantVisitor.

    public void visitIntegerConstant(Clazz clazz, IntegerConstant integerConstant)
    {
        // Nothing to do.
    }


    public void visitLongConstant(Clazz clazz, LongConstant longConstant)
    {
        // Nothing to do.
    }


    public void visitFloatConstant(Clazz clazz, FloatConstant floatConstant)
    {
        // Nothing to do.
    }


    public void visitDoubleConstant(Clazz clazz, DoubleConstant doubleConstant)
    {
        // Nothing to do.
    }


    public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
    {
        stringConstant.u2stringIndex =
            remapConstantIndex(stringConstant.u2stringIndex);
    }


    public void visitUtf8Constant(Clazz clazz, Utf8Constant utf8Constant)
    {
        // Nothing to do.
    }


    public void visitInvokeDynamicConstant(Clazz clazz, InvokeDynamicConstant invokeDynamicConstant)
    {
        invokeDynamicConstant.u2nameAndTypeIndex =
            remapConstantIndex(invokeDynamicConstant.u2nameAndTypeIndex);
    }


    public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
    {
        methodHandleConstant.u2referenceIndex =
            remapConstantIndex(methodHandleConstant.u2referenceIndex);
    }


    public void visitFieldrefConstant(Clazz clazz, FieldrefConstant fieldrefConstant)
    {
        fieldrefConstant.u2classIndex =
            remapConstantIndex(fieldrefConstant.u2classIndex);
        fieldrefConstant.u2nameAndTypeIndex =
            remapConstantIndex(fieldrefConstant.u2nameAndTypeIndex);
    }


    public void visitInterfaceMethodrefConstant(Clazz clazz, InterfaceMethodrefConstant interfaceMethodrefConstant)
    {
        interfaceMethodrefConstant.u2classIndex =
            remapConstantIndex(interfaceMethodrefConstant.u2classIndex);
        interfaceMethodrefConstant.u2nameAndTypeIndex =
            remapConstantIndex(interfaceMethodrefConstant.u2nameAndTypeIndex);
    }


    public void visitMethodrefConstant(Clazz clazz, MethodrefConstant methodrefConstant)
    {
        methodrefConstant.u2classIndex =
            remapConstantIndex(methodrefConstant.u2classIndex);
        methodrefConstant.u2nameAndTypeIndex =
            remapConstantIndex(methodrefConstant.u2nameAndTypeIndex);
    }


    public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
    {
        classConstant.u2nameIndex =
            remapConstantIndex(classConstant.u2nameIndex);
    }


    public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
    {
        methodTypeConstant.u2descriptorIndex =
            remapConstantIndex(methodTypeConstant.u2descriptorIndex);
    }


    public void visitNameAndTypeConstant(Clazz clazz, NameAndTypeConstant nameAndTypeConstant)
    {
        nameAndTypeConstant.u2nameIndex =
            remapConstantIndex(nameAndTypeConstant.u2nameIndex);
        nameAndTypeConstant.u2descriptorIndex =
            remapConstantIndex(nameAndTypeConstant.u2descriptorIndex);
    }


    // Implementations for MemberVisitor.

    public void visitProgramField(ProgramClass programClass, ProgramField programField)
    {
        visitMember(programClass, programField);
    }


    public void visitProgramMethod(ProgramClass programClass, ProgramMethod programMethod)
    {
        visitMember(programClass, programMethod);
    }


    private void visitMember(ProgramClass programClass, ProgramMember programMember)
    {
        // Remap the local constant pool references.
        programMember.u2nameIndex =
            remapConstantIndex(programMember.u2nameIndex);
        programMember.u2descriptorIndex =
            remapConstantIndex(programMember.u2descriptorIndex);

        // Remap the constant pool references of the remaining attributes.
        programMember.attributesAccept(programClass, this);
    }


    public void visitLibraryField(LibraryClass libraryClass, LibraryField libraryField)
    {
        // Library classes are left unchanged.
    }


    public void visitLibraryMethod(LibraryClass libraryClass, LibraryMethod libraryMethod)
    {
        // Library classes are left unchanged.
    }


    // Implementations for AttributeVisitor.

    public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
    {
        unknownAttribute.u2attributeNameIndex =
            remapConstantIndex(unknownAttribute.u2attributeNameIndex);

        // There's not much else we can do with unknown attributes.
    }


    public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
    {
        bootstrapMethodsAttribute.u2attributeNameIndex =
            remapConstantIndex(bootstrapMethodsAttribute.u2attributeNameIndex);

        // Remap the constant pool references of the bootstrap method entries.
        bootstrapMethodsAttribute.bootstrapMethodEntriesAccept(clazz, this);
    }


    public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
    {
        sourceFileAttribute.u2attributeNameIndex =
            remapConstantIndex(sourceFileAttribute.u2attributeNameIndex);
        sourceFileAttribute.u2sourceFileIndex =
            remapConstantIndex(sourceFileAttribute.u2sourceFileIndex);
    }


    public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
    {
        sourceDirAttribute.u2attributeNameIndex =
            remapConstantIndex(sourceDirAttribute.u2attributeNameIndex);
        sourceDirAttribute.u2sourceDirIndex       =
            remapConstantIndex(sourceDirAttribute.u2sourceDirIndex);
    }


    public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
    {
        innerClassesAttribute.u2attributeNameIndex =
            remapConstantIndex(innerClassesAttribute.u2attributeNameIndex);

        // Remap the constant pool references of the inner classes.
        innerClassesAttribute.innerClassEntriesAccept(clazz, this);
    }


    public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
    {
        enclosingMethodAttribute.u2attributeNameIndex =
            remapConstantIndex(enclosingMethodAttribute.u2attributeNameIndex);
        enclosingMethodAttribute.u2classIndex =
            remapConstantIndex(enclosingMethodAttribute.u2classIndex);
        enclosingMethodAttribute.u2nameAndTypeIndex =
            remapConstantIndex(enclosingMethodAttribute.u2nameAndTypeIndex);
    }


    public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
    {
        deprecatedAttribute.u2attributeNameIndex =
            remapConstantIndex(deprecatedAttribute.u2attributeNameIndex);
    }


    public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
    {
        syntheticAttribute.u2attributeNameIndex =
            remapConstantIndex(syntheticAttribute.u2attributeNameIndex);
    }


    public void visitSignatureAttribute(Clazz clazz, SignatureAttribute signatureAttribute)
    {
        signatureAttribute.u2attributeNameIndex =
            remapConstantIndex(signatureAttribute.u2attributeNameIndex);
        signatureAttribute.u2signatureIndex       =
            remapConstantIndex(signatureAttribute.u2signatureIndex);
    }


    public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
    {
        constantValueAttribute.u2attributeNameIndex =
            remapConstantIndex(constantValueAttribute.u2attributeNameIndex);
        constantValueAttribute.u2constantValueIndex =
            remapConstantIndex(constantValueAttribute.u2constantValueIndex);
    }


    public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
    {
        exceptionsAttribute.u2attributeNameIndex =
            remapConstantIndex(exceptionsAttribute.u2attributeNameIndex);

        // Remap the constant pool references of the exceptions.
        remapConstantIndexArray(exceptionsAttribute.u2exceptionIndexTable,
                                exceptionsAttribute.u2exceptionIndexTableLength);
    }


    public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
    {
        codeAttribute.u2attributeNameIndex =
            remapConstantIndex(codeAttribute.u2attributeNameIndex);

        // Initially, the code attribute editor doesn't contain any changes.
        codeAttributeEditor.reset(codeAttribute.u4codeLength);

        // Remap the constant pool references of the instructions.
        codeAttribute.instructionsAccept(clazz, method, this);

        // Apply the code atribute editor. It will only contain any changes if
        // the code length is changing at any point.
        codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute);

        // Remap the constant pool references of the exceptions and attributes.
        codeAttribute.exceptionsAccept(clazz, method, this);
        codeAttribute.attributesAccept(clazz, method, this);
    }


    public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
    {
        stackMapAttribute.u2attributeNameIndex =
            remapConstantIndex(stackMapAttribute.u2attributeNameIndex);

        // Remap the constant pool references of the stack map frames.
        stackMapAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
    }


    public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
    {
        stackMapTableAttribute.u2attributeNameIndex =
            remapConstantIndex(stackMapTableAttribute.u2attributeNameIndex);

        // Remap the constant pool references of the stack map frames.
        stackMapTableAttribute.stackMapFramesAccept(clazz, method, codeAttribute, this);
    }


    public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
    {
        lineNumberTableAttribute.u2attributeNameIndex =
            remapConstantIndex(lineNumberTableAttribute.u2attributeNameIndex);
    }


    public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
    {
        localVariableTableAttribute.u2attributeNameIndex =
            remapConstantIndex(localVariableTableAttribute.u2attributeNameIndex);

        // Remap the constant pool references of the local variables.
        localVariableTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
    }


    public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
    {
        localVariableTypeTableAttribute.u2attributeNameIndex =
            remapConstantIndex(localVariableTypeTableAttribute.u2attributeNameIndex);

        // Remap the constant pool references of the local variables.
        localVariableTypeTableAttribute.localVariablesAccept(clazz, method, codeAttribute, this);
    }


    public void visitAnyAnnotationsAttribute(Clazz clazz, AnnotationsAttribute annotationsAttribute)
    {
        annotationsAttribute.u2attributeNameIndex =
            remapConstantIndex(annotationsAttribute.u2attributeNameIndex);

        // Remap the constant pool references of the annotations.
        annotationsAttribute.annotationsAccept(clazz, this);
    }


    public void visitAnyParameterAnnotationsAttribute(Clazz clazz, Method method, ParameterAnnotationsAttribute parameterAnnotationsAttribute)
    {
        parameterAnnotationsAttribute.u2attributeNameIndex =
            remapConstantIndex(parameterAnnotationsAttribute.u2attributeNameIndex);

        // Remap the constant pool references of the annotations.
        parameterAnnotationsAttribute.annotationsAccept(clazz, method, this);
    }


    public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
    {
        annotationDefaultAttribute.u2attributeNameIndex =
            remapConstantIndex(annotationDefaultAttribute.u2attributeNameIndex);

        // Remap the constant pool references of the annotations.
        annotationDefaultAttribute.defaultValueAccept(clazz, this);
    }


    // Implementations for BootstrapMethodInfoVisitor.

    public void visitBootstrapMethodInfo(Clazz clazz, BootstrapMethodInfo bootstrapMethodInfo)
    {
        bootstrapMethodInfo.u2methodHandleIndex =
            remapConstantIndex(bootstrapMethodInfo.u2methodHandleIndex);

        // Remap the constant pool references of the bootstrap methods..
        remapConstantIndexArray(bootstrapMethodInfo.u2methodArguments,
                                bootstrapMethodInfo.u2methodArgumentCount);
    }


    // Implementations for InnerClassesInfoVisitor.

    public void visitInnerClassesInfo(Clazz clazz, InnerClassesInfo innerClassesInfo)
    {
        if (innerClassesInfo.u2innerClassIndex != 0)
        {
            innerClassesInfo.u2innerClassIndex =
                remapConstantIndex(innerClassesInfo.u2innerClassIndex);
        }

        if (innerClassesInfo.u2outerClassIndex != 0)
        {
            innerClassesInfo.u2outerClassIndex =
                remapConstantIndex(innerClassesInfo.u2outerClassIndex);
        }

        if (innerClassesInfo.u2innerNameIndex != 0)
        {
            innerClassesInfo.u2innerNameIndex =
                remapConstantIndex(innerClassesInfo.u2innerNameIndex);
        }
    }


    // Implementations for ExceptionInfoVisitor.

    public void visitExceptionInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, ExceptionInfo exceptionInfo)
    {
        if (exceptionInfo.u2catchType != 0)
        {
            exceptionInfo.u2catchType =
                remapConstantIndex(exceptionInfo.u2catchType);
        }
    }


    // Implementations for InstructionVisitor.

    public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction) {}


    public void visitConstantInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ConstantInstruction constantInstruction)
    {
        // Is the new constant pool index different from the original one?
        int newConstantIndex = remapConstantIndex(constantInstruction.constantIndex);
        if (newConstantIndex != constantInstruction.constantIndex)
        {
            // Replace the instruction.
            Instruction replacementInstruction =
                new ConstantInstruction(constantInstruction.opcode,
                                        newConstantIndex,
                                        constantInstruction.constant).shrink();

            codeAttributeEditor.replaceInstruction(offset, replacementInstruction);
        }
    }


    // Implementations for StackMapFrameVisitor.

    public void visitAnyStackMapFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, StackMapFrame stackMapFrame) {}


    public void visitSameOneFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, SameOneFrame sameOneFrame)
    {
        // Remap the constant pool references of the verification types.
        sameOneFrame.stackItemAccept(clazz, method, codeAttribute, offset, this);
    }


    public void visitMoreZeroFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, MoreZeroFrame moreZeroFrame)
    {
        // Remap the constant pool references of the verification types.
        moreZeroFrame.additionalVariablesAccept(clazz, method, codeAttribute, offset, this);
    }


    public void visitFullFrame(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, FullFrame fullFrame)
    {
        // Remap the constant pool references of the verification types.
        fullFrame.variablesAccept(clazz, method, codeAttribute, offset, this);
        fullFrame.stackAccept(clazz, method, codeAttribute, offset, this);
    }


    // Implementations for VerificationTypeVisitor.

    public void visitAnyVerificationType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, VerificationType verificationType) {}


    public void visitObjectType(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, ObjectType objectType)
    {
        objectType.u2classIndex =
            remapConstantIndex(objectType.u2classIndex);
    }


    // Implementations for LocalVariableInfoVisitor.

    public void visitLocalVariableInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableInfo localVariableInfo)
    {
        localVariableInfo.u2nameIndex =
            remapConstantIndex(localVariableInfo.u2nameIndex);
        localVariableInfo.u2descriptorIndex =
            remapConstantIndex(localVariableInfo.u2descriptorIndex);
    }


    // Implementations for LocalVariableTypeInfoVisitor.

    public void visitLocalVariableTypeInfo(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeInfo localVariableTypeInfo)
    {
        localVariableTypeInfo.u2nameIndex =
            remapConstantIndex(localVariableTypeInfo.u2nameIndex);
        localVariableTypeInfo.u2signatureIndex       =
            remapConstantIndex(localVariableTypeInfo.u2signatureIndex);
    }


    // Implementations for AnnotationVisitor.

    public void visitAnnotation(Clazz clazz, Annotation annotation)
    {
        annotation.u2typeIndex =
            remapConstantIndex(annotation.u2typeIndex);

        // Remap the constant pool references of the element values.
        annotation.elementValuesAccept(clazz, this);
    }


    // Implementations for ElementValueVisitor.

    public void visitConstantElementValue(Clazz clazz, Annotation annotation, ConstantElementValue constantElementValue)
    {
        constantElementValue.u2elementNameIndex =
            remapConstantIndex(constantElementValue.u2elementNameIndex);
        constantElementValue.u2constantValueIndex =
            remapConstantIndex(constantElementValue.u2constantValueIndex);
    }


    public void visitEnumConstantElementValue(Clazz clazz, Annotation annotation, EnumConstantElementValue enumConstantElementValue)
    {
        enumConstantElementValue.u2elementNameIndex =
            remapConstantIndex(enumConstantElementValue.u2elementNameIndex);
        enumConstantElementValue.u2typeNameIndex =
            remapConstantIndex(enumConstantElementValue.u2typeNameIndex);
        enumConstantElementValue.u2constantNameIndex =
            remapConstantIndex(enumConstantElementValue.u2constantNameIndex);
    }


    public void visitClassElementValue(Clazz clazz, Annotation annotation, ClassElementValue classElementValue)
    {
        classElementValue.u2elementNameIndex =
            remapConstantIndex(classElementValue.u2elementNameIndex);
        classElementValue.u2classInfoIndex       =
            remapConstantIndex(classElementValue.u2classInfoIndex);
    }


    public void visitAnnotationElementValue(Clazz clazz, Annotation annotation, AnnotationElementValue annotationElementValue)
    {
        annotationElementValue.u2elementNameIndex =
            remapConstantIndex(annotationElementValue.u2elementNameIndex);

        // Remap the constant pool references of the annotation.
        annotationElementValue.annotationAccept(clazz, this);
    }


    public void visitArrayElementValue(Clazz clazz, Annotation annotation, ArrayElementValue arrayElementValue)
    {
        arrayElementValue.u2elementNameIndex =
            remapConstantIndex(arrayElementValue.u2elementNameIndex);

        // Remap the constant pool references of the element values.
        arrayElementValue.elementValuesAccept(clazz, annotation, this);
    }


    // Small utility methods.

    /**
     * Remaps all constant pool indices in the given array.
     */
    private void remapConstantIndexArray(int[] array, int length)
    {
        for (int index = 0; index < length; index++)
        {
            array[index] = remapConstantIndex(array[index]);
        }
    }


    /**
     * Returns the new constant pool index of the entry at the
     * given index.
     */
    private int remapConstantIndex(int constantIndex)
    {
        return constantIndexMap[constantIndex];
    }
}
