1 /*
2  * Copyright (c) 2013, 2018, 2020, 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      */
buildAnnotatedType(byte[] rawAnnotations, ConstantPool cp, AnnotatedElement decl, Class<?> container, Type type, TypeAnnotationTarget filter)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      */
buildAnnotatedTypes(byte[] rawAnnotations, ConstantPool cp, AnnotatedElement decl, Class<?> container, Type[] types, TypeAnnotationTarget filter)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      */
buildAnnotatedSuperclass(byte[] rawAnnotations, ConstantPool cp, Class<?> decl)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      */
buildAnnotatedInterfaces(byte[] rawAnnotations, ConstantPool cp, Class<?> decl)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      */
parseTypeVariableAnnotations(D genericDecl, int typeVarIndex)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      */
parseAnnotatedBounds(Type[] bounds, D decl, int typeVarIndex)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
parseAnnotatedBounds(Type[] bounds, D decl, int typeVarIndex, LocationInfo loc)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             // According to JVMS 4.3.4, the first bound of a parameterized type is
269             // taken to be Object, if no explicit class bound is specified. As a
270             // consequence, the first interface's bound is always 1. To account for
271             // a potential mismatch between the indices of the bounds array that only
272             // contains explicit bounds and the actual bound's index, the startIndex
273             // is set to 1 if no explicit class type bound was set.
274             //
275             // This is achieved by examining the first element of the bound to be a
276             // class or an interface, if such a bound exists. Since a bound can itself
277             // be a parameterized type, the bound's raw type must be investigated,
278             // if applicable.
279             if (bounds.length > 0) {
280                 Type b0 = bounds[0];
281                 if (b0 instanceof Class<?>) {
282                     Class<?> c = (Class<?>) b0;
283                     if (c.isInterface()) {
284                         startIndex = 1;
285                     }
286                 } else if (b0 instanceof ParameterizedType) {
287                     ParameterizedType p = (ParameterizedType) b0;
288                     Class<?> c = (Class<?>) p.getRawType();
289                     if (c.isInterface()) {
290                         startIndex = 1;
291                     }
292                 }
293             }
294 
295             for (int i = 0; i < bounds.length; i++) {
296                 List<TypeAnnotation> l = new ArrayList<>(candidates.size());
297                 for (TypeAnnotation t : candidates) {
298                     TypeAnnotationTargetInfo tInfo = t.getTargetInfo();
299                     if (tInfo.getSecondaryIndex() == i + startIndex &&
300                             tInfo.getCount() == typeVarIndex) {
301                         l.add(t);
302                     }
303                 }
304                 res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i],
305                         AnnotatedTypeFactory.nestingForType(bounds[i], loc),
306                         l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
307                         candidates.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
308                         (AnnotatedElement)decl);
309             }
310             return res;
311         }
312         return new AnnotatedType[0];
313     }
fetchBounds(D decl)314     private static <D extends GenericDeclaration> List<TypeAnnotation> fetchBounds(D decl) {
315         AnnotatedElement boundsDecl;
316         TypeAnnotationTarget target;
317         if (decl instanceof Class) {
318             target = TypeAnnotationTarget.CLASS_TYPE_PARAMETER_BOUND;
319             boundsDecl = (Class)decl;
320         } else {
321             target = TypeAnnotationTarget.METHOD_TYPE_PARAMETER_BOUND;
322             boundsDecl = (Executable)decl;
323         }
324         return TypeAnnotation.filter(TypeAnnotationParser.parseAllTypeAnnotations(boundsDecl), target);
325     }
326 
327     /*
328      * Parse all type annotations on the declaration supplied. This is needed
329      * when you go from for example an annotated return type on a method that
330      * is a type variable declared on the class. In this case you need to
331      * 'jump' to the decl of the class and parse all type annotations there to
332      * find the ones that are applicable to the type variable.
333      */
parseAllTypeAnnotations(AnnotatedElement decl)334     static TypeAnnotation[] parseAllTypeAnnotations(AnnotatedElement decl) {
335         Class<?> container;
336         byte[] rawBytes;
337         JavaLangAccess javaLangAccess = SharedSecrets.getJavaLangAccess();
338         if (decl instanceof Class) {
339             container = (Class<?>)decl;
340             rawBytes = javaLangAccess.getRawClassTypeAnnotations(container);
341         } else if (decl instanceof Executable) {
342             container = ((Executable)decl).getDeclaringClass();
343             rawBytes = javaLangAccess.getRawExecutableTypeAnnotations((Executable)decl);
344         } else {
345             // Should not reach here. Assert?
346             return EMPTY_TYPE_ANNOTATION_ARRAY;
347         }
348         return parseTypeAnnotations(rawBytes, javaLangAccess.getConstantPool(container),
349                                     decl, container);
350     }
351 
352     /* Parse type annotations encoded as an array of bytes */
parseTypeAnnotations(byte[] rawAnnotations, ConstantPool cp, AnnotatedElement baseDecl, Class<?> container)353     private static TypeAnnotation[] parseTypeAnnotations(byte[] rawAnnotations,
354             ConstantPool cp,
355             AnnotatedElement baseDecl,
356             Class<?> container) {
357         if (rawAnnotations == null)
358             return EMPTY_TYPE_ANNOTATION_ARRAY;
359 
360         ByteBuffer buf = ByteBuffer.wrap(rawAnnotations);
361         int annotationCount = buf.getShort() & 0xFFFF;
362         List<TypeAnnotation> typeAnnotations = new ArrayList<>(annotationCount);
363 
364         // Parse each TypeAnnotation
365         for (int i = 0; i < annotationCount; i++) {
366              TypeAnnotation ta = parseTypeAnnotation(buf, cp, baseDecl, container);
367              if (ta != null)
368                  typeAnnotations.add(ta);
369         }
370 
371         return typeAnnotations.toArray(EMPTY_TYPE_ANNOTATION_ARRAY);
372     }
373 
374 
375     // Helper
mapTypeAnnotations(TypeAnnotation[] typeAnnos)376     static Map<Class<? extends Annotation>, Annotation> mapTypeAnnotations(TypeAnnotation[] typeAnnos) {
377         Map<Class<? extends Annotation>, Annotation> result =
378             new LinkedHashMap<>();
379         for (TypeAnnotation t : typeAnnos) {
380             Annotation a = t.getAnnotation();
381             if (a != null) {
382                 Class<? extends Annotation> klass = a.annotationType();
383                 AnnotationType type = AnnotationType.getInstance(klass);
384                 if (type.retention() == RetentionPolicy.RUNTIME &&
385                     result.put(klass, a) != null) {
386                     throw new AnnotationFormatError("Duplicate annotation for class: "+klass+": " + a);
387                 }
388             }
389         }
390         return result;
391     }
392 
393     // Position codes
394     // Regular type parameter annotations
395     private static final byte CLASS_TYPE_PARAMETER = 0x00;
396     private static final byte METHOD_TYPE_PARAMETER = 0x01;
397     // Type Annotations outside method bodies
398     private static final byte CLASS_EXTENDS = 0x10;
399     private static final byte CLASS_TYPE_PARAMETER_BOUND = 0x11;
400     private static final byte METHOD_TYPE_PARAMETER_BOUND = 0x12;
401     private static final byte FIELD = 0x13;
402     private static final byte METHOD_RETURN = 0x14;
403     private static final byte METHOD_RECEIVER = 0x15;
404     private static final byte METHOD_FORMAL_PARAMETER = 0x16;
405     private static final byte THROWS = 0x17;
406     // Type Annotations inside method bodies
407     private static final byte LOCAL_VARIABLE = (byte)0x40;
408     private static final byte RESOURCE_VARIABLE = (byte)0x41;
409     private static final byte EXCEPTION_PARAMETER = (byte)0x42;
410     private static final byte INSTANCEOF = (byte)0x43;
411     private static final byte NEW = (byte)0x44;
412     private static final byte CONSTRUCTOR_REFERENCE = (byte)0x45;
413     private static final byte METHOD_REFERENCE = (byte)0x46;
414     private static final byte CAST = (byte)0x47;
415     private static final byte CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT = (byte)0x48;
416     private static final byte METHOD_INVOCATION_TYPE_ARGUMENT = (byte)0x49;
417     private static final byte CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT = (byte)0x4A;
418     private static final byte METHOD_REFERENCE_TYPE_ARGUMENT = (byte)0x4B;
419 
parseTypeAnnotation(ByteBuffer buf, ConstantPool cp, AnnotatedElement baseDecl, Class<?> container)420     private static TypeAnnotation parseTypeAnnotation(ByteBuffer buf,
421             ConstantPool cp,
422             AnnotatedElement baseDecl,
423             Class<?> container) {
424         try {
425             TypeAnnotationTargetInfo ti = parseTargetInfo(buf);
426             LocationInfo locationInfo = LocationInfo.parseLocationInfo(buf);
427             Annotation a = AnnotationParser.parseAnnotation(buf, cp, container, false);
428             if (ti == null) // Inside a method for example
429                 return null;
430             return new TypeAnnotation(ti, locationInfo, a, baseDecl);
431         } catch (IllegalArgumentException | // Bad type in const pool at specified index
432                 BufferUnderflowException e) {
433             throw new AnnotationFormatError(e);
434         }
435     }
436 
parseTargetInfo(ByteBuffer buf)437     private static TypeAnnotationTargetInfo parseTargetInfo(ByteBuffer buf) {
438         int posCode = buf.get() & 0xFF;
439         switch(posCode) {
440         case CLASS_TYPE_PARAMETER:
441         case METHOD_TYPE_PARAMETER: {
442             int index = buf.get() & 0xFF;
443             TypeAnnotationTargetInfo res;
444             if (posCode == CLASS_TYPE_PARAMETER)
445                 res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_TYPE_PARAMETER,
446                         index);
447             else
448                 res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_TYPE_PARAMETER,
449                         index);
450             return res;
451             } // unreachable break;
452         case CLASS_EXTENDS: {
453             short index = buf.getShort(); //needs to be signed
454             if (index == -1) {
455                 return new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_EXTENDS);
456             } else if (index >= 0) {
457                 TypeAnnotationTargetInfo res = new TypeAnnotationTargetInfo(TypeAnnotationTarget.CLASS_IMPLEMENTS,
458                         index);
459                 return res;
460             }} break;
461         case CLASS_TYPE_PARAMETER_BOUND:
462             return parse2ByteTarget(TypeAnnotationTarget.CLASS_TYPE_PARAMETER_BOUND, buf);
463         case METHOD_TYPE_PARAMETER_BOUND:
464             return parse2ByteTarget(TypeAnnotationTarget.METHOD_TYPE_PARAMETER_BOUND, buf);
465         case FIELD:
466             return new TypeAnnotationTargetInfo(TypeAnnotationTarget.FIELD);
467         case METHOD_RETURN:
468             return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RETURN);
469         case METHOD_RECEIVER:
470             return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_RECEIVER);
471         case METHOD_FORMAL_PARAMETER: {
472             int index = buf.get() & 0xFF;
473             return new TypeAnnotationTargetInfo(TypeAnnotationTarget.METHOD_FORMAL_PARAMETER,
474                     index);
475             } //unreachable break;
476         case THROWS:
477             return parseShortTarget(TypeAnnotationTarget.THROWS, buf);
478 
479         /*
480          * The ones below are inside method bodies, we don't care about them for core reflection
481          * other than adjusting for them in the byte stream.
482          */
483         case LOCAL_VARIABLE:
484         case RESOURCE_VARIABLE:
485             short length = buf.getShort();
486             for (int i = 0; i < length; ++i) {
487                 short offset = buf.getShort();
488                 short varLength = buf.getShort();
489                 short index = buf.getShort();
490             }
491             return null;
492         case EXCEPTION_PARAMETER: {
493             byte index = buf.get();
494             }
495             return null;
496         case INSTANCEOF:
497         case NEW:
498         case CONSTRUCTOR_REFERENCE:
499         case METHOD_REFERENCE: {
500             short offset = buf.getShort();
501             }
502             return null;
503         case CAST:
504         case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
505         case METHOD_INVOCATION_TYPE_ARGUMENT:
506         case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
507         case METHOD_REFERENCE_TYPE_ARGUMENT: {
508             short offset = buf.getShort();
509             byte index = buf.get();
510             }
511             return null;
512 
513         default:
514             // will throw error below
515             break;
516         }
517         throw new AnnotationFormatError("Could not parse bytes for type annotations");
518     }
519 
parseShortTarget(TypeAnnotationTarget target, ByteBuffer buf)520     private static TypeAnnotationTargetInfo parseShortTarget(TypeAnnotationTarget target, ByteBuffer buf) {
521         int index = buf.getShort() & 0xFFFF;
522         return new TypeAnnotationTargetInfo(target, index);
523     }
parse2ByteTarget(TypeAnnotationTarget target, ByteBuffer buf)524     private static TypeAnnotationTargetInfo parse2ByteTarget(TypeAnnotationTarget target, ByteBuffer buf) {
525         int count = buf.get() & 0xFF;
526         int secondaryIndex = buf.get() & 0xFF;
527         return new TypeAnnotationTargetInfo(target,
528                                             count,
529                                             secondaryIndex);
530     }
531 }
532