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 LoadableDescriptorsMapper extends AbstractAttributeMapper<LoadableDescriptorsAttribute> {
314         public static final LoadableDescriptorsMapper INSTANCE = new LoadableDescriptorsMapper();
315 
316         private LoadableDescriptorsMapper() {
317             super(NAME_LOADABLE_DESCRIPTORS, AttributeStability.CP_REFS);
318         }
319 
320         @Override
321         public LoadableDescriptorsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
322             return new BoundAttribute.BoundLoadableDescriptorsAttribute(cf, this, p);
323         }
324 
325         @Override
326         protected void writeBody(BufWriter buf, LoadableDescriptorsAttribute attr) {
327             Util.writeListIndices(buf, attr.loadableDescriptors());
328         }
329     }
330 
331     public static final class LocalVariableTableMapper extends AbstractAttributeMapper<LocalVariableTableAttribute> {
332         public static final LocalVariableTableMapper INSTANCE = new LocalVariableTableMapper();
333 
334         private LocalVariableTableMapper() {
335             super(NAME_LOCAL_VARIABLE_TABLE, AttributeStability.LABELS, true);
336         }
337 
338         @Override
339         public LocalVariableTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
340             return new BoundAttribute.BoundLocalVariableTableAttribute(e, cf, this, p);
341         }
342 
343         @Override
344         protected void writeBody(BufWriter buf, LocalVariableTableAttribute attr) {
345             List<LocalVariableInfo> infos = attr.localVariables();
346             buf.writeU2(infos.size());
347             for (LocalVariableInfo info : infos) {
348                 buf.writeU2(info.startPc());
349                 buf.writeU2(info.length());
350                 buf.writeIndex(info.name());
351                 buf.writeIndex(info.type());
352                 buf.writeU2(info.slot());
353             }
354         }
355     }
356 
357     public static final class LocalVariableTypeTableMapper extends AbstractAttributeMapper<LocalVariableTypeTableAttribute> {
358         public static final LocalVariableTypeTableMapper INSTANCE = new LocalVariableTypeTableMapper();
359 
360         private LocalVariableTypeTableMapper() {
361             super(NAME_LOCAL_VARIABLE_TYPE_TABLE, AttributeStability.LABELS, true);
362         }
363 
364         @Override
365         public LocalVariableTypeTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
366             return new BoundAttribute.BoundLocalVariableTypeTableAttribute(e, cf, this, p);
367         }
368 
369         @Override
370         protected void writeBody(BufWriter buf, LocalVariableTypeTableAttribute attr) {
371             List<LocalVariableTypeInfo> infos = attr.localVariableTypes();
372             buf.writeU2(infos.size());
373             for (LocalVariableTypeInfo info : infos) {
374                 buf.writeU2(info.startPc());
375                 buf.writeU2(info.length());
376                 buf.writeIndex(info.name());
377                 buf.writeIndex(info.signature());
378                 buf.writeU2(info.slot());
379             }
380         }
381     }
382 
383     public static final class MethodParametersMapper extends AbstractAttributeMapper<MethodParametersAttribute> {
384         public static final MethodParametersMapper INSTANCE = new MethodParametersMapper();
385 
386         private MethodParametersMapper() {
387             super(NAME_METHOD_PARAMETERS, AttributeStability.CP_REFS);
388         }
389 
390         @Override
391         public MethodParametersAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
392             return new BoundAttribute.BoundMethodParametersAttribute(cf, this, p);
393         }
394 
395         @Override
396         protected void writeBody(BufWriter buf, MethodParametersAttribute attr) {
397             List<MethodParameterInfo> parameters = attr.parameters();
398             buf.writeU1(parameters.size());
399             for (MethodParameterInfo info : parameters) {
400                 buf.writeIndexOrZero(info.name().orElse(null));
401                 buf.writeU2(info.flagsMask());
402             }
403         }
404     }
405 
406     public static final class ModuleMapper extends AbstractAttributeMapper<ModuleAttribute> {
407         public static final ModuleMapper INSTANCE = new ModuleMapper();
408 
409         private ModuleMapper() {
410             super(NAME_MODULE, AttributeStability.CP_REFS);
411         }
412 
413         @Override
414         public ModuleAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
415             return new BoundAttribute.BoundModuleAttribute(cf, this, p);
416         }
417 
418         @Override
419         protected void writeBody(BufWriter buf, ModuleAttribute attr) {
420             buf.writeIndex(attr.moduleName());
421             buf.writeU2(attr.moduleFlagsMask());
422             buf.writeIndexOrZero(attr.moduleVersion().orElse(null));
423             buf.writeU2(attr.requires().size());
424             for (ModuleRequireInfo require : attr.requires()) {
425                 buf.writeIndex(require.requires());
426                 buf.writeU2(require.requiresFlagsMask());
427                 buf.writeIndexOrZero(require.requiresVersion().orElse(null));
428             }
429             buf.writeU2(attr.exports().size());
430             for (ModuleExportInfo export : attr.exports()) {
431                 buf.writeIndex(export.exportedPackage());
432                 buf.writeU2(export.exportsFlagsMask());
433                 Util.writeListIndices(buf, export.exportsTo());
434             }
435             buf.writeU2(attr.opens().size());
436             for (ModuleOpenInfo open : attr.opens()) {
437                 buf.writeIndex(open.openedPackage());
438                 buf.writeU2(open.opensFlagsMask());
439                 Util.writeListIndices(buf, open.opensTo());
440             }
441             Util.writeListIndices(buf, attr.uses());
442             buf.writeU2(attr.provides().size());
443             for (ModuleProvideInfo provide : attr.provides()) {
444                 buf.writeIndex(provide.provides());
445                 Util.writeListIndices(buf, provide.providesWith());
446             }
447         }
448     }
449 
450     public static final class ModuleHashesMapper extends AbstractAttributeMapper<ModuleHashesAttribute> {
451         public static final ModuleHashesMapper INSTANCE = new ModuleHashesMapper();
452 
453         private ModuleHashesMapper() {
454             super(NAME_MODULE_HASHES, AttributeStability.CP_REFS);
455         }
456 
457         @Override
458         public ModuleHashesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
459             return new BoundAttribute.BoundModuleHashesAttribute(cf, this, p);
460         }
461 
462         @Override
463         protected void writeBody(BufWriter buf, ModuleHashesAttribute attr) {
464             buf.writeIndex(attr.algorithm());
465             List<ModuleHashInfo> hashes = attr.hashes();
466             buf.writeU2(hashes.size());
467             for (ModuleHashInfo hash : hashes) {
468                 buf.writeIndex(hash.moduleName());
469                 buf.writeU2(hash.hash().length);
470                 buf.writeBytes(hash.hash());
471             }
472         }
473     }
474 
475     public static final class ModuleMainClassMapper extends AbstractAttributeMapper<ModuleMainClassAttribute> {
476         public static final ModuleMainClassMapper INSTANCE = new ModuleMainClassMapper();
477 
478         private ModuleMainClassMapper() {
479             super(NAME_MODULE_MAIN_CLASS, AttributeStability.CP_REFS);
480         }
481 
482         @Override
483         public ModuleMainClassAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
484             return new BoundAttribute.BoundModuleMainClassAttribute(cf, this, p);
485         }
486 
487         @Override
488         protected void writeBody(BufWriter buf, ModuleMainClassAttribute attr) {
489             buf.writeIndex(attr.mainClass());
490         }
491     }
492 
493     public static final class ModulePackagesMapper extends AbstractAttributeMapper<ModulePackagesAttribute> {
494         public static final ModulePackagesMapper INSTANCE = new ModulePackagesMapper();
495 
496         private ModulePackagesMapper() {
497             super(NAME_MODULE_PACKAGES, AttributeStability.CP_REFS);
498         }
499 
500         @Override
501         public ModulePackagesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
502             return new BoundAttribute.BoundModulePackagesAttribute(cf, this, p);
503         }
504 
505         @Override
506         protected void writeBody(BufWriter buf, ModulePackagesAttribute attr) {
507             Util.writeListIndices(buf, attr.packages());
508         }
509     }
510 
511     public static final class ModuleResolutionMapper extends AbstractAttributeMapper<ModuleResolutionAttribute> {
512         public static final ModuleResolutionMapper INSTANCE = new ModuleResolutionMapper();
513 
514         private ModuleResolutionMapper() {
515             super(NAME_MODULE_RESOLUTION, AttributeStability.STATELESS);
516         }
517 
518         @Override
519         public ModuleResolutionAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
520             return new BoundAttribute.BoundModuleResolutionAttribute(cf, this, p);
521         }
522 
523         @Override
524         protected void writeBody(BufWriter buf, ModuleResolutionAttribute attr) {
525             buf.writeU2(attr.resolutionFlags());
526         }
527     }
528 
529     public static final class ModuleTargetMapper extends AbstractAttributeMapper<ModuleTargetAttribute> {
530         public static final ModuleTargetMapper INSTANCE = new ModuleTargetMapper();
531 
532         private ModuleTargetMapper() {
533             super(NAME_MODULE_TARGET, AttributeStability.CP_REFS);
534         }
535 
536         @Override
537         public ModuleTargetAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
538             return new BoundAttribute.BoundModuleTargetAttribute(cf, this, p);
539         }
540 
541         @Override
542         protected void writeBody(BufWriter buf, ModuleTargetAttribute attr) {
543             buf.writeIndex(attr.targetPlatform());
544         }
545     }
546 
547     public static final class NestHostMapper extends AbstractAttributeMapper<NestHostAttribute> {
548         public static final NestHostMapper INSTANCE = new NestHostMapper();
549 
550         private NestHostMapper() {
551             super(NAME_NEST_HOST, AttributeStability.CP_REFS);
552         }
553 
554         @Override
555         public NestHostAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
556             return new BoundAttribute.BoundNestHostAttribute(cf, this, p);
557         }
558 
559         @Override
560         protected void writeBody(BufWriter buf, NestHostAttribute attr) {
561             buf.writeIndex(attr.nestHost());
562         }
563     }
564 
565     public static final class NestMembersMapper extends AbstractAttributeMapper<NestMembersAttribute> {
566         public static final NestMembersMapper INSTANCE = new NestMembersMapper();
567 
568         private NestMembersMapper() {
569             super(NAME_NEST_MEMBERS, AttributeStability.CP_REFS);
570         }
571 
572         @Override
573         public NestMembersAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
574             return new BoundAttribute.BoundNestMembersAttribute(cf, this, p);
575         }
576 
577         @Override
578         protected void writeBody(BufWriter buf, NestMembersAttribute attr) {
579             Util.writeListIndices(buf, attr.nestMembers());
580         }
581     }
582 
583     public static final class PermittedSubclassesMapper extends AbstractAttributeMapper<PermittedSubclassesAttribute> {
584         public static final PermittedSubclassesMapper INSTANCE = new PermittedSubclassesMapper();
585 
586         private PermittedSubclassesMapper() {
587             super(NAME_PERMITTED_SUBCLASSES, AttributeStability.CP_REFS);
588         }
589 
590         @Override
591         public PermittedSubclassesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
592             return new BoundAttribute.BoundPermittedSubclassesAttribute(cf, this, p);
593         }
594 
595         @Override
596         protected void writeBody(BufWriter buf, PermittedSubclassesAttribute attr) {
597             Util.writeListIndices(buf, attr.permittedSubclasses());
598         }
599     }
600 
601     public static final class RecordMapper extends AbstractAttributeMapper<RecordAttribute> {
602         public static final RecordMapper INSTANCE = new RecordMapper();
603 
604         private RecordMapper() {
605             super(NAME_RECORD, AttributeStability.CP_REFS);
606         }
607 
608         @Override
609         public RecordAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
610             return new BoundAttribute.BoundRecordAttribute(cf, this, p);
611         }
612 
613         @Override
614         protected void writeBody(BufWriter buf, RecordAttribute attr) {
615             List<RecordComponentInfo> components = attr.components();
616             buf.writeU2(components.size());
617             for (RecordComponentInfo info : components) {
618                 buf.writeIndex(info.name());
619                 buf.writeIndex(info.descriptor());
620                 Util.writeAttributes((BufWriterImpl) buf, info.attributes());
621             }
622         }
623     }
624 
625     public static final class RuntimeInvisibleAnnotationsMapper extends AbstractAttributeMapper<RuntimeInvisibleAnnotationsAttribute> {
626         public static final RuntimeInvisibleAnnotationsMapper INSTANCE = new RuntimeInvisibleAnnotationsMapper();
627 
628         private RuntimeInvisibleAnnotationsMapper() {
629             super(NAME_RUNTIME_INVISIBLE_ANNOTATIONS, AttributeStability.CP_REFS);
630         }
631 
632         @Override
633         public RuntimeInvisibleAnnotationsAttribute readAttribute(AttributedElement enclosing, ClassReader cf, int pos) {
634             return new BoundAttribute.BoundRuntimeInvisibleAnnotationsAttribute(cf, pos);
635         }
636 
637         @Override
638         protected void writeBody(BufWriter buf, RuntimeInvisibleAnnotationsAttribute attr) {
639             AnnotationReader.writeAnnotations(buf, attr.annotations());
640         }
641     }
642 
643     public static final class RuntimeInvisibleParameterAnnotationsMapper extends AbstractAttributeMapper<RuntimeInvisibleParameterAnnotationsAttribute> {
644         public static final RuntimeInvisibleParameterAnnotationsMapper INSTANCE = new RuntimeInvisibleParameterAnnotationsMapper();
645 
646         private RuntimeInvisibleParameterAnnotationsMapper() {
647             super(NAME_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, AttributeStability.CP_REFS);
648         }
649 
650         @Override
651         public RuntimeInvisibleParameterAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
652             return new BoundAttribute.BoundRuntimeInvisibleParameterAnnotationsAttribute(cf, this, p);
653         }
654 
655         @Override
656         protected void writeBody(BufWriter buf, RuntimeInvisibleParameterAnnotationsAttribute attr) {
657             List<List<Annotation>> lists = attr.parameterAnnotations();
658             buf.writeU1(lists.size());
659             for (List<Annotation> list : lists)
660                 AnnotationReader.writeAnnotations(buf, list);
661         }
662     }
663 
664     public static final class RuntimeInvisibleTypeAnnotationsMapper extends AbstractAttributeMapper<RuntimeInvisibleTypeAnnotationsAttribute> {
665         public static final RuntimeInvisibleTypeAnnotationsMapper INSTANCE = new RuntimeInvisibleTypeAnnotationsMapper();
666 
667         private RuntimeInvisibleTypeAnnotationsMapper() {
668             super(NAME_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, AttributeStability.UNSTABLE);
669         }
670 
671         @Override
672         public RuntimeInvisibleTypeAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
673             return new BoundAttribute.BoundRuntimeInvisibleTypeAnnotationsAttribute(e, cf, this, p);
674         }
675 
676         @Override
677         protected void writeBody(BufWriter buf, RuntimeInvisibleTypeAnnotationsAttribute attr) {
678             AnnotationReader.writeTypeAnnotations(buf, attr.annotations());
679         }
680     }
681 
682     public static final class RuntimeVisibleAnnotationsMapper extends AbstractAttributeMapper<RuntimeVisibleAnnotationsAttribute> {
683         public static final RuntimeVisibleAnnotationsMapper INSTANCE = new RuntimeVisibleAnnotationsMapper();
684 
685         private RuntimeVisibleAnnotationsMapper() {
686             super(NAME_RUNTIME_VISIBLE_ANNOTATIONS, AttributeStability.CP_REFS);
687         }
688 
689         @Override
690         public RuntimeVisibleAnnotationsAttribute readAttribute(AttributedElement enclosing, ClassReader cf, int pos) {
691             return new BoundAttribute.BoundRuntimeVisibleAnnotationsAttribute(cf, pos);
692         }
693 
694         @Override
695         protected void writeBody(BufWriter buf, RuntimeVisibleAnnotationsAttribute attr) {
696             AnnotationReader.writeAnnotations(buf, attr.annotations());
697         }
698     }
699 
700     public static final class RuntimeVisibleParameterAnnotationsMapper extends AbstractAttributeMapper<RuntimeVisibleParameterAnnotationsAttribute> {
701         public static final RuntimeVisibleParameterAnnotationsMapper INSTANCE = new RuntimeVisibleParameterAnnotationsMapper();
702 
703         private RuntimeVisibleParameterAnnotationsMapper() {
704             super(NAME_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, AttributeStability.CP_REFS);
705         }
706 
707         @Override
708         public RuntimeVisibleParameterAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
709             return new BoundAttribute.BoundRuntimeVisibleParameterAnnotationsAttribute(cf, this, p);
710         }
711 
712         @Override
713         protected void writeBody(BufWriter buf, RuntimeVisibleParameterAnnotationsAttribute attr) {
714             List<List<Annotation>> lists = attr.parameterAnnotations();
715             buf.writeU1(lists.size());
716             for (List<Annotation> list : lists)
717                 AnnotationReader.writeAnnotations(buf, list);
718         }
719     }
720 
721     public static final class RuntimeVisibleTypeAnnotationsMapper extends AbstractAttributeMapper<RuntimeVisibleTypeAnnotationsAttribute> {
722         public static final RuntimeVisibleTypeAnnotationsMapper INSTANCE = new RuntimeVisibleTypeAnnotationsMapper();
723 
724         private RuntimeVisibleTypeAnnotationsMapper() {
725             super(NAME_RUNTIME_VISIBLE_TYPE_ANNOTATIONS, AttributeStability.UNSTABLE);
726         }
727 
728         @Override
729         public RuntimeVisibleTypeAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
730             return new BoundAttribute.BoundRuntimeVisibleTypeAnnotationsAttribute(e, cf, this, p);
731         }
732 
733         @Override
734         protected void writeBody(BufWriter buf, RuntimeVisibleTypeAnnotationsAttribute attr) {
735             AnnotationReader.writeTypeAnnotations(buf, attr.annotations());
736         }
737     }
738 
739     public static final class SignatureMapper extends AbstractAttributeMapper<SignatureAttribute> {
740         public static final SignatureMapper INSTANCE = new SignatureMapper();
741 
742         private SignatureMapper() {
743             super(NAME_SIGNATURE, AttributeStability.CP_REFS);
744         }
745 
746         @Override
747         public SignatureAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
748             return new BoundAttribute.BoundSignatureAttribute(cf, this, p);
749         }
750 
751         @Override
752         protected void writeBody(BufWriter buf, SignatureAttribute attr) {
753             buf.writeIndex(attr.signature());
754         }
755     }
756 
757     public static final class SourceDebugExtensionMapper extends AbstractAttributeMapper<SourceDebugExtensionAttribute> {
758         public static final SourceDebugExtensionMapper INSTANCE = new SourceDebugExtensionMapper();
759 
760         private SourceDebugExtensionMapper() {
761             super(NAME_SOURCE_DEBUG_EXTENSION, AttributeStability.STATELESS);
762         }
763 
764         @Override
765         public SourceDebugExtensionAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
766             return new BoundAttribute.BoundSourceDebugExtensionAttribute(cf, this, p);
767         }
768 
769         @Override
770         protected void writeBody(BufWriter buf, SourceDebugExtensionAttribute attr) {
771             buf.writeBytes(attr.contents());
772         }
773     }
774 
775     public static final class SourceFileMapper extends AbstractAttributeMapper<SourceFileAttribute> {
776         public static final SourceFileMapper INSTANCE = new SourceFileMapper();
777 
778         private SourceFileMapper() {
779             super(NAME_SOURCE_FILE, AttributeStability.CP_REFS);
780         }
781 
782         @Override
783         public SourceFileAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
784             return new BoundAttribute.BoundSourceFileAttribute(cf, this, p);
785         }
786 
787         @Override
788         protected void writeBody(BufWriter buf, SourceFileAttribute attr) {
789             buf.writeIndex(attr.sourceFile());
790         }
791     }
792 
793     public static final class SourceIDMapper extends AbstractAttributeMapper<SourceIDAttribute> {
794         public static final SourceIDMapper INSTANCE = new SourceIDMapper();
795 
796         private SourceIDMapper() {
797             super(NAME_SOURCE_ID, AttributeStability.CP_REFS);
798         }
799 
800         @Override
801         public SourceIDAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
802             return new BoundAttribute.BoundSourceIDAttribute(cf, this, p);
803         }
804 
805         @Override
806         protected void writeBody(BufWriter buf, SourceIDAttribute attr) {
807             buf.writeIndex(attr.sourceId());
808         }
809     }
810 
811     public static final class StackMapTableMapper extends AbstractAttributeMapper<StackMapTableAttribute> {
812         public static final StackMapTableMapper INSTANCE = new StackMapTableMapper();
813 
814         private StackMapTableMapper() {
815             super(NAME_STACK_MAP_TABLE, AttributeStability.LABELS);
816         }
817 
818         @Override
819         public StackMapTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
820             return new BoundAttribute.BoundStackMapTableAttribute((CodeImpl)e, cf, this, p);
821         }
822 
823         @Override
824         protected void writeBody(BufWriter b, StackMapTableAttribute attr) {
825             StackMapDecoder.writeFrames(b, attr.entries());
826         }
827     }
828 
829     public static final class SyntheticMapper extends AbstractAttributeMapper<SyntheticAttribute> {
830         public static final SyntheticMapper INSTANCE = new SyntheticMapper();
831 
832         private SyntheticMapper() {
833             super(NAME_SYNTHETIC, AttributeStability.STATELESS, true);
834         }
835 
836         @Override
837         public SyntheticAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
838             return new BoundAttribute.BoundSyntheticAttribute(cf, this, p);
839         }
840 
841         @Override
842         protected void writeBody(BufWriter buf, SyntheticAttribute attr) {
843             // empty
844         }
845     }
846 }