# Interface AttributeMapper<A extends Attribute<A>>

Type Parameters:
  `A` - the attribute type

public interface AttributeMapper<A extends Attribute<A>>
Bidirectional mapper between the `class` file representation of an attribute and its API model. The attribute mapper identifies an attribute by its name, and is used to parse the `class` file representation into a model, and to write the model representation back to a `class` file.

`Attributes` defines the mappers for predefined attributes in the JVMS and certain conventional attributes. For other attributes (JVMS §4.7.1), users can define their own `AttributeMapper`; classes that model those attributes should extend `CustomAttribute`. To read those attributes, user-defined `AttributeMapper`s must be registered to the `ClassFile.AttributeMapperOption`.

Since:
  24
See Also:
  - `Attributes`
  - `ClassFile.AttributeMapperOption`
  - `java.lang.classfile.attribute`

## Nested Class Summary

Nested Classes
Modifier and Type
Interface
Description
`static enum`
`AttributeMapper.AttributeStability`
Indicates the data dependency of the `class` file representation of an attribute.

## Method Summary

Modifier and Type
Method
Description
`default boolean`
`allowMultiple()`
Returns whether this attribute may appear more than once in one structure.
`String`
`name()`
Returns the name of the attribute.
`A`
`readAttribute(AttributedElement enclosing, ClassReader cf, int pos)`
Creates an `Attribute` instance from a `class` file for the Class-File API.
`AttributeMapper.AttributeStability`
`stability()`
Returns the data dependency of this attribute on the `class` file.
`void`
`writeAttribute(BufWriter buf, A attr)`
Writes an `Attribute` instance to a `class` file for the Class-File API.

## Method Details

### name

String name()
Returns the name of the attribute.

Returns:
  the name of the attribute

### readAttribute

A readAttribute(AttributedElement enclosing, ClassReader cf, int pos)
Creates an `Attribute` instance from a `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 `Utf8Entry` for the name of the attribute is accessible with `cf.readEntry(pos - 6, Utf8Entry.class)`, and is validated;
- The length of the attribute is accessible with `cf.readInt(pos - 4)`, and is validated to be positive and not beyond the length of the `class` file;
- The `AttributedElement` attribute access functionalities on the `enclosing` model may not be accessed when this method is called, but can be accessed later by the returned attribute when it is accessible to users.

The returned `Attribute` must fulfill these requirements:

- `Attribute.attributeMapper()` returns this mapper;
- `Attribute.attributeName()` returns the attribute name in the `class` file.

API Note:
  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 `class` file data or performing actions that may throw exceptions.
Parameters:
  `enclosing` - the structure in which this attribute appears
  `cf` - provides access to the `class` file to read from
  `pos` - the offset into the `class` file at which the contents of the attribute starts
Returns:
  the read attribute

### writeAttribute

void writeAttribute(BufWriter buf, A attr)
Writes an `Attribute` instance to a `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:

- `attr.attributeMapper()` returns this mapper;
- The `buf` may already have data written, that its `size` may not be `0`.

The `class` file writing must fulfill these requirements:

- The attribute name `u2` and attribute length `u4` must be written to the `buf`;
- `attr.attributeName()` is written as if with `buf.writeIndex(attr.attributeName())`;
- The attribute length is the length, in bytes, of attribute contents written to the `buf`, not including the 6 bytes used by the name and the length;
- If any information in the API model of the attribute, `attr`, cannot be represented in the `class` file format of the attribute, an `IllegalArgumentException` is thrown.

API Note:
  `BufWriter.patchInt(int, int, int)` can be used to update the attribute length after the attribute contents are written to the `buf`.
Parameters:
  `buf` - the `BufWriter` to which the attribute should be written
  `attr` - the attribute to write
Throws:
  `IllegalArgumentException` - if some data in the API model of the attribute is invalid for the `class` file format

### allowMultiple

default boolean allowMultiple()
Returns 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 `ClassFileBuilder`, and multiple instances of the attribute are supplied to the builder, the last supplied attribute appears on the built structure.

Implementation Requirements:
  The default implementation returns `false`.
Returns:
  whether this attribute may appear more than once in one structure

### stability

AttributeMapper.AttributeStability stability()
Returns the data dependency of this attribute on the `class` file.

Returns:
  the data dependency of this attribute on the `class` file