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