/* * 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:
*
* 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:
*
* 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();
}
*
*
*
*
* @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.
*
*
*
*
*
* @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}
*