/*******************************************************************************
 * Copyright (c) 2005, 2016 BEA Systems, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    tyeung@bea.com - initial API and implementation
 *    olivier_thomann@ca.ibm.com - add hashCode() and equals(..) methods
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.classfmt;

import java.util.Arrays;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.codegen.ConstantPool;
import org.eclipse.jdt.internal.compiler.env.*;
import org.eclipse.jdt.internal.compiler.impl.*;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.util.Util;

public class AnnotationInfo extends ClassFileStruct implements IBinaryAnnotation {
	/** The name of the annotation type */
	private char[] typename;
	/**
	 * null until this annotation is initialized
	 * @see #getElementValuePairs()
	 */
	private ElementValuePairInfo[] pairs;

	long standardAnnotationTagBits = 0;
	int readOffset = 0;

	static Object[] EmptyValueArray = new Object[0];

AnnotationInfo(byte[] classFileBytes, int[] contantPoolOffsets, int offset) {
	super(classFileBytes, contantPoolOffsets, offset);
}
/**
 * @param classFileBytes
 * @param offset the offset into <code>classFileBytes</code> for the "type_index" of the annotation attribute.
 * @param populate <code>true</code> to indicate to build out the annotation structure.
 */
AnnotationInfo(byte[] classFileBytes, int[] contantPoolOffsets, int offset, boolean runtimeVisible, boolean populate) {
	this(classFileBytes, contantPoolOffsets, offset);
	if (populate)
		decodeAnnotation();
	else
		this.readOffset = scanAnnotation(0, runtimeVisible, true);
}
private void decodeAnnotation() {
	this.readOffset = 0;
	int utf8Offset = this.constantPoolOffsets[u2At(0)] - this.structOffset;
	this.typename = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
	int numberOfPairs = u2At(2);
	// u2 type_index + u2 num_member_value_pair
	this.readOffset += 4;
	this.pairs = numberOfPairs == 0 ? ElementValuePairInfo.NoMembers : new ElementValuePairInfo[numberOfPairs];
	int i = 0;
	try {
		while (i < numberOfPairs) {
			// u2 member_name_index;
			utf8Offset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
			char[] membername = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
			this.readOffset += 2;
			Object value = decodeDefaultValue();
			this.pairs[i++] = new ElementValuePairInfo(membername, value);
		}
	} catch (RuntimeException any) {
		sanitizePairs();
		StringBuilder newMessage = new StringBuilder(any.getMessage());
		newMessage.append(" while decoding pair #").append(i).append(" of annotation @").append(this.typename); //$NON-NLS-1$ //$NON-NLS-2$
		newMessage.append(", bytes at structOffset ").append(this.structOffset).append(":"); //$NON-NLS-1$ //$NON-NLS-2$
		int offset = this.structOffset;
		while (offset <= this.structOffset+this.readOffset && offset < this.reference.length) {
			newMessage.append(' ').append(Integer.toHexString(this.reference[offset++] & 0xFF));
		}
		throw new IllegalStateException(newMessage.toString(), any);
	}
}
private void sanitizePairs() {
	ElementValuePairInfo[] oldPairs = this.pairs;
	if (oldPairs != null) {
		ElementValuePairInfo[] newPairs = new ElementValuePairInfo[oldPairs.length];
		int count = 0;
		for (int i = 0; i < oldPairs.length; i++) {
			ElementValuePairInfo evpInfo = oldPairs[i];
			if (evpInfo != null)
				newPairs[count++] = evpInfo;
		}
		if (count < oldPairs.length) {
			this.pairs = Arrays.copyOf(newPairs, count);
		}
	}
}
Object decodeDefaultValue() {
	Object value = null;
	// u1 tag;
	int tag = u1At(this.readOffset);
	this.readOffset++;
	int constValueOffset = -1;
	switch (tag) {
		case 'Z': // boolean constant
			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
			value = BooleanConstant.fromValue(i4At(constValueOffset + 1) == 1);
			this.readOffset += 2;
			break;
		case 'I': // integer constant
			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
			value = IntConstant.fromValue(i4At(constValueOffset + 1));
			this.readOffset += 2;
			break;
		case 'C': // char constant
			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
			value = CharConstant.fromValue((char) i4At(constValueOffset + 1));
			this.readOffset += 2;
			break;
		case 'B': // byte constant
			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
			value = ByteConstant.fromValue((byte) i4At(constValueOffset + 1));
			this.readOffset += 2;
			break;
		case 'S': // short constant
			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
			value = ShortConstant.fromValue((short) i4At(constValueOffset + 1));
			this.readOffset += 2;
			break;
		case 'D': // double constant
			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
			value = DoubleConstant.fromValue(doubleAt(constValueOffset + 1));
			this.readOffset += 2;
			break;
		case 'F': // float constant
			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
			value = FloatConstant.fromValue(floatAt(constValueOffset + 1));
			this.readOffset += 2;
			break;
		case 'J': // long constant
			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
			value = LongConstant.fromValue(i8At(constValueOffset + 1));
			this.readOffset += 2;
			break;
		case 's': // String
			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
			value = StringConstant.fromValue(String.valueOf(utf8At(constValueOffset + 3, u2At(constValueOffset + 1))));
			this.readOffset += 2;
			break;
		case 'e':
			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
			char[] typeName = utf8At(constValueOffset + 3, u2At(constValueOffset + 1));
			this.readOffset += 2;
			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
			char[] constName = utf8At(constValueOffset + 3, u2At(constValueOffset + 1));
			this.readOffset += 2;
			value = new EnumConstantSignature(typeName, constName);
			break;
		case 'c':
			constValueOffset = this.constantPoolOffsets[u2At(this.readOffset)] - this.structOffset;
			char[] className = utf8At(constValueOffset + 3, u2At(constValueOffset + 1));
			value = new ClassSignature(className);
			this.readOffset += 2;
			break;
		case '@':
			value = new AnnotationInfo(this.reference, this.constantPoolOffsets, this.readOffset + this.structOffset, false, true);
			this.readOffset += ((AnnotationInfo) value).readOffset;
			break;
		case '[':
			int numberOfValues = u2At(this.readOffset);
			this.readOffset += 2;
			if (numberOfValues == 0) {
				value = EmptyValueArray;
			} else {
				Object[] arrayElements = new Object[numberOfValues];
				value = arrayElements;
				for (int i = 0; i < numberOfValues; i++)
					arrayElements[i] = decodeDefaultValue();
			}
			break;
		default:
			String tagDisplay = tag == 0 ? "0x00" : (char) tag + " ("+Integer.toHexString(tag&0xFF)+')';  //$NON-NLS-1$//$NON-NLS-2$
			throw new IllegalStateException("Unrecognized tag " + tagDisplay); //$NON-NLS-1$
	}
	return value;
}
public IBinaryElementValuePair[] getElementValuePairs() {
	if (this.pairs == null)
		initialize();
	return this.pairs;
}
public char[] getTypeName() {
	return this.typename;
}
@Override
public boolean isDeprecatedAnnotation() {
	return (this.standardAnnotationTagBits & (TagBits.AnnotationDeprecated | TagBits.AnnotationTerminallyDeprecated)) != 0;
}
void initialize() {
	if (this.pairs == null)
		decodeAnnotation();
}
private int readRetentionPolicy(int offset) {
	int currentOffset = offset;
	int tag = u1At(currentOffset);
	currentOffset++;
	switch (tag) {
		case 'e':
			int utf8Offset = this.constantPoolOffsets[u2At(currentOffset)] - this.structOffset;
			char[] typeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
			currentOffset += 2;
			if (typeName.length == 38 && CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_RETENTIONPOLICY)) {
				utf8Offset = this.constantPoolOffsets[u2At(currentOffset)] - this.structOffset;
				char[] constName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
				this.standardAnnotationTagBits |= Annotation.getRetentionPolicy(constName);
			}
			currentOffset += 2;
			break;
		case 'B':
		case 'C':
		case 'D':
		case 'F':
		case 'I':
		case 'J':
		case 'S':
		case 'Z':
		case 's':
		case 'c':
			currentOffset += 2;
			break;
		case '@':
			// none of the supported standard annotation are in the nested
			// level.
			currentOffset = scanAnnotation(currentOffset, false, false);
			break;
		case '[':
			int numberOfValues = u2At(currentOffset);
			currentOffset += 2;
			for (int i = 0; i < numberOfValues; i++)
				currentOffset = scanElementValue(currentOffset);
			break;
		default:
			throw new IllegalStateException();
	}
	return currentOffset;
}
private int readTargetValue(int offset) {
	int currentOffset = offset;
	int tag = u1At(currentOffset);
	currentOffset++;
	switch (tag) {
		case 'e':
			int utf8Offset = this.constantPoolOffsets[u2At(currentOffset)] - this.structOffset;
			char[] typeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
			currentOffset += 2;
			if (typeName.length == 34 && CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_ELEMENTTYPE)) {
				utf8Offset = this.constantPoolOffsets[u2At(currentOffset)] - this.structOffset;
				char[] constName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
				this.standardAnnotationTagBits |= Annotation.getTargetElementType(constName);
			}
			currentOffset += 2;
			break;
		case 'B':
		case 'C':
		case 'D':
		case 'F':
		case 'I':
		case 'J':
		case 'S':
		case 'Z':
		case 's':
		case 'c':
			currentOffset += 2;
			break;
		case '@':
			// none of the supported standard annotation are in the nested
			// level.
			currentOffset = scanAnnotation(currentOffset, false, false);
			break;
		case '[':
			int numberOfValues = u2At(currentOffset);
			currentOffset += 2;
			if (numberOfValues == 0) {
				this.standardAnnotationTagBits |= TagBits.AnnotationTarget;
			} else {
				for (int i = 0; i < numberOfValues; i++)
					currentOffset = readTargetValue(currentOffset);
			}
			break;
		default:
			throw new IllegalStateException();
	}
	return currentOffset;
}
/**
 * Read through this annotation in order to figure out the necessary tag
 * bits and the length of this annotation. The data structure will not be
 * flushed out.
 *
 * The tag bits are derived from the following (supported) standard
 * annotation. java.lang.annotation.Documented,
 * java.lang.annotation.Retention, java.lang.annotation.Target, and
 * java.lang.Deprecated
 *
 * @param expectRuntimeVisibleAnno
 *            <code>true</cod> to indicate that this is a runtime-visible annotation
 * @param toplevel <code>false</code> to indicate that an nested annotation is read.
 * 		<code>true</code> otherwise
 * @return the next offset to read.
 */
private int scanAnnotation(int offset, boolean expectRuntimeVisibleAnno, boolean toplevel) {
	int currentOffset = offset;
	int utf8Offset = this.constantPoolOffsets[u2At(offset)] - this.structOffset;
	char[] typeName = utf8At(utf8Offset + 3, u2At(utf8Offset + 1));
	if (toplevel)
		this.typename = typeName;
	int numberOfPairs = u2At(offset + 2);
	// u2 type_index + u2 number_member_value_pair
	currentOffset += 4;
	if (expectRuntimeVisibleAnno && toplevel) {
		switch (typeName.length) {
			case 22:
				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_DEPRECATED)) {
					this.standardAnnotationTagBits |= TagBits.AnnotationDeprecated;
				}
				break;
			case 23:
				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_SAFEVARARGS)) {
					this.standardAnnotationTagBits |= TagBits.AnnotationSafeVarargs;
					return currentOffset;
				}
				break;
			case 29:
				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_TARGET)) {
					currentOffset += 2;
					return readTargetValue(currentOffset);
				}
				break;
			case 32:
				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_RETENTION)) {
					currentOffset += 2;
					return readRetentionPolicy(currentOffset);
				}
				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_INHERITED)) {
					this.standardAnnotationTagBits |= TagBits.AnnotationInherited;
					return currentOffset;
				}
				break;
			case 33:
				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_ANNOTATION_DOCUMENTED)) {
					this.standardAnnotationTagBits |= TagBits.AnnotationDocumented;
					return currentOffset;
				}
				break;
			case 52:
				if (CharOperation.equals(typeName, ConstantPool.JAVA_LANG_INVOKE_METHODHANDLE_POLYMORPHICSIGNATURE)) {
					this.standardAnnotationTagBits |= TagBits.AnnotationPolymorphicSignature;
					return currentOffset;
				}
				break;
		}
	}
	for (int i = 0; i < numberOfPairs; i++) {
		// u2 member_name_index
		currentOffset += 2;
		currentOffset = scanElementValue(currentOffset);
	}
	return currentOffset;
}
/**
 * @param offset
 *            the offset to start reading.
 * @return the next offset to read.
 */
private int scanElementValue(int offset) {
	int currentOffset = offset;
	int tag = u1At(currentOffset);
	currentOffset++;
	switch (tag) {
		case 'B':
		case 'C':
		case 'D':
		case 'F':
		case 'I':
		case 'J':
		case 'S':
		case 'Z':
		case 's':
		case 'c':
			currentOffset += 2;
			break;
		case 'e':
			currentOffset += 4;
			break;
		case '@':
			// none of the supported standard annotation are in the nested
			// level.
			currentOffset = scanAnnotation(currentOffset, false, false);
			break;
		case '[':
			int numberOfValues = u2At(currentOffset);
			currentOffset += 2;
			for (int i = 0; i < numberOfValues; i++)
				currentOffset = scanElementValue(currentOffset);
			break;
		default:
			throw new IllegalStateException();
	}
	return currentOffset;
}
public String toString() {
	return BinaryTypeFormatter.annotationToString(this);
}
public int hashCode() {
	final int prime = 31;
	int result = 1;
	result = prime * result + Util.hashCode(this.pairs);
	result = prime * result + CharOperation.hashCode(this.typename);
	return result;
}
public boolean equals(Object obj) {
	if (this == obj) {
		return true;
	}
	if (obj == null) {
		return false;
	}
	if (getClass() != obj.getClass()) {
		return false;
	}
	AnnotationInfo other = (AnnotationInfo) obj;
	if (!Arrays.equals(this.pairs, other.pairs)) {
		return false;
	}
	if (!Arrays.equals(this.typename, other.typename)) {
		return false;
	}
	return true;
}
}
