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 }