All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.dmlloyd.classfile.impl.AbstractAttributeMapper Maven / Gradle / Ivy

/*
 * Copyright (c) 2022, 2024, 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 io.github.dmlloyd.classfile.impl;

import io.github.dmlloyd.classfile.Annotation;
import io.github.dmlloyd.classfile.Attribute;
import io.github.dmlloyd.classfile.AttributeMapper;
import io.github.dmlloyd.classfile.AttributedElement;
import io.github.dmlloyd.classfile.BufWriter;
import io.github.dmlloyd.classfile.ClassReader;
import io.github.dmlloyd.classfile.attribute.*;
import java.util.List;

import static io.github.dmlloyd.classfile.Attributes.*;

public sealed abstract class AbstractAttributeMapper>
        implements AttributeMapper {

    private final String name;
    private final AttributeMapper.AttributeStability stability;
    private final boolean allowMultiple;

    protected abstract void writeBody(BufWriter buf, T attr);

    public AbstractAttributeMapper(String name, AttributeMapper.AttributeStability stability) {
        this(name, stability, false);
    }

    public AbstractAttributeMapper(String name,
                                   AttributeMapper.AttributeStability stability,
                                   boolean allowMultiple) {
        this.name = name;
        this.stability = stability;
        this.allowMultiple = allowMultiple;
    }

    @Override
    public final String name() {
        return name;
    }

    @Override
    public final void writeAttribute(BufWriter writer, T attr) {
        BufWriterImpl buf = (BufWriterImpl) writer;
        buf.writeIndex(buf.constantPool().utf8Entry(name));
        int lengthIndex = buf.skip(4);
        writeBody(buf, attr);
        int written = buf.size() - lengthIndex - 4;
        buf.patchInt(lengthIndex, written);
    }

    @Override
    public AttributeMapper.AttributeStability stability() {
        return stability;
    }

    @Override
    public boolean allowMultiple() {
        return allowMultiple;
    }

    @Override
    public String toString() {
        return String.format("AttributeMapper[name=%s, allowMultiple=%b, stability=%s]",
                name, allowMultiple, stability());
    }

    public static final class AnnotationDefaultMapper extends AbstractAttributeMapper {
        public static final AnnotationDefaultMapper INSTANCE = new AnnotationDefaultMapper();

        private AnnotationDefaultMapper() {
            super(NAME_ANNOTATION_DEFAULT, AttributeStability.CP_REFS);
        }

        @Override
        public AnnotationDefaultAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundAnnotationDefaultAttr(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, AnnotationDefaultAttribute attr) {
            AnnotationReader.writeAnnotationValue((BufWriterImpl) buf, attr.defaultValue());
        }
    }

    public static final class BootstrapMethodsMapper extends AbstractAttributeMapper {
        public static final BootstrapMethodsMapper INSTANCE = new BootstrapMethodsMapper();

        private BootstrapMethodsMapper() {
            super(NAME_BOOTSTRAP_METHODS, AttributeStability.CP_REFS);
        }

        @Override
        public BootstrapMethodsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundBootstrapMethodsAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, BootstrapMethodsAttribute attr) {
            var b = (BufWriterImpl) buf;
            b.writeU2(attr.bootstrapMethodsSize());
            for (var bsm : attr.bootstrapMethods()) {
                ((BootstrapMethodEntryImpl) bsm).writeTo(b);
            }
        }
    }

    public static final class CharacterRangeTableMapper extends AbstractAttributeMapper {
        public static final CharacterRangeTableMapper INSTANCE = new CharacterRangeTableMapper();

        private CharacterRangeTableMapper() {
            super(NAME_CHARACTER_RANGE_TABLE, AttributeStability.LABELS, true);
        }

        @Override
        public CharacterRangeTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundCharacterRangeTableAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, CharacterRangeTableAttribute attr) {
            List ranges = attr.characterRangeTable();
            buf.writeU2(ranges.size());
            for (CharacterRangeInfo info : ranges) {
                buf.writeU2(info.startPc());
                buf.writeU2(info.endPc());
                buf.writeInt(info.characterRangeStart());
                buf.writeInt(info.characterRangeEnd());
                buf.writeU2(info.flags());
            }
        }
    }

    public static final class CodeMapper extends AbstractAttributeMapper {
        public static final CodeMapper INSTANCE = new CodeMapper();

        private CodeMapper() {
            super(NAME_CODE, AttributeStability.CP_REFS);
        }

        @Override
        public CodeAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new CodeImpl(e, cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, CodeAttribute attr) {
            throw new UnsupportedOperationException("Code attribute does not support direct write");
        }
    }

    public static final class CompilationIDMapper extends AbstractAttributeMapper {
        public static final CompilationIDMapper INSTANCE = new CompilationIDMapper();

        private CompilationIDMapper() {
            super(NAME_COMPILATION_ID, AttributeStability.CP_REFS);
        }

        @Override
        public CompilationIDAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundCompilationIDAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, CompilationIDAttribute attr) {
            buf.writeIndex(attr.compilationId());
        }
    }

    public static final class ConstantValueMapper extends AbstractAttributeMapper {
        public static final ConstantValueMapper INSTANCE = new ConstantValueMapper();

        private ConstantValueMapper() {
            super(NAME_CONSTANT_VALUE, AttributeStability.CP_REFS);
        }

        @Override
        public ConstantValueAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundConstantValueAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, ConstantValueAttribute attr) {
            buf.writeIndex(attr.constant());
        }
    }

    public static final class DeprecatedMapper extends AbstractAttributeMapper {
        public static final DeprecatedMapper INSTANCE = new DeprecatedMapper();

        private DeprecatedMapper() {
            super(NAME_DEPRECATED, AttributeStability.STATELESS, true);
        }

        @Override
        public DeprecatedAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundDeprecatedAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, DeprecatedAttribute attr) {
            // empty
        }
    }

    public static final class EnclosingMethodMapper extends AbstractAttributeMapper {
        public static final EnclosingMethodMapper INSTANCE = new EnclosingMethodMapper();

        private EnclosingMethodMapper() {
            super(NAME_ENCLOSING_METHOD, AttributeStability.CP_REFS);
        }

        @Override
        public EnclosingMethodAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundEnclosingMethodAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, EnclosingMethodAttribute attr) {
            buf.writeIndex(attr.enclosingClass());
            buf.writeIndexOrZero(attr.enclosingMethod().orElse(null));
        }
    }

    public static final class ExceptionsMapper extends AbstractAttributeMapper {
        public static final ExceptionsMapper INSTANCE = new ExceptionsMapper();

        private ExceptionsMapper() {
            super(NAME_EXCEPTIONS, AttributeStability.CP_REFS);
        }

        @Override
        public ExceptionsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundExceptionsAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, ExceptionsAttribute attr) {
            Util.writeListIndices(buf, attr.exceptions());
        }
    }

    public static final class InnerClassesMapper extends AbstractAttributeMapper {
        public static final InnerClassesMapper INSTANCE = new InnerClassesMapper();

        private InnerClassesMapper() {
            super(NAME_INNER_CLASSES, AttributeStability.CP_REFS);
        }

        @Override
        public InnerClassesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundInnerClassesAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, InnerClassesAttribute attr) {
            List classes = attr.classes();
            buf.writeU2(classes.size());
            for (InnerClassInfo ic : classes) {
                buf.writeIndex(ic.innerClass());
                buf.writeIndexOrZero(ic.outerClass().orElse(null));
                buf.writeIndexOrZero(ic.innerName().orElse(null));
                buf.writeU2(ic.flagsMask());
            }
        }
    }

    public static final class LineNumberTableMapper extends AbstractAttributeMapper {
        public static final LineNumberTableMapper INSTANCE = new LineNumberTableMapper();

        private LineNumberTableMapper() {
            super(NAME_LINE_NUMBER_TABLE, AttributeStability.LABELS, true);
        }

        @Override
        public LineNumberTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundLineNumberTableAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, LineNumberTableAttribute attr) {
            List lines = attr.lineNumbers();
            buf.writeU2(lines.size());
            for (LineNumberInfo line : lines) {
                buf.writeU2(line.startPc());
                buf.writeU2(line.lineNumber());
            }
        }
    }

    public static final class LocalVariableTableMapper extends AbstractAttributeMapper {
        public static final LocalVariableTableMapper INSTANCE = new LocalVariableTableMapper();

        private LocalVariableTableMapper() {
            super(NAME_LOCAL_VARIABLE_TABLE, AttributeStability.LABELS, true);
        }

        @Override
        public LocalVariableTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundLocalVariableTableAttribute(e, cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, LocalVariableTableAttribute attr) {
            List infos = attr.localVariables();
            buf.writeU2(infos.size());
            for (LocalVariableInfo info : infos) {
                buf.writeU2(info.startPc());
                buf.writeU2(info.length());
                buf.writeIndex(info.name());
                buf.writeIndex(info.type());
                buf.writeU2(info.slot());
            }
        }
    }

    public static final class LocalVariableTypeTableMapper extends AbstractAttributeMapper {
        public static final LocalVariableTypeTableMapper INSTANCE = new LocalVariableTypeTableMapper();

        private LocalVariableTypeTableMapper() {
            super(NAME_LOCAL_VARIABLE_TYPE_TABLE, AttributeStability.LABELS, true);
        }

        @Override
        public LocalVariableTypeTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundLocalVariableTypeTableAttribute(e, cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, LocalVariableTypeTableAttribute attr) {
            List infos = attr.localVariableTypes();
            buf.writeU2(infos.size());
            for (LocalVariableTypeInfo info : infos) {
                buf.writeU2(info.startPc());
                buf.writeU2(info.length());
                buf.writeIndex(info.name());
                buf.writeIndex(info.signature());
                buf.writeU2(info.slot());
            }
        }
    }

    public static final class MethodParametersMapper extends AbstractAttributeMapper {
        public static final MethodParametersMapper INSTANCE = new MethodParametersMapper();

        private MethodParametersMapper() {
            super(NAME_METHOD_PARAMETERS, AttributeStability.CP_REFS);
        }

        @Override
        public MethodParametersAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundMethodParametersAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, MethodParametersAttribute attr) {
            List parameters = attr.parameters();
            buf.writeU1(parameters.size());
            for (MethodParameterInfo info : parameters) {
                buf.writeIndexOrZero(info.name().orElse(null));
                buf.writeU2(info.flagsMask());
            }
        }
    }

    public static final class ModuleMapper extends AbstractAttributeMapper {
        public static final ModuleMapper INSTANCE = new ModuleMapper();

        private ModuleMapper() {
            super(NAME_MODULE, AttributeStability.CP_REFS);
        }

        @Override
        public ModuleAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundModuleAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, ModuleAttribute attr) {
            buf.writeIndex(attr.moduleName());
            buf.writeU2(attr.moduleFlagsMask());
            buf.writeIndexOrZero(attr.moduleVersion().orElse(null));
            buf.writeU2(attr.requires().size());
            for (ModuleRequireInfo require : attr.requires()) {
                buf.writeIndex(require.requires());
                buf.writeU2(require.requiresFlagsMask());
                buf.writeIndexOrZero(require.requiresVersion().orElse(null));
            }
            buf.writeU2(attr.exports().size());
            for (ModuleExportInfo export : attr.exports()) {
                buf.writeIndex(export.exportedPackage());
                buf.writeU2(export.exportsFlagsMask());
                Util.writeListIndices(buf, export.exportsTo());
            }
            buf.writeU2(attr.opens().size());
            for (ModuleOpenInfo open : attr.opens()) {
                buf.writeIndex(open.openedPackage());
                buf.writeU2(open.opensFlagsMask());
                Util.writeListIndices(buf, open.opensTo());
            }
            Util.writeListIndices(buf, attr.uses());
            buf.writeU2(attr.provides().size());
            for (ModuleProvideInfo provide : attr.provides()) {
                buf.writeIndex(provide.provides());
                Util.writeListIndices(buf, provide.providesWith());
            }
        }
    }

    public static final class ModuleHashesMapper extends AbstractAttributeMapper {
        public static final ModuleHashesMapper INSTANCE = new ModuleHashesMapper();

        private ModuleHashesMapper() {
            super(NAME_MODULE_HASHES, AttributeStability.CP_REFS);
        }

        @Override
        public ModuleHashesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundModuleHashesAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, ModuleHashesAttribute attr) {
            buf.writeIndex(attr.algorithm());
            List hashes = attr.hashes();
            buf.writeU2(hashes.size());
            for (ModuleHashInfo hash : hashes) {
                buf.writeIndex(hash.moduleName());
                buf.writeU2(hash.hash().length);
                buf.writeBytes(hash.hash());
            }
        }
    }

    public static final class ModuleMainClassMapper extends AbstractAttributeMapper {
        public static final ModuleMainClassMapper INSTANCE = new ModuleMainClassMapper();

        private ModuleMainClassMapper() {
            super(NAME_MODULE_MAIN_CLASS, AttributeStability.CP_REFS);
        }

        @Override
        public ModuleMainClassAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundModuleMainClassAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, ModuleMainClassAttribute attr) {
            buf.writeIndex(attr.mainClass());
        }
    }

    public static final class ModulePackagesMapper extends AbstractAttributeMapper {
        public static final ModulePackagesMapper INSTANCE = new ModulePackagesMapper();

        private ModulePackagesMapper() {
            super(NAME_MODULE_PACKAGES, AttributeStability.CP_REFS);
        }

        @Override
        public ModulePackagesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundModulePackagesAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, ModulePackagesAttribute attr) {
            Util.writeListIndices(buf, attr.packages());
        }
    }

    public static final class ModuleResolutionMapper extends AbstractAttributeMapper {
        public static final ModuleResolutionMapper INSTANCE = new ModuleResolutionMapper();

        private ModuleResolutionMapper() {
            super(NAME_MODULE_RESOLUTION, AttributeStability.STATELESS);
        }

        @Override
        public ModuleResolutionAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundModuleResolutionAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, ModuleResolutionAttribute attr) {
            buf.writeU2(attr.resolutionFlags());
        }
    }

    public static final class ModuleTargetMapper extends AbstractAttributeMapper {
        public static final ModuleTargetMapper INSTANCE = new ModuleTargetMapper();

        private ModuleTargetMapper() {
            super(NAME_MODULE_TARGET, AttributeStability.CP_REFS);
        }

        @Override
        public ModuleTargetAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundModuleTargetAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, ModuleTargetAttribute attr) {
            buf.writeIndex(attr.targetPlatform());
        }
    }

    public static final class NestHostMapper extends AbstractAttributeMapper {
        public static final NestHostMapper INSTANCE = new NestHostMapper();

        private NestHostMapper() {
            super(NAME_NEST_HOST, AttributeStability.CP_REFS);
        }

        @Override
        public NestHostAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundNestHostAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, NestHostAttribute attr) {
            buf.writeIndex(attr.nestHost());
        }
    }

    public static final class NestMembersMapper extends AbstractAttributeMapper {
        public static final NestMembersMapper INSTANCE = new NestMembersMapper();

        private NestMembersMapper() {
            super(NAME_NEST_MEMBERS, AttributeStability.CP_REFS);
        }

        @Override
        public NestMembersAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundNestMembersAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, NestMembersAttribute attr) {
            Util.writeListIndices(buf, attr.nestMembers());
        }
    }

    public static final class PermittedSubclassesMapper extends AbstractAttributeMapper {
        public static final PermittedSubclassesMapper INSTANCE = new PermittedSubclassesMapper();

        private PermittedSubclassesMapper() {
            super(NAME_PERMITTED_SUBCLASSES, AttributeStability.CP_REFS);
        }

        @Override
        public PermittedSubclassesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundPermittedSubclassesAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, PermittedSubclassesAttribute attr) {
            Util.writeListIndices(buf, attr.permittedSubclasses());
        }
    }

    public static final class RecordMapper extends AbstractAttributeMapper {
        public static final RecordMapper INSTANCE = new RecordMapper();

        private RecordMapper() {
            super(NAME_RECORD, AttributeStability.CP_REFS);
        }

        @Override
        public RecordAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundRecordAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, RecordAttribute attr) {
            List components = attr.components();
            buf.writeU2(components.size());
            for (RecordComponentInfo info : components) {
                buf.writeIndex(info.name());
                buf.writeIndex(info.descriptor());
                Util.writeAttributes((BufWriterImpl) buf, info.attributes());
            }
        }
    }

    public static final class RuntimeInvisibleAnnotationsMapper extends AbstractAttributeMapper {
        public static final RuntimeInvisibleAnnotationsMapper INSTANCE = new RuntimeInvisibleAnnotationsMapper();

        private RuntimeInvisibleAnnotationsMapper() {
            super(NAME_RUNTIME_INVISIBLE_ANNOTATIONS, AttributeStability.CP_REFS);
        }

        @Override
        public RuntimeInvisibleAnnotationsAttribute readAttribute(AttributedElement enclosing, ClassReader cf, int pos) {
            return new BoundAttribute.BoundRuntimeInvisibleAnnotationsAttribute(cf, pos);
        }

        @Override
        protected void writeBody(BufWriter buf, RuntimeInvisibleAnnotationsAttribute attr) {
            AnnotationReader.writeAnnotations(buf, attr.annotations());
        }
    }

    public static final class RuntimeInvisibleParameterAnnotationsMapper extends AbstractAttributeMapper {
        public static final RuntimeInvisibleParameterAnnotationsMapper INSTANCE = new RuntimeInvisibleParameterAnnotationsMapper();

        private RuntimeInvisibleParameterAnnotationsMapper() {
            super(NAME_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS, AttributeStability.CP_REFS);
        }

        @Override
        public RuntimeInvisibleParameterAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundRuntimeInvisibleParameterAnnotationsAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, RuntimeInvisibleParameterAnnotationsAttribute attr) {
            List> lists = attr.parameterAnnotations();
            buf.writeU1(lists.size());
            for (List list : lists)
                AnnotationReader.writeAnnotations(buf, list);
        }
    }

    public static final class RuntimeInvisibleTypeAnnotationsMapper extends AbstractAttributeMapper {
        public static final RuntimeInvisibleTypeAnnotationsMapper INSTANCE = new RuntimeInvisibleTypeAnnotationsMapper();

        private RuntimeInvisibleTypeAnnotationsMapper() {
            super(NAME_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS, AttributeStability.UNSTABLE);
        }

        @Override
        public RuntimeInvisibleTypeAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundRuntimeInvisibleTypeAnnotationsAttribute(e, cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, RuntimeInvisibleTypeAnnotationsAttribute attr) {
            AnnotationReader.writeTypeAnnotations(buf, attr.annotations());
        }
    }

    public static final class RuntimeVisibleAnnotationsMapper extends AbstractAttributeMapper {
        public static final RuntimeVisibleAnnotationsMapper INSTANCE = new RuntimeVisibleAnnotationsMapper();

        private RuntimeVisibleAnnotationsMapper() {
            super(NAME_RUNTIME_VISIBLE_ANNOTATIONS, AttributeStability.CP_REFS);
        }

        @Override
        public RuntimeVisibleAnnotationsAttribute readAttribute(AttributedElement enclosing, ClassReader cf, int pos) {
            return new BoundAttribute.BoundRuntimeVisibleAnnotationsAttribute(cf, pos);
        }

        @Override
        protected void writeBody(BufWriter buf, RuntimeVisibleAnnotationsAttribute attr) {
            AnnotationReader.writeAnnotations(buf, attr.annotations());
        }
    }

    public static final class RuntimeVisibleParameterAnnotationsMapper extends AbstractAttributeMapper {
        public static final RuntimeVisibleParameterAnnotationsMapper INSTANCE = new RuntimeVisibleParameterAnnotationsMapper();

        private RuntimeVisibleParameterAnnotationsMapper() {
            super(NAME_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS, AttributeStability.CP_REFS);
        }

        @Override
        public RuntimeVisibleParameterAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundRuntimeVisibleParameterAnnotationsAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, RuntimeVisibleParameterAnnotationsAttribute attr) {
            List> lists = attr.parameterAnnotations();
            buf.writeU1(lists.size());
            for (List list : lists)
                AnnotationReader.writeAnnotations(buf, list);
        }
    }

    public static final class RuntimeVisibleTypeAnnotationsMapper extends AbstractAttributeMapper {
        public static final RuntimeVisibleTypeAnnotationsMapper INSTANCE = new RuntimeVisibleTypeAnnotationsMapper();

        private RuntimeVisibleTypeAnnotationsMapper() {
            super(NAME_RUNTIME_VISIBLE_TYPE_ANNOTATIONS, AttributeStability.UNSTABLE);
        }

        @Override
        public RuntimeVisibleTypeAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundRuntimeVisibleTypeAnnotationsAttribute(e, cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, RuntimeVisibleTypeAnnotationsAttribute attr) {
            AnnotationReader.writeTypeAnnotations(buf, attr.annotations());
        }
    }

    public static final class SignatureMapper extends AbstractAttributeMapper {
        public static final SignatureMapper INSTANCE = new SignatureMapper();

        private SignatureMapper() {
            super(NAME_SIGNATURE, AttributeStability.CP_REFS);
        }

        @Override
        public SignatureAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundSignatureAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, SignatureAttribute attr) {
            buf.writeIndex(attr.signature());
        }
    }

    public static final class SourceDebugExtensionMapper extends AbstractAttributeMapper {
        public static final SourceDebugExtensionMapper INSTANCE = new SourceDebugExtensionMapper();

        private SourceDebugExtensionMapper() {
            super(NAME_SOURCE_DEBUG_EXTENSION, AttributeStability.STATELESS);
        }

        @Override
        public SourceDebugExtensionAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundSourceDebugExtensionAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, SourceDebugExtensionAttribute attr) {
            buf.writeBytes(attr.contents());
        }
    }

    public static final class SourceFileMapper extends AbstractAttributeMapper {
        public static final SourceFileMapper INSTANCE = new SourceFileMapper();

        private SourceFileMapper() {
            super(NAME_SOURCE_FILE, AttributeStability.CP_REFS);
        }

        @Override
        public SourceFileAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundSourceFileAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, SourceFileAttribute attr) {
            buf.writeIndex(attr.sourceFile());
        }
    }

    public static final class SourceIDMapper extends AbstractAttributeMapper {
        public static final SourceIDMapper INSTANCE = new SourceIDMapper();

        private SourceIDMapper() {
            super(NAME_SOURCE_ID, AttributeStability.CP_REFS);
        }

        @Override
        public SourceIDAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundSourceIDAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, SourceIDAttribute attr) {
            buf.writeIndex(attr.sourceId());
        }
    }

    public static final class StackMapTableMapper extends AbstractAttributeMapper {
        public static final StackMapTableMapper INSTANCE = new StackMapTableMapper();

        private StackMapTableMapper() {
            super(NAME_STACK_MAP_TABLE, AttributeStability.LABELS);
        }

        @Override
        public StackMapTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundStackMapTableAttribute((CodeImpl)e, cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter b, StackMapTableAttribute attr) {
            StackMapDecoder.writeFrames(b, attr.entries());
        }
    }

    public static final class SyntheticMapper extends AbstractAttributeMapper {
        public static final SyntheticMapper INSTANCE = new SyntheticMapper();

        private SyntheticMapper() {
            super(NAME_SYNTHETIC, AttributeStability.STATELESS, true);
        }

        @Override
        public SyntheticAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
            return new BoundAttribute.BoundSyntheticAttribute(cf, this, p);
        }

        @Override
        protected void writeBody(BufWriter buf, SyntheticAttribute attr) {
            // empty
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy