1 /* 2 * Copyright (c) 2013, 2016, 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.misc.SharedSecrets; 38 import jdk.internal.misc.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 for (int i = 0; i < size; i++) { 127 @SuppressWarnings("unchecked") 128 ArrayList<TypeAnnotation> list = l[i]; 129 TypeAnnotation[] typeAnnotations; 130 if (list != null) { 131 typeAnnotations = list.toArray(new TypeAnnotation[list.size()]); 132 } else { 133 typeAnnotations = EMPTY_TYPE_ANNOTATION_ARRAY; 134 } 135 result[i] = AnnotatedTypeFactory.buildAnnotatedType(types[i], 136 AnnotatedTypeFactory.nestingForType(types[i], LocationInfo.BASE_LOCATION), 137 typeAnnotations, 138 typeAnnotations, 139 decl); 140 141 } 142 return result; 143 } 144 145 // Class helpers 146 147 /** 148 * Build an AnnotatedType for the class decl's supertype. 149 * 150 * @param rawAnnotations the byte[] encoding of all type annotations on this declaration 151 * @param cp the ConstantPool needed to parse the embedded Annotation 152 * @param decl the Class which annotated supertype is being built 153 */ 154 public static AnnotatedType buildAnnotatedSuperclass(byte[] rawAnnotations, 155 ConstantPool cp, 156 Class<?> decl) { 157 Type supertype = decl.getGenericSuperclass(); 158 if (supertype == null) 159 return AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE; 160 return buildAnnotatedType(rawAnnotations, 161 cp, 162 decl, 163 decl, 164 supertype, 165 TypeAnnotationTarget.CLASS_EXTENDS); 166 } 167 168 /** 169 * Build an array of AnnotatedTypes for the class decl's implemented 170 * interfaces. 171 * 172 * @param rawAnnotations the byte[] encoding of all type annotations on this declaration 173 * @param cp the ConstantPool needed to parse the embedded Annotation 174 * @param decl the Class whose annotated implemented interfaces is being built 175 */ 176 public static AnnotatedType[] buildAnnotatedInterfaces(byte[] rawAnnotations, 177 ConstantPool cp, 178 Class<?> decl) { 179 if (decl == Object.class || 180 decl.isArray() || 181 decl.isPrimitive() || 182 decl == Void.TYPE) 183 return AnnotatedTypeFactory.EMPTY_ANNOTATED_TYPE_ARRAY; 184 return buildAnnotatedTypes(rawAnnotations, 185 cp, 186 decl, 187 decl, 188 decl.getGenericInterfaces(), 189 TypeAnnotationTarget.CLASS_IMPLEMENTS); 190 } 191 192 // TypeVariable helpers 193 194 /** 195 * Parse regular annotations on a TypeVariable declared on genericDecl. 196 * 197 * Regular Annotations on TypeVariables are stored in the type 198 * annotation byte[] in the class file. 199 * 200 * @param genericDecl the declaration declaring the type variable 201 * @param typeVarIndex the 0-based index of this type variable in the declaration 202 */ 203 public static <D extends GenericDeclaration> Annotation[] parseTypeVariableAnnotations(D genericDecl, 204 int typeVarIndex) { 205 AnnotatedElement decl; 206 TypeAnnotationTarget predicate; 207 if (genericDecl instanceof Class) { 208 decl = (Class<?>)genericDecl; 209 predicate = TypeAnnotationTarget.CLASS_TYPE_PARAMETER; 210 } else if (genericDecl instanceof Executable) { 211 decl = (Executable)genericDecl; 212 predicate = TypeAnnotationTarget.METHOD_TYPE_PARAMETER; 213 } else { 214 throw new AssertionError("Unknown GenericDeclaration " + genericDecl + "\nthis should not happen."); 215 } 216 List<TypeAnnotation> typeVarAnnos = TypeAnnotation.filter(parseAllTypeAnnotations(decl), 217 predicate); 218 List<Annotation> res = new ArrayList<>(typeVarAnnos.size()); 219 for (TypeAnnotation t : typeVarAnnos) 220 if (t.getTargetInfo().getCount() == typeVarIndex) 221 res.add(t.getAnnotation()); 222 return res.toArray(new Annotation[0]); 223 } 224 225 /** 226 * Build an array of AnnotatedTypes for the declaration decl's bounds. 227 * 228 * @param bounds the bounds corresponding to the annotated bounds 229 * @param decl the declaration whose annotated bounds is being built 230 * @param typeVarIndex the index of this type variable on the decl 231 */ 232 public static <D extends GenericDeclaration> AnnotatedType[] parseAnnotatedBounds(Type[] bounds, 233 D decl, 234 int typeVarIndex) { 235 return parseAnnotatedBounds(bounds, decl, typeVarIndex, LocationInfo.BASE_LOCATION); 236 } 237 //helper for above 238 private static <D extends GenericDeclaration> AnnotatedType[] parseAnnotatedBounds(Type[] bounds, 239 D decl, 240 int typeVarIndex, 241 LocationInfo loc) { 242 List<TypeAnnotation> candidates = fetchBounds(decl); 243 if (bounds != null) { 244 int startIndex = 0; 245 AnnotatedType[] res = new AnnotatedType[bounds.length]; 246 247 // Adjust bounds index 248 // 249 // Figure out if the type annotations for this bound starts with 0 250 // or 1. The spec says within a bound the 0:th type annotation will 251 // always be on an bound of a Class type (not Interface type). So 252 // if the programmer starts with an Interface type for the first 253 // (and following) bound(s) the implicit Object bound is considered 254 // the first (that is 0:th) bound and type annotations start on 255 // index 1. 256 if (bounds.length > 0) { 257 Type b0 = bounds[0]; 258 if (!(b0 instanceof Class<?>)) { 259 startIndex = 1; 260 } else { 261 Class<?> c = (Class<?>)b0; 262 if (c.isInterface()) { 263 startIndex = 1; 264 } 265 } 266 } 267 268 for (int i = 0; i < bounds.length; i++) { 269 List<TypeAnnotation> l = new ArrayList<>(candidates.size()); 270 for (TypeAnnotation t : candidates) { 271 TypeAnnotationTargetInfo tInfo = t.getTargetInfo(); 272 if (tInfo.getSecondaryIndex() == i + startIndex && 273 tInfo.getCount() == typeVarIndex) { 274 l.add(t); 275 } 276 } 277 res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i], 278 AnnotatedTypeFactory.nestingForType(bounds[i], loc), 279 l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), 280 candidates.toArray(EMPTY_TYPE_ANNOTATION_ARRAY), 281 (AnnotatedElement)decl); 282 } 283 return res; 284 } 285 return new AnnotatedType[0]; 286 } 287 private static <D extends GenericDeclaration> List<TypeAnnotation> fetchBounds(D decl) { 288 AnnotatedElement boundsDecl; 289 TypeAnnotationTarget target; 290 if (decl instanceof Class) { 291 target = TypeAnnotationTarget.CLASS_TYPE_PARAMETER_BOUND; 292 boundsDecl = (Class)decl; 293 } else { 294 target = TypeAnnotationTarget.METHOD_TYPE_PARAMETER_BOUND; 295 boundsDecl = (Executable)decl; 296 } 297 return TypeAnnotation.filter(TypeAnnotationParser.parseAllTypeAnnotations(boundsDecl), target); 298 } 299 300 /* 301 * Parse all type annotations on the declaration supplied. This is needed 302 * when you go from for example an annotated return type on a method that 303 * is a type variable declared on the class. In this case you need to 304 * 'jump' to the decl of the class and parse all type annotations there to 305 * find the ones that are applicable to the type variable. 306 */ 307 static TypeAnnotation[] parseAllTypeAnnotations(AnnotatedElement decl) { 308 Class<?> container; 309 byte[] rawBytes; 310 JavaLangAccess javaLangAccess = SharedSecrets.getJavaLangAccess(); 311 if (decl instanceof Class) { 312 container = (Class<?>)decl; 313 rawBytes = javaLangAccess.getRawClassTypeAnnotations(container); 314 } else if (decl instanceof Executable) { 315 container = ((Executable)decl).getDeclaringClass(); 316 rawBytes = javaLangAccess.getRawExecutableTypeAnnotations((Executable)decl); 317 } else { 318 // Should not reach here. Assert? 319 return EMPTY_TYPE_ANNOTATION_ARRAY; 320 } 321 return parseTypeAnnotations(rawBytes, javaLangAccess.getConstantPool(container), 322 decl, container); 323 } 324 325 /* Parse type annotations encoded as an array of bytes */ 326 private static TypeAnnotation[] parseTypeAnnotations(byte[] rawAnnotations, 327 ConstantPool cp, 328 AnnotatedElement baseDecl, 329 Class<?> container) { 330 if (rawAnnotations == null) 331 return EMPTY_TYPE_ANNOTATION_ARRAY; 332 333 ByteBuffer buf = ByteBuffer.wrap(rawAnnotations); 334 int annotationCount = buf.getShort() & 0xFFFF; 335 List<TypeAnnotation> typeAnnotations = new ArrayList<>(annotationCount); 336 337 // Parse each TypeAnnotation 338 for (int i = 0; i < annotationCount; i++) { 339 TypeAnnotation ta = parseTypeAnnotation(buf, cp, baseDecl, container); 340 if (ta != null) 341 typeAnnotations.add(ta); 342 } 343 344 return typeAnnotations.toArray(EMPTY_TYPE_ANNOTATION_ARRAY); 345 } 346 347 348 // Helper 349 static Map<Class<? extends Annotation>, Annotation> mapTypeAnnotations(TypeAnnotation[] typeAnnos) { 350 Map<Class<? extends Annotation>, Annotation> result = 351 new LinkedHashMap<>(); 352 for (TypeAnnotation t : typeAnnos) { 353 Annotation a = t.getAnnotation(); 354 if (a != null) { 355 Class<? extends Annotation> klass = a.annotationType(); 356 AnnotationType type = AnnotationType.getInstance(klass); 357 if (type.retention() == RetentionPolicy.RUNTIME && 358 result.put(klass, a) != null) { 359 throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a); 360 } 361 } 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 }