1 /*
  2  * Copyright (c) 2022, 2024, 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 package jdk.internal.classfile.impl;
 26 
 27 import java.lang.classfile.Annotation;
 28 import java.lang.classfile.Attribute;
 29 import java.lang.classfile.AttributeMapper;
 30 import java.lang.classfile.AttributedElement;
 31 import java.lang.classfile.BufWriter;
 32 import java.lang.classfile.ClassReader;
 33 import java.lang.classfile.attribute.*;
 34 import java.util.List;
 35 
 36 import static java.lang.classfile.Attributes.*;
 37 
 38 public sealed abstract class AbstractAttributeMapper<T extends Attribute<T>>
 39         implements AttributeMapper<T> {
 40 
 41     private final String name;
 42     private final AttributeMapper.AttributeStability stability;
 43     private final boolean allowMultiple;
 44 
 45     protected abstract void writeBody(BufWriter buf, T attr);
 46 
 47     public AbstractAttributeMapper(String name, AttributeMapper.AttributeStability stability) {
 48         this(name, stability, false);
 49     }
 50 
 51     public AbstractAttributeMapper(String name,
 52                                    AttributeMapper.AttributeStability stability,
 53                                    boolean allowMultiple) {
 54         this.name = name;
 55         this.stability = stability;
 56         this.allowMultiple = allowMultiple;
 57     }
 58 
 59     @Override
 60     public final String name() {
 61         return name;
 62     }
 63 
 64     @Override
 65     public final void writeAttribute(BufWriter buf, T attr) {
 66         buf.writeIndex(buf.constantPool().utf8Entry(name));
 67         buf.writeInt(0);
 68         int start = buf.size();
 69         writeBody(buf, attr);
 70         int written = buf.size() - start;
 71         buf.patchInt(start - 4, 4, written);
 72     }
 73 
 74     @Override
 75     public AttributeMapper.AttributeStability stability() {
 76         return stability;
 77     }
 78 
 79     @Override
 80     public boolean allowMultiple() {
 81         return allowMultiple;
 82     }
 83 
 84     @Override
 85     public String toString() {
 86         return String.format("AttributeMapper[name=%s, allowMultiple=%b, stability=%s]",
 87                 name, allowMultiple, stability());
 88     }
 89 
 90     public static final class AnnotationDefaultMapper extends AbstractAttributeMapper<AnnotationDefaultAttribute> {
 91         public static final AnnotationDefaultMapper INSTANCE = new AnnotationDefaultMapper();
 92 
 93         private AnnotationDefaultMapper() {
 94             super(NAME_ANNOTATION_DEFAULT, AttributeStability.CP_REFS);
 95         }
 96 
 97         @Override
 98         public AnnotationDefaultAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 99             return new BoundAttribute.BoundAnnotationDefaultAttr(cf, this, p);
100         }
101 
102         @Override
103         protected void writeBody(BufWriter buf, AnnotationDefaultAttribute attr) {
104             AnnotationReader.writeAnnotationValue((BufWriterImpl) buf, attr.defaultValue());
105         }
106     }
107 
108     public static final class BootstrapMethodsMapper extends AbstractAttributeMapper<BootstrapMethodsAttribute> {
109         public static final BootstrapMethodsMapper INSTANCE = new BootstrapMethodsMapper();
110 
111         private BootstrapMethodsMapper() {
112             super(NAME_BOOTSTRAP_METHODS, AttributeStability.CP_REFS);
113         }
114 
115         @Override
116         public BootstrapMethodsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
117             return new BoundAttribute.BoundBootstrapMethodsAttribute(cf, this, p);
118         }
119 
120         @Override
121         protected void writeBody(BufWriter buf, BootstrapMethodsAttribute attr) {
122             var b = (BufWriterImpl) buf;
123             b.writeU2(attr.bootstrapMethodsSize());
124             for (var bsm : attr.bootstrapMethods()) {
125                 ((BootstrapMethodEntryImpl) bsm).writeTo(b);
126             }
127         }
128     }
129 
130     public static final class CharacterRangeTableMapper extends AbstractAttributeMapper<CharacterRangeTableAttribute> {
131         public static final CharacterRangeTableMapper INSTANCE = new CharacterRangeTableMapper();
132 
133         private CharacterRangeTableMapper() {
134             super(NAME_CHARACTER_RANGE_TABLE, AttributeStability.LABELS, true);
135         }
136 
137         @Override
138         public CharacterRangeTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
139             return new BoundAttribute.BoundCharacterRangeTableAttribute(cf, this, p);
140         }
141 
142         @Override
143         protected void writeBody(BufWriter buf, CharacterRangeTableAttribute attr) {
144             List<CharacterRangeInfo> ranges = attr.characterRangeTable();
145             buf.writeU2(ranges.size());
146             for (CharacterRangeInfo info : ranges) {
147                 buf.writeU2(info.startPc());
148                 buf.writeU2(info.endPc());
149                 buf.writeInt(info.characterRangeStart());
150                 buf.writeInt(info.characterRangeEnd());
151                 buf.writeU2(info.flags());
152             }
153         }
154     }
155 
156     public static final class CodeMapper extends AbstractAttributeMapper<CodeAttribute> {
157         public static final CodeMapper INSTANCE = new CodeMapper();
158 
159         private CodeMapper() {
160             super(NAME_CODE, AttributeStability.CP_REFS);
161         }
162 
163         @Override
164         public CodeAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
165             return new CodeImpl(e, cf, this, p);
166         }
167 
168         @Override
169         protected void writeBody(BufWriter buf, CodeAttribute attr) {
170             throw new UnsupportedOperationException("Code attribute does not support direct write");
171         }
172     }
173 
174     public static final class CompilationIDMapper extends AbstractAttributeMapper<CompilationIDAttribute> {
175         public static final CompilationIDMapper INSTANCE = new CompilationIDMapper();
176 
177         private CompilationIDMapper() {
178             super(NAME_COMPILATION_ID, AttributeStability.CP_REFS);
179         }
180 
181         @Override
182         public CompilationIDAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
183             return new BoundAttribute.BoundCompilationIDAttribute(cf, this, p);
184         }
185 
186         @Override
187         protected void writeBody(BufWriter buf, CompilationIDAttribute attr) {
188             buf.writeIndex(attr.compilationId());
189         }
190     }
191 
192     public static final class ConstantValueMapper extends AbstractAttributeMapper<ConstantValueAttribute> {
193         public static final ConstantValueMapper INSTANCE = new ConstantValueMapper();
194 
195         private ConstantValueMapper() {
196             super(NAME_CONSTANT_VALUE, AttributeStability.CP_REFS);
197         }
198 
199         @Override
200         public ConstantValueAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
201             return new BoundAttribute.BoundConstantValueAttribute(cf, this, p);
202         }
203 
204         @Override
205         protected void writeBody(BufWriter buf, ConstantValueAttribute attr) {
206             buf.writeIndex(attr.constant());
207         }
208     }
209 
210     public static final class DeprecatedMapper extends AbstractAttributeMapper<DeprecatedAttribute> {
211         public static final DeprecatedMapper INSTANCE = new DeprecatedMapper();
212 
213         private DeprecatedMapper() {
214             super(NAME_DEPRECATED, AttributeStability.STATELESS, true);
215         }
216 
217         @Override
218         public DeprecatedAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
219             return new BoundAttribute.BoundDeprecatedAttribute(cf, this, p);
220         }
221 
222         @Override
223         protected void writeBody(BufWriter buf, DeprecatedAttribute attr) {
224             // empty
225         }
226     }
227 
228     public static final class EnclosingMethodMapper extends AbstractAttributeMapper<EnclosingMethodAttribute> {
229         public static final EnclosingMethodMapper INSTANCE = new EnclosingMethodMapper();
230 
231         private EnclosingMethodMapper() {
232             super(NAME_ENCLOSING_METHOD, AttributeStability.CP_REFS);
233         }
234 
235         @Override
236         public EnclosingMethodAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
237             return new BoundAttribute.BoundEnclosingMethodAttribute(cf, this, p);
238         }
239 
240         @Override
241         protected void writeBody(BufWriter buf, EnclosingMethodAttribute attr) {
242             buf.writeIndex(attr.enclosingClass());
243             buf.writeIndexOrZero(attr.enclosingMethod().orElse(null));
244         }
245     }
246 
247     public static final class ExceptionsMapper extends AbstractAttributeMapper<ExceptionsAttribute> {
248         public static final ExceptionsMapper INSTANCE = new ExceptionsMapper();
249 
250         private ExceptionsMapper() {
251             super(NAME_EXCEPTIONS, AttributeStability.CP_REFS);
252         }
253 
254         @Override
255         public ExceptionsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
256             return new BoundAttribute.BoundExceptionsAttribute(cf, this, p);
257         }
258 
259         @Override
260         protected void writeBody(BufWriter buf, ExceptionsAttribute attr) {
261             Util.writeListIndices(buf, attr.exceptions());
262         }
263     }
264 
265     public static final class InnerClassesMapper extends AbstractAttributeMapper<InnerClassesAttribute> {
266         public static final InnerClassesMapper INSTANCE = new InnerClassesMapper();
267 
268         private InnerClassesMapper() {
269             super(NAME_INNER_CLASSES, AttributeStability.CP_REFS);
270         }
271 
272         @Override
273         public InnerClassesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
274             return new BoundAttribute.BoundInnerClassesAttribute(cf, this, p);
275         }
276 
277         @Override
278         protected void writeBody(BufWriter buf, InnerClassesAttribute attr) {
279             List<InnerClassInfo> classes = attr.classes();
280             buf.writeU2(classes.size());
281             for (InnerClassInfo ic : classes) {
282                 buf.writeIndex(ic.innerClass());
283                 buf.writeIndexOrZero(ic.outerClass().orElse(null));
284                 buf.writeIndexOrZero(ic.innerName().orElse(null));
285                 buf.writeU2(ic.flagsMask());
286             }
287         }
288     }
289 
290     public static final class LineNumberTableMapper extends AbstractAttributeMapper<LineNumberTableAttribute> {
291         public static final LineNumberTableMapper INSTANCE = new LineNumberTableMapper();
292 
293         private LineNumberTableMapper() {
294             super(NAME_LINE_NUMBER_TABLE, AttributeStability.LABELS, true);
295         }
296 
297         @Override
298         public LineNumberTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
299             return new BoundAttribute.BoundLineNumberTableAttribute(cf, this, p);
300         }
301 
302         @Override
303         protected void writeBody(BufWriter buf, LineNumberTableAttribute attr) {
304             List<LineNumberInfo> lines = attr.lineNumbers();
305             buf.writeU2(lines.size());
306             for (LineNumberInfo line : lines) {
307                 buf.writeU2(line.startPc());
308                 buf.writeU2(line.lineNumber());
309             }
310         }
311     }
312 
313     public static final class LocalVariableTableMapper extends AbstractAttributeMapper<LocalVariableTableAttribute> {
314         public static final LocalVariableTableMapper INSTANCE = new LocalVariableTableMapper();
315 
316         private LocalVariableTableMapper() {
317             super(NAME_LOCAL_VARIABLE_TABLE, AttributeStability.LABELS, true);
318         }
319 
320         @Override
321         public LocalVariableTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
322             return new BoundAttribute.BoundLocalVariableTableAttribute(e, cf, this, p);
323         }
324 
325         @Override
326         protected void writeBody(BufWriter buf, LocalVariableTableAttribute attr) {
327             List<LocalVariableInfo> infos = attr.localVariables();
328             buf.writeU2(infos.size());
329             for (LocalVariableInfo info : infos) {
330                 buf.writeU2(info.startPc());
331                 buf.writeU2(info.length());
332                 buf.writeIndex(info.name());
333                 buf.writeIndex(info.type());
334                 buf.writeU2(info.slot());
335             }
336         }
337     }
338 
339     public static final class LocalVariableTypeTableMapper extends AbstractAttributeMapper<LocalVariableTypeTableAttribute> {
340         public static final LocalVariableTypeTableMapper INSTANCE = new LocalVariableTypeTableMapper();
341 
342         private LocalVariableTypeTableMapper() {
343             super(NAME_LOCAL_VARIABLE_TYPE_TABLE, AttributeStability.LABELS, true);
344         }
345 
346         @Override
347         public LocalVariableTypeTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
348             return new BoundAttribute.BoundLocalVariableTypeTableAttribute(e, cf, this, p);
349         }
350 
351         @Override
352         protected void writeBody(BufWriter buf, LocalVariableTypeTableAttribute attr) {
353             List<LocalVariableTypeInfo> infos = attr.localVariableTypes();
354             buf.writeU2(infos.size());
355             for (LocalVariableTypeInfo info : infos) {
356                 buf.writeU2(info.startPc());
357                 buf.writeU2(info.length());
358                 buf.writeIndex(info.name());
359                 buf.writeIndex(info.signature());
360                 buf.writeU2(info.slot());
361             }
362         }
363     }
364 
365     public static final class MethodParametersMapper extends AbstractAttributeMapper<MethodParametersAttribute> {
366         public static final MethodParametersMapper INSTANCE = new MethodParametersMapper();
367 
368         private MethodParametersMapper() {
369             super(NAME_METHOD_PARAMETERS, AttributeStability.CP_REFS);
370         }
371 
372         @Override
373         public MethodParametersAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
374             return new BoundAttribute.BoundMethodParametersAttribute(cf, this, p);
375         }
376 
377         @Override
378         protected void writeBody(BufWriter buf, MethodParametersAttribute attr) {
379             List<MethodParameterInfo> parameters = attr.parameters();
380             buf.writeU1(parameters.size());
381             for (MethodParameterInfo info : parameters) {
382                 buf.writeIndexOrZero(info.name().orElse(null));
383                 buf.writeU2(info.flagsMask());
384             }
385         }
386     }
387 
388     public static final class ModuleMapper extends AbstractAttributeMapper<ModuleAttribute> {
389         public static final ModuleMapper INSTANCE = new ModuleMapper();
390 
391         private ModuleMapper() {
392             super(NAME_MODULE, AttributeStability.CP_REFS);
393         }
394 
395         @Override
396         public ModuleAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
397             return new BoundAttribute.BoundModuleAttribute(cf, this, p);
398         }
399 
400         @Override
401         protected void writeBody(BufWriter buf, ModuleAttribute attr) {
402             buf.writeIndex(attr.moduleName());
403             buf.writeU2(attr.moduleFlagsMask());
404             buf.writeIndexOrZero(attr.moduleVersion().orElse(null));
405             buf.writeU2(attr.requires().size());
406             for (ModuleRequireInfo require : attr.requires()) {
407                 buf.writeIndex(require.requires());
408                 buf.writeU2(require.requiresFlagsMask());
409                 buf.writeIndexOrZero(require.requiresVersion().orElse(null));
410             }
411             buf.writeU2(attr.exports().size());
412             for (ModuleExportInfo export : attr.exports()) {
413                 buf.writeIndex(export.exportedPackage());
414                 buf.writeU2(export.exportsFlagsMask());
415                 Util.writeListIndices(buf, export.exportsTo());
416             }
417             buf.writeU2(attr.opens().size());
418             for (ModuleOpenInfo open : attr.opens()) {
419                 buf.writeIndex(open.openedPackage());
420                 buf.writeU2(open.opensFlagsMask());
421                 Util.writeListIndices(buf, open.opensTo());
422             }
423             Util.writeListIndices(buf, attr.uses());
424             buf.writeU2(attr.provides().size());
425             for (ModuleProvideInfo provide : attr.provides()) {
426                 buf.writeIndex(provide.provides());
427                 Util.writeListIndices(buf, provide.providesWith());
428             }
429         }
430     }
431 
432     public static final class ModuleHashesMapper extends AbstractAttributeMapper<ModuleHashesAttribute> {
433         public static final ModuleHashesMapper INSTANCE = new ModuleHashesMapper();
434 
435         private ModuleHashesMapper() {
436             super(NAME_MODULE_HASHES, AttributeStability.CP_REFS);
437         }
438 
439         @Override
440         public ModuleHashesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
441             return new BoundAttribute.BoundModuleHashesAttribute(cf, this, p);
442         }
443 
444         @Override
445         protected void writeBody(BufWriter buf, ModuleHashesAttribute attr) {
446             buf.writeIndex(attr.algorithm());
447             List<ModuleHashInfo> hashes = attr.hashes();
448             buf.writeU2(hashes.size());
449             for (ModuleHashInfo hash : hashes) {
450                 buf.writeIndex(hash.moduleName());
451                 buf.writeU2(hash.hash().length);
452                 buf.writeBytes(hash.hash());
453             }
454         }
455     }
456 
457     public static final class ModuleMainClassMapper extends AbstractAttributeMapper<ModuleMainClassAttribute> {
458         public static final ModuleMainClassMapper INSTANCE = new ModuleMainClassMapper();
459 
460         private ModuleMainClassMapper() {
461             super(NAME_MODULE_MAIN_CLASS, AttributeStability.CP_REFS);
462         }
463 
464         @Override
465         public ModuleMainClassAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
466             return new BoundAttribute.BoundModuleMainClassAttribute(cf, this, p);
467         }
468 
469         @Override
470         protected void writeBody(BufWriter buf, ModuleMainClassAttribute attr) {
471             buf.writeIndex(attr.mainClass());
472         }
473     }
474 
475     public static final class ModulePackagesMapper extends AbstractAttributeMapper<ModulePackagesAttribute> {
476         public static final ModulePackagesMapper INSTANCE = new ModulePackagesMapper();
477 
478         private ModulePackagesMapper() {
479             super(NAME_MODULE_PACKAGES, AttributeStability.CP_REFS);
480         }
481 
482         @Override
483         public ModulePackagesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
484             return new BoundAttribute.BoundModulePackagesAttribute(cf, this, p);
485         }
486 
487         @Override
488         protected void writeBody(BufWriter buf, ModulePackagesAttribute attr) {
489             Util.writeListIndices(buf, attr.packages());
490         }
491     }
492 
493     public static final class ModuleResolutionMapper extends AbstractAttributeMapper<ModuleResolutionAttribute> {
494         public static final ModuleResolutionMapper INSTANCE = new ModuleResolutionMapper();
495 
496         private ModuleResolutionMapper() {
497             super(NAME_MODULE_RESOLUTION, AttributeStability.STATELESS);
498         }
499 
500         @Override
501         public ModuleResolutionAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
502             return new BoundAttribute.BoundModuleResolutionAttribute(cf, this, p);
503         }
504 
505         @Override
506         protected void writeBody(BufWriter buf, ModuleResolutionAttribute attr) {
507             buf.writeU2(attr.resolutionFlags());
508         }
509     }
510 
511     public static final class ModuleTargetMapper extends AbstractAttributeMapper<ModuleTargetAttribute> {
512         public static final ModuleTargetMapper INSTANCE = new ModuleTargetMapper();
513 
514         private ModuleTargetMapper() {
515             super(NAME_MODULE_TARGET, AttributeStability.CP_REFS);
516         }
517 
518         @Override
519         public ModuleTargetAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
520             return new BoundAttribute.BoundModuleTargetAttribute(cf, this, p);
521         }
522 
523         @Override
524         protected void writeBody(BufWriter buf, ModuleTargetAttribute attr) {
525             buf.writeIndex(attr.targetPlatform());
526         }
527     }
528 
529     public static final class NestHostMapper extends AbstractAttributeMapper<NestHostAttribute> {
530         public static final NestHostMapper INSTANCE = new NestHostMapper();
531 
532         private NestHostMapper() {
533             super(NAME_NEST_HOST, AttributeStability.CP_REFS);
534         }
535 
536         @Override
537         public NestHostAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
538             return new BoundAttribute.BoundNestHostAttribute(cf, this, p);
539         }
540 
541         @Override
542         protected void writeBody(BufWriter buf, NestHostAttribute attr) {
543             buf.writeIndex(attr.nestHost());
544         }
545     }
546 
547     public static final class NestMembersMapper extends AbstractAttributeMapper<NestMembersAttribute> {
548         public static final NestMembersMapper INSTANCE = new NestMembersMapper();
549 
550         private NestMembersMapper() {
551             super(NAME_NEST_MEMBERS, AttributeStability.CP_REFS);
552         }
553 
554         @Override
555         public NestMembersAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
556             return new BoundAttribute.BoundNestMembersAttribute(cf, this, p);
557         }
558 
559         @Override
560         protected void writeBody(BufWriter buf, NestMembersAttribute attr) {
561             Util.writeListIndices(buf, attr.nestMembers());
562         }
563     }
564 
565     public static final class PermittedSubclassesMapper extends AbstractAttributeMapper<PermittedSubclassesAttribute> {
566         public static final PermittedSubclassesMapper INSTANCE = new PermittedSubclassesMapper();
567 
568         private PermittedSubclassesMapper() {
569             super(NAME_PERMITTED_SUBCLASSES, AttributeStability.CP_REFS);
570         }
571 
572         @Override
573         public PermittedSubclassesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
574             return new BoundAttribute.BoundPermittedSubclassesAttribute(cf, this, p);
575         }
576 
577         @Override
578         protected void writeBody(BufWriter buf, PermittedSubclassesAttribute attr) {
579             Util.writeListIndices(buf, attr.permittedSubclasses());
580         }
581     }
582 
583     public static final class RecordMapper extends AbstractAttributeMapper<RecordAttribute> {
584         public static final RecordMapper INSTANCE = new RecordMapper();
585 
586         private RecordMapper() {
587             super(NAME_RECORD, AttributeStability.CP_REFS);
588         }
589 
590         @Override
591         public RecordAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
592             return new BoundAttribute.BoundRecordAttribute(cf, this, p);
593         }
594 
595         @Override
596         protected void writeBody(BufWriter buf, RecordAttribute attr) {
597             List<RecordComponentInfo> components = attr.components();
598             buf.writeU2(components.size());
599             for (RecordComponentInfo info : components) {
600                 buf.writeIndex(info.name());
601                 buf.writeIndex(info.descriptor());
602                 Util.writeAttributes((BufWriterImpl) buf, info.attributes());
603             }
604         }
605     }
606 
607     public static final class RuntimeInvisibleAnnotationsMapper extends AbstractAttributeMapper<RuntimeInvisibleAnnotationsAttribute> {
608         public static final RuntimeInvisibleAnnotationsMapper INSTANCE = new RuntimeInvisibleAnnotationsMapper();
609 
610         private RuntimeInvisibleAnnotationsMapper() {
611             super(NAME_RUNTIME_INVISIBLE_ANNOTATIONS, AttributeStability.CP_REFS);
612         }
613 
614         @Override
615         public RuntimeInvisibleAnnotationsAttribute readAttribute(AttributedElement enclosing, ClassReader cf, int pos) {
616             return new BoundAttribute.BoundRuntimeInvisibleAnnotationsAttribute(cf, pos);
617         }
618 
619         @Override
620         protected void writeBody(BufWriter buf, RuntimeInvisibleAnnotationsAttribute attr) {
621             AnnotationReader.writeAnnotations(buf, attr.annotations());
622         }
623     }
624 
625     public static final class RuntimeInvisibleParameterAnnotationsMapper extends AbstractAttributeMapper<RuntimeInvisibleParameterAnnotationsAttribute> {
626         public static final RuntimeInvisibleParameterAnnotationsMapper INSTANCE = new RuntimeInvisibleParameterAnnotationsMapper();
627 
628         private RuntimeInvisibleParameterAnnotationsMapper() {
629             super(NAME_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, AttributeStability.CP_REFS);
630         }
631 
632         @Override
633         public RuntimeInvisibleParameterAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
634             return new BoundAttribute.BoundRuntimeInvisibleParameterAnnotationsAttribute(cf, this, p);
635         }
636 
637         @Override
638         protected void writeBody(BufWriter buf, RuntimeInvisibleParameterAnnotationsAttribute attr) {
639             List<List<Annotation>> lists = attr.parameterAnnotations();
640             buf.writeU1(lists.size());
641             for (List<Annotation> list : lists)
642                 AnnotationReader.writeAnnotations(buf, list);
643         }
644     }
645 
646     public static final class RuntimeInvisibleTypeAnnotationsMapper extends AbstractAttributeMapper<RuntimeInvisibleTypeAnnotationsAttribute> {
647         public static final RuntimeInvisibleTypeAnnotationsMapper INSTANCE = new RuntimeInvisibleTypeAnnotationsMapper();
648 
649         private RuntimeInvisibleTypeAnnotationsMapper() {
650             super(NAME_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, AttributeStability.UNSTABLE);
651         }
652 
653         @Override
654         public RuntimeInvisibleTypeAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
655             return new BoundAttribute.BoundRuntimeInvisibleTypeAnnotationsAttribute(e, cf, this, p);
656         }
657 
658         @Override
659         protected void writeBody(BufWriter buf, RuntimeInvisibleTypeAnnotationsAttribute attr) {
660             AnnotationReader.writeTypeAnnotations(buf, attr.annotations());
661         }
662     }
663 
664     public static final class RuntimeVisibleAnnotationsMapper extends AbstractAttributeMapper<RuntimeVisibleAnnotationsAttribute> {
665         public static final RuntimeVisibleAnnotationsMapper INSTANCE = new RuntimeVisibleAnnotationsMapper();
666 
667         private RuntimeVisibleAnnotationsMapper() {
668             super(NAME_RUNTIME_VISIBLE_ANNOTATIONS, AttributeStability.CP_REFS);
669         }
670 
671         @Override
672         public RuntimeVisibleAnnotationsAttribute readAttribute(AttributedElement enclosing, ClassReader cf, int pos) {
673             return new BoundAttribute.BoundRuntimeVisibleAnnotationsAttribute(cf, pos);
674         }
675 
676         @Override
677         protected void writeBody(BufWriter buf, RuntimeVisibleAnnotationsAttribute attr) {
678             AnnotationReader.writeAnnotations(buf, attr.annotations());
679         }
680     }
681 
682     public static final class RuntimeVisibleParameterAnnotationsMapper extends AbstractAttributeMapper<RuntimeVisibleParameterAnnotationsAttribute> {
683         public static final RuntimeVisibleParameterAnnotationsMapper INSTANCE = new RuntimeVisibleParameterAnnotationsMapper();
684 
685         private RuntimeVisibleParameterAnnotationsMapper() {
686             super(NAME_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, AttributeStability.CP_REFS);
687         }
688 
689         @Override
690         public RuntimeVisibleParameterAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
691             return new BoundAttribute.BoundRuntimeVisibleParameterAnnotationsAttribute(cf, this, p);
692         }
693 
694         @Override
695         protected void writeBody(BufWriter buf, RuntimeVisibleParameterAnnotationsAttribute attr) {
696             List<List<Annotation>> lists = attr.parameterAnnotations();
697             buf.writeU1(lists.size());
698             for (List<Annotation> list : lists)
699                 AnnotationReader.writeAnnotations(buf, list);
700         }
701     }
702 
703     public static final class RuntimeVisibleTypeAnnotationsMapper extends AbstractAttributeMapper<RuntimeVisibleTypeAnnotationsAttribute> {
704         public static final RuntimeVisibleTypeAnnotationsMapper INSTANCE = new RuntimeVisibleTypeAnnotationsMapper();
705 
706         private RuntimeVisibleTypeAnnotationsMapper() {
707             super(NAME_RUNTIME_VISIBLE_TYPE_ANNOTATIONS, AttributeStability.UNSTABLE);
708         }
709 
710         @Override
711         public RuntimeVisibleTypeAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
712             return new BoundAttribute.BoundRuntimeVisibleTypeAnnotationsAttribute(e, cf, this, p);
713         }
714 
715         @Override
716         protected void writeBody(BufWriter buf, RuntimeVisibleTypeAnnotationsAttribute attr) {
717             AnnotationReader.writeTypeAnnotations(buf, attr.annotations());
718         }
719     }
720 
721     public static final class SignatureMapper extends AbstractAttributeMapper<SignatureAttribute> {
722         public static final SignatureMapper INSTANCE = new SignatureMapper();
723 
724         private SignatureMapper() {
725             super(NAME_SIGNATURE, AttributeStability.CP_REFS);
726         }
727 
728         @Override
729         public SignatureAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
730             return new BoundAttribute.BoundSignatureAttribute(cf, this, p);
731         }
732 
733         @Override
734         protected void writeBody(BufWriter buf, SignatureAttribute attr) {
735             buf.writeIndex(attr.signature());
736         }
737     }
738 
739     public static final class SourceDebugExtensionMapper extends AbstractAttributeMapper<SourceDebugExtensionAttribute> {
740         public static final SourceDebugExtensionMapper INSTANCE = new SourceDebugExtensionMapper();
741 
742         private SourceDebugExtensionMapper() {
743             super(NAME_SOURCE_DEBUG_EXTENSION, AttributeStability.STATELESS);
744         }
745 
746         @Override
747         public SourceDebugExtensionAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
748             return new BoundAttribute.BoundSourceDebugExtensionAttribute(cf, this, p);
749         }
750 
751         @Override
752         protected void writeBody(BufWriter buf, SourceDebugExtensionAttribute attr) {
753             buf.writeBytes(attr.contents());
754         }
755     }
756 
757     public static final class SourceFileMapper extends AbstractAttributeMapper<SourceFileAttribute> {
758         public static final SourceFileMapper INSTANCE = new SourceFileMapper();
759 
760         private SourceFileMapper() {
761             super(NAME_SOURCE_FILE, AttributeStability.CP_REFS);
762         }
763 
764         @Override
765         public SourceFileAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
766             return new BoundAttribute.BoundSourceFileAttribute(cf, this, p);
767         }
768 
769         @Override
770         protected void writeBody(BufWriter buf, SourceFileAttribute attr) {
771             buf.writeIndex(attr.sourceFile());
772         }
773     }
774 
775     public static final class SourceIDMapper extends AbstractAttributeMapper<SourceIDAttribute> {
776         public static final SourceIDMapper INSTANCE = new SourceIDMapper();
777 
778         private SourceIDMapper() {
779             super(NAME_SOURCE_ID, AttributeStability.CP_REFS);
780         }
781 
782         @Override
783         public SourceIDAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
784             return new BoundAttribute.BoundSourceIDAttribute(cf, this, p);
785         }
786 
787         @Override
788         protected void writeBody(BufWriter buf, SourceIDAttribute attr) {
789             buf.writeIndex(attr.sourceId());
790         }
791     }
792 
793     public static final class StackMapTableMapper extends AbstractAttributeMapper<StackMapTableAttribute> {
794         public static final StackMapTableMapper INSTANCE = new StackMapTableMapper();
795 
796         private StackMapTableMapper() {
797             super(NAME_STACK_MAP_TABLE, AttributeStability.LABELS);
798         }
799 
800         @Override
801         public StackMapTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
802             return new BoundAttribute.BoundStackMapTableAttribute((CodeImpl)e, cf, this, p);
803         }
804 
805         @Override
806         protected void writeBody(BufWriter b, StackMapTableAttribute attr) {
807             StackMapDecoder.writeFrames(b, attr.entries());
808         }
809     }
810 
811     public static final class SyntheticMapper extends AbstractAttributeMapper<SyntheticAttribute> {
812         public static final SyntheticMapper INSTANCE = new SyntheticMapper();
813 
814         private SyntheticMapper() {
815             super(NAME_SYNTHETIC, AttributeStability.STATELESS, true);
816         }
817 
818         @Override
819         public SyntheticAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
820             return new BoundAttribute.BoundSyntheticAttribute(cf, this, p);
821         }
822 
823         @Override
824         protected void writeBody(BufWriter buf, SyntheticAttribute attr) {
825             // empty
826         }
827     }
828 }