1 /*
   2  * Copyright (c) 2022, 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.util.Collections;
  28 import java.util.HashMap;
  29 import java.util.List;
  30 import java.util.Map;
  31 import java.util.Set;
  32 
  33 import java.lang.classfile.attribute.AnnotationDefaultAttribute;
  34 import java.lang.classfile.attribute.BootstrapMethodsAttribute;
  35 import java.lang.classfile.attribute.CharacterRangeInfo;
  36 import java.lang.classfile.attribute.CharacterRangeTableAttribute;
  37 import java.lang.classfile.attribute.CodeAttribute;
  38 import java.lang.classfile.attribute.CompilationIDAttribute;
  39 import java.lang.classfile.attribute.ConstantValueAttribute;
  40 import java.lang.classfile.attribute.DeprecatedAttribute;
  41 import java.lang.classfile.attribute.EnclosingMethodAttribute;
  42 import java.lang.classfile.attribute.ExceptionsAttribute;
  43 import java.lang.classfile.attribute.InnerClassInfo;
  44 import java.lang.classfile.attribute.InnerClassesAttribute;
  45 import java.lang.classfile.attribute.LineNumberInfo;
  46 import java.lang.classfile.attribute.LineNumberTableAttribute;
  47 import java.lang.classfile.attribute.LocalVariableInfo;
  48 import java.lang.classfile.attribute.LocalVariableTableAttribute;
  49 import java.lang.classfile.attribute.LocalVariableTypeInfo;
  50 import java.lang.classfile.attribute.LocalVariableTypeTableAttribute;
  51 import java.lang.classfile.attribute.MethodParameterInfo;
  52 import java.lang.classfile.attribute.MethodParametersAttribute;
  53 import java.lang.classfile.attribute.ModuleAttribute;
  54 import java.lang.classfile.attribute.ModuleExportInfo;
  55 import java.lang.classfile.attribute.ModuleHashInfo;
  56 import java.lang.classfile.attribute.ModuleHashesAttribute;
  57 import java.lang.classfile.attribute.ModuleMainClassAttribute;
  58 import java.lang.classfile.attribute.ModuleOpenInfo;
  59 import java.lang.classfile.attribute.ModulePackagesAttribute;
  60 import java.lang.classfile.attribute.ModuleProvideInfo;
  61 import java.lang.classfile.attribute.ModuleRequireInfo;
  62 import java.lang.classfile.attribute.ModuleResolutionAttribute;
  63 import java.lang.classfile.attribute.ModuleTargetAttribute;
  64 import java.lang.classfile.attribute.NestHostAttribute;
  65 import java.lang.classfile.attribute.NestMembersAttribute;
  66 import java.lang.classfile.attribute.PermittedSubclassesAttribute;
  67 import java.lang.classfile.attribute.RecordAttribute;
  68 import java.lang.classfile.attribute.RecordComponentInfo;
  69 import java.lang.classfile.attribute.RuntimeInvisibleAnnotationsAttribute;
  70 import java.lang.classfile.attribute.RuntimeInvisibleParameterAnnotationsAttribute;
  71 import java.lang.classfile.attribute.RuntimeInvisibleTypeAnnotationsAttribute;
  72 import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute;
  73 import java.lang.classfile.attribute.RuntimeVisibleParameterAnnotationsAttribute;
  74 import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute;
  75 import java.lang.classfile.attribute.SignatureAttribute;
  76 import java.lang.classfile.attribute.SourceDebugExtensionAttribute;
  77 import java.lang.classfile.attribute.SourceFileAttribute;
  78 import java.lang.classfile.attribute.SourceIDAttribute;
  79 import java.lang.classfile.attribute.StackMapTableAttribute;
  80 import java.lang.classfile.attribute.SyntheticAttribute;
  81 import java.lang.classfile.constantpool.Utf8Entry;
  82 import jdk.internal.classfile.impl.AbstractAttributeMapper;
  83 import jdk.internal.classfile.impl.BoundAttribute;
  84 import jdk.internal.classfile.impl.CodeImpl;
  85 import jdk.internal.classfile.impl.AbstractPoolEntry;
  86 import jdk.internal.classfile.impl.StackMapDecoder;
  87 import jdk.internal.javac.PreviewFeature;
  88 
  89 /**
  90  * Attribute mappers for standard classfile attributes.
  91  *
  92  * @see AttributeMapper
  93  *
  94  * @since 22
  95  */
  96 @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API)
  97 public class Attributes {
  98 
  99     /** AnnotationDefault */
 100     public static final String NAME_ANNOTATION_DEFAULT = "AnnotationDefault";
 101 
 102     /** BootstrapMethods */
 103     public static final String NAME_BOOTSTRAP_METHODS = "BootstrapMethods";
 104 
 105     /** CharacterRangeTable */
 106     public static final String NAME_CHARACTER_RANGE_TABLE = "CharacterRangeTable";
 107 
 108     /** Code */
 109     public static final String NAME_CODE = "Code";
 110 
 111     /** CompilationID */
 112     public static final String NAME_COMPILATION_ID = "CompilationID";
 113 
 114     /** ConstantValue */
 115     public static final String NAME_CONSTANT_VALUE = "ConstantValue";
 116 
 117     /** Deprecated */
 118     public static final String NAME_DEPRECATED = "Deprecated";
 119 
 120     /** EnclosingMethod */
 121     public static final String NAME_ENCLOSING_METHOD = "EnclosingMethod";
 122 
 123     /** Exceptions */
 124     public static final String NAME_EXCEPTIONS = "Exceptions";
 125 
 126     /** InnerClasses */
 127     public static final String NAME_INNER_CLASSES = "InnerClasses";
 128 
 129     /** LineNumberTable */
 130     public static final String NAME_LINE_NUMBER_TABLE = "LineNumberTable";
 131 
 132     /** LocalVariableTable */
 133     public static final String NAME_LOCAL_VARIABLE_TABLE = "LocalVariableTable";
 134 
 135     /** LocalVariableTypeTable */
 136     public static final String NAME_LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable";
 137 
 138     /** MethodParameters */
 139     public static final String NAME_METHOD_PARAMETERS = "MethodParameters";
 140 
 141     /** Module */
 142     public static final String NAME_MODULE = "Module";
 143 
 144     /** ModuleHashes */
 145     public static final String NAME_MODULE_HASHES = "ModuleHashes";
 146 
 147     /** ModuleMainClass */
 148     public static final String NAME_MODULE_MAIN_CLASS = "ModuleMainClass";
 149 
 150     /** ModulePackages */
 151     public static final String NAME_MODULE_PACKAGES = "ModulePackages";
 152 
 153     /** ModuleResolution */
 154     public static final String NAME_MODULE_RESOLUTION = "ModuleResolution";
 155 
 156     /** ModuleTarget */
 157     public static final String NAME_MODULE_TARGET = "ModuleTarget";
 158 
 159     /** NestHost */
 160     public static final String NAME_NEST_HOST = "NestHost";
 161 
 162     /** NestMembers */
 163     public static final String NAME_NEST_MEMBERS = "NestMembers";
 164 
 165     /** PermittedSubclasses */
 166     public static final String NAME_PERMITTED_SUBCLASSES = "PermittedSubclasses";
 167 
 168     /** Record */
 169     public static final String NAME_RECORD = "Record";
 170 
 171     /** RuntimeInvisibleAnnotations */
 172     public static final String NAME_RUNTIME_INVISIBLE_ANNOTATIONS = "RuntimeInvisibleAnnotations";
 173 
 174     /** RuntimeInvisibleParameterAnnotations */
 175     public static final String NAME_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = "RuntimeInvisibleParameterAnnotations";
 176 
 177     /** RuntimeInvisibleTypeAnnotations */
 178     public static final String NAME_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = "RuntimeInvisibleTypeAnnotations";
 179 
 180     /** RuntimeVisibleAnnotations */
 181     public static final String NAME_RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations";
 182 
 183     /** RuntimeVisibleParameterAnnotations */
 184     public static final String NAME_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = "RuntimeVisibleParameterAnnotations";
 185 
 186     /** RuntimeVisibleTypeAnnotations */
 187     public static final String NAME_RUNTIME_VISIBLE_TYPE_ANNOTATIONS = "RuntimeVisibleTypeAnnotations";
 188 
 189     /** Signature */
 190     public static final String NAME_SIGNATURE = "Signature";
 191 
 192     /** SourceDebugExtension */
 193     public static final String NAME_SOURCE_DEBUG_EXTENSION = "SourceDebugExtension";
 194 
 195     /** SourceFile */
 196     public static final String NAME_SOURCE_FILE = "SourceFile";
 197 
 198     /** SourceID */
 199     public static final String NAME_SOURCE_ID = "SourceID";
 200 
 201     /** StackMapTable */
 202     public static final String NAME_STACK_MAP_TABLE = "StackMapTable";
 203 
 204     /** Synthetic */
 205     public static final String NAME_SYNTHETIC = "Synthetic";
 206 
 207     private Attributes() {
 208     }
 209 
 210     /** Attribute mapper for the {@code AnnotationDefault} attribute */
 211     public static final AttributeMapper<AnnotationDefaultAttribute>
 212             ANNOTATION_DEFAULT = new AbstractAttributeMapper<>(NAME_ANNOTATION_DEFAULT) {
 213                 @Override
 214                 public AnnotationDefaultAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 215                     return new BoundAttribute.BoundAnnotationDefaultAttr(cf, this, p);
 216                 }
 217 
 218                 @Override
 219                 protected void writeBody(BufWriter buf, AnnotationDefaultAttribute attr) {
 220                     attr.defaultValue().writeTo(buf);
 221                 }
 222 
 223                 @Override
 224                 public AttributeMapper.AttributeStability stability() {
 225                     return AttributeStability.CP_REFS;
 226                 }
 227             };
 228 
 229     /** Attribute mapper for the {@code BootstrapMethods} attribute */
 230     public static final AttributeMapper<BootstrapMethodsAttribute>
 231             BOOTSTRAP_METHODS = new AbstractAttributeMapper<>(NAME_BOOTSTRAP_METHODS) {
 232                 @Override
 233                 public BootstrapMethodsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 234                     return new BoundAttribute.BoundBootstrapMethodsAttribute(cf, this, p);
 235                 }
 236 
 237                 @Override
 238                 protected void writeBody(BufWriter buf, BootstrapMethodsAttribute attr) {
 239                     buf.writeList(attr.bootstrapMethods());
 240                 }
 241 
 242                 @Override
 243                 public AttributeMapper.AttributeStability stability() {
 244                     return AttributeStability.CP_REFS;
 245                 }
 246             };
 247 
 248     /** Attribute mapper for the {@code CharacterRangeTable} attribute */
 249     public static final AttributeMapper<CharacterRangeTableAttribute>
 250             CHARACTER_RANGE_TABLE = new AbstractAttributeMapper<>(NAME_CHARACTER_RANGE_TABLE, true) {
 251                 @Override
 252                 public CharacterRangeTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 253                     return new BoundAttribute.BoundCharacterRangeTableAttribute(cf, this, p);
 254                 }
 255 
 256                 @Override
 257                 protected void writeBody(BufWriter buf, CharacterRangeTableAttribute attr) {
 258                     List<CharacterRangeInfo> ranges = attr.characterRangeTable();
 259                     buf.writeU2(ranges.size());
 260                     for (CharacterRangeInfo info : ranges) {
 261                         buf.writeU2(info.startPc());
 262                         buf.writeU2(info.endPc());
 263                         buf.writeInt(info.characterRangeStart());
 264                         buf.writeInt(info.characterRangeEnd());
 265                         buf.writeU2(info.flags());
 266                     }
 267                 }
 268 
 269                 @Override
 270                 public AttributeMapper.AttributeStability stability() {
 271                     return AttributeStability.LABELS;
 272                 }
 273             };
 274 
 275     /** Attribute mapper for the {@code Code} attribute */
 276     public static final AttributeMapper<CodeAttribute>
 277             CODE = new AbstractAttributeMapper<>(NAME_CODE) {
 278                 @Override
 279                 public CodeAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 280                     return new CodeImpl(e, cf, this, p);
 281                 }
 282 
 283                 @Override
 284                 protected void writeBody(BufWriter buf, CodeAttribute attr) {
 285                     throw new UnsupportedOperationException("Code attribute does not support direct write");
 286                 }
 287 
 288                 @Override
 289                 public AttributeMapper.AttributeStability stability() {
 290                     return AttributeStability.CP_REFS;
 291                 }
 292             };
 293 
 294 
 295     /** Attribute mapper for the {@code CompilationID} attribute */
 296     public static final AttributeMapper<CompilationIDAttribute>
 297             COMPILATION_ID = new AbstractAttributeMapper<>(NAME_COMPILATION_ID, true) {
 298                 @Override
 299                 public CompilationIDAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 300                     return new BoundAttribute.BoundCompilationIDAttribute(cf, this, p);
 301                 }
 302 
 303                 @Override
 304                 protected void writeBody(BufWriter buf, CompilationIDAttribute attr) {
 305                     buf.writeIndex(attr.compilationId());
 306                 }
 307 
 308                 @Override
 309                 public AttributeMapper.AttributeStability stability() {
 310                     return AttributeStability.CP_REFS;
 311                 }
 312             };
 313 
 314     /** Attribute mapper for the {@code ConstantValue} attribute */
 315     public static final AttributeMapper<ConstantValueAttribute>
 316             CONSTANT_VALUE = new AbstractAttributeMapper<>(NAME_CONSTANT_VALUE) {
 317                 @Override
 318                 public ConstantValueAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 319                     return new BoundAttribute.BoundConstantValueAttribute(cf, this, p);
 320                 }
 321 
 322                 @Override
 323                 protected void writeBody(BufWriter buf, ConstantValueAttribute attr) {
 324                     buf.writeIndex(attr.constant());
 325                 }
 326 
 327                 @Override
 328                 public AttributeMapper.AttributeStability stability() {
 329                     return AttributeStability.CP_REFS;
 330                 }
 331             };
 332 
 333     /** Attribute mapper for the {@code Deprecated} attribute */
 334     public static final AttributeMapper<DeprecatedAttribute>
 335             DEPRECATED = new AbstractAttributeMapper<>(NAME_DEPRECATED, true) {
 336                 @Override
 337                 public DeprecatedAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 338                     return new BoundAttribute.BoundDeprecatedAttribute(cf, this, p);
 339                 }
 340 
 341                 @Override
 342                 protected void writeBody(BufWriter buf, DeprecatedAttribute attr) {
 343                     // empty
 344                 }
 345 
 346                 @Override
 347                 public AttributeMapper.AttributeStability stability() {
 348                     return AttributeStability.STATELESS;
 349                 }
 350             };
 351 
 352     /** Attribute mapper for the {@code EnclosingMethod} attribute */
 353     public static final AttributeMapper<EnclosingMethodAttribute>
 354             ENCLOSING_METHOD = new AbstractAttributeMapper<>(NAME_ENCLOSING_METHOD) {
 355                 @Override
 356                 public EnclosingMethodAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 357                     return new BoundAttribute.BoundEnclosingMethodAttribute(cf, this, p);
 358                 }
 359 
 360                 @Override
 361                 protected void writeBody(BufWriter buf, EnclosingMethodAttribute attr) {
 362                     buf.writeIndex(attr.enclosingClass());
 363                     buf.writeIndexOrZero(attr.enclosingMethod().orElse(null));
 364                 }
 365 
 366                 @Override
 367                 public AttributeMapper.AttributeStability stability() {
 368                     return AttributeStability.CP_REFS;
 369                 }
 370             };
 371 
 372     /** Attribute mapper for the {@code Exceptions} attribute */
 373     public static final AttributeMapper<ExceptionsAttribute>
 374             EXCEPTIONS = new AbstractAttributeMapper<>(NAME_EXCEPTIONS) {
 375                 @Override
 376                 public ExceptionsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 377                     return new BoundAttribute.BoundExceptionsAttribute(cf, this, p);
 378                 }
 379 
 380                 @Override
 381                 protected void writeBody(BufWriter buf, ExceptionsAttribute attr) {
 382                     buf.writeListIndices(attr.exceptions());
 383                 }
 384 
 385                 @Override
 386                 public AttributeMapper.AttributeStability stability() {
 387                     return AttributeStability.CP_REFS;
 388                 }
 389             };
 390 
 391     /** Attribute mapper for the {@code InnerClasses} attribute */
 392     public static final AttributeMapper<InnerClassesAttribute>
 393             INNER_CLASSES = new AbstractAttributeMapper<>(NAME_INNER_CLASSES) {
 394                 @Override
 395                 public InnerClassesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 396                     return new BoundAttribute.BoundInnerClassesAttribute(cf, this, p);
 397                 }
 398 
 399                 @Override
 400                 protected void writeBody(BufWriter buf, InnerClassesAttribute attr) {
 401                     List<InnerClassInfo> classes = attr.classes();
 402                     buf.writeU2(classes.size());
 403                     for (InnerClassInfo ic : classes) {
 404                         buf.writeIndex(ic.innerClass());
 405                         buf.writeIndexOrZero(ic.outerClass().orElse(null));
 406                         buf.writeIndexOrZero(ic.innerName().orElse(null));
 407                         buf.writeU2(ic.flagsMask());
 408                     }
 409                 }
 410 
 411                 @Override
 412                 public AttributeMapper.AttributeStability stability() {
 413                     return AttributeStability.CP_REFS;
 414                 }
 415             };
 416 
 417     /** Attribute mapper for the {@code LineNumberTable} attribute */
 418     public static final AttributeMapper<LineNumberTableAttribute>
 419             LINE_NUMBER_TABLE = new AbstractAttributeMapper<>(NAME_LINE_NUMBER_TABLE, true) {
 420                 @Override
 421                 public LineNumberTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 422                     return new BoundAttribute.BoundLineNumberTableAttribute(cf, this, p);
 423                 }
 424 
 425                 @Override
 426                 protected void writeBody(BufWriter buf, LineNumberTableAttribute attr) {
 427                     List<LineNumberInfo> lines = attr.lineNumbers();
 428                     buf.writeU2(lines.size());
 429                     for (LineNumberInfo line : lines) {
 430                         buf.writeU2(line.startPc());
 431                         buf.writeU2(line.lineNumber());
 432                     }
 433                 }
 434 
 435                 @Override
 436                 public AttributeMapper.AttributeStability stability() {
 437                     return AttributeStability.LABELS;
 438                 }
 439             };
 440 
 441     /** Attribute mapper for the {@code LocalVariableTable} attribute */
 442     public static final AttributeMapper<LocalVariableTableAttribute>
 443             LOCAL_VARIABLE_TABLE = new AbstractAttributeMapper<>(NAME_LOCAL_VARIABLE_TABLE, true) {
 444                 @Override
 445                 public LocalVariableTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 446                     return new BoundAttribute.BoundLocalVariableTableAttribute(e, cf, this, p);
 447                 }
 448 
 449                 @Override
 450                 protected void writeBody(BufWriter buf, LocalVariableTableAttribute attr) {
 451                     List<LocalVariableInfo> infos = attr.localVariables();
 452                     buf.writeU2(infos.size());
 453                     for (LocalVariableInfo info : infos) {
 454                         buf.writeU2(info.startPc());
 455                         buf.writeU2(info.length());
 456                         buf.writeIndex(info.name());
 457                         buf.writeIndex(info.type());
 458                         buf.writeU2(info.slot());
 459                     }
 460                 }
 461 
 462                 @Override
 463                 public AttributeMapper.AttributeStability stability() {
 464                     return AttributeStability.LABELS;
 465                 }
 466             };
 467 
 468     /** Attribute mapper for the {@code LocalVariableTypeTable} attribute */
 469     public static final AttributeMapper<LocalVariableTypeTableAttribute>
 470             LOCAL_VARIABLE_TYPE_TABLE = new AbstractAttributeMapper<>(NAME_LOCAL_VARIABLE_TYPE_TABLE, true) {
 471                 @Override
 472                 public LocalVariableTypeTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 473                     return new BoundAttribute.BoundLocalVariableTypeTableAttribute(e, cf, this, p);
 474                 }
 475 
 476                 @Override
 477                 protected void writeBody(BufWriter buf, LocalVariableTypeTableAttribute attr) {
 478                     List<LocalVariableTypeInfo> infos = attr.localVariableTypes();
 479                     buf.writeU2(infos.size());
 480                     for (LocalVariableTypeInfo info : infos) {
 481                         buf.writeU2(info.startPc());
 482                         buf.writeU2(info.length());
 483                         buf.writeIndex(info.name());
 484                         buf.writeIndex(info.signature());
 485                         buf.writeU2(info.slot());
 486                     }
 487                 }
 488 
 489                 @Override
 490                 public AttributeMapper.AttributeStability stability() {
 491                     return AttributeStability.LABELS;
 492                 }
 493             };
 494 
 495     /** Attribute mapper for the {@code MethodParameters} attribute */
 496     public static final AttributeMapper<MethodParametersAttribute>
 497             METHOD_PARAMETERS = new AbstractAttributeMapper<>(NAME_METHOD_PARAMETERS) {
 498                 @Override
 499                 public MethodParametersAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 500                     return new BoundAttribute.BoundMethodParametersAttribute(cf, this, p);
 501                 }
 502 
 503                 @Override
 504                 protected void writeBody(BufWriter buf, MethodParametersAttribute attr) {
 505                     List<MethodParameterInfo> parameters = attr.parameters();
 506                     buf.writeU1(parameters.size());
 507                     for (MethodParameterInfo info : parameters) {
 508                         buf.writeIndexOrZero(info.name().orElse(null));
 509                         buf.writeU2(info.flagsMask());
 510                     }
 511                 }
 512 
 513                 @Override
 514                 public AttributeMapper.AttributeStability stability() {
 515                     return AttributeStability.CP_REFS;
 516                 }
 517             };
 518 
 519     /** Attribute mapper for the {@code Module} attribute */
 520     public static final AttributeMapper<ModuleAttribute>
 521             MODULE = new AbstractAttributeMapper<>(NAME_MODULE) {
 522                 @Override
 523                 public ModuleAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 524                     return new BoundAttribute.BoundModuleAttribute(cf, this, p);
 525                 }
 526 
 527                 @Override
 528                 protected void writeBody(BufWriter buf, ModuleAttribute attr) {
 529                     buf.writeIndex(attr.moduleName());
 530                     buf.writeU2(attr.moduleFlagsMask());
 531                     buf.writeIndexOrZero(attr.moduleVersion().orElse(null));
 532                     buf.writeU2(attr.requires().size());
 533                     for (ModuleRequireInfo require : attr.requires()) {
 534                         buf.writeIndex(require.requires());
 535                         buf.writeU2(require.requiresFlagsMask());
 536                         buf.writeIndexOrZero(require.requiresVersion().orElse(null));
 537                     }
 538                     buf.writeU2(attr.exports().size());
 539                     for (ModuleExportInfo export : attr.exports()) {
 540                         buf.writeIndex(export.exportedPackage());
 541                         buf.writeU2(export.exportsFlagsMask());
 542                         buf.writeListIndices(export.exportsTo());
 543                     }
 544                     buf.writeU2(attr.opens().size());
 545                     for (ModuleOpenInfo open : attr.opens()) {
 546                         buf.writeIndex(open.openedPackage());
 547                         buf.writeU2(open.opensFlagsMask());
 548                         buf.writeListIndices(open.opensTo());
 549                     }
 550                     buf.writeListIndices(attr.uses());
 551                     buf.writeU2(attr.provides().size());
 552                     for (ModuleProvideInfo provide : attr.provides()) {
 553                         buf.writeIndex(provide.provides());
 554                         buf.writeListIndices(provide.providesWith());
 555                     }
 556                 }
 557 
 558                 @Override
 559                 public AttributeMapper.AttributeStability stability() {
 560                     return AttributeStability.CP_REFS;
 561                 }
 562             };
 563 
 564     /** Attribute mapper for the {@code ModuleHashes} attribute */
 565     public static final AttributeMapper<ModuleHashesAttribute>
 566             MODULE_HASHES = new AbstractAttributeMapper<>(NAME_MODULE_HASHES) {
 567                 @Override
 568                 public ModuleHashesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 569                     return new BoundAttribute.BoundModuleHashesAttribute(cf, this, p);
 570                 }
 571 
 572                 @Override
 573                 protected void writeBody(BufWriter buf, ModuleHashesAttribute attr) {
 574                     buf.writeIndex(attr.algorithm());
 575                     List<ModuleHashInfo> hashes = attr.hashes();
 576                     buf.writeU2(hashes.size());
 577                     for (ModuleHashInfo hash : hashes) {
 578                         buf.writeIndex(hash.moduleName());
 579                         buf.writeU2(hash.hash().length);
 580                         buf.writeBytes(hash.hash());
 581                     }
 582                 }
 583 
 584                 @Override
 585                 public AttributeMapper.AttributeStability stability() {
 586                     return AttributeStability.CP_REFS;
 587                 }
 588             };
 589 
 590     /** Attribute mapper for the {@code ModuleMainClass} attribute */
 591     public static final AttributeMapper<ModuleMainClassAttribute>
 592             MODULE_MAIN_CLASS = new AbstractAttributeMapper<>(NAME_MODULE_MAIN_CLASS) {
 593                 @Override
 594                 public ModuleMainClassAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 595                     return new BoundAttribute.BoundModuleMainClassAttribute(cf, this, p);
 596                 }
 597 
 598                 @Override
 599                 protected void writeBody(BufWriter buf, ModuleMainClassAttribute attr) {
 600                     buf.writeIndex(attr.mainClass());
 601                 }
 602 
 603                 @Override
 604                 public AttributeMapper.AttributeStability stability() {
 605                     return AttributeStability.CP_REFS;
 606                 }
 607             };
 608 
 609     /** Attribute mapper for the {@code ModulePackages} attribute */
 610     public static final AttributeMapper<ModulePackagesAttribute>
 611             MODULE_PACKAGES = new AbstractAttributeMapper<>(NAME_MODULE_PACKAGES) {
 612                 @Override
 613                 public ModulePackagesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 614                     return new BoundAttribute.BoundModulePackagesAttribute(cf, this, p);
 615                 }
 616 
 617                 @Override
 618                 protected void writeBody(BufWriter buf, ModulePackagesAttribute attr) {
 619                     buf.writeListIndices(attr.packages());
 620                 }
 621 
 622                 @Override
 623                 public AttributeMapper.AttributeStability stability() {
 624                     return AttributeStability.CP_REFS;
 625                 }
 626             };
 627 
 628     /** Attribute mapper for the {@code ModuleResolution} attribute */
 629     public static final AttributeMapper<ModuleResolutionAttribute>
 630             MODULE_RESOLUTION = new AbstractAttributeMapper<>(NAME_MODULE_RESOLUTION) {
 631                 @Override
 632                 public ModuleResolutionAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 633                     return new BoundAttribute.BoundModuleResolutionAttribute(cf, this, p);
 634                 }
 635 
 636                 @Override
 637                 protected void writeBody(BufWriter buf, ModuleResolutionAttribute attr) {
 638                     buf.writeU2(attr.resolutionFlags());
 639                 }
 640 
 641                 @Override
 642                 public AttributeMapper.AttributeStability stability() {
 643                     return AttributeStability.STATELESS;
 644                 }
 645             };
 646 
 647     /** Attribute mapper for the {@code ModuleTarget} attribute */
 648     public static final AttributeMapper<ModuleTargetAttribute>
 649             MODULE_TARGET = new AbstractAttributeMapper<>(NAME_MODULE_TARGET) {
 650                 @Override
 651                 public ModuleTargetAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 652                     return new BoundAttribute.BoundModuleTargetAttribute(cf, this, p);
 653                 }
 654 
 655                 @Override
 656                 protected void writeBody(BufWriter buf, ModuleTargetAttribute attr) {
 657                     buf.writeIndex(attr.targetPlatform());
 658                 }
 659 
 660                 @Override
 661                 public AttributeMapper.AttributeStability stability() {
 662                     return AttributeStability.CP_REFS;
 663                 }
 664             };
 665 
 666     /** Attribute mapper for the {@code NestHost} attribute */
 667     public static final AttributeMapper<NestHostAttribute>
 668             NEST_HOST = new AbstractAttributeMapper<>(NAME_NEST_HOST) {
 669                 @Override
 670                 public NestHostAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 671                     return new BoundAttribute.BoundNestHostAttribute(cf, this, p);
 672                 }
 673 
 674                 @Override
 675                 protected void writeBody(BufWriter buf, NestHostAttribute attr) {
 676                     buf.writeIndex(attr.nestHost());
 677                 }
 678 
 679                 @Override
 680                 public AttributeMapper.AttributeStability stability() {
 681                     return AttributeStability.CP_REFS;
 682                 }
 683             };
 684 
 685     /** Attribute mapper for the {@code NestMembers} attribute */
 686     public static final AttributeMapper<NestMembersAttribute>
 687             NEST_MEMBERS = new AbstractAttributeMapper<>(NAME_NEST_MEMBERS) {
 688                 @Override
 689                 public NestMembersAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 690                     return new BoundAttribute.BoundNestMembersAttribute(cf, this, p);
 691                 }
 692 
 693                 @Override
 694                 protected void writeBody(BufWriter buf, NestMembersAttribute attr) {
 695                     buf.writeListIndices(attr.nestMembers());
 696                 }
 697 
 698                 @Override
 699                 public AttributeMapper.AttributeStability stability() {
 700                     return AttributeStability.CP_REFS;
 701                 }
 702             };
 703 
 704     /** Attribute mapper for the {@code PermittedSubclasses} attribute */
 705     public static final AttributeMapper<PermittedSubclassesAttribute>
 706             PERMITTED_SUBCLASSES = new AbstractAttributeMapper<>(NAME_PERMITTED_SUBCLASSES) {
 707                 @Override
 708                 public PermittedSubclassesAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 709                     return new BoundAttribute.BoundPermittedSubclassesAttribute(cf, this, p);
 710                 }
 711 
 712                 @Override
 713                 protected void writeBody(BufWriter buf, PermittedSubclassesAttribute attr) {
 714                     buf.writeListIndices(attr.permittedSubclasses());
 715                 }
 716 
 717                 @Override
 718                 public AttributeMapper.AttributeStability stability() {
 719                     return AttributeStability.CP_REFS;
 720                 }
 721             };
 722 
 723     /** Attribute mapper for the {@code Record} attribute */
 724     public static final AttributeMapper<RecordAttribute>
 725             RECORD = new AbstractAttributeMapper<>(NAME_RECORD) {
 726                 @Override
 727                 public RecordAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 728                     return new BoundAttribute.BoundRecordAttribute(cf, this, p);
 729                 }
 730 
 731                 @Override
 732                 protected void writeBody(BufWriter buf, RecordAttribute attr) {
 733                     List<RecordComponentInfo> components = attr.components();
 734                     buf.writeU2(components.size());
 735                     for (RecordComponentInfo info : components) {
 736                         buf.writeIndex(info.name());
 737                         buf.writeIndex(info.descriptor());
 738                         buf.writeList(info.attributes());
 739                     }
 740                 }
 741 
 742                 @Override
 743                 public AttributeMapper.AttributeStability stability() {
 744                     return AttributeStability.CP_REFS;
 745                 }
 746             };
 747 
 748     /** Attribute mapper for the {@code RuntimeInvisibleAnnotations} attribute */
 749     public static final AttributeMapper<RuntimeInvisibleAnnotationsAttribute>
 750             RUNTIME_INVISIBLE_ANNOTATIONS = new AbstractAttributeMapper<>(NAME_RUNTIME_INVISIBLE_ANNOTATIONS) {
 751                 @Override
 752                 public RuntimeInvisibleAnnotationsAttribute readAttribute(AttributedElement enclosing, ClassReader cf, int pos) {
 753                     return new BoundAttribute.BoundRuntimeInvisibleAnnotationsAttribute(cf, pos);
 754                 }
 755 
 756                 @Override
 757                 protected void writeBody(BufWriter buf, RuntimeInvisibleAnnotationsAttribute attr) {
 758                     buf.writeList(attr.annotations());
 759                 }
 760 
 761                 @Override
 762                 public AttributeMapper.AttributeStability stability() {
 763                     return AttributeStability.CP_REFS;
 764                 }
 765             };
 766 
 767     /** Attribute mapper for the {@code RuntimeInvisibleParameterAnnotations} attribute */
 768     public static final AttributeMapper<RuntimeInvisibleParameterAnnotationsAttribute>
 769             RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS = new AbstractAttributeMapper<>(NAME_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS) {
 770                 @Override
 771                 public RuntimeInvisibleParameterAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 772                     return new BoundAttribute.BoundRuntimeInvisibleParameterAnnotationsAttribute(cf, this, p);
 773                 }
 774 
 775                 @Override
 776                 protected void writeBody(BufWriter buf, RuntimeInvisibleParameterAnnotationsAttribute attr) {
 777                     List<List<Annotation>> lists = attr.parameterAnnotations();
 778                     buf.writeU1(lists.size());
 779                     for (List<Annotation> list : lists)
 780                         buf.writeList(list);
 781                 }
 782 
 783                 @Override
 784                 public AttributeMapper.AttributeStability stability() {
 785                     return AttributeStability.CP_REFS;
 786                 }
 787             };
 788 
 789     /** Attribute mapper for the {@code RuntimeInvisibleTypeAnnotations} attribute */
 790     public static final AttributeMapper<RuntimeInvisibleTypeAnnotationsAttribute>
 791             RUNTIME_INVISIBLE_TYPE_ANNOTATIONS = new AbstractAttributeMapper<>(NAME_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS) {
 792                 @Override
 793                 public RuntimeInvisibleTypeAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 794                     return new BoundAttribute.BoundRuntimeInvisibleTypeAnnotationsAttribute(e, cf, this, p);
 795                 }
 796 
 797                 @Override
 798                 protected void writeBody(BufWriter buf, RuntimeInvisibleTypeAnnotationsAttribute attr) {
 799                     buf.writeList(attr.annotations());
 800                 }
 801 
 802                 @Override
 803                 public AttributeMapper.AttributeStability stability() {
 804                     return AttributeStability.UNSTABLE;
 805                 }
 806             };
 807 
 808     /** Attribute mapper for the {@code RuntimeVisibleAnnotations} attribute */
 809     public static final AttributeMapper<RuntimeVisibleAnnotationsAttribute>
 810             RUNTIME_VISIBLE_ANNOTATIONS = new AbstractAttributeMapper<>(NAME_RUNTIME_VISIBLE_ANNOTATIONS) {
 811                 @Override
 812                 public RuntimeVisibleAnnotationsAttribute readAttribute(AttributedElement enclosing, ClassReader cf, int pos) {
 813                     return new BoundAttribute.BoundRuntimeVisibleAnnotationsAttribute(cf, pos);
 814                 }
 815 
 816                 @Override
 817                 protected void writeBody(BufWriter buf, RuntimeVisibleAnnotationsAttribute attr) {
 818                     buf.writeList(attr.annotations());
 819                 }
 820 
 821                 @Override
 822                 public AttributeMapper.AttributeStability stability() {
 823                     return AttributeStability.CP_REFS;
 824                 }
 825             };
 826 
 827     /** Attribute mapper for the {@code RuntimeVisibleParameterAnnotations} attribute */
 828     public static final AttributeMapper<RuntimeVisibleParameterAnnotationsAttribute>
 829             RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS = new AbstractAttributeMapper<>(NAME_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS) {
 830                 @Override
 831                 public RuntimeVisibleParameterAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 832                     return new BoundAttribute.BoundRuntimeVisibleParameterAnnotationsAttribute(cf, this, p);
 833                 }
 834 
 835                 @Override
 836                 protected void writeBody(BufWriter buf, RuntimeVisibleParameterAnnotationsAttribute attr) {
 837                     List<List<Annotation>> lists = attr.parameterAnnotations();
 838                     buf.writeU1(lists.size());
 839                     for (List<Annotation> list : lists)
 840                         buf.writeList(list);
 841                 }
 842 
 843                 @Override
 844                 public AttributeMapper.AttributeStability stability() {
 845                     return AttributeStability.CP_REFS;
 846                 }
 847             };
 848 
 849     /** Attribute mapper for the {@code RuntimeVisibleTypeAnnotations} attribute */
 850     public static final AttributeMapper<RuntimeVisibleTypeAnnotationsAttribute>
 851             RUNTIME_VISIBLE_TYPE_ANNOTATIONS = new AbstractAttributeMapper<>(NAME_RUNTIME_VISIBLE_TYPE_ANNOTATIONS) {
 852                 @Override
 853                 public RuntimeVisibleTypeAnnotationsAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 854                     return new BoundAttribute.BoundRuntimeVisibleTypeAnnotationsAttribute(e, cf, this, p);
 855                 }
 856 
 857                 @Override
 858                 protected void writeBody(BufWriter buf, RuntimeVisibleTypeAnnotationsAttribute attr) {
 859                     buf.writeList(attr.annotations());
 860                 }
 861 
 862                 @Override
 863                 public AttributeMapper.AttributeStability stability() {
 864                     return AttributeStability.UNSTABLE;
 865                 }
 866             };
 867 
 868     /** Attribute mapper for the {@code Signature} attribute */
 869     public static final AttributeMapper<SignatureAttribute>
 870             SIGNATURE = new AbstractAttributeMapper<>(NAME_SIGNATURE) {
 871                 @Override
 872                 public SignatureAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 873                     return new BoundAttribute.BoundSignatureAttribute(cf, this, p);
 874                 }
 875 
 876                 @Override
 877                 protected void writeBody(BufWriter buf, SignatureAttribute attr) {
 878                     buf.writeIndex(attr.signature());
 879                 }
 880 
 881                 @Override
 882                 public AttributeMapper.AttributeStability stability() {
 883                     return AttributeStability.CP_REFS;
 884                 }
 885             };
 886 
 887     /** Attribute mapper for the {@code SourceDebugExtension} attribute */
 888     public static final AttributeMapper<SourceDebugExtensionAttribute>
 889             SOURCE_DEBUG_EXTENSION = new AbstractAttributeMapper<>(NAME_SOURCE_DEBUG_EXTENSION) {
 890                 @Override
 891                 public SourceDebugExtensionAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 892                     return new BoundAttribute.BoundSourceDebugExtensionAttribute(cf, this, p);
 893                 }
 894 
 895                 @Override
 896                 protected void writeBody(BufWriter buf, SourceDebugExtensionAttribute attr) {
 897                     buf.writeBytes(attr.contents());
 898                 }
 899 
 900                 @Override
 901                 public AttributeMapper.AttributeStability stability() {
 902                     return AttributeStability.STATELESS;
 903                 }
 904             };
 905 
 906     /** Attribute mapper for the {@code SourceFile} attribute */
 907     public static final AttributeMapper<SourceFileAttribute>
 908             SOURCE_FILE = new AbstractAttributeMapper<>(NAME_SOURCE_FILE) {
 909                 @Override
 910                 public SourceFileAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 911                     return new BoundAttribute.BoundSourceFileAttribute(cf, this, p);
 912                 }
 913 
 914                 @Override
 915                 protected void writeBody(BufWriter buf, SourceFileAttribute attr) {
 916                     buf.writeIndex(attr.sourceFile());
 917                 }
 918 
 919                 @Override
 920                 public AttributeMapper.AttributeStability stability() {
 921                     return AttributeStability.CP_REFS;
 922                 }
 923             };
 924 
 925     /** Attribute mapper for the {@code SourceID} attribute */
 926     public static final AttributeMapper<SourceIDAttribute>
 927             SOURCE_ID = new AbstractAttributeMapper<>(NAME_SOURCE_ID) {
 928                 @Override
 929                 public SourceIDAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 930                     return new BoundAttribute.BoundSourceIDAttribute(cf, this, p);
 931                 }
 932 
 933                 @Override
 934                 protected void writeBody(BufWriter buf, SourceIDAttribute attr) {
 935                     buf.writeIndex(attr.sourceId());
 936                 }
 937 
 938                 @Override
 939                 public AttributeMapper.AttributeStability stability() {
 940                     return AttributeStability.CP_REFS;
 941                 }
 942             };
 943 
 944     /** Attribute mapper for the {@code StackMapTable} attribute */
 945     public static final AttributeMapper<StackMapTableAttribute>
 946             STACK_MAP_TABLE = new AbstractAttributeMapper<>(NAME_STACK_MAP_TABLE) {
 947                 @Override
 948                 public StackMapTableAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 949                     return new BoundAttribute.BoundStackMapTableAttribute((CodeImpl)e, cf, this, p);
 950                 }
 951 
 952                 @Override
 953                 protected void writeBody(BufWriter b, StackMapTableAttribute attr) {
 954                     StackMapDecoder.writeFrames(b, attr.entries());
 955                 }
 956 
 957                 @Override
 958                 public AttributeMapper.AttributeStability stability() {
 959                     return AttributeStability.LABELS;
 960                 }
 961             };
 962 
 963 
 964     /** Attribute mapper for the {@code Synthetic} attribute */
 965     public static final AttributeMapper<SyntheticAttribute>
 966             SYNTHETIC = new AbstractAttributeMapper<>(NAME_SYNTHETIC, true) {
 967                 @Override
 968                 public SyntheticAttribute readAttribute(AttributedElement e, ClassReader cf, int p) {
 969                     return new BoundAttribute.BoundSyntheticAttribute(cf, this, p);
 970                 }
 971 
 972                 @Override
 973                 protected void writeBody(BufWriter buf, SyntheticAttribute attr) {
 974                     // empty
 975                 }
 976 
 977                 @Override
 978                 public AttributeMapper.AttributeStability stability() {
 979                     return AttributeStability.STATELESS;
 980                 }
 981             };
 982 
 983     /**
 984      * {@return the attribute mapper for a standard attribute}
 985      *
 986      * @param name the name of the attribute to find
 987      */
 988     public static AttributeMapper<?> standardAttribute(Utf8Entry name) {
 989         return _ATTR_MAP.get(name);
 990     }
 991 
 992     /**
 993      * All standard attribute mappers.
 994      */
 995     public static final Set<AttributeMapper<?>> PREDEFINED_ATTRIBUTES = Set.of(
 996             ANNOTATION_DEFAULT,
 997             BOOTSTRAP_METHODS,
 998             CHARACTER_RANGE_TABLE,
 999             CODE,
1000             COMPILATION_ID,
1001             CONSTANT_VALUE,
1002             DEPRECATED,
1003             ENCLOSING_METHOD,
1004             EXCEPTIONS,
1005             INNER_CLASSES,
1006             LINE_NUMBER_TABLE,
1007             LOCAL_VARIABLE_TABLE,
1008             LOCAL_VARIABLE_TYPE_TABLE,
1009             METHOD_PARAMETERS,
1010             MODULE,
1011             MODULE_HASHES,
1012             MODULE_MAIN_CLASS,
1013             MODULE_PACKAGES,
1014             MODULE_RESOLUTION,
1015             MODULE_TARGET,
1016             NEST_HOST,
1017             NEST_MEMBERS,
1018             PERMITTED_SUBCLASSES,
1019             RECORD,
1020             RUNTIME_INVISIBLE_ANNOTATIONS,
1021             RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS,
1022             RUNTIME_INVISIBLE_TYPE_ANNOTATIONS,
1023             RUNTIME_VISIBLE_ANNOTATIONS,
1024             RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS,
1025             RUNTIME_VISIBLE_TYPE_ANNOTATIONS,
1026             SIGNATURE,
1027             SOURCE_DEBUG_EXTENSION,
1028             SOURCE_FILE,
1029             SOURCE_ID,
1030             STACK_MAP_TABLE,
1031             SYNTHETIC);
1032 
1033     private static final Map<Utf8Entry, AttributeMapper<?>> _ATTR_MAP;
1034     //no lambdas here as this is on critical JDK boostrap path
1035     static {
1036         var map = new HashMap<Utf8Entry, AttributeMapper<?>>(64);
1037         for (var am : PREDEFINED_ATTRIBUTES) {
1038             map.put(AbstractPoolEntry.rawUtf8EntryFromStandardAttributeName(am.name()), am);
1039         }
1040         _ATTR_MAP = Collections.unmodifiableMap(map);
1041     }
1042 }