<s> 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 { private char [ ] typename ; 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 ) ; } 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 ) ; this . readOffset += 4 ; this . pairs = numberOfPairs == 0 ? ElementValuePairInfo . NoMembers : new ElementValuePairInfo [ numberOfPairs ] ; for ( int i = 0 ; i < numberOfPairs ; i ++ ) { 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 ) ; } } Object decodeDefaultValue ( ) { Object value = null ; int tag = u1At ( this . readOffset ) ; this . readOffset ++ ; int constValueOffset = - 1 ; switch ( tag ) { case 'Z' : constValueOffset = this . constantPoolOffsets [ u2At ( this . readOffset ) ] - this . structOffset ; value = BooleanConstant . fromValue ( i4At ( constValueOffset + 1 ) == 1 ) ; this . readOffset += 2 ; break ; case 'I' : constValueOffset = this . constantPoolOffsets [ u2At ( this . readOffset ) ] - this . structOffset ; value = IntConstant . fromValue ( i4At ( constValueOffset + 1 ) ) ; this . readOffset += 2 ; break ; case 'C' : constValueOffset = this . constantPoolOffsets [ u2At ( this . readOffset ) ] - this . structOffset ; value = CharConstant . fromValue ( ( char ) i4At ( constValueOffset + 1 ) ) ; this . readOffset += 2 ; break ; case 'B' : constValueOffset = this . constantPoolOffsets [ u2At ( this . readOffset ) ] - this . structOffset ; value = ByteConstant . fromValue ( ( byte ) i4At ( constValueOffset + 1 ) ) ; this . readOffset += 2 ; break ; case 'S' : constValueOffset = this . constantPoolOffsets [ u2At ( this . readOffset ) ] - this . structOffset ; value = ShortConstant . fromValue ( ( short ) i4At ( constValueOffset + 1 ) ) ; this . readOffset += 2 ; break ; case 'D' : constValueOffset = this . constantPoolOffsets [ u2At ( this . readOffset ) ] - this . structOffset ; value = DoubleConstant . fromValue ( doubleAt ( constValueOffset + 1 ) ) ; this . readOffset += 2 ; break ; case 'F' : constValueOffset = this . constantPoolOffsets [ u2At ( this . readOffset ) ] - this . structOffset ; value = FloatConstant . fromValue ( floatAt ( constValueOffset + 1 ) ) ; this . readOffset += 2 ; break ; case 'J' : constValueOffset = this . constantPoolOffsets [ u2At ( this . readOffset ) ] - this . structOffset ; value = LongConstant . fromValue ( i8At ( constValueOffset + 1 ) ) ; this . readOffset += 2 ; break ; case 's' : 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 : throw new IllegalStateException ( "" + ( char ) tag ) ; } return value ; } public IBinaryElementValuePair [ ] getElementValuePairs ( ) { if ( this . pairs == null ) initialize ( ) ; return this . pairs ; } public char [ ] getTypeName ( ) { return this . typename ; } 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 '@' : 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 '@' : 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 ; } 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 ) ; currentOffset += 4 ; if ( expectRuntimeVisibleAnno && toplevel ) { switch ( typeName . length ) { case 22 : if ( CharOperation . equals ( typeName , ConstantPool . JAVA_LANG_DEPRECATED ) ) { this . standardAnnotationTagBits |= TagBits . AnnotationDeprecated ; return currentOffset ; } 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 ++ ) { currentOffset += 2 ; currentOffset = scanElementValue ( currentOffset ) ; } return currentOffset ; } 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 '@' : 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 ( ) { StringBuffer buffer = new StringBuffer ( ) ; buffer . append ( '@' ) ; buffer . append ( this . typename ) ; if ( this . pairs != null ) { buffer . append ( '(' ) ; buffer . append ( "nt" ) ; for ( int i = 0 , len = this . pairs . length ; i < len ; i ++ ) { if ( i > 0 ) buffer . append ( ",nt" ) ; buffer . append ( this . pairs [ i ] ) ; } buffer . append ( ')' ) ; } return buffer . toString ( ) ; } 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 ; } } </s>