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.*; 28 import java.lang.classfile.attribute.*; 29 import java.lang.classfile.constantpool.ClassEntry; 30 import java.lang.classfile.constantpool.ConstantValueEntry; 31 import java.lang.classfile.constantpool.ModuleEntry; 32 import java.lang.classfile.constantpool.NameAndTypeEntry; 33 import java.lang.classfile.constantpool.PackageEntry; 34 import java.lang.classfile.constantpool.Utf8Entry; 35 import java.util.Collection; 36 import java.util.List; 37 import java.util.Optional; 38 39 import jdk.internal.access.SharedSecrets; 40 41 import static java.util.Objects.requireNonNull; 42 43 public abstract sealed class UnboundAttribute<T extends Attribute<T>> 44 extends AbstractElement 45 implements Attribute<T>, Util.Writable { 46 protected final AttributeMapper<T> mapper; 47 48 public UnboundAttribute(AttributeMapper<T> mapper) { 49 this.mapper = mapper; 50 } 51 52 @Override 53 public AttributeMapper<T> attributeMapper() { 54 return mapper; 55 } 56 57 @Override 58 @SuppressWarnings("unchecked") 59 public void writeTo(BufWriterImpl buf) { 60 mapper.writeAttribute(buf, (T) this); 61 } 62 63 @Override 64 public void writeTo(DirectClassBuilder builder) { 65 builder.writeAttribute(this); 66 } 67 68 @Override 69 public void writeTo(DirectCodeBuilder builder) { 70 builder.writeAttribute(this); 71 } 72 73 @Override 74 public void writeTo(DirectMethodBuilder builder) { 75 builder.writeAttribute(this); 76 } 77 78 @Override 79 public void writeTo(DirectFieldBuilder builder) { 80 builder.writeAttribute(this); 81 } 82 83 @Override 84 public String toString() { 85 return String.format("Attribute[name=%s]", mapper.name()); 86 } 87 public static final class UnboundConstantValueAttribute 88 extends UnboundAttribute<ConstantValueAttribute> 89 implements ConstantValueAttribute { 90 91 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_CONSTANT_VALUE); 92 93 private final ConstantValueEntry entry; 94 95 public UnboundConstantValueAttribute(ConstantValueEntry entry) { 96 super(Attributes.constantValue()); 97 this.entry = requireNonNull(entry); 98 } 99 100 @Override 101 public ConstantValueEntry constant() { 102 return entry; 103 } 104 105 @Override 106 public Utf8Entry attributeName() { 107 return NAME; 108 } 109 } 110 111 public static final class UnboundDeprecatedAttribute 112 extends UnboundAttribute<DeprecatedAttribute> 113 implements DeprecatedAttribute { 114 115 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_DEPRECATED); 116 117 public UnboundDeprecatedAttribute() { 118 super(Attributes.deprecated()); 119 } 120 121 @Override 122 public Utf8Entry attributeName() { 123 return NAME; 124 } 125 } 126 127 public static final class UnboundSyntheticAttribute 128 extends UnboundAttribute<SyntheticAttribute> 129 implements SyntheticAttribute { 130 131 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SYNTHETIC); 132 133 public UnboundSyntheticAttribute() { 134 super(Attributes.synthetic()); 135 } 136 137 @Override 138 public Utf8Entry attributeName() { 139 return NAME; 140 } 141 } 142 143 public static final class UnboundSignatureAttribute 144 extends UnboundAttribute<SignatureAttribute> 145 implements SignatureAttribute { 146 147 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SIGNATURE); 148 149 private final Utf8Entry signature; 150 151 public UnboundSignatureAttribute(Utf8Entry signature) { 152 super(Attributes.signature()); 153 this.signature = requireNonNull(signature); 154 } 155 156 @Override 157 public Utf8Entry signature() { 158 return signature; 159 } 160 161 @Override 162 public Utf8Entry attributeName() { 163 return NAME; 164 } 165 } 166 167 public static final class UnboundExceptionsAttribute 168 extends UnboundAttribute<ExceptionsAttribute> 169 implements ExceptionsAttribute { 170 171 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_EXCEPTIONS); 172 173 private final List<ClassEntry> exceptions; 174 175 public UnboundExceptionsAttribute(List<ClassEntry> exceptions) { 176 super(Attributes.exceptions()); 177 this.exceptions = List.copyOf(exceptions); 178 } 179 180 @Override 181 public List<ClassEntry> exceptions() { 182 return exceptions; 183 } 184 185 @Override 186 public Utf8Entry attributeName() { 187 return NAME; 188 } 189 } 190 191 public static final class UnboundAnnotationDefaultAttribute 192 extends UnboundAttribute<AnnotationDefaultAttribute> 193 implements AnnotationDefaultAttribute { 194 195 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_ANNOTATION_DEFAULT); 196 197 private final AnnotationValue annotationDefault; 198 199 public UnboundAnnotationDefaultAttribute(AnnotationValue annotationDefault) { 200 super(Attributes.annotationDefault()); 201 this.annotationDefault = requireNonNull(annotationDefault); 202 } 203 204 @Override 205 public AnnotationValue defaultValue() { 206 return annotationDefault; 207 } 208 209 @Override 210 public Utf8Entry attributeName() { 211 return NAME; 212 } 213 } 214 215 public static final class UnboundSourceFileAttribute extends UnboundAttribute<SourceFileAttribute> 216 implements SourceFileAttribute { 217 218 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SOURCE_FILE); 219 220 private final Utf8Entry sourceFile; 221 222 public UnboundSourceFileAttribute(Utf8Entry sourceFile) { 223 super(Attributes.sourceFile()); 224 this.sourceFile = requireNonNull(sourceFile); 225 } 226 227 @Override 228 public Utf8Entry sourceFile() { 229 return sourceFile; 230 } 231 232 @Override 233 public Utf8Entry attributeName() { 234 return NAME; 235 } 236 } 237 238 public static final class UnboundStackMapTableAttribute extends UnboundAttribute<StackMapTableAttribute> 239 implements StackMapTableAttribute { 240 241 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_STACK_MAP_TABLE); 242 243 private final List<StackMapFrameInfo> entries; 244 245 public UnboundStackMapTableAttribute(List<StackMapFrameInfo> entries) { 246 super(Attributes.stackMapTable()); 247 this.entries = List.copyOf(entries); 248 } 249 250 @Override 251 public List<StackMapFrameInfo> entries() { 252 return entries; 253 } 254 255 @Override 256 public Utf8Entry attributeName() { 257 return NAME; 258 } 259 } 260 261 public static final class UnboundInnerClassesAttribute 262 extends UnboundAttribute<InnerClassesAttribute> 263 implements InnerClassesAttribute { 264 265 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_INNER_CLASSES); 266 267 private final List<InnerClassInfo> innerClasses; 268 269 public UnboundInnerClassesAttribute(List<InnerClassInfo> innerClasses) { 270 super(Attributes.innerClasses()); 271 this.innerClasses = List.copyOf(innerClasses); 272 } 273 274 @Override 275 public List<InnerClassInfo> classes() { 276 return innerClasses; 277 } 278 279 @Override 280 public Utf8Entry attributeName() { 281 return NAME; 282 } 283 } 284 285 public static final class UnboundRecordAttribute 286 extends UnboundAttribute<RecordAttribute> 287 implements RecordAttribute { 288 289 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RECORD); 290 291 private final List<RecordComponentInfo> components; 292 293 public UnboundRecordAttribute(List<RecordComponentInfo> components) { 294 super(Attributes.record()); 295 this.components = List.copyOf(components); 296 } 297 298 @Override 299 public List<RecordComponentInfo> components() { 300 return components; 301 } 302 303 @Override 304 public Utf8Entry attributeName() { 305 return NAME; 306 } 307 } 308 309 public static final class UnboundEnclosingMethodAttribute 310 extends UnboundAttribute<EnclosingMethodAttribute> 311 implements EnclosingMethodAttribute { 312 313 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_ENCLOSING_METHOD); 314 315 private final ClassEntry classEntry; 316 private final NameAndTypeEntry method; 317 318 public UnboundEnclosingMethodAttribute(ClassEntry classEntry, NameAndTypeEntry method) { 319 super(Attributes.enclosingMethod()); 320 this.classEntry = requireNonNull(classEntry); 321 this.method = method; 322 } 323 324 @Override 325 public ClassEntry enclosingClass() { 326 return classEntry; 327 } 328 329 @Override 330 public Optional<NameAndTypeEntry> enclosingMethod() { 331 return Optional.ofNullable(method); 332 } 333 334 @Override 335 public Utf8Entry attributeName() { 336 return NAME; 337 } 338 } 339 340 public static final class UnboundMethodParametersAttribute 341 extends UnboundAttribute<MethodParametersAttribute> 342 implements MethodParametersAttribute { 343 344 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_METHOD_PARAMETERS); 345 346 private final List<MethodParameterInfo> parameters; 347 348 public UnboundMethodParametersAttribute(List<MethodParameterInfo> parameters) { 349 super(Attributes.methodParameters()); 350 this.parameters = List.copyOf(parameters); 351 } 352 353 @Override 354 public List<MethodParameterInfo> parameters() { 355 return parameters; 356 } 357 358 @Override 359 public Utf8Entry attributeName() { 360 return NAME; 361 } 362 } 363 364 public static final class UnboundModuleTargetAttribute 365 extends UnboundAttribute<ModuleTargetAttribute> 366 implements ModuleTargetAttribute { 367 368 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_TARGET); 369 370 final Utf8Entry moduleTarget; 371 372 public UnboundModuleTargetAttribute(Utf8Entry moduleTarget) { 373 super(Attributes.moduleTarget()); 374 this.moduleTarget = requireNonNull(moduleTarget); 375 } 376 377 @Override 378 public Utf8Entry targetPlatform() { 379 return moduleTarget; 380 } 381 382 @Override 383 public Utf8Entry attributeName() { 384 return NAME; 385 } 386 } 387 388 public static final class UnboundModuleMainClassAttribute 389 extends UnboundAttribute<ModuleMainClassAttribute> 390 implements ModuleMainClassAttribute { 391 392 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_MAIN_CLASS); 393 394 final ClassEntry mainClass; 395 396 public UnboundModuleMainClassAttribute(ClassEntry mainClass) { 397 super(Attributes.moduleMainClass()); 398 this.mainClass = requireNonNull(mainClass); 399 } 400 401 @Override 402 public ClassEntry mainClass() { 403 return mainClass; 404 } 405 406 @Override 407 public Utf8Entry attributeName() { 408 return NAME; 409 } 410 } 411 412 public static final class UnboundModuleHashesAttribute 413 extends UnboundAttribute<ModuleHashesAttribute> 414 implements ModuleHashesAttribute { 415 416 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_HASHES); 417 418 private final Utf8Entry algorithm; 419 private final List<ModuleHashInfo> hashes; 420 421 public UnboundModuleHashesAttribute(Utf8Entry algorithm, List<ModuleHashInfo> hashes) { 422 super(Attributes.moduleHashes()); 423 this.algorithm = requireNonNull(algorithm); 424 this.hashes = List.copyOf(hashes); 425 } 426 427 @Override 428 public Utf8Entry algorithm() { 429 return algorithm; 430 } 431 432 @Override 433 public List<ModuleHashInfo> hashes() { 434 return hashes; 435 } 436 437 @Override 438 public Utf8Entry attributeName() { 439 return NAME; 440 } 441 } 442 443 public static final class UnboundModulePackagesAttribute 444 extends UnboundAttribute<ModulePackagesAttribute> 445 implements ModulePackagesAttribute { 446 447 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_PACKAGES); 448 449 private final Collection<PackageEntry> packages; 450 451 public UnboundModulePackagesAttribute(Collection<PackageEntry> packages) { 452 super(Attributes.modulePackages()); 453 this.packages = List.copyOf(packages); 454 } 455 456 @Override 457 public List<PackageEntry> packages() { 458 return List.copyOf(packages); 459 } 460 461 @Override 462 public Utf8Entry attributeName() { 463 return NAME; 464 } 465 } 466 467 public static final class UnboundModuleResolutionAttribute 468 extends UnboundAttribute<ModuleResolutionAttribute> 469 implements ModuleResolutionAttribute { 470 471 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_RESOLUTION); 472 473 private final int resolutionFlags; 474 475 public UnboundModuleResolutionAttribute(int flags) { 476 super(Attributes.moduleResolution()); 477 resolutionFlags = flags; 478 } 479 480 @Override 481 public int resolutionFlags() { 482 return resolutionFlags; 483 } 484 485 @Override 486 public Utf8Entry attributeName() { 487 return NAME; 488 } 489 } 490 491 public static final class UnboundPermittedSubclassesAttribute 492 extends UnboundAttribute<PermittedSubclassesAttribute> 493 implements PermittedSubclassesAttribute { 494 495 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_PERMITTED_SUBCLASSES); 496 497 private final List<ClassEntry> permittedSubclasses; 498 499 public UnboundPermittedSubclassesAttribute(List<ClassEntry> permittedSubclasses) { 500 super(Attributes.permittedSubclasses()); 501 this.permittedSubclasses = List.copyOf(permittedSubclasses); 502 } 503 504 @Override 505 public List<ClassEntry> permittedSubclasses() { 506 return permittedSubclasses; 507 } 508 509 @Override 510 public Utf8Entry attributeName() { 511 return NAME; 512 } 513 } 514 515 public static final class UnboundLoadableDescriptorsAttribute 516 extends UnboundAttribute<LoadableDescriptorsAttribute> 517 implements LoadableDescriptorsAttribute { 518 519 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_LOADABLE_DESCRIPTORS); 520 521 private final List<Utf8Entry> loadableDescriptors; 522 523 public UnboundLoadableDescriptorsAttribute(List<Utf8Entry> loadableDescriptors) { 524 super(Attributes.loadableDescriptors()); 525 this.loadableDescriptors = List.copyOf(loadableDescriptors); 526 } 527 528 @Override 529 public List<Utf8Entry> loadableDescriptors() { 530 return loadableDescriptors; 531 } 532 533 @Override 534 public Utf8Entry attributeName() { 535 return NAME; 536 } 537 } 538 539 public static final class UnboundNestMembersAttribute 540 extends UnboundAttribute<NestMembersAttribute> 541 implements NestMembersAttribute { 542 543 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_NEST_MEMBERS); 544 545 private final List<ClassEntry> memberEntries; 546 547 public UnboundNestMembersAttribute(List<ClassEntry> memberEntries) { 548 super(Attributes.nestMembers()); 549 this.memberEntries = List.copyOf(memberEntries); 550 } 551 552 @Override 553 public List<ClassEntry> nestMembers() { 554 return memberEntries; 555 } 556 557 @Override 558 public Utf8Entry attributeName() { 559 return NAME; 560 } 561 } 562 563 public static final class UnboundNestHostAttribute 564 extends UnboundAttribute<NestHostAttribute> 565 implements NestHostAttribute { 566 567 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_NEST_HOST); 568 569 private final ClassEntry hostEntry; 570 571 public UnboundNestHostAttribute(ClassEntry hostEntry) { 572 super(Attributes.nestHost()); 573 this.hostEntry = requireNonNull(hostEntry); 574 } 575 576 @Override 577 public ClassEntry nestHost() { 578 return hostEntry; 579 } 580 581 @Override 582 public Utf8Entry attributeName() { 583 return NAME; 584 } 585 } 586 587 public static final class UnboundCompilationIDAttribute 588 extends UnboundAttribute<CompilationIDAttribute> 589 implements CompilationIDAttribute { 590 591 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_COMPILATION_ID); 592 593 private final Utf8Entry idEntry; 594 595 public UnboundCompilationIDAttribute(Utf8Entry idEntry) { 596 super(Attributes.compilationId()); 597 this.idEntry = requireNonNull(idEntry); 598 } 599 600 @Override 601 public Utf8Entry compilationId() { 602 return idEntry; 603 } 604 605 @Override 606 public Utf8Entry attributeName() { 607 return NAME; 608 } 609 } 610 611 public static final class UnboundSourceIDAttribute 612 extends UnboundAttribute<SourceIDAttribute> 613 implements SourceIDAttribute { 614 615 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SOURCE_ID); 616 617 private final Utf8Entry idEntry; 618 619 public UnboundSourceIDAttribute(Utf8Entry idEntry) { 620 super(Attributes.sourceId()); 621 this.idEntry = requireNonNull(idEntry); 622 } 623 624 @Override 625 public Utf8Entry sourceId() { 626 return idEntry; 627 } 628 629 @Override 630 public Utf8Entry attributeName() { 631 return NAME; 632 } 633 } 634 635 public static final class UnboundSourceDebugExtensionAttribute 636 extends UnboundAttribute<SourceDebugExtensionAttribute> 637 implements SourceDebugExtensionAttribute { 638 639 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SOURCE_DEBUG_EXTENSION); 640 641 private final byte[] contents; 642 643 public UnboundSourceDebugExtensionAttribute(byte[] contents) { 644 super(Attributes.sourceDebugExtension()); 645 this.contents = requireNonNull(contents); 646 } 647 648 @Override 649 public byte[] contents() { 650 return contents; 651 } 652 653 @Override 654 public Utf8Entry attributeName() { 655 return NAME; 656 } 657 } 658 659 public static final class UnboundCharacterRangeTableAttribute 660 extends UnboundAttribute<CharacterRangeTableAttribute> 661 implements CharacterRangeTableAttribute { 662 663 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_CHARACTER_RANGE_TABLE); 664 665 private final List<CharacterRangeInfo> ranges; 666 667 public UnboundCharacterRangeTableAttribute(List<CharacterRangeInfo> ranges) { 668 super(Attributes.characterRangeTable()); 669 this.ranges = List.copyOf(ranges); 670 } 671 672 @Override 673 public List<CharacterRangeInfo> characterRangeTable() { 674 return ranges; 675 } 676 677 @Override 678 public Utf8Entry attributeName() { 679 return NAME; 680 } 681 } 682 683 public static final class UnboundLineNumberTableAttribute 684 extends UnboundAttribute<LineNumberTableAttribute> 685 implements LineNumberTableAttribute { 686 687 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_LINE_NUMBER_TABLE); 688 689 private final List<LineNumberInfo> lines; 690 691 public UnboundLineNumberTableAttribute(List<LineNumberInfo> lines) { 692 super(Attributes.lineNumberTable()); 693 this.lines = List.copyOf(lines); 694 } 695 696 @Override 697 public List<LineNumberInfo> lineNumbers() { 698 return lines; 699 } 700 701 @Override 702 public Utf8Entry attributeName() { 703 return NAME; 704 } 705 } 706 707 public static final class UnboundLocalVariableTableAttribute 708 extends UnboundAttribute<LocalVariableTableAttribute> 709 implements LocalVariableTableAttribute { 710 711 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TABLE); 712 713 private final List<LocalVariableInfo> locals; 714 715 public UnboundLocalVariableTableAttribute(List<LocalVariableInfo> locals) { 716 super(Attributes.localVariableTable()); 717 this.locals = List.copyOf(locals); 718 } 719 720 @Override 721 public List<LocalVariableInfo> localVariables() { 722 return locals; 723 } 724 725 @Override 726 public Utf8Entry attributeName() { 727 return NAME; 728 } 729 } 730 731 public static final class UnboundLocalVariableTypeTableAttribute 732 extends UnboundAttribute<LocalVariableTypeTableAttribute> 733 implements LocalVariableTypeTableAttribute { 734 735 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TYPE_TABLE); 736 737 private final List<LocalVariableTypeInfo> locals; 738 739 public UnboundLocalVariableTypeTableAttribute(List<LocalVariableTypeInfo> locals) { 740 super(Attributes.localVariableTypeTable()); 741 this.locals = List.copyOf(locals); 742 } 743 744 @Override 745 public List<LocalVariableTypeInfo> localVariableTypes() { 746 return locals; 747 } 748 749 @Override 750 public Utf8Entry attributeName() { 751 return NAME; 752 } 753 } 754 755 public static final class UnboundRuntimeVisibleAnnotationsAttribute 756 extends UnboundAttribute<RuntimeVisibleAnnotationsAttribute> 757 implements RuntimeVisibleAnnotationsAttribute { 758 759 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_VISIBLE_ANNOTATIONS); 760 761 private final List<Annotation> elements; 762 763 public UnboundRuntimeVisibleAnnotationsAttribute(List<Annotation> elements) { 764 super(Attributes.runtimeVisibleAnnotations()); 765 this.elements = List.copyOf(elements); 766 } 767 768 @Override 769 public List<Annotation> annotations() { 770 return elements; 771 } 772 773 @Override 774 public Utf8Entry attributeName() { 775 return NAME; 776 } 777 } 778 779 public static final class UnboundRuntimeInvisibleAnnotationsAttribute 780 extends UnboundAttribute<RuntimeInvisibleAnnotationsAttribute> 781 implements RuntimeInvisibleAnnotationsAttribute { 782 783 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_INVISIBLE_ANNOTATIONS); 784 785 private final List<Annotation> elements; 786 787 public UnboundRuntimeInvisibleAnnotationsAttribute(List<Annotation> elements) { 788 super(Attributes.runtimeInvisibleAnnotations()); 789 this.elements = List.copyOf(elements); 790 } 791 792 @Override 793 public List<Annotation> annotations() { 794 return elements; 795 } 796 797 @Override 798 public Utf8Entry attributeName() { 799 return NAME; 800 } 801 } 802 803 public static final class UnboundRuntimeVisibleParameterAnnotationsAttribute 804 extends UnboundAttribute<RuntimeVisibleParameterAnnotationsAttribute> 805 implements RuntimeVisibleParameterAnnotationsAttribute { 806 807 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS); 808 809 private final List<List<Annotation>> elements; 810 811 public UnboundRuntimeVisibleParameterAnnotationsAttribute(List<List<Annotation>> elements) { 812 super(Attributes.runtimeVisibleParameterAnnotations()); 813 // deep copy 814 var array = elements.toArray().clone(); 815 for (int i = 0; i < array.length; i++) { 816 array[i] = List.copyOf((List<?>) array[i]); 817 } 818 819 this.elements = SharedSecrets.getJavaUtilCollectionAccess().listFromTrustedArray(array); 820 } 821 822 @Override 823 public List<List<Annotation>> parameterAnnotations() { 824 return elements; 825 } 826 827 @Override 828 public Utf8Entry attributeName() { 829 return NAME; 830 } 831 } 832 833 public static final class UnboundRuntimeInvisibleParameterAnnotationsAttribute 834 extends UnboundAttribute<RuntimeInvisibleParameterAnnotationsAttribute> 835 implements RuntimeInvisibleParameterAnnotationsAttribute { 836 837 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS); 838 839 private final List<List<Annotation>> elements; 840 841 public UnboundRuntimeInvisibleParameterAnnotationsAttribute(List<List<Annotation>> elements) { 842 super(Attributes.runtimeInvisibleParameterAnnotations()); 843 // deep copy 844 var array = elements.toArray().clone(); 845 for (int i = 0; i < array.length; i++) { 846 array[i] = List.copyOf((List<?>) array[i]); 847 } 848 849 this.elements = SharedSecrets.getJavaUtilCollectionAccess().listFromTrustedArray(array); 850 } 851 852 @Override 853 public List<List<Annotation>> parameterAnnotations() { 854 return elements; 855 } 856 857 @Override 858 public Utf8Entry attributeName() { 859 return NAME; 860 } 861 } 862 863 public static final class UnboundRuntimeVisibleTypeAnnotationsAttribute 864 extends UnboundAttribute<RuntimeVisibleTypeAnnotationsAttribute> 865 implements RuntimeVisibleTypeAnnotationsAttribute { 866 867 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); 868 869 private final List<TypeAnnotation> elements; 870 871 public UnboundRuntimeVisibleTypeAnnotationsAttribute(List<TypeAnnotation> elements) { 872 super(Attributes.runtimeVisibleTypeAnnotations()); 873 this.elements = List.copyOf(elements); 874 } 875 876 @Override 877 public List<TypeAnnotation> annotations() { 878 return elements; 879 } 880 881 @Override 882 public Utf8Entry attributeName() { 883 return NAME; 884 } 885 } 886 887 public static final class UnboundRuntimeInvisibleTypeAnnotationsAttribute 888 extends UnboundAttribute<RuntimeInvisibleTypeAnnotationsAttribute> 889 implements RuntimeInvisibleTypeAnnotationsAttribute { 890 891 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS); 892 893 private final List<TypeAnnotation> elements; 894 895 public UnboundRuntimeInvisibleTypeAnnotationsAttribute(List<TypeAnnotation> elements) { 896 super(Attributes.runtimeInvisibleTypeAnnotations()); 897 this.elements = List.copyOf(elements); 898 } 899 900 @Override 901 public List<TypeAnnotation> annotations() { 902 return elements; 903 } 904 905 @Override 906 public Utf8Entry attributeName() { 907 return NAME; 908 } 909 } 910 911 public record UnboundCharacterRangeInfo(int startPc, int endPc, 912 int characterRangeStart, 913 int characterRangeEnd, 914 int flags) 915 implements CharacterRangeInfo { } 916 917 public record UnboundInnerClassInfo(ClassEntry innerClass, 918 Optional<ClassEntry> outerClass, 919 Optional<Utf8Entry> innerName, 920 int flagsMask) 921 implements InnerClassInfo { 922 public UnboundInnerClassInfo { 923 requireNonNull(innerClass); 924 requireNonNull(outerClass); 925 requireNonNull(innerName); 926 } 927 } 928 929 public record UnboundLineNumberInfo(int startPc, int lineNumber) 930 implements LineNumberInfo { } 931 932 public record UnboundLocalVariableInfo(int startPc, int length, 933 Utf8Entry name, 934 Utf8Entry type, 935 int slot) 936 implements LocalVariableInfo { 937 public UnboundLocalVariableInfo { 938 requireNonNull(name); 939 requireNonNull(type); 940 } 941 } 942 943 public record UnboundLocalVariableTypeInfo(int startPc, int length, 944 Utf8Entry name, 945 Utf8Entry signature, 946 int slot) 947 implements LocalVariableTypeInfo { 948 public UnboundLocalVariableTypeInfo { 949 requireNonNull(name); 950 requireNonNull(signature); 951 } 952 } 953 954 public record UnboundMethodParameterInfo(Optional<Utf8Entry> name, int flagsMask) 955 implements MethodParameterInfo { 956 public UnboundMethodParameterInfo { 957 requireNonNull(name); 958 } 959 } 960 961 public record UnboundModuleExportInfo(PackageEntry exportedPackage, 962 int exportsFlagsMask, 963 List<ModuleEntry> exportsTo) 964 implements ModuleExportInfo { 965 public UnboundModuleExportInfo { 966 requireNonNull(exportedPackage); 967 exportsTo = List.copyOf(exportsTo); 968 } 969 } 970 971 public record UnboundModuleHashInfo(ModuleEntry moduleName, 972 byte[] hash) implements ModuleHashInfo { 973 public UnboundModuleHashInfo { 974 requireNonNull(moduleName); 975 requireNonNull(hash); 976 } 977 } 978 979 public record UnboundModuleOpenInfo(PackageEntry openedPackage, int opensFlagsMask, 980 List<ModuleEntry> opensTo) 981 implements ModuleOpenInfo { 982 public UnboundModuleOpenInfo { 983 requireNonNull(openedPackage); 984 opensTo = List.copyOf(opensTo); 985 } 986 } 987 988 public record UnboundModuleProvideInfo(ClassEntry provides, 989 List<ClassEntry> providesWith) 990 implements ModuleProvideInfo { 991 public UnboundModuleProvideInfo { 992 requireNonNull(provides); 993 providesWith = List.copyOf(providesWith); 994 } 995 } 996 997 public record UnboundModuleRequiresInfo(ModuleEntry requires, int requiresFlagsMask, 998 Optional<Utf8Entry> requiresVersion) 999 implements ModuleRequireInfo { 1000 public UnboundModuleRequiresInfo { 1001 requireNonNull(requires); 1002 requireNonNull(requiresVersion); 1003 } 1004 } 1005 1006 public record UnboundRecordComponentInfo(Utf8Entry name, 1007 Utf8Entry descriptor, 1008 List<Attribute<?>> attributes) 1009 implements RecordComponentInfo { 1010 public UnboundRecordComponentInfo { 1011 requireNonNull(name); 1012 requireNonNull(descriptor); 1013 attributes = List.copyOf(attributes); 1014 } 1015 } 1016 1017 public record UnboundTypeAnnotation(TargetInfo targetInfo, 1018 List<TypePathComponent> targetPath, 1019 Annotation annotation) implements TypeAnnotation { 1020 1021 public UnboundTypeAnnotation { 1022 requireNonNull(targetInfo); 1023 targetPath = List.copyOf(targetPath); 1024 requireNonNull(annotation); 1025 } 1026 } 1027 1028 public record TypePathComponentImpl(TypeAnnotation.TypePathComponent.Kind typePathKind, int typeArgumentIndex) 1029 implements TypeAnnotation.TypePathComponent {} 1030 1031 public static final class UnboundModuleAttribute extends UnboundAttribute<ModuleAttribute> implements ModuleAttribute { 1032 1033 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE); 1034 1035 private final ModuleEntry moduleName; 1036 private final int moduleFlags; 1037 private final Utf8Entry moduleVersion; 1038 private final List<ModuleRequireInfo> requires; 1039 private final List<ModuleExportInfo> exports; 1040 private final List<ModuleOpenInfo> opens; 1041 private final List<ClassEntry> uses; 1042 private final List<ModuleProvideInfo> provides; 1043 1044 public UnboundModuleAttribute(ModuleEntry moduleName, 1045 int moduleFlags, 1046 Utf8Entry moduleVersion, 1047 Collection<ModuleRequireInfo> requires, 1048 Collection<ModuleExportInfo> exports, 1049 Collection<ModuleOpenInfo> opens, 1050 Collection<ClassEntry> uses, 1051 Collection<ModuleProvideInfo> provides) 1052 { 1053 super(Attributes.module()); 1054 this.moduleName = requireNonNull(moduleName); 1055 this.moduleFlags = moduleFlags; 1056 this.moduleVersion = moduleVersion; 1057 this.requires = List.copyOf(requires); 1058 this.exports = List.copyOf(exports); 1059 this.opens = List.copyOf(opens); 1060 this.uses = List.copyOf(uses); 1061 this.provides = List.copyOf(provides); 1062 } 1063 1064 @Override 1065 public ModuleEntry moduleName() { 1066 return moduleName; 1067 } 1068 1069 @Override 1070 public int moduleFlagsMask() { 1071 return moduleFlags; 1072 } 1073 1074 @Override 1075 public Optional<Utf8Entry> moduleVersion() { 1076 return Optional.ofNullable(moduleVersion); 1077 } 1078 1079 @Override 1080 public List<ModuleRequireInfo> requires() { 1081 return requires; 1082 } 1083 1084 @Override 1085 public List<ModuleExportInfo> exports() { 1086 return exports; 1087 } 1088 1089 @Override 1090 public List<ModuleOpenInfo> opens() { 1091 return opens; 1092 } 1093 1094 @Override 1095 public List<ClassEntry> uses() { 1096 return uses; 1097 } 1098 1099 @Override 1100 public List<ModuleProvideInfo> provides() { 1101 return provides; 1102 } 1103 1104 @Override 1105 public Utf8Entry attributeName() { 1106 return NAME; 1107 } 1108 } 1109 1110 public abstract static non-sealed class AdHocAttribute<T extends Attribute<T>> 1111 extends UnboundAttribute<T> { 1112 1113 public AdHocAttribute(AttributeMapper<T> mapper) { 1114 super(mapper); 1115 } 1116 1117 public abstract void writeBody(BufWriterImpl b); 1118 1119 @Override 1120 public void writeTo(BufWriterImpl b) { 1121 b.writeIndex(b.constantPool().utf8Entry(mapper.name())); 1122 int lengthIndex = b.skip(4); 1123 writeBody(b); 1124 int written = b.size() - lengthIndex - 4; 1125 b.patchInt(lengthIndex, written); 1126 } 1127 } 1128 1129 public static final class EmptyBootstrapAttribute 1130 extends UnboundAttribute<BootstrapMethodsAttribute> 1131 implements BootstrapMethodsAttribute { 1132 1133 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_BOOTSTRAP_METHODS); 1134 1135 public EmptyBootstrapAttribute() { 1136 super(Attributes.bootstrapMethods()); 1137 } 1138 1139 @Override 1140 public int bootstrapMethodsSize() { 1141 return 0; 1142 } 1143 1144 @Override 1145 public List<BootstrapMethodEntry> bootstrapMethods() { 1146 return List.of(); 1147 } 1148 1149 @Override 1150 public Utf8Entry attributeName() { 1151 return NAME; 1152 } 1153 } 1154 }