/* * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package java.lang.classfile; import java.lang.classfile.attribute.BootstrapMethodsAttribute; import java.lang.classfile.attribute.CodeAttribute; import java.lang.classfile.attribute.UnknownAttribute; import java.lang.classfile.constantpool.ConstantPoolBuilder; import java.lang.classfile.constantpool.Utf8Entry; /** * Bidirectional mapper between the {@code class} file representation of an * attribute and its API model. The attribute mapper identifies an attribute * by its {@linkplain Attribute#attributeName name}, and is used to parse the * {@code class} file representation into a model, and to write the model * representation back to a {@code class} file. *

* {@link Attributes} defines the mappers for predefined attributes in the JVMS * and certain conventional attributes. For other attributes (JVMS {@jvms * 4.7.1}), users can define their own {@code AttributeMapper}; classes that * model those attributes should extend {@link CustomAttribute}. To read those * attributes, user-defined {@code AttributeMapper}s must be registered to the * {@link ClassFile.AttributeMapperOption}. * * @param the attribute type * @see Attributes * @see ClassFile.AttributeMapperOption * @see java.lang.classfile.attribute * @since 24 */ public interface AttributeMapper> { /** * Indicates the data dependency of the {@code class} file representation * of an attribute. Whether an attribute can be bulk-copied by its binary * representation to a new {@code class} file depends on if its data refers * to other parts of its enclosing {@code class} file. * * @apiNote * This dependency is called "stability" because it indicates the conditions * for a {@code class} file attribute to be eligible for bulk-copying to * another {@code class} file. * * @see AttributeMapper#stability() * @since 24 */ enum AttributeStability { /** * The attribute contains only standalone data, and has no reference to * other parts of its enclosing {@code class} file, besides the name of * the attribute. Thus, its contents can always be bulk-copied to * another {@code class} file. *

* For example, a bit mask is standalone data. */ STATELESS, /** * In addition to standalone data, the attribute refers to the constant * pool, including the {@link BootstrapMethodsAttribute BootstrapMethods} * attribute, of its enclosing {@code class} file. Thus, it can be * bulk-copied when the destination {@code class} file extends its * constant pool from that of the original {@code class}. It must be * expanded to translate constant pool references and rewritten when * constant pool indices are not compatible. *

* For example, a {@link Utf8Entry} is a reference to the constant pool. * * @see ConstantPoolBuilder#of(ClassModel) * @see ClassFile.ConstantPoolSharingOption */ CP_REFS, /** * In addition to standalone data and references to the constant pool, * the attribute refers to positions into the {@code code} array of a * {@link CodeAttribute Code} attribute. Thus, it can be bulked-copied * when the {@code code} array is unchanged, which requires that the * destination {@code class} file extends its constant pool from that of * the original {@code class}. It must be expanded to translate {@link * Label}s or constant pool references and rewritten if the {@code code} * array is perturbed, including when constant pool indices are not * compatible. *

* For example, a bci value, modeled by a {@link Label}, is a reference * to a position in the {@code code} array. */ LABELS, /** * The attribute refers to structures not managed by the library (type * variable lists, etc.). As a result, even when the attribute is * expanded, those references may not be correctly translated, and the * rewritten results may be incorrect. *

* If the attribute is read from a {@code class} file, {@link * ClassFile.AttributesProcessingOption} determines whether to preserve * or drop the attribute during transformation. * * @see ClassFile.AttributesProcessingOption#DROP_UNSTABLE_ATTRIBUTES */ UNSTABLE, /** * The attribute is completely unknown. As a result, expanding and * rewriting is not possible, and any difference between the destination * {@code class} file and its enclosing {@code class} file may make the * attribute incorrect. *

* {@link ClassFile.AttributesProcessingOption} determines whether to * preserve or drop the attribute during transformation. * * @see UnknownAttribute * @see ClassFile.AttributesProcessingOption#DROP_UNSTABLE_ATTRIBUTES * @see ClassFile.AttributesProcessingOption#DROP_UNKNOWN_ATTRIBUTES */ UNKNOWN } /** * {@return the name of the attribute} */ String name(); /** * Creates an {@link Attribute} instance from a {@code class} file for the * Class-File API. *

* This method is called by the Class-File API to support reading of * attributes. Users should never call this method. *

* The Class-File API makes these promises about the call to this method: *

*

* The returned {@code Attribute} must fulfill these requirements: *

* * @apiNote * Implementations of this method should perform minimal work to return an * attribute, as this method is called even if the resulting attribute is * never used. In particular, the implementation should avoid checking the * validity of the attribute {@code class} file data or performing actions * that may throw exceptions. * * @param enclosing the structure in which this attribute appears * @param cf provides access to the {@code class} file to read from * @param pos the offset into the {@code class} file at which the contents * of the attribute starts * @return the read attribute */ A readAttribute(AttributedElement enclosing, ClassReader cf, int pos); /** * Writes an {@link Attribute} instance to a {@code class} file for the * Class-File API. *

* This method is called by the Class-File API to support writing of * attributes. Users should never call this method. *

* The Class-File API makes these promises about the call to this method: *

*

* The {@code class} file writing must fulfill these requirements: *

* * @apiNote * {@link BufWriter#patchInt} can be used to update the attribute length * after the attribute contents are written to the {@code buf}. * * @param buf the {@link BufWriter} to which the attribute should be written * @param attr the attribute to write * @throws IllegalArgumentException if some data in the API model of the * attribute is invalid for the {@code class} file format */ void writeAttribute(BufWriter buf, A attr); /** * {@return whether this attribute may appear more than once in one * structure} *

* If an attribute does not allow multiple instances in one structure, * can be supplied to a {@link ClassFileBuilder}, and multiple instances of * the attribute are supplied to the builder, the last supplied attribute * appears on the built structure. * * @implSpec The default implementation returns {@code false}. */ default boolean allowMultiple() { return false; } /** * {@return the data dependency of this attribute on the {@code class} file} */ AttributeStability stability(); }