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 writer, T attr) {
66 BufWriterImpl buf = (BufWriterImpl) writer;
67 buf.writeIndex(attr.attributeName());
68 int lengthIndex = buf.skip(4);
69 writeBody(buf, attr);
70 int written = buf.size() - lengthIndex - 4;
71 buf.patchInt(lengthIndex, 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 bufWriter, CharacterRangeTableAttribute attr) {
144 List<CharacterRangeInfo> ranges = attr.characterRangeTable();
145 BufWriterImpl buf = (BufWriterImpl) bufWriter;
146 buf.writeU2(ranges.size());
147 for (CharacterRangeInfo info : ranges) {
148 buf.writeU2U2(info.startPc(), info.endPc());
149 buf.writeIntInt(info.characterRangeStart(), info.characterRangeEnd());
150 buf.writeU2(info.flags());
151 }
152 }
153 }
154
155 public static final class CodeMapper extends AbstractAttributeMapper<CodeAttribute> {
156 public static final CodeMapper INSTANCE = new CodeMapper();
157
158 private CodeMapper() {
159 super(NAME_CODE, AttributeStability.CP_REFS);
160 }
161
162 @Override
163 public CodeAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
164 return new CodeImpl(e, cf, this, p);
165 }
166
167 @Override
168 protected void writeBody(BufWriter buf, CodeAttribute attr) {
169 throw new UnsupportedOperationException("Code attribute does not support direct write");
170 }
171 }
172
173 public static final class CompilationIDMapper extends AbstractAttributeMapper<CompilationIDAttribute> {
174 public static final CompilationIDMapper INSTANCE = new CompilationIDMapper();
175
176 private CompilationIDMapper() {
177 super(NAME_COMPILATION_ID, AttributeStability.CP_REFS);
178 }
179
180 @Override
181 public CompilationIDAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
182 return new BoundAttribute.BoundCompilationIDAttribute(cf, this, p);
183 }
184
185 @Override
186 protected void writeBody(BufWriter buf, CompilationIDAttribute attr) {
187 buf.writeIndex(attr.compilationId());
188 }
189 }
190
191 public static final class ConstantValueMapper extends AbstractAttributeMapper<ConstantValueAttribute> {
192 public static final ConstantValueMapper INSTANCE = new ConstantValueMapper();
193
194 private ConstantValueMapper() {
195 super(NAME_CONSTANT_VALUE, AttributeStability.CP_REFS);
196 }
197
198 @Override
199 public ConstantValueAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
200 return new BoundAttribute.BoundConstantValueAttribute(cf, this, p);
201 }
202
203 @Override
204 protected void writeBody(BufWriter buf, ConstantValueAttribute attr) {
205 buf.writeIndex(attr.constant());
206 }
207 }
208
209 public static final class DeprecatedMapper extends AbstractAttributeMapper<DeprecatedAttribute> {
210 public static final DeprecatedMapper INSTANCE = new DeprecatedMapper();
211
212 private DeprecatedMapper() {
213 super(NAME_DEPRECATED, AttributeStability.STATELESS, true);
214 }
215
216 @Override
217 public DeprecatedAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
218 return new BoundAttribute.BoundDeprecatedAttribute(cf, this, p);
219 }
220
221 @Override
222 protected void writeBody(BufWriter buf, DeprecatedAttribute attr) {
223 // empty
224 }
225 }
226
227 public static final class EnclosingMethodMapper extends AbstractAttributeMapper<EnclosingMethodAttribute> {
228 public static final EnclosingMethodMapper INSTANCE = new EnclosingMethodMapper();
229
230 private EnclosingMethodMapper() {
231 super(NAME_ENCLOSING_METHOD, AttributeStability.CP_REFS);
232 }
233
234 @Override
235 public EnclosingMethodAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
236 return new BoundAttribute.BoundEnclosingMethodAttribute(cf, this, p);
237 }
238
239 @Override
240 protected void writeBody(BufWriter bufWriter, EnclosingMethodAttribute attr) {
241 BufWriterImpl buf = (BufWriterImpl) bufWriter;
242 buf.writeU2U2(buf.cpIndex(attr.enclosingClass()),
243 buf.cpIndexOrZero(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 bufWriter, InnerClassesAttribute attr) {
279 List<InnerClassInfo> classes = attr.classes();
280 BufWriterImpl buf = (BufWriterImpl) bufWriter;
281 buf.writeU2(classes.size());
282 for (InnerClassInfo ic : classes) {
283 buf.writeU2U2U2(buf.cpIndex(ic.innerClass()),
284 buf.cpIndexOrZero(ic.outerClass().orElse(null)),
285 buf.cpIndexOrZero(ic.innerName().orElse(null)));
286 buf.writeU2(ic.flagsMask());
287 }
288 }
289 }
290
291 public static final class LineNumberTableMapper extends AbstractAttributeMapper<LineNumberTableAttribute> {
292 public static final LineNumberTableMapper INSTANCE = new LineNumberTableMapper();
293
294 private LineNumberTableMapper() {
295 super(NAME_LINE_NUMBER_TABLE, AttributeStability.LABELS, true);
296 }
297
298 @Override
299 public LineNumberTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
300 return new BoundAttribute.BoundLineNumberTableAttribute(cf, this, p);
301 }
302
303 @Override
304 protected void writeBody(BufWriter bufWriter, LineNumberTableAttribute attr) {
305 List<LineNumberInfo> lines = attr.lineNumbers();
306 BufWriterImpl buf = (BufWriterImpl) bufWriter;
307 buf.writeU2(lines.size());
308 for (LineNumberInfo line : lines) {
309 buf.writeU2U2(line.startPc(), line.lineNumber());
310 }
311 }
312 }
313
314 public static final class LoadableDescriptorsMapper extends AbstractAttributeMapper<LoadableDescriptorsAttribute> {
315 public static final LoadableDescriptorsMapper INSTANCE = new LoadableDescriptorsMapper();
316
317 private LoadableDescriptorsMapper() {
318 super(NAME_LOADABLE_DESCRIPTORS, AttributeStability.CP_REFS);
319 }
320
321 @Override
322 public LoadableDescriptorsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
323 return new BoundAttribute.BoundLoadableDescriptorsAttribute(cf, this, p);
324 }
325
326 @Override
327 protected void writeBody(BufWriter buf, LoadableDescriptorsAttribute attr) {
328 Util.writeListIndices(buf, attr.loadableDescriptors());
329 }
330 }
331
332 public static final class LocalVariableTableMapper extends AbstractAttributeMapper<LocalVariableTableAttribute> {
333 public static final LocalVariableTableMapper INSTANCE = new LocalVariableTableMapper();
334
335 private LocalVariableTableMapper() {
336 super(NAME_LOCAL_VARIABLE_TABLE, AttributeStability.LABELS, true);
337 }
338
339 @Override
340 public LocalVariableTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
341 return new BoundAttribute.BoundLocalVariableTableAttribute(e, cf, this, p);
342 }
343
344 @Override
345 protected void writeBody(BufWriter bufWriter, LocalVariableTableAttribute attr) {
346 List<LocalVariableInfo> infos = attr.localVariables();
347 BufWriterImpl buf = (BufWriterImpl) bufWriter;
348 buf.writeU2(infos.size());
349 for (LocalVariableInfo info : infos) {
350 buf.writeU2U2(info.startPc(), info.length());
351 buf.writeU2U2U2(buf.cpIndex(info.name()), buf.cpIndex(info.type()), info.slot());
352 }
353 }
354 }
355
356 public static final class LocalVariableTypeTableMapper extends AbstractAttributeMapper<LocalVariableTypeTableAttribute> {
357 public static final LocalVariableTypeTableMapper INSTANCE = new LocalVariableTypeTableMapper();
358
359 private LocalVariableTypeTableMapper() {
360 super(NAME_LOCAL_VARIABLE_TYPE_TABLE, AttributeStability.LABELS, true);
361 }
362
363 @Override
364 public LocalVariableTypeTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
365 return new BoundAttribute.BoundLocalVariableTypeTableAttribute(e, cf, this, p);
366 }
367
368 @Override
369 protected void writeBody(BufWriter bufWriter, LocalVariableTypeTableAttribute attr) {
370 List<LocalVariableTypeInfo> infos = attr.localVariableTypes();
371 BufWriterImpl buf = (BufWriterImpl) bufWriter;
372 buf.writeU2(infos.size());
373 for (LocalVariableTypeInfo info : infos) {
374 buf.writeU2U2(info.startPc(), info.length());
375 buf.writeU2U2U2(buf.cpIndex(info.name()), buf.cpIndex(info.signature()), info.slot());
376 }
377 }
378 }
379
380 public static final class MethodParametersMapper extends AbstractAttributeMapper<MethodParametersAttribute> {
381 public static final MethodParametersMapper INSTANCE = new MethodParametersMapper();
382
383 private MethodParametersMapper() {
384 super(NAME_METHOD_PARAMETERS, AttributeStability.CP_REFS);
385 }
386
387 @Override
388 public MethodParametersAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
389 return new BoundAttribute.BoundMethodParametersAttribute(cf, this, p);
390 }
391
392 @Override
393 protected void writeBody(BufWriter bufWriter, MethodParametersAttribute attr) {
394 List<MethodParameterInfo> parameters = attr.parameters();
395 BufWriterImpl buf = (BufWriterImpl) bufWriter;
396 buf.writeU1(parameters.size());
397 for (MethodParameterInfo info : parameters) {
398 buf.writeU2U2(buf.cpIndexOrZero(info.name().orElse(null)),
399 info.flagsMask());
400 }
401 }
402 }
403
404 public static final class ModuleMapper extends AbstractAttributeMapper<ModuleAttribute> {
405 public static final ModuleMapper INSTANCE = new ModuleMapper();
406
407 private ModuleMapper() {
408 super(NAME_MODULE, AttributeStability.CP_REFS);
409 }
410
411 @Override
412 public ModuleAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
413 return new BoundAttribute.BoundModuleAttribute(cf, this, p);
414 }
415
416 @Override
417 protected void writeBody(BufWriter bufWriter, ModuleAttribute attr) {
418 BufWriterImpl buf = (BufWriterImpl) bufWriter;
419 buf.writeU2U2U2(buf.cpIndex(attr.moduleName()),
420 attr.moduleFlagsMask(),
421 buf.cpIndexOrZero(attr.moduleVersion().orElse(null)));
422 buf.writeU2(attr.requires().size());
423 for (ModuleRequireInfo require : attr.requires()) {
424 buf.writeU2U2U2(buf.cpIndex(require.requires()),
425 require.requiresFlagsMask(),
426 buf.cpIndexOrZero(require.requiresVersion().orElse(null)));
427 }
428 buf.writeU2(attr.exports().size());
429 for (ModuleExportInfo export : attr.exports()) {
430 buf.writeU2U2(buf.cpIndex(export.exportedPackage()),
431 export.exportsFlagsMask());
432 Util.writeListIndices(buf, export.exportsTo());
433 }
434 buf.writeU2(attr.opens().size());
435 for (ModuleOpenInfo open : attr.opens()) {
436 buf.writeU2U2(buf.cpIndex(open.openedPackage()),
437 open.opensFlagsMask());
438 Util.writeListIndices(buf, open.opensTo());
439 }
440 Util.writeListIndices(buf, attr.uses());
441 buf.writeU2(attr.provides().size());
442 for (ModuleProvideInfo provide : attr.provides()) {
443 buf.writeIndex(provide.provides());
444 Util.writeListIndices(buf, provide.providesWith());
445 }
446 }
447 }
448
449 public static final class ModuleHashesMapper extends AbstractAttributeMapper<ModuleHashesAttribute> {
450 public static final ModuleHashesMapper INSTANCE = new ModuleHashesMapper();
451
452 private ModuleHashesMapper() {
453 super(NAME_MODULE_HASHES, AttributeStability.CP_REFS);
454 }
455
456 @Override
457 public ModuleHashesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
458 return new BoundAttribute.BoundModuleHashesAttribute(cf, this, p);
459 }
460
461 @Override
462 protected void writeBody(BufWriter bufWriter, ModuleHashesAttribute attr) {
463 List<ModuleHashInfo> hashes = attr.hashes();
464 BufWriterImpl buf = (BufWriterImpl) bufWriter;
465 buf.writeU2U2(buf.cpIndex(attr.algorithm()), hashes.size());
466 for (ModuleHashInfo hash : hashes) {
467 buf.writeU2U2(buf.cpIndex(hash.moduleName()),
468 hash.hash().length);
469 buf.writeBytes(hash.hash());
470 }
471 }
472 }
473
474 public static final class ModuleMainClassMapper extends AbstractAttributeMapper<ModuleMainClassAttribute> {
475 public static final ModuleMainClassMapper INSTANCE = new ModuleMainClassMapper();
476
477 private ModuleMainClassMapper() {
478 super(NAME_MODULE_MAIN_CLASS, AttributeStability.CP_REFS);
479 }
480
481 @Override
482 public ModuleMainClassAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
483 return new BoundAttribute.BoundModuleMainClassAttribute(cf, this, p);
484 }
485
486 @Override
487 protected void writeBody(BufWriter buf, ModuleMainClassAttribute attr) {
488 buf.writeIndex(attr.mainClass());
489 }
490 }
491
492 public static final class ModulePackagesMapper extends AbstractAttributeMapper<ModulePackagesAttribute> {
493 public static final ModulePackagesMapper INSTANCE = new ModulePackagesMapper();
494
495 private ModulePackagesMapper() {
496 super(NAME_MODULE_PACKAGES, AttributeStability.CP_REFS);
497 }
498
499 @Override
500 public ModulePackagesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
501 return new BoundAttribute.BoundModulePackagesAttribute(cf, this, p);
502 }
503
504 @Override
505 protected void writeBody(BufWriter buf, ModulePackagesAttribute attr) {
506 Util.writeListIndices(buf, attr.packages());
507 }
508 }
509
510 public static final class ModuleResolutionMapper extends AbstractAttributeMapper<ModuleResolutionAttribute> {
511 public static final ModuleResolutionMapper INSTANCE = new ModuleResolutionMapper();
512
513 private ModuleResolutionMapper() {
514 super(NAME_MODULE_RESOLUTION, AttributeStability.STATELESS);
515 }
516
517 @Override
518 public ModuleResolutionAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
519 return new BoundAttribute.BoundModuleResolutionAttribute(cf, this, p);
520 }
521
522 @Override
523 protected void writeBody(BufWriter buf, ModuleResolutionAttribute attr) {
524 buf.writeU2(attr.resolutionFlags());
525 }
526 }
527
528 public static final class ModuleTargetMapper extends AbstractAttributeMapper<ModuleTargetAttribute> {
529 public static final ModuleTargetMapper INSTANCE = new ModuleTargetMapper();
530
531 private ModuleTargetMapper() {
532 super(NAME_MODULE_TARGET, AttributeStability.CP_REFS);
533 }
534
535 @Override
536 public ModuleTargetAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
537 return new BoundAttribute.BoundModuleTargetAttribute(cf, this, p);
538 }
539
540 @Override
541 protected void writeBody(BufWriter buf, ModuleTargetAttribute attr) {
542 buf.writeIndex(attr.targetPlatform());
543 }
544 }
545
546 public static final class NestHostMapper extends AbstractAttributeMapper<NestHostAttribute> {
547 public static final NestHostMapper INSTANCE = new NestHostMapper();
548
549 private NestHostMapper() {
550 super(NAME_NEST_HOST, AttributeStability.CP_REFS);
551 }
552
553 @Override
554 public NestHostAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
555 return new BoundAttribute.BoundNestHostAttribute(cf, this, p);
556 }
557
558 @Override
559 protected void writeBody(BufWriter buf, NestHostAttribute attr) {
560 buf.writeIndex(attr.nestHost());
561 }
562 }
563
564 public static final class NestMembersMapper extends AbstractAttributeMapper<NestMembersAttribute> {
565 public static final NestMembersMapper INSTANCE = new NestMembersMapper();
566
567 private NestMembersMapper() {
568 super(NAME_NEST_MEMBERS, AttributeStability.CP_REFS);
569 }
570
571 @Override
572 public NestMembersAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
573 return new BoundAttribute.BoundNestMembersAttribute(cf, this, p);
574 }
575
576 @Override
577 protected void writeBody(BufWriter buf, NestMembersAttribute attr) {
578 Util.writeListIndices(buf, attr.nestMembers());
579 }
580 }
581
582 public static final class PermittedSubclassesMapper extends AbstractAttributeMapper<PermittedSubclassesAttribute> {
583 public static final PermittedSubclassesMapper INSTANCE = new PermittedSubclassesMapper();
584
585 private PermittedSubclassesMapper() {
586 super(NAME_PERMITTED_SUBCLASSES, AttributeStability.CP_REFS);
587 }
588
589 @Override
590 public PermittedSubclassesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
591 return new BoundAttribute.BoundPermittedSubclassesAttribute(cf, this, p);
592 }
593
594 @Override
595 protected void writeBody(BufWriter buf, PermittedSubclassesAttribute attr) {
596 Util.writeListIndices(buf, attr.permittedSubclasses());
597 }
598 }
599
600 public static final class RecordMapper extends AbstractAttributeMapper<RecordAttribute> {
601 public static final RecordMapper INSTANCE = new RecordMapper();
602
603 private RecordMapper() {
604 super(NAME_RECORD, AttributeStability.CP_REFS);
605 }
606
607 @Override
608 public RecordAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
609 return new BoundAttribute.BoundRecordAttribute(cf, this, p);
610 }
611
612 @Override
613 protected void writeBody(BufWriter bufWriter, RecordAttribute attr) {
614 List<RecordComponentInfo> components = attr.components();
615 BufWriterImpl buf = (BufWriterImpl) bufWriter;
616 buf.writeU2(components.size());
617 for (RecordComponentInfo info : components) {
618 buf.writeU2U2(buf.cpIndex(info.name()),
619 buf.cpIndex(info.descriptor()));
620 Util.writeAttributes(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 }