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 UnboundNestMembersAttribute 516 extends UnboundAttribute<NestMembersAttribute> 517 implements NestMembersAttribute { 518 519 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_NEST_MEMBERS); 520 521 private final List<ClassEntry> memberEntries; 522 523 public UnboundNestMembersAttribute(List<ClassEntry> memberEntries) { 524 super(Attributes.nestMembers()); 525 this.memberEntries = List.copyOf(memberEntries); 526 } 527 528 @Override 529 public List<ClassEntry> nestMembers() { 530 return memberEntries; 531 } 532 533 @Override 534 public Utf8Entry attributeName() { 535 return NAME; 536 } 537 } 538 539 public static final class UnboundNestHostAttribute 540 extends UnboundAttribute<NestHostAttribute> 541 implements NestHostAttribute { 542 543 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_NEST_HOST); 544 545 private final ClassEntry hostEntry; 546 547 public UnboundNestHostAttribute(ClassEntry hostEntry) { 548 super(Attributes.nestHost()); 549 this.hostEntry = requireNonNull(hostEntry); 550 } 551 552 @Override 553 public ClassEntry nestHost() { 554 return hostEntry; 555 } 556 557 @Override 558 public Utf8Entry attributeName() { 559 return NAME; 560 } 561 } 562 563 public static final class UnboundCompilationIDAttribute 564 extends UnboundAttribute<CompilationIDAttribute> 565 implements CompilationIDAttribute { 566 567 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_COMPILATION_ID); 568 569 private final Utf8Entry idEntry; 570 571 public UnboundCompilationIDAttribute(Utf8Entry idEntry) { 572 super(Attributes.compilationId()); 573 this.idEntry = requireNonNull(idEntry); 574 } 575 576 @Override 577 public Utf8Entry compilationId() { 578 return idEntry; 579 } 580 581 @Override 582 public Utf8Entry attributeName() { 583 return NAME; 584 } 585 } 586 587 public static final class UnboundSourceIDAttribute 588 extends UnboundAttribute<SourceIDAttribute> 589 implements SourceIDAttribute { 590 591 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SOURCE_ID); 592 593 private final Utf8Entry idEntry; 594 595 public UnboundSourceIDAttribute(Utf8Entry idEntry) { 596 super(Attributes.sourceId()); 597 this.idEntry = requireNonNull(idEntry); 598 } 599 600 @Override 601 public Utf8Entry sourceId() { 602 return idEntry; 603 } 604 605 @Override 606 public Utf8Entry attributeName() { 607 return NAME; 608 } 609 } 610 611 public static final class UnboundSourceDebugExtensionAttribute 612 extends UnboundAttribute<SourceDebugExtensionAttribute> 613 implements SourceDebugExtensionAttribute { 614 615 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SOURCE_DEBUG_EXTENSION); 616 617 private final byte[] contents; 618 619 public UnboundSourceDebugExtensionAttribute(byte[] contents) { 620 super(Attributes.sourceDebugExtension()); 621 this.contents = requireNonNull(contents); 622 } 623 624 @Override 625 public byte[] contents() { 626 return contents; 627 } 628 629 @Override 630 public Utf8Entry attributeName() { 631 return NAME; 632 } 633 } 634 635 public static final class UnboundCharacterRangeTableAttribute 636 extends UnboundAttribute<CharacterRangeTableAttribute> 637 implements CharacterRangeTableAttribute { 638 639 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_CHARACTER_RANGE_TABLE); 640 641 private final List<CharacterRangeInfo> ranges; 642 643 public UnboundCharacterRangeTableAttribute(List<CharacterRangeInfo> ranges) { 644 super(Attributes.characterRangeTable()); 645 this.ranges = List.copyOf(ranges); 646 } 647 648 @Override 649 public List<CharacterRangeInfo> characterRangeTable() { 650 return ranges; 651 } 652 653 @Override 654 public Utf8Entry attributeName() { 655 return NAME; 656 } 657 } 658 659 public static final class UnboundLineNumberTableAttribute 660 extends UnboundAttribute<LineNumberTableAttribute> 661 implements LineNumberTableAttribute { 662 663 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_LINE_NUMBER_TABLE); 664 665 private final List<LineNumberInfo> lines; 666 667 public UnboundLineNumberTableAttribute(List<LineNumberInfo> lines) { 668 super(Attributes.lineNumberTable()); 669 this.lines = List.copyOf(lines); 670 } 671 672 @Override 673 public List<LineNumberInfo> lineNumbers() { 674 return lines; 675 } 676 677 @Override 678 public Utf8Entry attributeName() { 679 return NAME; 680 } 681 } 682 683 public static final class UnboundLocalVariableTableAttribute 684 extends UnboundAttribute<LocalVariableTableAttribute> 685 implements LocalVariableTableAttribute { 686 687 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TABLE); 688 689 private final List<LocalVariableInfo> locals; 690 691 public UnboundLocalVariableTableAttribute(List<LocalVariableInfo> locals) { 692 super(Attributes.localVariableTable()); 693 this.locals = List.copyOf(locals); 694 } 695 696 @Override 697 public List<LocalVariableInfo> localVariables() { 698 return locals; 699 } 700 701 @Override 702 public Utf8Entry attributeName() { 703 return NAME; 704 } 705 } 706 707 public static final class UnboundLocalVariableTypeTableAttribute 708 extends UnboundAttribute<LocalVariableTypeTableAttribute> 709 implements LocalVariableTypeTableAttribute { 710 711 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TYPE_TABLE); 712 713 private final List<LocalVariableTypeInfo> locals; 714 715 public UnboundLocalVariableTypeTableAttribute(List<LocalVariableTypeInfo> locals) { 716 super(Attributes.localVariableTypeTable()); 717 this.locals = List.copyOf(locals); 718 } 719 720 @Override 721 public List<LocalVariableTypeInfo> localVariableTypes() { 722 return locals; 723 } 724 725 @Override 726 public Utf8Entry attributeName() { 727 return NAME; 728 } 729 } 730 731 public static final class UnboundRuntimeVisibleAnnotationsAttribute 732 extends UnboundAttribute<RuntimeVisibleAnnotationsAttribute> 733 implements RuntimeVisibleAnnotationsAttribute { 734 735 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_VISIBLE_ANNOTATIONS); 736 737 private final List<Annotation> elements; 738 739 public UnboundRuntimeVisibleAnnotationsAttribute(List<Annotation> elements) { 740 super(Attributes.runtimeVisibleAnnotations()); 741 this.elements = List.copyOf(elements); 742 } 743 744 @Override 745 public List<Annotation> annotations() { 746 return elements; 747 } 748 749 @Override 750 public Utf8Entry attributeName() { 751 return NAME; 752 } 753 } 754 755 public static final class UnboundRuntimeInvisibleAnnotationsAttribute 756 extends UnboundAttribute<RuntimeInvisibleAnnotationsAttribute> 757 implements RuntimeInvisibleAnnotationsAttribute { 758 759 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_INVISIBLE_ANNOTATIONS); 760 761 private final List<Annotation> elements; 762 763 public UnboundRuntimeInvisibleAnnotationsAttribute(List<Annotation> elements) { 764 super(Attributes.runtimeInvisibleAnnotations()); 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 UnboundRuntimeVisibleParameterAnnotationsAttribute 780 extends UnboundAttribute<RuntimeVisibleParameterAnnotationsAttribute> 781 implements RuntimeVisibleParameterAnnotationsAttribute { 782 783 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS); 784 785 private final List<List<Annotation>> elements; 786 787 public UnboundRuntimeVisibleParameterAnnotationsAttribute(List<List<Annotation>> elements) { 788 super(Attributes.runtimeVisibleParameterAnnotations()); 789 // deep copy 790 var array = elements.toArray().clone(); 791 for (int i = 0; i < array.length; i++) { 792 array[i] = List.copyOf((List<?>) array[i]); 793 } 794 795 this.elements = SharedSecrets.getJavaUtilCollectionAccess().listFromTrustedArray(array); 796 } 797 798 @Override 799 public List<List<Annotation>> parameterAnnotations() { 800 return elements; 801 } 802 803 @Override 804 public Utf8Entry attributeName() { 805 return NAME; 806 } 807 } 808 809 public static final class UnboundRuntimeInvisibleParameterAnnotationsAttribute 810 extends UnboundAttribute<RuntimeInvisibleParameterAnnotationsAttribute> 811 implements RuntimeInvisibleParameterAnnotationsAttribute { 812 813 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS); 814 815 private final List<List<Annotation>> elements; 816 817 public UnboundRuntimeInvisibleParameterAnnotationsAttribute(List<List<Annotation>> elements) { 818 super(Attributes.runtimeInvisibleParameterAnnotations()); 819 // deep copy 820 var array = elements.toArray().clone(); 821 for (int i = 0; i < array.length; i++) { 822 array[i] = List.copyOf((List<?>) array[i]); 823 } 824 825 this.elements = SharedSecrets.getJavaUtilCollectionAccess().listFromTrustedArray(array); 826 } 827 828 @Override 829 public List<List<Annotation>> parameterAnnotations() { 830 return elements; 831 } 832 833 @Override 834 public Utf8Entry attributeName() { 835 return NAME; 836 } 837 } 838 839 public static final class UnboundRuntimeVisibleTypeAnnotationsAttribute 840 extends UnboundAttribute<RuntimeVisibleTypeAnnotationsAttribute> 841 implements RuntimeVisibleTypeAnnotationsAttribute { 842 843 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); 844 845 private final List<TypeAnnotation> elements; 846 847 public UnboundRuntimeVisibleTypeAnnotationsAttribute(List<TypeAnnotation> elements) { 848 super(Attributes.runtimeVisibleTypeAnnotations()); 849 this.elements = List.copyOf(elements); 850 } 851 852 @Override 853 public List<TypeAnnotation> annotations() { 854 return elements; 855 } 856 857 @Override 858 public Utf8Entry attributeName() { 859 return NAME; 860 } 861 } 862 863 public static final class UnboundRuntimeInvisibleTypeAnnotationsAttribute 864 extends UnboundAttribute<RuntimeInvisibleTypeAnnotationsAttribute> 865 implements RuntimeInvisibleTypeAnnotationsAttribute { 866 867 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS); 868 869 private final List<TypeAnnotation> elements; 870 871 public UnboundRuntimeInvisibleTypeAnnotationsAttribute(List<TypeAnnotation> elements) { 872 super(Attributes.runtimeInvisibleTypeAnnotations()); 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 record UnboundCharacterRangeInfo(int startPc, int endPc, 888 int characterRangeStart, 889 int characterRangeEnd, 890 int flags) 891 implements CharacterRangeInfo { } 892 893 public record UnboundInnerClassInfo(ClassEntry innerClass, 894 Optional<ClassEntry> outerClass, 895 Optional<Utf8Entry> innerName, 896 int flagsMask) 897 implements InnerClassInfo { 898 public UnboundInnerClassInfo { 899 requireNonNull(innerClass); 900 requireNonNull(outerClass); 901 requireNonNull(innerName); 902 } 903 } 904 905 public record UnboundLineNumberInfo(int startPc, int lineNumber) 906 implements LineNumberInfo { } 907 908 public record UnboundLocalVariableInfo(int startPc, int length, 909 Utf8Entry name, 910 Utf8Entry type, 911 int slot) 912 implements LocalVariableInfo { 913 public UnboundLocalVariableInfo { 914 requireNonNull(name); 915 requireNonNull(type); 916 } 917 } 918 919 public record UnboundLocalVariableTypeInfo(int startPc, int length, 920 Utf8Entry name, 921 Utf8Entry signature, 922 int slot) 923 implements LocalVariableTypeInfo { 924 public UnboundLocalVariableTypeInfo { 925 requireNonNull(name); 926 requireNonNull(signature); 927 } 928 } 929 930 public record UnboundMethodParameterInfo(Optional<Utf8Entry> name, int flagsMask) 931 implements MethodParameterInfo { 932 public UnboundMethodParameterInfo { 933 requireNonNull(name); 934 } 935 } 936 937 public record UnboundModuleExportInfo(PackageEntry exportedPackage, 938 int exportsFlagsMask, 939 List<ModuleEntry> exportsTo) 940 implements ModuleExportInfo { 941 public UnboundModuleExportInfo { 942 requireNonNull(exportedPackage); 943 exportsTo = List.copyOf(exportsTo); 944 } 945 } 946 947 public record UnboundModuleHashInfo(ModuleEntry moduleName, 948 byte[] hash) implements ModuleHashInfo { 949 public UnboundModuleHashInfo { 950 requireNonNull(moduleName); 951 requireNonNull(hash); 952 } 953 } 954 955 public record UnboundModuleOpenInfo(PackageEntry openedPackage, int opensFlagsMask, 956 List<ModuleEntry> opensTo) 957 implements ModuleOpenInfo { 958 public UnboundModuleOpenInfo { 959 requireNonNull(openedPackage); 960 opensTo = List.copyOf(opensTo); 961 } 962 } 963 964 public record UnboundModuleProvideInfo(ClassEntry provides, 965 List<ClassEntry> providesWith) 966 implements ModuleProvideInfo { 967 public UnboundModuleProvideInfo { 968 requireNonNull(provides); 969 providesWith = List.copyOf(providesWith); 970 } 971 } 972 973 public record UnboundModuleRequiresInfo(ModuleEntry requires, int requiresFlagsMask, 974 Optional<Utf8Entry> requiresVersion) 975 implements ModuleRequireInfo { 976 public UnboundModuleRequiresInfo { 977 requireNonNull(requires); 978 requireNonNull(requiresVersion); 979 } 980 } 981 982 public record UnboundRecordComponentInfo(Utf8Entry name, 983 Utf8Entry descriptor, 984 List<Attribute<?>> attributes) 985 implements RecordComponentInfo { 986 public UnboundRecordComponentInfo { 987 requireNonNull(name); 988 requireNonNull(descriptor); 989 attributes = List.copyOf(attributes); 990 } 991 } 992 993 public record UnboundTypeAnnotation(TargetInfo targetInfo, 994 List<TypePathComponent> targetPath, 995 Annotation annotation) implements TypeAnnotation { 996 997 public UnboundTypeAnnotation { 998 requireNonNull(targetInfo); 999 targetPath = List.copyOf(targetPath); 1000 requireNonNull(annotation); 1001 } 1002 } 1003 1004 public record TypePathComponentImpl(TypeAnnotation.TypePathComponent.Kind typePathKind, int typeArgumentIndex) 1005 implements TypeAnnotation.TypePathComponent {} 1006 1007 public static final class UnboundModuleAttribute extends UnboundAttribute<ModuleAttribute> implements ModuleAttribute { 1008 1009 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE); 1010 1011 private final ModuleEntry moduleName; 1012 private final int moduleFlags; 1013 private final Utf8Entry moduleVersion; 1014 private final List<ModuleRequireInfo> requires; 1015 private final List<ModuleExportInfo> exports; 1016 private final List<ModuleOpenInfo> opens; 1017 private final List<ClassEntry> uses; 1018 private final List<ModuleProvideInfo> provides; 1019 1020 public UnboundModuleAttribute(ModuleEntry moduleName, 1021 int moduleFlags, 1022 Utf8Entry moduleVersion, 1023 Collection<ModuleRequireInfo> requires, 1024 Collection<ModuleExportInfo> exports, 1025 Collection<ModuleOpenInfo> opens, 1026 Collection<ClassEntry> uses, 1027 Collection<ModuleProvideInfo> provides) 1028 { 1029 super(Attributes.module()); 1030 this.moduleName = requireNonNull(moduleName); 1031 this.moduleFlags = moduleFlags; 1032 this.moduleVersion = moduleVersion; 1033 this.requires = List.copyOf(requires); 1034 this.exports = List.copyOf(exports); 1035 this.opens = List.copyOf(opens); 1036 this.uses = List.copyOf(uses); 1037 this.provides = List.copyOf(provides); 1038 } 1039 1040 @Override 1041 public ModuleEntry moduleName() { 1042 return moduleName; 1043 } 1044 1045 @Override 1046 public int moduleFlagsMask() { 1047 return moduleFlags; 1048 } 1049 1050 @Override 1051 public Optional<Utf8Entry> moduleVersion() { 1052 return Optional.ofNullable(moduleVersion); 1053 } 1054 1055 @Override 1056 public List<ModuleRequireInfo> requires() { 1057 return requires; 1058 } 1059 1060 @Override 1061 public List<ModuleExportInfo> exports() { 1062 return exports; 1063 } 1064 1065 @Override 1066 public List<ModuleOpenInfo> opens() { 1067 return opens; 1068 } 1069 1070 @Override 1071 public List<ClassEntry> uses() { 1072 return uses; 1073 } 1074 1075 @Override 1076 public List<ModuleProvideInfo> provides() { 1077 return provides; 1078 } 1079 1080 @Override 1081 public Utf8Entry attributeName() { 1082 return NAME; 1083 } 1084 } 1085 1086 public abstract static non-sealed class AdHocAttribute<T extends Attribute<T>> 1087 extends UnboundAttribute<T> { 1088 1089 public AdHocAttribute(AttributeMapper<T> mapper) { 1090 super(mapper); 1091 } 1092 1093 public abstract void writeBody(BufWriterImpl b); 1094 1095 @Override 1096 public void writeTo(BufWriterImpl b) { 1097 b.writeIndex(b.constantPool().utf8Entry(mapper.name())); 1098 int lengthIndex = b.skip(4); 1099 writeBody(b); 1100 int written = b.size() - lengthIndex - 4; 1101 b.patchInt(lengthIndex, written); 1102 } 1103 } 1104 1105 public static final class EmptyBootstrapAttribute 1106 extends UnboundAttribute<BootstrapMethodsAttribute> 1107 implements BootstrapMethodsAttribute { 1108 1109 private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_BOOTSTRAP_METHODS); 1110 1111 public EmptyBootstrapAttribute() { 1112 super(Attributes.bootstrapMethods()); 1113 } 1114 1115 @Override 1116 public int bootstrapMethodsSize() { 1117 return 0; 1118 } 1119 1120 @Override 1121 public List<BootstrapMethodEntry> bootstrapMethods() { 1122 return List.of(); 1123 } 1124 1125 @Override 1126 public Utf8Entry attributeName() { 1127 return NAME; 1128 } 1129 } 1130 }