Skip to main content

java_class_rs/
attribute.rs

1use nom::{
2    bytes::complete::take,
3    multi::count,
4    number::complete::{be_u16, be_u32, be_u8},
5    IResult,
6};
7
8use crate::constant_pool::get_utf8;
9
10use crate::types::*;
11
12/// Parse a generic attribute (name_index + length + raw bytes).
13pub(crate) fn parse_attribute(input: &[u8]) -> IResult<&[u8], AttributeInfo> {
14    let (input, attribute_name_index) = be_u16(input)?;
15    let (input, length) = be_u32(input)?;
16    let (input, info) = take(length as usize)(input)?;
17    Ok((
18        input,
19        AttributeInfo {
20            attribute_name_index,
21            info: info.to_vec(),
22        },
23    ))
24}
25
26/// Parse multiple attributes.
27pub(crate) fn parse_attributes(input: &[u8]) -> IResult<&[u8], Vec<AttributeInfo>> {
28    let (input, attributes_count) = be_u16(input)?;
29    let (input, attributes) = count(parse_attribute, attributes_count as usize)(input)?;
30    Ok((input, attributes))
31}
32
33/// Try to parse a raw attribute into a specialized attribute type based on the attribute name.
34pub fn parse_specialized_attribute(
35    attr: &AttributeInfo,
36    pool: &[ConstantPoolEntry],
37) -> ParsedAttribute {
38    let name = match get_utf8(pool, attr.attribute_name_index) {
39        Some(n) => n,
40        None => return ParsedAttribute::Unknown(attr.clone()),
41    };
42
43    match name {
44        "Code" => parse_code_attribute(&attr.info)
45            .map(|(_, a)| ParsedAttribute::Code(a))
46            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
47        "ConstantValue" => parse_constant_value_attribute(&attr.info)
48            .map(|(_, a)| ParsedAttribute::ConstantValue(a))
49            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
50        "Exceptions" => parse_exceptions_attribute(&attr.info)
51            .map(|(_, a)| ParsedAttribute::Exceptions(a))
52            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
53        "BootstrapMethods" => parse_bootstrap_methods_attribute(&attr.info)
54            .map(|(_, a)| ParsedAttribute::BootstrapMethods(a))
55            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
56        "StackMapTable" => parse_stack_map_table_attribute(&attr.info)
57            .map(|(_, a)| ParsedAttribute::StackMapTable(a))
58            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
59        "InnerClasses" => parse_inner_classes_attribute(&attr.info)
60            .map(|(_, a)| ParsedAttribute::InnerClasses(a))
61            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
62        "SourceFile" => parse_source_file_attribute(&attr.info)
63            .map(|(_, a)| ParsedAttribute::SourceFile(a))
64            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
65        "LineNumberTable" => parse_line_number_table_attribute(&attr.info)
66            .map(|(_, a)| ParsedAttribute::LineNumberTable(a))
67            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
68        "LocalVariableTable" => parse_local_variable_table_attribute(&attr.info)
69            .map(|(_, a)| ParsedAttribute::LocalVariableTable(a))
70            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
71        "LocalVariableTypeTable" => parse_local_variable_type_table_attribute(&attr.info)
72            .map(|(_, a)| ParsedAttribute::LocalVariableTypeTable(a))
73            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
74        "RuntimeVisibleAnnotations" => parse_runtime_annotations_attribute(&attr.info)
75            .map(|(_, a)| ParsedAttribute::RuntimeVisibleAnnotations(a))
76            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
77        "RuntimeInvisibleAnnotations" => parse_runtime_annotations_attribute(&attr.info)
78            .map(|(_, a)| ParsedAttribute::RuntimeInvisibleAnnotations(a))
79            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
80        "RuntimeVisibleParameterAnnotations" => {
81            parse_runtime_parameter_annotations_attribute(&attr.info)
82                .map(|(_, a)| ParsedAttribute::RuntimeVisibleParameterAnnotations(a))
83                .unwrap_or(ParsedAttribute::Unknown(attr.clone()))
84        }
85        "RuntimeInvisibleParameterAnnotations" => {
86            parse_runtime_parameter_annotations_attribute(&attr.info)
87                .map(|(_, a)| ParsedAttribute::RuntimeInvisibleParameterAnnotations(a))
88                .unwrap_or(ParsedAttribute::Unknown(attr.clone()))
89        }
90        "RuntimeVisibleTypeAnnotations" => parse_runtime_type_annotations_attribute(&attr.info)
91            .map(|(_, a)| ParsedAttribute::RuntimeVisibleTypeAnnotations(a))
92            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
93        "RuntimeInvisibleTypeAnnotations" => parse_runtime_type_annotations_attribute(&attr.info)
94            .map(|(_, a)| ParsedAttribute::RuntimeInvisibleTypeAnnotations(a))
95            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
96        "NestHost" => parse_nest_host_attribute(&attr.info)
97            .map(|(_, a)| ParsedAttribute::NestHost(a))
98            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
99        "NestMembers" => parse_nest_members_attribute(&attr.info)
100            .map(|(_, a)| ParsedAttribute::NestMembers(a))
101            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
102        "Record" => parse_record_attribute(&attr.info)
103            .map(|(_, a)| ParsedAttribute::Record(a))
104            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
105        "PermittedSubclasses" => parse_permitted_subclasses_attribute(&attr.info)
106            .map(|(_, a)| ParsedAttribute::PermittedSubclasses(a))
107            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
108        "Deprecated" => ParsedAttribute::Deprecated,
109        "Synthetic" => ParsedAttribute::Synthetic,
110        "Signature" => parse_signature_attribute(&attr.info)
111            .map(|(_, signature_index)| ParsedAttribute::Signature { signature_index })
112            .unwrap_or(ParsedAttribute::Unknown(attr.clone())),
113        _ => ParsedAttribute::Unknown(attr.clone()),
114    }
115}
116
117fn parse_code_attribute(input: &[u8]) -> IResult<&[u8], CodeAttribute> {
118    let (input, max_stack) = be_u16(input)?;
119    let (input, max_locals) = be_u16(input)?;
120    let (input, code_length) = be_u32(input)?;
121    let (input, code) = take(code_length as usize)(input)?;
122    let (input, exception_table_length) = be_u16(input)?;
123    let (input, exception_table) =
124        count(parse_exception_table_entry, exception_table_length as usize)(input)?;
125    let (input, attributes) = parse_attributes(input)?;
126    Ok((
127        input,
128        CodeAttribute {
129            max_stack,
130            max_locals,
131            code: code.to_vec(),
132            exception_table,
133            attributes,
134        },
135    ))
136}
137
138fn parse_exception_table_entry(input: &[u8]) -> IResult<&[u8], ExceptionTableEntry> {
139    let (input, start_pc) = be_u16(input)?;
140    let (input, end_pc) = be_u16(input)?;
141    let (input, handler_pc) = be_u16(input)?;
142    let (input, catch_type) = be_u16(input)?;
143    Ok((
144        input,
145        ExceptionTableEntry {
146            start_pc,
147            end_pc,
148            handler_pc,
149            catch_type,
150        },
151    ))
152}
153
154fn parse_constant_value_attribute(input: &[u8]) -> IResult<&[u8], ConstantValueAttribute> {
155    let (input, constantvalue_index) = be_u16(input)?;
156    Ok((
157        input,
158        ConstantValueAttribute {
159            constantvalue_index,
160        },
161    ))
162}
163
164fn parse_exceptions_attribute(input: &[u8]) -> IResult<&[u8], ExceptionsAttribute> {
165    let (input, number_of_exceptions) = be_u16(input)?;
166    let (input, exception_index_table) = count(be_u16, number_of_exceptions as usize)(input)?;
167    Ok((
168        input,
169        ExceptionsAttribute {
170            exception_index_table,
171        },
172    ))
173}
174
175fn parse_bootstrap_methods_attribute(input: &[u8]) -> IResult<&[u8], BootstrapMethodsAttribute> {
176    let (input, num_bootstrap_methods) = be_u16(input)?;
177    let (input, bootstrap_methods) =
178        count(parse_bootstrap_method_entry, num_bootstrap_methods as usize)(input)?;
179    Ok((input, BootstrapMethodsAttribute { bootstrap_methods }))
180}
181
182fn parse_bootstrap_method_entry(input: &[u8]) -> IResult<&[u8], BootstrapMethodEntry> {
183    let (input, bootstrap_method_ref) = be_u16(input)?;
184    let (input, num_bootstrap_arguments) = be_u16(input)?;
185    let (input, bootstrap_arguments) = count(be_u16, num_bootstrap_arguments as usize)(input)?;
186    Ok((
187        input,
188        BootstrapMethodEntry {
189            bootstrap_method_ref,
190            bootstrap_arguments,
191        },
192    ))
193}
194
195fn parse_stack_map_table_attribute(input: &[u8]) -> IResult<&[u8], StackMapTableAttribute> {
196    let (input, number_of_entries) = be_u16(input)?;
197    let mut remaining = input;
198    let mut entries = Vec::with_capacity(number_of_entries as usize);
199    for _ in 0..number_of_entries {
200        let (rem, frame) = parse_stack_map_frame(remaining)?;
201        entries.push(frame);
202        remaining = rem;
203    }
204    Ok((remaining, StackMapTableAttribute { entries }))
205}
206
207fn parse_stack_map_frame(input: &[u8]) -> IResult<&[u8], StackMapFrame> {
208    let (input, frame_type) = be_u8(input)?;
209    match frame_type {
210        0..=63 => Ok((input, StackMapFrame::SameFrame { frame_type })),
211        64..=127 => {
212            let (input, stack) = parse_verification_type_info(input)?;
213            Ok((
214                input,
215                StackMapFrame::SameLocals1StackItemFrame { frame_type, stack },
216            ))
217        }
218        247 => {
219            let (input, offset_delta) = be_u16(input)?;
220            let (input, stack) = parse_verification_type_info(input)?;
221            Ok((
222                input,
223                StackMapFrame::SameLocals1StackItemFrameExtended {
224                    offset_delta,
225                    stack,
226                },
227            ))
228        }
229        248..=250 => {
230            let (input, offset_delta) = be_u16(input)?;
231            Ok((
232                input,
233                StackMapFrame::ChopFrame {
234                    frame_type,
235                    offset_delta,
236                },
237            ))
238        }
239        251 => {
240            let (input, offset_delta) = be_u16(input)?;
241            Ok((input, StackMapFrame::SameFrameExtended { offset_delta }))
242        }
243        252..=254 => {
244            let (input, offset_delta) = be_u16(input)?;
245            let num_locals = (frame_type - 251) as usize;
246            let (input, locals) = count(parse_verification_type_info, num_locals)(input)?;
247            Ok((
248                input,
249                StackMapFrame::AppendFrame {
250                    frame_type,
251                    offset_delta,
252                    locals,
253                },
254            ))
255        }
256        255 => {
257            let (input, offset_delta) = be_u16(input)?;
258            let (input, number_of_locals) = be_u16(input)?;
259            let (input, locals) =
260                count(parse_verification_type_info, number_of_locals as usize)(input)?;
261            let (input, number_of_stack_items) = be_u16(input)?;
262            let (input, stack) =
263                count(parse_verification_type_info, number_of_stack_items as usize)(input)?;
264            Ok((
265                input,
266                StackMapFrame::FullFrame {
267                    offset_delta,
268                    locals,
269                    stack,
270                },
271            ))
272        }
273        // Reserved frame types 128-246
274        _ => Err(nom::Err::Error(nom::error::Error::new(
275            input,
276            nom::error::ErrorKind::Tag,
277        ))),
278    }
279}
280
281fn parse_verification_type_info(input: &[u8]) -> IResult<&[u8], VerificationTypeInfo> {
282    let (input, tag) = be_u8(input)?;
283    match tag {
284        0 => Ok((input, VerificationTypeInfo::Top)),
285        1 => Ok((input, VerificationTypeInfo::Integer)),
286        2 => Ok((input, VerificationTypeInfo::Float)),
287        3 => Ok((input, VerificationTypeInfo::Double)),
288        4 => Ok((input, VerificationTypeInfo::Long)),
289        5 => Ok((input, VerificationTypeInfo::Null)),
290        6 => Ok((input, VerificationTypeInfo::UninitializedThis)),
291        7 => {
292            let (input, cpool_index) = be_u16(input)?;
293            Ok((input, VerificationTypeInfo::Object { cpool_index }))
294        }
295        8 => {
296            let (input, offset) = be_u16(input)?;
297            Ok((input, VerificationTypeInfo::Uninitialized { offset }))
298        }
299        _ => Err(nom::Err::Error(nom::error::Error::new(
300            input,
301            nom::error::ErrorKind::Tag,
302        ))),
303    }
304}
305
306fn parse_inner_classes_attribute(input: &[u8]) -> IResult<&[u8], InnerClassesAttribute> {
307    let (input, number_of_classes) = be_u16(input)?;
308    let (input, classes) = count(parse_inner_class, number_of_classes as usize)(input)?;
309    Ok((input, InnerClassesAttribute { classes }))
310}
311
312fn parse_inner_class(input: &[u8]) -> IResult<&[u8], InnerClass> {
313    let (input, inner_class_info_index) = be_u16(input)?;
314    let (input, outer_class_info_index) = be_u16(input)?;
315    let (input, inner_name_index) = be_u16(input)?;
316    let (input, access_flags) = be_u16(input)?;
317    Ok((
318        input,
319        InnerClass {
320            inner_class_info_index,
321            outer_class_info_index,
322            inner_name_index,
323            inner_class_access_flags: ClassAccessFlags::from_bits_truncate(access_flags),
324        },
325    ))
326}
327
328fn parse_source_file_attribute(input: &[u8]) -> IResult<&[u8], SourceFileAttribute> {
329    let (input, sourcefile_index) = be_u16(input)?;
330    Ok((input, SourceFileAttribute { sourcefile_index }))
331}
332
333fn parse_line_number_table_attribute(input: &[u8]) -> IResult<&[u8], LineNumberTableAttribute> {
334    let (input, line_number_table_length) = be_u16(input)?;
335    let (input, line_number_table) =
336        count(parse_line_number_entry, line_number_table_length as usize)(input)?;
337    Ok((input, LineNumberTableAttribute { line_number_table }))
338}
339
340fn parse_line_number_entry(input: &[u8]) -> IResult<&[u8], LineNumberEntry> {
341    let (input, start_pc) = be_u16(input)?;
342    let (input, line_number) = be_u16(input)?;
343    Ok((
344        input,
345        LineNumberEntry {
346            start_pc,
347            line_number,
348        },
349    ))
350}
351
352fn parse_local_variable_table_attribute(
353    input: &[u8],
354) -> IResult<&[u8], LocalVariableTableAttribute> {
355    let (input, local_variable_table_length) = be_u16(input)?;
356    let (input, local_variable_table) = count(
357        parse_local_variable_entry,
358        local_variable_table_length as usize,
359    )(input)?;
360    Ok((
361        input,
362        LocalVariableTableAttribute {
363            local_variable_table,
364        },
365    ))
366}
367
368fn parse_local_variable_entry(input: &[u8]) -> IResult<&[u8], LocalVariableEntry> {
369    let (input, start_pc) = be_u16(input)?;
370    let (input, length) = be_u16(input)?;
371    let (input, name_index) = be_u16(input)?;
372    let (input, descriptor_index) = be_u16(input)?;
373    let (input, index) = be_u16(input)?;
374    Ok((
375        input,
376        LocalVariableEntry {
377            start_pc,
378            length,
379            name_index,
380            descriptor_index,
381            index,
382        },
383    ))
384}
385
386fn parse_local_variable_type_table_attribute(
387    input: &[u8],
388) -> IResult<&[u8], LocalVariableTypeTableAttribute> {
389    let (input, local_variable_type_table_length) = be_u16(input)?;
390    let (input, local_variable_type_table) = count(
391        parse_local_variable_type_entry,
392        local_variable_type_table_length as usize,
393    )(input)?;
394    Ok((
395        input,
396        LocalVariableTypeTableAttribute {
397            local_variable_type_table,
398        },
399    ))
400}
401
402fn parse_local_variable_type_entry(input: &[u8]) -> IResult<&[u8], LocalVariableTypeEntry> {
403    let (input, start_pc) = be_u16(input)?;
404    let (input, length) = be_u16(input)?;
405    let (input, name_index) = be_u16(input)?;
406    let (input, signature_index) = be_u16(input)?;
407    let (input, index) = be_u16(input)?;
408    Ok((
409        input,
410        LocalVariableTypeEntry {
411            start_pc,
412            length,
413            name_index,
414            signature_index,
415            index,
416        },
417    ))
418}
419
420fn parse_runtime_annotations_attribute(
421    input: &[u8],
422) -> IResult<&[u8], RuntimeAnnotationsAttribute> {
423    let (input, num_annotations) = be_u16(input)?;
424    let (input, annotations) = count(parse_annotation, num_annotations as usize)(input)?;
425    Ok((input, RuntimeAnnotationsAttribute { annotations }))
426}
427
428fn parse_annotation(input: &[u8]) -> IResult<&[u8], Annotation> {
429    let (input, type_index) = be_u16(input)?;
430    let (input, num_element_value_pairs) = be_u16(input)?;
431    let (input, element_value_pairs) =
432        count(parse_element_value_pair, num_element_value_pairs as usize)(input)?;
433    Ok((
434        input,
435        Annotation {
436            type_index,
437            element_value_pairs,
438        },
439    ))
440}
441
442fn parse_element_value_pair(input: &[u8]) -> IResult<&[u8], (u16, ElementValue)> {
443    let (input, element_name_index) = be_u16(input)?;
444    let (input, value) = parse_element_value(input)?;
445    Ok((input, (element_name_index, value)))
446}
447
448fn parse_element_value(input: &[u8]) -> IResult<&[u8], ElementValue> {
449    let (input, tag) = be_u8(input)?;
450    match tag {
451        b'B' | b'C' | b'D' | b'F' | b'I' | b'J' | b'S' | b'Z' | b's' => {
452            let (input, const_value_index) = be_u16(input)?;
453            let ev = match tag {
454                b'B' => ElementValue::Byte { const_value_index },
455                b'C' => ElementValue::Char { const_value_index },
456                b'D' => ElementValue::Double { const_value_index },
457                b'F' => ElementValue::Float { const_value_index },
458                b'I' => ElementValue::Int { const_value_index },
459                b'J' => ElementValue::Long { const_value_index },
460                b'S' => ElementValue::Short { const_value_index },
461                b'Z' => ElementValue::Boolean { const_value_index },
462                b's' => ElementValue::String { const_value_index },
463                _ => unreachable!(),
464            };
465            Ok((input, ev))
466        }
467        b'e' => {
468            let (input, type_name_index) = be_u16(input)?;
469            let (input, const_name_index) = be_u16(input)?;
470            Ok((
471                input,
472                ElementValue::Enum {
473                    type_name_index,
474                    const_name_index,
475                },
476            ))
477        }
478        b'c' => {
479            let (input, class_info_index) = be_u16(input)?;
480            Ok((input, ElementValue::Class { class_info_index }))
481        }
482        b'@' => {
483            let (input, annotation) = parse_annotation(input)?;
484            Ok((input, ElementValue::AnnotationType { annotation }))
485        }
486        b'[' => {
487            let (input, num_values) = be_u16(input)?;
488            let (input, values) = count(parse_element_value, num_values as usize)(input)?;
489            Ok((input, ElementValue::Array { values }))
490        }
491        _ => Err(nom::Err::Error(nom::error::Error::new(
492            input,
493            nom::error::ErrorKind::Tag,
494        ))),
495    }
496}
497
498fn parse_nest_host_attribute(input: &[u8]) -> IResult<&[u8], NestHostAttribute> {
499    let (input, host_class_index) = be_u16(input)?;
500    Ok((input, NestHostAttribute { host_class_index }))
501}
502
503fn parse_nest_members_attribute(input: &[u8]) -> IResult<&[u8], NestMembersAttribute> {
504    let (input, number_of_classes) = be_u16(input)?;
505    let (input, classes) = count(be_u16, number_of_classes as usize)(input)?;
506    Ok((input, NestMembersAttribute { classes }))
507}
508
509fn parse_record_attribute(input: &[u8]) -> IResult<&[u8], RecordAttribute> {
510    let (input, number_of_components) = be_u16(input)?;
511    let (input, components) = count(parse_record_component, number_of_components as usize)(input)?;
512    Ok((input, RecordAttribute { components }))
513}
514
515fn parse_record_component(input: &[u8]) -> IResult<&[u8], RecordComponentInfo> {
516    let (input, name_index) = be_u16(input)?;
517    let (input, descriptor_index) = be_u16(input)?;
518    let (input, attributes) = parse_attributes(input)?;
519    Ok((
520        input,
521        RecordComponentInfo {
522            name_index,
523            descriptor_index,
524            attributes,
525        },
526    ))
527}
528
529fn parse_permitted_subclasses_attribute(
530    input: &[u8],
531) -> IResult<&[u8], PermittedSubclassesAttribute> {
532    let (input, number_of_classes) = be_u16(input)?;
533    let (input, classes) = count(be_u16, number_of_classes as usize)(input)?;
534    Ok((input, PermittedSubclassesAttribute { classes }))
535}
536
537fn parse_signature_attribute(input: &[u8]) -> IResult<&[u8], u16> {
538    let (input, signature_index) = be_u16(input)?;
539    Ok((input, signature_index))
540}
541
542fn parse_runtime_parameter_annotations_attribute(
543    input: &[u8],
544) -> IResult<&[u8], RuntimeParameterAnnotationsAttribute> {
545    let (input, num_parameters) = be_u8(input)?;
546    let mut remaining = input;
547    let mut parameter_annotations = Vec::with_capacity(num_parameters as usize);
548    for _ in 0..num_parameters {
549        let (rem, annotations) = parse_runtime_annotations_attribute(remaining)?;
550        parameter_annotations.push(ParameterAnnotation {
551            annotations: annotations.annotations,
552        });
553        remaining = rem;
554    }
555    Ok((
556        remaining,
557        RuntimeParameterAnnotationsAttribute {
558            parameter_annotations,
559        },
560    ))
561}
562
563fn parse_runtime_type_annotations_attribute(
564    input: &[u8],
565) -> IResult<&[u8], RuntimeTypeAnnotationsAttribute> {
566    let (input, num_annotations) = be_u16(input)?;
567    let mut remaining = input;
568    let mut annotations = Vec::with_capacity(num_annotations as usize);
569    for _ in 0..num_annotations {
570        let (rem, annotation) = parse_type_annotation(remaining)?;
571        annotations.push(annotation);
572        remaining = rem;
573    }
574    Ok((remaining, RuntimeTypeAnnotationsAttribute { annotations }))
575}
576
577fn parse_type_annotation(input: &[u8]) -> IResult<&[u8], TypeAnnotation> {
578    let (input, target) = parse_type_annotation_target(input)?;
579    let (input, target_path) = parse_type_path(input)?;
580    let (input, type_index) = be_u16(input)?;
581    let (input, num_element_value_pairs) = be_u16(input)?;
582    let (input, element_value_pairs) =
583        count(parse_element_value_pair, num_element_value_pairs as usize)(input)?;
584    Ok((
585        input,
586        TypeAnnotation {
587            target,
588            target_path,
589            type_index,
590            element_value_pairs,
591        },
592    ))
593}
594
595fn parse_type_annotation_target(input: &[u8]) -> IResult<&[u8], TypeAnnotationTarget> {
596    let (input, target_type) = be_u8(input)?;
597    match target_type {
598        0x00 | 0x01 => {
599            let (input, type_parameter_index) = be_u8(input)?;
600            Ok((
601                input,
602                TypeAnnotationTarget::TypeParameter {
603                    type_parameter_index,
604                },
605            ))
606        }
607        0x10 => {
608            let (input, super_type_index) = be_u16(input)?;
609            Ok((input, TypeAnnotationTarget::SuperType { super_type_index }))
610        }
611        0x11 | 0x12 => {
612            let (input, type_parameter_index) = be_u8(input)?;
613            let (input, bound_index) = be_u8(input)?;
614            Ok((
615                input,
616                TypeAnnotationTarget::TypeParameterBound {
617                    type_parameter_index,
618                    bound_index,
619                },
620            ))
621        }
622        0x13..=0x15 => Ok((input, TypeAnnotationTarget::Empty)),
623        0x16 => {
624            let (input, formal_parameter_index) = be_u8(input)?;
625            Ok((
626                input,
627                TypeAnnotationTarget::FormalParameter {
628                    formal_parameter_index,
629                },
630            ))
631        }
632        0x17 => {
633            let (input, throws_type_index) = be_u16(input)?;
634            Ok((input, TypeAnnotationTarget::Throws { throws_type_index }))
635        }
636        0x40 | 0x41 => {
637            let (input, table_length) = be_u16(input)?;
638            let (input, table) = count(parse_local_var_target_entry, table_length as usize)(input)?;
639            Ok((input, TypeAnnotationTarget::LocalVar { table }))
640        }
641        0x42 => {
642            let (input, exception_table_index) = be_u16(input)?;
643            Ok((
644                input,
645                TypeAnnotationTarget::Catch {
646                    exception_table_index,
647                },
648            ))
649        }
650        0x43..=0x46 => {
651            let (input, offset) = be_u16(input)?;
652            Ok((input, TypeAnnotationTarget::Offset { offset }))
653        }
654        0x47..=0x4B => {
655            let (input, offset) = be_u16(input)?;
656            let (input, type_argument_index) = be_u8(input)?;
657            Ok((
658                input,
659                TypeAnnotationTarget::TypeArgument {
660                    offset,
661                    type_argument_index,
662                },
663            ))
664        }
665        _ => Err(nom::Err::Error(nom::error::Error::new(
666            input,
667            nom::error::ErrorKind::Tag,
668        ))),
669    }
670}
671
672fn parse_local_var_target_entry(input: &[u8]) -> IResult<&[u8], LocalVarTargetEntry> {
673    let (input, start_pc) = be_u16(input)?;
674    let (input, length) = be_u16(input)?;
675    let (input, index) = be_u16(input)?;
676    Ok((
677        input,
678        LocalVarTargetEntry {
679            start_pc,
680            length,
681            index,
682        },
683    ))
684}
685
686fn parse_type_path(input: &[u8]) -> IResult<&[u8], Vec<TypePathEntry>> {
687    let (input, path_length) = be_u8(input)?;
688    let (input, entries) = count(parse_type_path_entry, path_length as usize)(input)?;
689    Ok((input, entries))
690}
691
692fn parse_type_path_entry(input: &[u8]) -> IResult<&[u8], TypePathEntry> {
693    let (input, type_path_kind) = be_u8(input)?;
694    let (input, type_argument_index) = be_u8(input)?;
695    Ok((
696        input,
697        TypePathEntry {
698            type_path_kind,
699            type_argument_index,
700        },
701    ))
702}