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