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 }