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