1 /*
   2  * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.reflect.annotation;
  27 
  28 import java.lang.annotation.*;
  29 import java.lang.reflect.*;
  30 import java.nio.ByteBuffer;
  31 import java.nio.BufferUnderflowException;
  32 import java.util.ArrayList;
  33 import java.util.Arrays;
  34 import java.util.List;
  35 import java.util.HashMap;
  36 import java.util.LinkedHashMap;
  37 import java.util.Map;
  38 import jdk.internal.misc.SharedSecrets;
  39 import jdk.internal.misc.JavaLangAccess;
  40 import sun.reflect.ConstantPool;
  41 import static sun.reflect.annotation.TypeAnnotation.*;
  42 
  43 /**
  44  * TypeAnnotationParser implements the logic needed to parse
  45  * TypeAnnotations from an array of bytes.
  46  */
  47 public final class TypeAnnotationParser {
  48     private static final TypeAnnotation[] EMPTY_TYPE_ANNOTATION_ARRAY = new TypeAnnotation[0];
  49 
  50     /**
  51      * Build an AnnotatedType from the parameters supplied.
  52      *
  53      * This method and {@code buildAnnotatedTypes} are probably
  54      * the entry points you are looking for.
  55      *
  56      * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
  57      * @param cp the ConstantPool needed to parse the embedded Annotation
  58      * @param decl the declaration this type annotation is on
  59      * @param container the Class this type annotation is on (may be the same as decl)
  60      * @param type the type the AnnotatedType corresponds to
  61      * @param filter the type annotation targets included in this AnnotatedType
  62      */
  63     public static AnnotatedType buildAnnotatedType(byte[] rawAnnotations,
  64             ConstantPool cp,
  65             AnnotatedElement decl,
  66             Class<?> container,
  67             Type type,
  68             TypeAnnotationTarget filter) {
  69         TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations,
  70                                                     cp,
  71                                                     decl,
  72                                                     container);
  73         List<TypeAnnotation> l = new ArrayList<>(tas.length);
  74         for (TypeAnnotation t : tas) {
  75             TypeAnnotationTargetInfo ti = t.getTargetInfo();
  76             if (ti.getTarget() == filter)
  77                 l.add(t);
  78         }
  79         TypeAnnotation[] typeAnnotations = l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY);
  80         return AnnotatedTypeFactory.buildAnnotatedType(type,
  81                                                        LocationInfo.BASE_LOCATION,
  82                                                        typeAnnotations,
  83                                                        typeAnnotations,
  84                                                        decl);
  85     }
  86 
  87     /**
  88      * Build an array of AnnotatedTypes from the parameters supplied.
  89      *
  90      * This method and {@code buildAnnotatedType} are probably
  91      * the entry points you are looking for.
  92      *
  93      * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
  94      * @param cp the ConstantPool needed to parse the embedded Annotation
  95      * @param decl the declaration this type annotation is on
  96      * @param container the Class this type annotation is on (may be the same as decl)
  97      * @param types the Types the AnnotatedTypes corresponds to
  98      * @param filter the type annotation targets that included in this AnnotatedType
  99      */
 100     public static AnnotatedType[] buildAnnotatedTypes(byte[] rawAnnotations,
 101             ConstantPool cp,
 102             AnnotatedElement decl,
 103             Class<?> container,
 104             Type[] types,
 105             TypeAnnotationTarget filter) {
 106         int size = types.length;
 107         AnnotatedType[] result = new AnnotatedType[size];
 108         Arrays.fill(result, AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE);
 109         @SuppressWarnings("rawtypes")
 110         ArrayList[] l = new ArrayList[size]; // array of ArrayList<TypeAnnotation>
 111 
 112         TypeAnnotation[] tas = parseTypeAnnotations(rawAnnotations,
 113                                                     cp,
 114                                                     decl,
 115                                                     container);
 116         for (TypeAnnotation t : tas) {
 117             TypeAnnotationTargetInfo ti = t.getTargetInfo();
 118             if (ti.getTarget() == filter) {
 119                 int pos = ti.getCount();
 120                 if (l[pos] == null) {
 121                     ArrayList<TypeAnnotation> tmp = new ArrayList<>(tas.length);
 122                     l[pos] = tmp;
 123                 }
 124                 @SuppressWarnings("unchecked")
 125                 ArrayList<TypeAnnotation> tmp = l[pos];
 126                 tmp.add(t);
 127             }
 128         }
 129         for (int i = 0; i < size; i++) {
 130             @SuppressWarnings("unchecked")
 131             ArrayList<TypeAnnotation> list = l[i];
 132             TypeAnnotation[] typeAnnotations;
 133             if (list != null) {
 134                 typeAnnotations = list.toArray(new TypeAnnotation[list.size()]);
 135             } else {
 136                 typeAnnotations = EMPTY_TYPE_ANNOTATION_ARRAY;
 137             }
 138             result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i],
 139                                                                 LocationInfo.BASE_LOCATION,
 140                                                                 typeAnnotations,
 141                                                                 typeAnnotations,
 142                                                                 decl);
 143 
 144         }
 145         return result;
 146     }
 147 
 148     // Class helpers
 149 
 150     /**
 151      * Build an AnnotatedType for the class decl's supertype.
 152      *
 153      * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
 154      * @param cp the ConstantPool needed to parse the embedded Annotation
 155      * @param decl the Class which annotated supertype is being built
 156      */
 157     public static AnnotatedType buildAnnotatedSuperclass(byte[] rawAnnotations,
 158             ConstantPool cp,
 159             Class<?> decl) {
 160         Type supertype = decl.getGenericSuperclass();
 161         if (supertype == null)
 162             return AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE;
 163         return buildAnnotatedType(rawAnnotations,
 164                                   cp,
 165                                   decl,
 166                                   decl,
 167                                   supertype,
 168                                   TypeAnnotationTarget.CLASS_EXTENDS);
 169     }
 170 
 171     /**
 172      * Build an array of AnnotatedTypes for the class decl's implemented
 173      * interfaces.
 174      *
 175      * @param rawAnnotations the byte[] encoding of all type annotations on this declaration
 176      * @param cp the ConstantPool needed to parse the embedded Annotation
 177      * @param decl the Class whose annotated implemented interfaces is being built
 178      */
 179     public static AnnotatedType[] buildAnnotatedInterfaces(byte[] rawAnnotations,
 180             ConstantPool cp,
 181             Class<?> decl) {
 182         if (decl == Object.class ||
 183                 decl.isArray() ||
 184                 decl.isPrimitive() ||
 185                 decl == Void.TYPE)
 186             return AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE_ARRAY;
 187         return buildAnnotatedTypes(rawAnnotations,
 188                                    cp,
 189                                    decl,
 190                                    decl,
 191                                    decl.getGenericInterfaces(),
 192                                    TypeAnnotationTarget.CLASS_IMPLEMENTS);
 193     }
 194 
 195     // TypeVariable helpers
 196 
 197     /**
 198      * Parse regular annotations on a TypeVariable declared on genericDecl.
 199      *
 200      * Regular Annotations on TypeVariables are stored in the type
 201      * annotation byte[] in the class file.
 202      *
 203      * @param genericDecl the declaration declaring the type variable
 204      * @param typeVarIndex the 0-based index of this type variable in the declaration
 205      */
 206     public static <D extends GenericDeclaration> Annotation[] parseTypeVariableAnnotations(D genericDecl,
 207             int typeVarIndex) {
 208         AnnotatedElement decl;
 209         TypeAnnotationTarget predicate;
 210         if (genericDecl instanceof Class) {
 211             decl = (Class<?>)genericDecl;
 212             predicate = TypeAnnotationTarget.CLASS_TYPE_PARAMETER;
 213         } else if (genericDecl instanceof Executable) {
 214             decl = (Executable)genericDecl;
 215             predicate = TypeAnnotationTarget.METHOD_TYPE_PARAMETER;
 216         } else {
 217             throw new AssertionError("Unknown GenericDeclaration " + genericDecl + "\nthis should not happen.");
 218         }
 219         List<TypeAnnotation> typeVarAnnos = TypeAnnotation.filter(parseAllTypeAnnotations(decl),
 220                                                                   predicate);
 221         List<Annotation> res = new ArrayList<>(typeVarAnnos.size());
 222         for (TypeAnnotation t : typeVarAnnos)
 223             if (t.getTargetInfo().getCount() == typeVarIndex)
 224                 res.add(t.getAnnotation());
 225         return res.toArray(new Annotation[0]);
 226     }
 227 
 228     /**
 229      * Build an array of AnnotatedTypes for the declaration decl's bounds.
 230      *
 231      * @param bounds the bounds corresponding to the annotated bounds
 232      * @param decl the declaration whose annotated bounds is being built
 233      * @param typeVarIndex the index of this type variable on the decl
 234      */
 235     public static <D extends GenericDeclaration> AnnotatedType[] parseAnnotatedBounds(Type[] bounds,
 236             D decl,
 237             int typeVarIndex) {
 238         return parseAnnotatedBounds(bounds, decl, typeVarIndex, LocationInfo.BASE_LOCATION);
 239     }
 240     //helper for above
 241     private static <D extends GenericDeclaration> AnnotatedType[] parseAnnotatedBounds(Type[] bounds,
 242             D decl,
 243             int typeVarIndex,
 244             LocationInfo loc) {
 245         List<TypeAnnotation> candidates = fetchBounds(decl);
 246         if (bounds != null) {
 247             int startIndex = 0;
 248             AnnotatedType[] res = new AnnotatedType[bounds.length];
 249 
 250             // Adjust bounds index
 251             //
 252             // Figure out if the type annotations for this bound starts with 0
 253             // or 1. The spec says within a bound the 0:th type annotation will
 254             // always be on an bound of a Class type (not Interface type). So
 255             // if the programmer starts with an Interface type for the first
 256             // (and following) bound(s) the implicit Object bound is considered
 257             // the first (that is 0:th) bound and type annotations start on
 258             // index 1.
 259             if (bounds.length > 0) {
 260                 Type b0 = bounds[0];
 261                 if (!(b0 instanceof Class<?>)) {
 262                     startIndex = 1;
 263                 } else {
 264                     Class<?> c = (Class<?>)b0;
 265                     if (c.isInterface()) {
 266                         startIndex = 1;
 267                     }
 268                 }
 269             }
 270 
 271             for (int i = 0; i < bounds.length; i++) {
 272                 List<TypeAnnotation> l = new ArrayList<>(candidates.size());
 273                 for (TypeAnnotation t : candidates) {
 274                     TypeAnnotationTargetInfo tInfo = t.getTargetInfo();
 275                     if (tInfo.getSecondaryIndex() == i + startIndex &&
 276                             tInfo.getCount() == typeVarIndex) {
 277                         l.add(t);
 278                     }
 279                 }
 280                 res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i],
 281                         loc,
 282                         l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
 283                         candidates.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
 284                         (AnnotatedElement)decl);
 285             }
 286             return res;
 287         }
 288         return new AnnotatedType[0];
 289     }
 290     private static <D extends GenericDeclaration> List<TypeAnnotation> fetchBounds(D decl) {
 291         AnnotatedElement boundsDecl;
 292         TypeAnnotationTarget target;
 293         if (decl instanceof Class) {
 294             target = TypeAnnotationTarget.CLASS_TYPE_PARAMETER_BOUND;
 295             boundsDecl = (Class)decl;
 296         } else {
 297             target = TypeAnnotationTarget.METHOD_TYPE_PARAMETER_BOUND;
 298             boundsDecl = (Executable)decl;
 299         }
 300         return TypeAnnotation.filter(TypeAnnotationParser.parseAllTypeAnnotations(boundsDecl), target);
 301     }
 302 
 303     /*
 304      * Parse all type annotations on the declaration supplied. This is needed
 305      * when you go from for example an annotated return type on a method that
 306      * is a type variable declared on the class. In this case you need to
 307      * 'jump' to the decl of the class and parse all type annotations there to
 308      * find the ones that are applicable to the type variable.
 309      */
 310     static TypeAnnotation[] parseAllTypeAnnotations(AnnotatedElement decl) {
 311         Class<?> container;
 312         byte[] rawBytes;
 313         JavaLangAccess javaLangAccess = SharedSecrets.getJavaLangAccess();
 314         if (decl instanceof Class) {
 315             container = (Class<?>)decl;
 316             rawBytes = javaLangAccess.getRawClassTypeAnnotations(container);
 317         } else if (decl instanceof Executable) {
 318             container = ((Executable)decl).getDeclaringClass();
 319             rawBytes = javaLangAccess.getRawExecutableTypeAnnotations((Executable)decl);
 320         } else {
 321             // Should not reach here. Assert?
 322             return EMPTY_TYPE_ANNOTATION_ARRAY;
 323         }
 324         return parseTypeAnnotations(rawBytes, javaLangAccess.getConstantPool(container),
 325                                     decl, container);
 326     }
 327 
 328     /* Parse type annotations encoded as an array of bytes */
 329     private static TypeAnnotation[] parseTypeAnnotations(byte[] rawAnnotations,
 330             ConstantPool cp,
 331             AnnotatedElement baseDecl,
 332             Class<?> container) {
 333         if (rawAnnotations == null)
 334             return EMPTY_TYPE_ANNOTATION_ARRAY;
 335 
 336         ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
 337         int annotationCount = buf.getShort() & 0xFFFF;
 338         List<TypeAnnotation> typeAnnotations = new ArrayList<>(annotationCount);
 339 
 340         // Parse each TypeAnnotation
 341         for (int i = 0; i < annotationCount; i++) {
 342              TypeAnnotation ta = parseTypeAnnotation(buf, cp, baseDecl, container);
 343              if (ta != null)
 344                  typeAnnotations.add(ta);
 345         }
 346 
 347         return typeAnnotations.toArray(EMPTY_TYPE_ANNOTATION_ARRAY);
 348     }
 349 
 350 
 351     // Helper
 352     static Map<Class<? extends Annotation>, Annotation> mapTypeAnnotations(TypeAnnotation[] typeAnnos) {
 353         Map<Class<? extends Annotation>, Annotation> result =
 354             new LinkedHashMap<>();
 355         for (TypeAnnotation t : typeAnnos) {
 356             Annotation a = t.getAnnotation();
 357             Class<? extends Annotation> klass = a.annotationType();
 358             AnnotationType type = AnnotationType.getInstance(klass);
 359             if (type.retention() == RetentionPolicy.RUNTIME)
 360                 if (result.put(klass, a) != null)
 361                     throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a);
 362         }
 363         return result;
 364     }
 365 
 366     // Position codes
 367     // Regular type parameter annotations
 368     private static final byte CLASS_TYPE_PARAMETER = 0x00;
 369     private static final byte METHOD_TYPE_PARAMETER = 0x01;
 370     // Type Annotations outside method bodies
 371     private static final byte CLASS_EXTENDS = 0x10;
 372     private static final byte CLASS_TYPE_PARAMETER_BOUND = 0x11;
 373     private static final byte METHOD_TYPE_PARAMETER_BOUND = 0x12;
 374     private static final byte FIELD = 0x13;
 375     private static final byte METHOD_RETURN = 0x14;
 376     private static final byte METHOD_RECEIVER = 0x15;
 377     private static final byte METHOD_FORMAL_PARAMETER = 0x16;
 378     private static final byte THROWS = 0x17;
 379     // Type Annotations inside method bodies
 380     private static final byte LOCAL_VARIABLE = (byte)0x40;
 381     private static final byte RESOURCE_VARIABLE = (byte)0x41;
 382     private static final byte EXCEPTION_PARAMETER = (byte)0x42;
 383     private static final byte INSTANCEOF = (byte)0x43;
 384     private static final byte NEW = (byte)0x44;
 385     private static final byte CONSTRUCTOR_REFERENCE = (byte)0x45;
 386     private static final byte METHOD_REFERENCE = (byte)0x46;
 387     private static final byte CAST = (byte)0x47;
 388     private static final byte CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = (byte)0x48;
 389     private static final byte METHOD_INVOCATION_TYPE_ARGUMENT = (byte)0x49;
 390     private static final byte CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = (byte)0x4A;
 391     private static final byte METHOD_REFERENCE_TYPE_ARGUMENT = (byte)0x4B;
 392 
 393     private static TypeAnnotation parseTypeAnnotation(ByteBuffer buf,
 394             ConstantPool cp,
 395             AnnotatedElement baseDecl,
 396             Class<?> container) {
 397         try {
 398             TypeAnnotationTargetInfo ti = parseTargetInfo(buf);
 399             LocationInfo locationInfo = LocationInfo.parseLocationInfo(buf);
 400             Annotation a = AnnotationParser.parseAnnotation(buf, cp, container, false);
 401             if (ti == null) // Inside a method for example
 402                 return null;
 403             return new TypeAnnotation(ti, locationInfo, a, baseDecl);
 404         } catch (IllegalArgumentException | // Bad type in const pool at specified index
 405                 BufferUnderflowException e) {
 406             throw new AnnotationFormatError(e);
 407         }
 408     }
 409 
 410     private static TypeAnnotationTargetInfo parseTargetInfo(ByteBuffer buf) {
 411         int posCode = buf.get() & 0xFF;
 412         switch(posCode) {
 413         case CLASS_TYPE_PARAMETER:
 414         case METHOD_TYPE_PARAMETER: {
 415             int index = buf.get() & 0xFF;
 416             TypeAnnotationTargetInfo res;
 417             if (posCode == CLASS_TYPE_PARAMETER)
 418                 res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_TYPE_PARAMETER,
 419                         index);
 420             else
 421                 res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_TYPE_PARAMETER,
 422                         index);
 423             return res;
 424             } // unreachable break;
 425         case CLASS_EXTENDS: {
 426             short index = buf.getShort(); //needs to be signed
 427             if (index == -1) {
 428                 return new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_EXTENDS);
 429             } else if (index >= 0) {
 430                 TypeAnnotationTargetInfo res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_IMPLEMENTS,
 431                         index);
 432                 return res;
 433             }} break;
 434         case CLASS_TYPE_PARAMETER_BOUND:
 435             return parse2ByteTarget(TypeAnnotationTarget.CLASS_TYPE_PARAMETER_BOUND, buf);
 436         case METHOD_TYPE_PARAMETER_BOUND:
 437             return parse2ByteTarget(TypeAnnotationTarget.METHOD_TYPE_PARAMETER_BOUND, buf);
 438         case FIELD:
 439             return new TypeAnnotationTargetInfo(TypeAnnotationTarget.FIELD);
 440         case METHOD_RETURN:
 441             return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RETURN);
 442         case METHOD_RECEIVER:
 443             return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RECEIVER);
 444         case METHOD_FORMAL_PARAMETER: {
 445             int index = buf.get() & 0xFF;
 446             return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_FORMAL_PARAMETER,
 447                     index);
 448             } //unreachable break;
 449         case THROWS:
 450             return parseShortTarget(TypeAnnotationTarget.THROWS, buf);
 451 
 452         /*
 453          * The ones below are inside method bodies, we don't care about them for core reflection
 454          * other than adjusting for them in the byte stream.
 455          */
 456         case LOCAL_VARIABLE:
 457         case RESOURCE_VARIABLE:
 458             short length = buf.getShort();
 459             for (int i = 0; i < length; ++i) {
 460                 short offset = buf.getShort();
 461                 short varLength = buf.getShort();
 462                 short index = buf.getShort();
 463             }
 464             return null;
 465         case EXCEPTION_PARAMETER: {
 466             byte index = buf.get();
 467             }
 468             return null;
 469         case INSTANCEOF:
 470         case NEW:
 471         case CONSTRUCTOR_REFERENCE:
 472         case METHOD_REFERENCE: {
 473             short offset = buf.getShort();
 474             }
 475             return null;
 476         case CAST:
 477         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
 478         case METHOD_INVOCATION_TYPE_ARGUMENT:
 479         case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
 480         case METHOD_REFERENCE_TYPE_ARGUMENT: {
 481             short offset = buf.getShort();
 482             byte index = buf.get();
 483             }
 484             return null;
 485 
 486         default:
 487             // will throw error below
 488             break;
 489         }
 490         throw new AnnotationFormatError("Could not parse bytes for type annotations");
 491     }
 492 
 493     private static TypeAnnotationTargetInfo parseShortTarget(TypeAnnotationTarget target, ByteBuffer buf) {
 494         int index = buf.getShort() & 0xFFFF;
 495         return new TypeAnnotationTargetInfo(target, index);
 496     }
 497     private static TypeAnnotationTargetInfo parse2ByteTarget(TypeAnnotationTarget target, ByteBuffer buf) {
 498         int count = buf.get() & 0xFF;
 499         int secondaryIndex = buf.get() & 0xFF;
 500         return new TypeAnnotationTargetInfo(target,
 501                                             count,
 502                                             secondaryIndex);
 503     }
 504 }