1 /*
   2  * Copyright (c) 2022, 2025, 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 java.lang.classfile;
  26 
  27 import java.io.IOException;
  28 import java.lang.classfile.AttributeMapper.AttributeStability;
  29 import java.lang.classfile.attribute.CharacterRangeInfo;
  30 import java.lang.classfile.attribute.CodeAttribute;
  31 import java.lang.classfile.attribute.LocalVariableInfo;
  32 import java.lang.classfile.attribute.LocalVariableTypeInfo;
  33 import java.lang.classfile.attribute.ModuleAttribute;
  34 import java.lang.classfile.attribute.StackMapTableAttribute;
  35 import java.lang.classfile.attribute.UnknownAttribute;
  36 import java.lang.classfile.constantpool.ClassEntry;
  37 import java.lang.classfile.constantpool.ConstantPoolBuilder;
  38 import java.lang.classfile.constantpool.Utf8Entry;
  39 import java.lang.classfile.instruction.BranchInstruction;
  40 import java.lang.classfile.instruction.CharacterRange;
  41 import java.lang.classfile.instruction.DiscontinuedInstruction;
  42 import java.lang.classfile.instruction.ExceptionCatch;
  43 import java.lang.classfile.instruction.LineNumber;
  44 import java.lang.classfile.instruction.LocalVariable;
  45 import java.lang.classfile.instruction.LocalVariableType;
  46 import java.lang.constant.ClassDesc;
  47 import java.lang.reflect.AccessFlag;
  48 import java.lang.reflect.ClassFileFormatVersion;
  49 import java.nio.file.Files;
  50 import java.nio.file.Path;
  51 import java.util.List;
  52 import java.util.function.Consumer;
  53 import java.util.function.Function;
  54 
  55 import jdk.internal.classfile.impl.ClassFileImpl;
  56 import jdk.internal.classfile.impl.TemporaryConstantPool;
  57 
  58 import static java.util.Objects.requireNonNull;
  59 import static jdk.internal.constant.ConstantUtils.CD_module_info;
  60 
  61 /**
  62  * Provides ability to parse, transform, and generate {@code class} files.
  63  * A {@code ClassFile} is a context with a set of options that condition how
  64  * parsing and generation are done.
  65  *
  66  * @since 24
  67  */
  68 public sealed interface ClassFile
  69         permits ClassFileImpl {
  70 
  71     /**
  72      * {@return a context with default options}  Each subtype of {@link Option}
  73      * specifies its default.
  74      * <p>
  75      * The default {@link AttributeMapperOption} and {@link
  76      * ClassHierarchyResolverOption} may be unsuitable for some {@code class}
  77      * files and result in parsing or generation errors.
  78      */
  79     static ClassFile of() {
  80         return ClassFileImpl.DEFAULT_CONTEXT;
  81     }
  82 
  83     /**
  84      * {@return a context with options altered from the default}  Equivalent to
  85      * {@link #of() ClassFile.of().withOptions(options)}.
  86      * @param options the desired processing options
  87      */
  88     static ClassFile of(Option... options) {
  89         return of().withOptions(options);
  90     }
  91 
  92     /**
  93      * {@return a context with altered options from this context}
  94      * @param options the desired processing options
  95      */
  96     ClassFile withOptions(Option... options);
  97 
  98     /**
  99      * An option that affects the parsing or writing of {@code class} files.
 100      *
 101      * @see java.lang.classfile##options Options
 102      * @sealedGraph
 103      * @since 24
 104      */
 105     sealed interface Option {
 106     }
 107 
 108     /**
 109      * The option describing user-defined attributes for parsing {@code class}
 110      * files.  The default does not recognize any user-defined attribute.
 111      * <p>
 112      * An {@code AttributeMapperOption} contains a function that maps an
 113      * attribute name to a user attribute mapper. The function may return {@code
 114      * null} if it does not recognize an attribute name.  The returned mapper
 115      * must ensure its {@link AttributeMapper#name() name()} is equivalent to
 116      * the {@link Utf8Entry#stringValue() stringValue()} of the input {@link
 117      * Utf8Entry}.
 118      * <p>
 119      * The mapping function in this attribute has lower priority than mappers in
 120      * {@link Attributes}, so it is impossible to override built-in attributes
 121      * with this option.  If an attribute is not recognized by any mapper in
 122      * {@link Attributes} and is not assigned a mapper, or recognized, by this
 123      * option, that attribute will be modeled by an {@link UnknownAttribute}.
 124      *
 125      * @see AttributeMapper
 126      * @see CustomAttribute
 127      * @since 24
 128      */
 129     sealed interface AttributeMapperOption extends Option
 130             permits ClassFileImpl.AttributeMapperOptionImpl {
 131 
 132         /**
 133          * {@return an option describing user-defined attributes for parsing}
 134          *
 135          * @param attributeMapper a function mapping attribute names to attribute mappers
 136          */
 137         static AttributeMapperOption of(Function<Utf8Entry, AttributeMapper<?>> attributeMapper) {
 138             requireNonNull(attributeMapper);
 139             return new ClassFileImpl.AttributeMapperOptionImpl(attributeMapper);
 140         }
 141 
 142         /**
 143          * {@return the function mapping attribute names to attribute mappers}
 144          */
 145         Function<Utf8Entry, AttributeMapper<?>> attributeMapper();
 146     }
 147 
 148     /**
 149      * The option describing the class hierarchy resolver to use when generating
 150      * stack maps or verifying classes.  The default is {@link
 151      * ClassHierarchyResolver#defaultResolver()}, which uses core reflection to
 152      * find a class with a given name in {@linkplain ClassLoader#getSystemClassLoader()
 153      * system class loader} and inspect it, and is insufficient if a class is
 154      * not present in the system class loader as in applications, or if loading
 155      * of system classes is not desired as in agents.
 156      * <p>
 157      * A {@code ClassHierarchyResolverOption} contains a {@link ClassHierarchyResolver}.
 158      * The resolver must be able to process all classes and interfaces, including
 159      * those appearing as the component types of array types, that appear in the
 160      * operand stack of the generated bytecode.  If the resolver fails on any
 161      * of the classes and interfaces with an {@link IllegalArgumentException},
 162      * the {@code class} file generation fails.
 163      *
 164      * @see ClassHierarchyResolver
 165      * @jvms 4.10.1.2 Verification Type System
 166      * @since 24
 167      */
 168     sealed interface ClassHierarchyResolverOption extends Option
 169             permits ClassFileImpl.ClassHierarchyResolverOptionImpl {
 170 
 171         /**
 172          * {@return an option describing the class hierarchy resolver to use}
 173          *
 174          * @param classHierarchyResolver the resolver
 175          */
 176         static ClassHierarchyResolverOption of(ClassHierarchyResolver classHierarchyResolver) {
 177             requireNonNull(classHierarchyResolver);
 178             return new ClassFileImpl.ClassHierarchyResolverOptionImpl(classHierarchyResolver);
 179         }
 180 
 181         /**
 182          * {@return the class hierarchy resolver}
 183          */
 184         ClassHierarchyResolver classHierarchyResolver();
 185     }
 186 
 187     /**
 188      * Option describing whether to extend from the original constant pool when
 189      * transforming a {@code class} file.  The default is {@link #SHARED_POOL}
 190      * to extend from the original constant pool.
 191      * <p>
 192      * This option affects all overloads of {@link #transformClass transformClass}.
 193      * Extending from the original constant pool keeps the indices into the
 194      * constant pool intact, which enables significant optimizations in processing
 195      * time and minimizes differences between the original and transformed {@code
 196      * class} files, but may result in a bigger transformed {@code class} file
 197      * when many elements of the original {@code class} file are dropped and
 198      * many original constant pool entries become unused.
 199      * <p>
 200      * An alternative to this option is to use {@link #build(ClassEntry,
 201      * ConstantPoolBuilder, Consumer)} directly.  It allows extension from
 202      * arbitrary constant pools, and may be useful if a built {@code class} file
 203      * reuses structures from multiple original {@code class} files.
 204      *
 205      * @see ConstantPoolBuilder
 206      * @see #build(ClassEntry, ConstantPoolBuilder, Consumer)
 207      * @see #transformClass(ClassModel, ClassTransform)
 208      * @since 24
 209      */
 210     enum ConstantPoolSharingOption implements Option {
 211 
 212         /**
 213          * Extend the new constant pool from the original constant pool when
 214          * transforming the {@code class} file.
 215          * <p>
 216          * These two transformations below are equivalent:
 217          * {@snippet lang=java :
 218          * ClassModel originalClass = null; // @replace substring=null; replacement=...
 219          * ClassDesc resultClassName = null; // @replace substring=null; replacement=...
 220          * ClassTransform classTransform = null; // @replace substring=null; replacement=...
 221          * var resultOne = ClassFile.of(ConstantPoolSharingOption.SHARED_POOL)
 222          *         .transformClass(originalClass, resultClassName, classTransform);
 223          * var resultTwo = ClassFile.of().build(resultClassName, ConstantPoolBuilder.of(originalClass),
 224          *         clb -> clb.transform(originalClass, classTransform));
 225          * }
 226          *
 227          * @see ConstantPoolBuilder#of(ClassModel) ConstantPoolBuilder::of(ClassModel)
 228          */
 229         SHARED_POOL,
 230 
 231         /**
 232          * Creates a new constant pool when transforming the {@code class} file.
 233          * <p>
 234          * These two transformations below are equivalent:
 235          * {@snippet lang=java :
 236          * ClassModel originalClass = null; // @replace substring=null; replacement=...
 237          * ClassDesc resultClassName = null; // @replace substring=null; replacement=...
 238          * ClassTransform classTransform = null; // @replace substring=null; replacement=...
 239          * var resultOne = ClassFile.of(ConstantPoolSharingOption.NEW_POOL)
 240          *         .transformClass(originalClass, resultClassName, classTransform);
 241          * var resultTwo = ClassFile.of().build(resultClassName, ConstantPoolBuilder.of(),
 242          *         clb -> clb.transform(originalClass, classTransform));
 243          * }
 244          *
 245          * @see ConstantPoolBuilder#of() ConstantPoolBuilder::of()
 246          */
 247         NEW_POOL
 248     }
 249 
 250     /**
 251      * The option describing whether to patch out unreachable code for stack map
 252      * generation.  The default is {@link #PATCH_DEAD_CODE} to automatically
 253      * patch unreachable code and generate a valid stack map entry for the
 254      * patched code.
 255      * <p>
 256      * The stack map generation process may fail when it encounters unreachable
 257      * code and {@link #KEEP_DEAD_CODE} is set.  In such cases, users should
 258      * set {@link StackMapsOption#DROP_STACK_MAPS} and provide their own stack
 259      * maps that passes verification (JVMS {@jvms 4.10.1}).
 260      *
 261      * @see StackMapsOption
 262      * @jvms 4.10.1 Verification by Type Checking
 263      * @since 24
 264      */
 265     enum DeadCodeOption implements Option {
 266 
 267         /**
 268          * Patch unreachable code with dummy code, and generate valid dummy
 269          * stack map entries.  This ensures the generated code can pass
 270          * verification (JVMS {@jvms 4.10.1}).
 271          */
 272         PATCH_DEAD_CODE,
 273 
 274         /**
 275          * Keep the unreachable code for the accuracy of the generated {@code
 276          * class} file.  Users should set {@link StackMapsOption#DROP_STACK_MAPS}
 277          * to prevent stack map generation from running and provide their own
 278          * {@link StackMapTableAttribute} to a {@link CodeBuilder}.
 279          */
 280         KEEP_DEAD_CODE
 281     }
 282 
 283     /**
 284      * The option describing whether to filter {@linkplain
 285      * CodeBuilder#labelBinding(Label) unbound labels} and drop their
 286      * enclosing structures if possible.  The default is {@link
 287      * #FAIL_ON_DEAD_LABELS} to fail fast with an {@link IllegalArgumentException}
 288      * when a {@link PseudoInstruction} refers to an unbound label during
 289      * bytecode generation.
 290      * <p>
 291      * The affected {@link PseudoInstruction}s include {@link ExceptionCatch},
 292      * {@link LocalVariable}, {@link LocalVariableType}, and {@link
 293      * CharacterRange}.  Setting this option to {@link #DROP_DEAD_LABELS}
 294      * filters these pseudo-instructions from a {@link CodeBuilder} instead.
 295      * Note that instructions, such as {@link BranchInstruction}, with unbound
 296      * labels always fail-fast with an {@link IllegalArgumentException}.
 297      *
 298      * @see DebugElementsOption
 299      * @since 24
 300      */
 301     enum DeadLabelsOption implements Option {
 302 
 303         /**
 304          * Fail fast on {@linkplain CodeBuilder#labelBinding(Label) unbound
 305          * labels}.  This also ensures the accuracy of the generated {@code
 306          * class} files.
 307          */
 308         FAIL_ON_DEAD_LABELS,
 309 
 310         /**
 311          * Filter {@link PseudoInstruction}s with {@linkplain
 312          * CodeBuilder#labelBinding(Label) unbound labels}.  Note that
 313          * instructions with unbound labels still cause an {@link
 314          * IllegalArgumentException}.
 315          */
 316         DROP_DEAD_LABELS
 317     }
 318 
 319     /**
 320      * The option describing whether to process or discard debug {@link
 321      * PseudoInstruction}s in the traversal of a {@link CodeModel} or a {@link
 322      * CodeBuilder}.  The default is {@link #PASS_DEBUG} to process debug
 323      * pseudo-instructions as all other {@link CodeElement}.
 324      * <p>
 325      * Debug pseudo-instructions include {@link LocalVariable}, {@link
 326      * LocalVariableType}, and {@link CharacterRange}.  Discarding debug
 327      * elements may reduce the overhead of parsing or transforming {@code class}
 328      * files and has no impact on the run-time behavior.
 329      *
 330      * @see LineNumbersOption
 331      * @since 24
 332      */
 333     enum DebugElementsOption implements Option {
 334 
 335         /**
 336          * Process debug pseudo-instructions like other member elements of a
 337          * {@link CodeModel}.
 338          */
 339         PASS_DEBUG,
 340 
 341         /**
 342          * Drop debug pseudo-instructions from traversal and builders.
 343          */
 344         DROP_DEBUG
 345     }
 346 
 347     /**
 348      * The option describing whether to process or discard {@link LineNumber}s
 349      * in the traversal of a {@link CodeModel} or a {@link CodeBuilder}.  The
 350      * default is {@link #PASS_LINE_NUMBERS} to process all line number entries
 351      * as all other {@link CodeElement}.
 352      * <p>
 353      * Discarding line numbers may reduce the overhead of parsing or transforming
 354      * {@code class} files and has no impact on the run-time behavior.
 355      *
 356      * @see DebugElementsOption
 357      * @since 24
 358      */
 359     enum LineNumbersOption implements Option {
 360 
 361         /**
 362          * Process {@link LineNumber} like other member elements of a {@link
 363          * CodeModel}.
 364          */
 365         PASS_LINE_NUMBERS,
 366 
 367         /**
 368          * Drop {@link LineNumber} from traversal and builders.
 369          */
 370         DROP_LINE_NUMBERS;
 371     }
 372 
 373     /**
 374      * The option describing whether to automatically rewrite short jumps to
 375      * equivalent instructions when necessary.  The default is {@link
 376      * #FIX_SHORT_JUMPS} to automatically rewrite.
 377      * <p>
 378      * Due to physical restrictions, some types of instructions cannot encode
 379      * certain jump targets with bci offsets less than -32768 or greater than
 380      * 32767, as they use a {@code s2} to encode such an offset.  (The maximum
 381      * length of the {@code code} array is 65535.)  These types of instructions
 382      * are called "short jumps".
 383      * <p>
 384      * Disabling rewrite can ensure the physical accuracy of a generated {@code
 385      * class} file and avoid the overhead from a failed first attempt for
 386      * overflowing forward jumps in some cases, if the generated {@code class}
 387      * file is stable.
 388      *
 389      * @see BranchInstruction
 390      * @see DiscontinuedInstruction.JsrInstruction
 391      * @since 24
 392      */
 393     enum ShortJumpsOption implements Option {
 394 
 395         /**
 396          * Automatically convert short jumps to long when necessary.
 397          * <p>
 398          * For an invalid instruction model, a {@link CodeBuilder} may generate
 399          * another or a few other instructions to accomplish the same effect.
 400          */
 401         FIX_SHORT_JUMPS,
 402 
 403         /**
 404          * Fail with an {@link IllegalArgumentException} if short jump overflows.
 405          * <p>
 406          * This is useful to ensure the physical accuracy of a generated {@code
 407          * class} file and avoids the overhead from a failed first attempt for
 408          * overflowing forward jumps in some cases.
 409          */
 410         FAIL_ON_SHORT_JUMPS
 411     }
 412 
 413     /**
 414      * The option describing whether to generate stack maps.  The default is
 415      * {@link #STACK_MAPS_WHEN_REQUIRED} to generate stack maps or reuse
 416      * existing ones if compatible.
 417      * <p>
 418      * The {@link StackMapTableAttribute} is a derived property from a {@link
 419      * CodeAttribute Code} attribute to allow a Java Virtual Machine to perform
 420      * verification in one pass.  Thus, it is not modeled as part of a {@link
 421      * CodeModel}, but computed on-demand instead via stack maps generation.
 422      * <p>
 423      * Stack map generation may fail with an {@link IllegalArgumentException} if
 424      * there is {@linkplain DeadCodeOption unreachable code} or legacy
 425      * {@linkplain DiscontinuedInstruction.JsrInstruction jump routine}
 426      * instructions.  When {@link #DROP_STACK_MAPS} option is used, users can
 427      * provide their own stack maps by supplying a {@link StackMapTableAttribute}
 428      * to a {@link CodeBuilder}.
 429      *
 430      * @see StackMapTableAttribute
 431      * @see DeadCodeOption
 432      * @jvms 4.10.1 Verification by Type Checking
 433      * @since 24
 434      */
 435     enum StackMapsOption implements Option {
 436 
 437         /**
 438          * Generate stack maps or reuse existing ones if compatible.  Stack maps
 439          * are present on major versions {@value #JAVA_6_VERSION} or above.  For
 440          * these versions, {@link CodeBuilder} tries to reuse compatible stack
 441          * maps information if the code array and exception handlers are still
 442          * compatible after a transformation; otherwise, it runs stack map
 443          * generation.  However, it does not fail fast if the major version is
 444          * {@value #JAVA_6_VERSION}, which allows jump subroutine instructions
 445          * that are incompatible with stack maps to exist in the {@code code}
 446          * array.
 447          */
 448         STACK_MAPS_WHEN_REQUIRED,
 449 
 450         /**
 451          * Forces running stack map generation.  This runs stack map generation
 452          * unconditionally and fails fast if the generation fails due to any
 453          * reason.
 454          */
 455         GENERATE_STACK_MAPS,
 456 
 457         /**
 458          * Do not run stack map generation.  Users must supply their own
 459          * {@link StackMapTableAttribute} to a {@link CodeBuilder} if the code
 460          * has branches or exception handlers; otherwise, the generated code
 461          * will fail verification (JVMS {@jvms 4.10.1}).
 462          * <p>
 463          * This option is required for user-supplied {@link StackMapTableAttribute}
 464          * to be respected.  Stack maps on an existing {@link CodeAttribute Code}
 465          * attribute can be reused as below with this option:
 466          * {@snippet lang=java file="PackageSnippets.java" region="manual-reuse-stack-maps"}
 467          */
 468         DROP_STACK_MAPS
 469     }
 470 
 471     /**
 472      * The option describing whether to retain or discard attributes that cannot
 473      * verify their correctness after a transformation.  The default is {@link
 474      * #PASS_ALL_ATTRIBUTES} to retain all attributes as-is.
 475      * <p>
 476      * Many attributes only depend on data managed by the Class-File API, such
 477      * as constant pool entries or labels into the {@code code} array.  If they
 478      * change, the Class-File API knows their updated values and can write a
 479      * correct version by expanding the structures and recomputing the updated
 480      * indexes, known as "explosion".  However, some attributes, such as type
 481      * annotations, depend on arbitrary data that may be modified during
 482      * transformations but the Class-File API does not track, such as index to
 483      * an entry in the {@linkplain ClassModel#interfaces() interfaces} of a
 484      * {@code ClassFile} structure.  As a result, the Class-File API cannot
 485      * verify the correctness of such information.
 486      *
 487      * @see AttributeStability
 488      * @since 24
 489      */
 490     enum AttributesProcessingOption implements Option {
 491 
 492         /**
 493          * Retain all original attributes during transformation.
 494          */
 495         PASS_ALL_ATTRIBUTES,
 496 
 497         /**
 498          * Drop attributes with {@link AttributeStability#UNKNOWN} data
 499          * dependency during transformation.
 500          */
 501         DROP_UNKNOWN_ATTRIBUTES,
 502 
 503         /**
 504          * Drop attributes with {@link AttributeStability#UNSTABLE} or higher
 505          * data dependency during transformation.
 506          */
 507         DROP_UNSTABLE_ATTRIBUTES
 508     }
 509 
 510     /**
 511      * Parses a {@code class} file into a {@link ClassModel}.
 512      * <p>
 513      * Due to the on-demand nature of {@code class} file parsing, an {@link
 514      * IllegalArgumentException} may be thrown on any accessor method invocation
 515      * on the returned model or any structure returned by the accessors in the
 516      * structure hierarchy.
 517      *
 518      * @param bytes the bytes of the {@code class} file
 519      * @return the class model
 520      * @throws IllegalArgumentException if the {@code class} file is malformed
 521      *         or of a version {@linkplain #latestMajorVersion() not supported}
 522      *         by the current runtime
 523      */
 524     ClassModel parse(byte[] bytes);
 525 
 526     /**
 527      * Parses a {@code class} into a {@link ClassModel}.
 528      * <p>
 529      * Due to the on-demand nature of {@code class} file parsing, an {@link
 530      * IllegalArgumentException} may be thrown on any accessor method invocation
 531      * on the returned model or any structure returned by the accessors in the
 532      * structure hierarchy.
 533      *
 534      * @param path the path to the {@code class} file
 535      * @return the class model
 536      * @throws IOException if an I/O error occurs
 537      * @throws IllegalArgumentException if the {@code class} file is malformed
 538      *         or of a version {@linkplain #latestMajorVersion() not supported}
 539      *         by the current runtime
 540      * @see #parse(byte[])
 541      */
 542     default ClassModel parse(Path path) throws IOException {
 543         return parse(Files.readAllBytes(path));
 544     }
 545 
 546     /**
 547      * Builds a {@code class} file into a byte array.
 548      *
 549      * @param thisClass the name of the class to build
 550      * @param handler a handler that receives a {@link ClassBuilder}
 551      * @return the {@code class} file bytes
 552      * @throws IllegalArgumentException if {@code thisClass} represents a
 553      *         primitive type or building encounters a failure
 554      */
 555     default byte[] build(ClassDesc thisClass,
 556                          Consumer<? super ClassBuilder> handler) {
 557         ConstantPoolBuilder pool = ConstantPoolBuilder.of();
 558         return build(pool.classEntry(thisClass), pool, handler);
 559     }
 560 
 561     /**
 562      * Builds a {@code class} file into a byte array using the provided constant
 563      * pool builder.
 564      *
 565      * @param thisClassEntry the name of the class to build
 566      * @param constantPool the constant pool builder
 567      * @param handler a handler that receives a {@link ClassBuilder}
 568      * @return the {@code class} file bytes
 569      * @throws IllegalArgumentException if building encounters a failure
 570      */
 571     byte[] build(ClassEntry thisClassEntry,
 572                  ConstantPoolBuilder constantPool,
 573                  Consumer<? super ClassBuilder> handler);
 574 
 575     /**
 576      * Builds a {@code class} file into a file in a file system.
 577      *
 578      * @param path the path to the file to write
 579      * @param thisClass the name of the class to build
 580      * @param handler a handler that receives a {@link ClassBuilder}
 581      * @throws IOException if an I/O error occurs
 582      * @throws IllegalArgumentException if building encounters a failure
 583      */
 584     default void buildTo(Path path,
 585                          ClassDesc thisClass,
 586                          Consumer<ClassBuilder> handler) throws IOException {
 587         Files.write(path, build(thisClass, handler));
 588     }
 589 
 590     /**
 591      * Builds a {@code class} file into a file in a file system using the
 592      * provided constant pool builder.
 593      *
 594      * @param path the path to the file to write
 595      * @param thisClassEntry the name of the class to build
 596      * @param constantPool the constant pool builder
 597      * @param handler a handler that receives a {@link ClassBuilder}
 598      * @throws IOException if an I/O error occurs
 599      * @throws IllegalArgumentException if building encounters a failure
 600      */
 601     default void buildTo(Path path,
 602                          ClassEntry thisClassEntry,
 603                          ConstantPoolBuilder constantPool,
 604                          Consumer<? super ClassBuilder> handler) throws IOException {
 605         Files.write(path, build(thisClassEntry, constantPool, handler));
 606     }
 607 
 608     /**
 609      * Builds a module descriptor into a byte array.
 610      *
 611      * @param moduleAttribute the {@code Module} attribute
 612      * @return the {@code class} file bytes
 613      * @throws IllegalArgumentException if building encounters a failure
 614      */
 615     default byte[] buildModule(ModuleAttribute moduleAttribute) {
 616         return buildModule(moduleAttribute, clb -> {});
 617     }
 618 
 619     /**
 620      * Builds a module descriptor into a byte array.
 621      *
 622      * @param moduleAttribute the {@code Module} attribute
 623      * @param handler a handler that receives a {@link ClassBuilder}
 624      * @return the {@code class} file bytes
 625      * @throws IllegalArgumentException if building encounters a failure
 626      */
 627     default byte[] buildModule(ModuleAttribute moduleAttribute,
 628                                Consumer<? super ClassBuilder> handler) {
 629         return build(CD_module_info, clb -> {
 630             clb.withFlags(AccessFlag.MODULE);
 631             clb.with(moduleAttribute);
 632             handler.accept(clb);
 633         });
 634     }
 635 
 636     /**
 637      * Builds a module descriptor into a file in a file system.
 638      *
 639      * @param path the file to write
 640      * @param moduleAttribute the {@code Module} attribute
 641      * @throws IOException if an I/O error occurs
 642      * @throws IllegalArgumentException if building encounters a failure
 643      */
 644     default void buildModuleTo(Path path,
 645                                      ModuleAttribute moduleAttribute) throws IOException {
 646         buildModuleTo(path, moduleAttribute, clb -> {});
 647     }
 648 
 649     /**
 650      * Builds a module descriptor into a file in a file system.
 651      *
 652      * @param path the file to write
 653      * @param moduleAttribute the {@code Module} attribute
 654      * @param handler a handler that receives a {@link ClassBuilder}
 655      * @throws IOException if an I/O error occurs
 656      * @throws IllegalArgumentException if building encounters a failure
 657      */
 658     default void buildModuleTo(Path path,
 659                                      ModuleAttribute moduleAttribute,
 660                                      Consumer<? super ClassBuilder> handler) throws IOException {
 661         Files.write(path, buildModule(moduleAttribute, handler));
 662     }
 663 
 664     /**
 665      * Transform one {@code class} file into a new {@code class} file according
 666      * to a {@link ClassTransform}.  The transform will receive each element of
 667      * this class, as well as a {@link ClassBuilder} for building the new class.
 668      * The transform is free to preserve, remove, or replace elements as it
 669      * sees fit.
 670      * <p>
 671      * This method behaves as if:
 672      * {@snippet lang=java :
 673      * ConstantPoolBuilder cpb = null; // @replace substring=null; replacement=...
 674      * this.build(model.thisClass(), cpb,
 675      *            clb -> clb.transform(model, transform));
 676      * }
 677      * where {@code cpb} is determined by {@link ConstantPoolSharingOption}.
 678      *
 679      * @apiNote
 680      * This is named {@code transformClass} instead of {@code transform} for
 681      * consistency with {@link ClassBuilder#transformField}, {@link
 682      * ClassBuilder#transformMethod}, and {@link MethodBuilder#transformCode},
 683      * and to distinguish from {@link ClassFileBuilder#transform}, which is
 684      * more generic and powerful.
 685      *
 686      * @param model the class model to transform
 687      * @param transform the transform
 688      * @return the bytes of the new class
 689      * @throws IllegalArgumentException if building encounters a failure
 690      * @see ConstantPoolSharingOption
 691      */
 692     default byte[] transformClass(ClassModel model, ClassTransform transform) {
 693         return transformClass(model, model.thisClass(), transform);
 694     }
 695 
 696     /**
 697      * Transform one {@code class} file into a new {@code class} file according
 698      * to a {@link ClassTransform}.  The transform will receive each element of
 699      * this class, as well as a {@link ClassBuilder} for building the new class.
 700      * The transform is free to preserve, remove, or replace elements as it
 701      * sees fit.
 702      *
 703      * @apiNote
 704      * This is named {@code transformClass} instead of {@code transform} for
 705      * consistency with {@link ClassBuilder#transformField}, {@link
 706      * ClassBuilder#transformMethod}, and {@link MethodBuilder#transformCode},
 707      * and to distinguish from {@link ClassFileBuilder#transform}, which is
 708      * more generic and powerful.
 709      *
 710      * @param model the class model to transform
 711      * @param newClassName new class name
 712      * @param transform the transform
 713      * @return the bytes of the new class
 714      * @throws IllegalArgumentException if building encounters a failure
 715      * @see ConstantPoolSharingOption
 716      */
 717     default byte[] transformClass(ClassModel model, ClassDesc newClassName, ClassTransform transform) {
 718         return transformClass(model, TemporaryConstantPool.INSTANCE.classEntry(newClassName), transform);
 719     }
 720 
 721     /**
 722      * Transform one {@code class} file into a new {@code class} file according
 723      * to a {@link ClassTransform}.  The transform will receive each element of
 724      * this class, as well as a {@link ClassBuilder} for building the new class.
 725      * The transform is free to preserve, remove, or replace elements as it
 726      * sees fit.
 727      * <p>
 728      * This method behaves as if:
 729      * {@snippet lang=java :
 730      * ConstantPoolBuilder cpb = null; // @replace substring=null; replacement=...
 731      * this.build(newClassName, cpb, clb -> clb.transform(model, transform));
 732      * }
 733      * where {@code cpb} is determined by {@link ConstantPoolSharingOption}.
 734      *
 735      * @apiNote
 736      * This is named {@code transformClass} instead of {@code transform} for
 737      * consistency with {@link ClassBuilder#transformField}, {@link
 738      * ClassBuilder#transformMethod}, and {@link MethodBuilder#transformCode},
 739      * and to distinguish from {@link ClassFileBuilder#transform}, which is
 740      * more generic and powerful.
 741      *
 742      * @param model the class model to transform
 743      * @param newClassName new class name
 744      * @param transform the transform
 745      * @return the bytes of the new class
 746      * @throws IllegalArgumentException if building encounters a failure
 747      * @see ConstantPoolSharingOption
 748      */
 749     byte[] transformClass(ClassModel model, ClassEntry newClassName, ClassTransform transform);
 750 
 751     /**
 752      * Verify a {@code class} file.  All verification errors found will be returned.
 753      *
 754      * @param model the class model to verify
 755      * @return a list of verification errors, or an empty list if no error is
 756      * found
 757      */
 758     List<VerifyError> verify(ClassModel model);
 759 
 760     /**
 761      * Verify a {@code class} file.  All verification errors found will be returned.
 762      *
 763      * @param bytes the {@code class} file bytes to verify
 764      * @return a list of verification errors, or an empty list if no error is
 765      * found
 766      */
 767     List<VerifyError> verify(byte[] bytes);
 768 
 769     /**
 770      * Verify a {@code class} file.  All verification errors found will be returned.
 771      *
 772      * @param path the {@code class} file path to verify
 773      * @return a list of verification errors, or an empty list if no error is
 774      * found
 775      * @throws IOException if an I/O error occurs
 776      */
 777     default List<VerifyError> verify(Path path) throws IOException {
 778         return verify(Files.readAllBytes(path));
 779     }
 780 
 781     /**
 782      * The magic number identifying the {@code class} file format,  {@value
 783      * "0x%04x" #MAGIC_NUMBER}.  It is a big-endian 4-byte value.
 784      */
 785     int MAGIC_NUMBER = 0xCAFEBABE;
 786 
 787     /** The bit mask of {@link AccessFlag#PUBLIC} access and property modifier. */
 788     int ACC_PUBLIC = 0x0001;
 789 
 790     /** The bit mask of {@link AccessFlag#PROTECTED} access and property modifier. */
 791     int ACC_PROTECTED = 0x0004;
 792 
 793     /** The bit mask of {@link AccessFlag#PRIVATE} access and property modifier. */
 794     int ACC_PRIVATE = 0x0002;
 795 
 796     /** The bit mask of {@link AccessFlag#INTERFACE} access and property modifier. */
 797     int ACC_INTERFACE = 0x0200;
 798 
 799     /** The bit mask of {@link AccessFlag#ENUM} access and property modifier. */
 800     int ACC_ENUM = 0x4000;
 801 
 802     /** The bit mask of {@link AccessFlag#ANNOTATION} access and property modifier. */
 803     int ACC_ANNOTATION = 0x2000;
 804 
 805     /** The bit mask of {@link AccessFlag#SUPER} access and property modifier. */
 806     int ACC_SUPER = 0x0020;
 807 
 808     /** The bit mask of {@link AccessFlag#IDENTITY} access and property modifier. */
 809     int ACC_IDENTITY = 0x0020;
 810 
 811     /** The bit mask of {@link AccessFlag#ABSTRACT} access and property modifier. */
 812     int ACC_ABSTRACT = 0x0400;
 813 
 814     /** The bit mask of {@link AccessFlag#VOLATILE} access and property modifier. */
 815     int ACC_VOLATILE = 0x0040;
 816 
 817     /** The bit mask of {@link AccessFlag#TRANSIENT} access and property modifier. */
 818     int ACC_TRANSIENT = 0x0080;
 819 
 820     /** The bit mask of {@link AccessFlag#SYNTHETIC} access and property modifier. */
 821     int ACC_SYNTHETIC = 0x1000;
 822 
 823     /** The bit mask of {@link AccessFlag#STATIC} access and property modifier. */
 824     int ACC_STATIC = 0x0008;
 825 
 826     /** The bit mask of {@link AccessFlag#FINAL} access and property modifier. */
 827     int ACC_FINAL = 0x0010;
 828 
 829     /** The bit mask of {@link AccessFlag#SYNCHRONIZED} access and property modifier. */
 830     int ACC_SYNCHRONIZED = 0x0020;
 831 
 832     /** The bit mask of {@link AccessFlag#BRIDGE} access and property modifier. */
 833     int ACC_BRIDGE = 0x0040;
 834 
 835     /** The bit mask of {@link AccessFlag#VARARGS} access and property modifier. */
 836     int ACC_VARARGS = 0x0080;
 837 
 838     /** The bit mask of {@link AccessFlag#NATIVE} access and property modifier. */
 839     int ACC_NATIVE = 0x0100;
 840 
 841     /** The bit mask of {@link AccessFlag#STRICT} access and property modifier. */
 842     int ACC_STRICT = 0x0800;
 843 
 844     /** The bit mask of {@link AccessFlag#MODULE} access and property modifier. */
 845     int ACC_MODULE = 0x8000;
 846 
 847     /** The bit mask of {@link AccessFlag#OPEN} access and property modifier. */
 848     int ACC_OPEN = 0x20;
 849 
 850     /** The bit mask of {@link AccessFlag#MANDATED} access and property modifier. */
 851     int ACC_MANDATED = 0x8000;
 852 
 853     /** The bit mask of {@link AccessFlag#TRANSITIVE} access and property modifier. */
 854     int ACC_TRANSITIVE = 0x20;
 855 
 856     /** The bit mask of {@link AccessFlag#STATIC_PHASE} access and property modifier. */
 857     int ACC_STATIC_PHASE = 0x40;
 858 
 859     /**
 860      * The class major version of the initial version of Java, {@value}.
 861      *
 862      * @see ClassFileFormatVersion#RELEASE_0
 863      * @see ClassFileFormatVersion#RELEASE_1
 864      */
 865     int JAVA_1_VERSION = 45;
 866 
 867     /**
 868      * The class major version introduced by Java 2 SE 1.2, {@value}.
 869      *
 870      * @see ClassFileFormatVersion#RELEASE_2
 871      */
 872     int JAVA_2_VERSION = 46;
 873 
 874     /**
 875      * The class major version introduced by Java 2 SE 1.3, {@value}.
 876      *
 877      * @see ClassFileFormatVersion#RELEASE_3
 878      */
 879     int JAVA_3_VERSION = 47;
 880 
 881     /**
 882      * The class major version introduced by Java 2 SE 1.4, {@value}.
 883      *
 884      * @see ClassFileFormatVersion#RELEASE_4
 885      */
 886     int JAVA_4_VERSION = 48;
 887 
 888     /**
 889      * The class major version introduced by Java 2 SE 5.0, {@value}.
 890      *
 891      * @see ClassFileFormatVersion#RELEASE_5
 892      */
 893     int JAVA_5_VERSION = 49;
 894 
 895     /**
 896      * The class major version introduced by Java SE 6, {@value}.
 897      *
 898      * @see ClassFileFormatVersion#RELEASE_6
 899      */
 900     int JAVA_6_VERSION = 50;
 901 
 902     /**
 903      * The class major version introduced by Java SE 7, {@value}.
 904      *
 905      * @see ClassFileFormatVersion#RELEASE_7
 906      */
 907     int JAVA_7_VERSION = 51;
 908 
 909     /**
 910      * The class major version introduced by Java SE 8, {@value}.
 911      *
 912      * @see ClassFileFormatVersion#RELEASE_8
 913      */
 914     int JAVA_8_VERSION = 52;
 915 
 916     /**
 917      * The class major version introduced by Java SE 9, {@value}.
 918      *
 919      * @see ClassFileFormatVersion#RELEASE_9
 920      */
 921     int JAVA_9_VERSION = 53;
 922 
 923     /**
 924      * The class major version introduced by Java SE 10, {@value}.
 925      *
 926      * @see ClassFileFormatVersion#RELEASE_10
 927      */
 928     int JAVA_10_VERSION = 54;
 929 
 930     /**
 931      * The class major version introduced by Java SE 11, {@value}.
 932      *
 933      * @see ClassFileFormatVersion#RELEASE_11
 934      */
 935     int JAVA_11_VERSION = 55;
 936 
 937     /**
 938      * The class major version introduced by Java SE 12, {@value}.
 939      *
 940      * @see ClassFileFormatVersion#RELEASE_12
 941      */
 942     int JAVA_12_VERSION = 56;
 943 
 944     /**
 945      * The class major version introduced by Java SE 13, {@value}.
 946      *
 947      * @see ClassFileFormatVersion#RELEASE_13
 948      */
 949     int JAVA_13_VERSION = 57;
 950 
 951     /**
 952      * The class major version introduced by Java SE 14, {@value}.
 953      *
 954      * @see ClassFileFormatVersion#RELEASE_14
 955      */
 956     int JAVA_14_VERSION = 58;
 957 
 958     /**
 959      * The class major version introduced by Java SE 15, {@value}.
 960      *
 961      * @see ClassFileFormatVersion#RELEASE_15
 962      */
 963     int JAVA_15_VERSION = 59;
 964 
 965     /**
 966      * The class major version introduced by Java SE 16, {@value}.
 967      *
 968      * @see ClassFileFormatVersion#RELEASE_16
 969      */
 970     int JAVA_16_VERSION = 60;
 971 
 972     /**
 973      * The class major version introduced by Java SE 17, {@value}.
 974      *
 975      * @see ClassFileFormatVersion#RELEASE_17
 976      */
 977     int JAVA_17_VERSION = 61;
 978 
 979     /**
 980      * The class major version introduced by Java SE 18, {@value}.
 981      *
 982      * @see ClassFileFormatVersion#RELEASE_18
 983      */
 984     int JAVA_18_VERSION = 62;
 985 
 986     /**
 987      * The class major version introduced by Java SE 19, {@value}.
 988      *
 989      * @see ClassFileFormatVersion#RELEASE_19
 990      */
 991     int JAVA_19_VERSION = 63;
 992 
 993     /**
 994      * The class major version introduced by Java SE 20, {@value}.
 995      *
 996      * @see ClassFileFormatVersion#RELEASE_20
 997      */
 998     int JAVA_20_VERSION = 64;
 999 
1000     /**
1001      * The class major version introduced by Java SE 21, {@value}.
1002      *
1003      * @see ClassFileFormatVersion#RELEASE_21
1004      */
1005     int JAVA_21_VERSION = 65;
1006 
1007     /**
1008      * The class major version introduced by Java SE 22, {@value}.
1009      *
1010      * @see ClassFileFormatVersion#RELEASE_22
1011      */
1012     int JAVA_22_VERSION = 66;
1013 
1014     /**
1015      * The class major version introduced by Java SE 23, {@value}.
1016      *
1017      * @see ClassFileFormatVersion#RELEASE_23
1018      */
1019     int JAVA_23_VERSION = 67;
1020 
1021     /**
1022      * The class major version introduced by Java SE 24, {@value}.
1023      *
1024      * @see ClassFileFormatVersion#RELEASE_24
1025      */
1026     int JAVA_24_VERSION = 68;
1027 
1028     /**
1029      * The class major version introduced by Java SE 25, {@value}.
1030      *
1031      * @see ClassFileFormatVersion#RELEASE_25
1032      * @since 25
1033      */
1034     int JAVA_25_VERSION = 69;
1035 
1036     /**
1037      * A minor version number {@value} indicating a class uses preview features
1038      * of a Java SE release since 12, for major versions {@value
1039      * #JAVA_12_VERSION} and above.
1040      */
1041     int PREVIEW_MINOR_VERSION = 65535;
1042 
1043     /**
1044      * {@return the latest class major version supported by the current runtime}
1045      */
1046     static int latestMajorVersion() {
1047         return JAVA_25_VERSION;
1048     }
1049 
1050     /**
1051      * {@return the latest class minor version supported by the current runtime}
1052      *
1053      * @apiNote
1054      * This does not report the {@link #PREVIEW_MINOR_VERSION} when the current
1055      * runtime has preview feature enabled, as {@code class} files with a major
1056      * version other than {@link #latestMajorVersion()} and the preview minor
1057      * version are not supported.
1058      */
1059     static int latestMinorVersion() {
1060         return 0;
1061     }
1062 
1063 }