xref: /aosp_15_r20/external/javassist/src/main/javassist/bytecode/AttributeInfo.java (revision f1fbf3c2ab775ce834e0af96b7a85bdc7a0eac65)
1*f1fbf3c2SXin Li /*
2*f1fbf3c2SXin Li  * Javassist, a Java-bytecode translator toolkit.
3*f1fbf3c2SXin Li  * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
4*f1fbf3c2SXin Li  *
5*f1fbf3c2SXin Li  * The contents of this file are subject to the Mozilla Public License Version
6*f1fbf3c2SXin Li  * 1.1 (the "License"); you may not use this file except in compliance with
7*f1fbf3c2SXin Li  * the License.  Alternatively, the contents of this file may be used under
8*f1fbf3c2SXin Li  * the terms of the GNU Lesser General Public License Version 2.1 or later,
9*f1fbf3c2SXin Li  * or the Apache License Version 2.0.
10*f1fbf3c2SXin Li  *
11*f1fbf3c2SXin Li  * Software distributed under the License is distributed on an "AS IS" basis,
12*f1fbf3c2SXin Li  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13*f1fbf3c2SXin Li  * for the specific language governing rights and limitations under the
14*f1fbf3c2SXin Li  * License.
15*f1fbf3c2SXin Li  */
16*f1fbf3c2SXin Li 
17*f1fbf3c2SXin Li package javassist.bytecode;
18*f1fbf3c2SXin Li 
19*f1fbf3c2SXin Li import java.io.DataInputStream;
20*f1fbf3c2SXin Li import java.io.DataOutputStream;
21*f1fbf3c2SXin Li import java.io.IOException;
22*f1fbf3c2SXin Li import java.util.ArrayList;
23*f1fbf3c2SXin Li import java.util.Arrays;
24*f1fbf3c2SXin Li import java.util.List;
25*f1fbf3c2SXin Li import java.util.Map;
26*f1fbf3c2SXin Li 
27*f1fbf3c2SXin Li // Note: if you define a new subclass of AttributeInfo, then
28*f1fbf3c2SXin Li //       update AttributeInfo.read(), .copy(), and (maybe) write().
29*f1fbf3c2SXin Li 
30*f1fbf3c2SXin Li /**
31*f1fbf3c2SXin Li  * <code>attribute_info</code> structure.
32*f1fbf3c2SXin Li  *
33*f1fbf3c2SXin Li  * @see ClassFile#getAttribute(String)
34*f1fbf3c2SXin Li  * @see MethodInfo#getAttribute(String)
35*f1fbf3c2SXin Li  * @see FieldInfo#getAttribute(String)
36*f1fbf3c2SXin Li  */
37*f1fbf3c2SXin Li public class AttributeInfo {
38*f1fbf3c2SXin Li     protected ConstPool constPool;
39*f1fbf3c2SXin Li     int name;
40*f1fbf3c2SXin Li     byte[] info;
41*f1fbf3c2SXin Li 
AttributeInfo(ConstPool cp, int attrname, byte[] attrinfo)42*f1fbf3c2SXin Li     protected AttributeInfo(ConstPool cp, int attrname, byte[] attrinfo) {
43*f1fbf3c2SXin Li         constPool = cp;
44*f1fbf3c2SXin Li         name = attrname;
45*f1fbf3c2SXin Li         info = attrinfo;
46*f1fbf3c2SXin Li     }
47*f1fbf3c2SXin Li 
AttributeInfo(ConstPool cp, String attrname)48*f1fbf3c2SXin Li     protected AttributeInfo(ConstPool cp, String attrname) {
49*f1fbf3c2SXin Li         this(cp, attrname, (byte[])null);
50*f1fbf3c2SXin Li     }
51*f1fbf3c2SXin Li 
52*f1fbf3c2SXin Li     /**
53*f1fbf3c2SXin Li      * Constructs an <code>attribute_info</code> structure.
54*f1fbf3c2SXin Li      *
55*f1fbf3c2SXin Li      * @param cp                constant pool table
56*f1fbf3c2SXin Li      * @param attrname          attribute name
57*f1fbf3c2SXin Li      * @param attrinfo          <code>info</code> field
58*f1fbf3c2SXin Li      *                          of <code>attribute_info</code> structure.
59*f1fbf3c2SXin Li      */
AttributeInfo(ConstPool cp, String attrname, byte[] attrinfo)60*f1fbf3c2SXin Li     public AttributeInfo(ConstPool cp, String attrname, byte[] attrinfo) {
61*f1fbf3c2SXin Li         this(cp, cp.addUtf8Info(attrname), attrinfo);
62*f1fbf3c2SXin Li     }
63*f1fbf3c2SXin Li 
AttributeInfo(ConstPool cp, int n, DataInputStream in)64*f1fbf3c2SXin Li     protected AttributeInfo(ConstPool cp, int n, DataInputStream in)
65*f1fbf3c2SXin Li         throws IOException
66*f1fbf3c2SXin Li     {
67*f1fbf3c2SXin Li         constPool = cp;
68*f1fbf3c2SXin Li         name = n;
69*f1fbf3c2SXin Li         int len = in.readInt();
70*f1fbf3c2SXin Li         info = new byte[len];
71*f1fbf3c2SXin Li         if (len > 0)
72*f1fbf3c2SXin Li             in.readFully(info);
73*f1fbf3c2SXin Li     }
74*f1fbf3c2SXin Li 
read(ConstPool cp, DataInputStream in)75*f1fbf3c2SXin Li     static AttributeInfo read(ConstPool cp, DataInputStream in)
76*f1fbf3c2SXin Li         throws IOException
77*f1fbf3c2SXin Li     {
78*f1fbf3c2SXin Li         int name = in.readUnsignedShort();
79*f1fbf3c2SXin Li         String nameStr = cp.getUtf8Info(name);
80*f1fbf3c2SXin Li         char first = nameStr.charAt(0);
81*f1fbf3c2SXin Li         if (first < 'E')
82*f1fbf3c2SXin Li             if (nameStr.equals(AnnotationDefaultAttribute.tag))
83*f1fbf3c2SXin Li                 return new AnnotationDefaultAttribute(cp, name, in);
84*f1fbf3c2SXin Li             else if (nameStr.equals(BootstrapMethodsAttribute.tag))
85*f1fbf3c2SXin Li                 return new BootstrapMethodsAttribute(cp, name, in);
86*f1fbf3c2SXin Li             else if (nameStr.equals(CodeAttribute.tag))
87*f1fbf3c2SXin Li                 return new CodeAttribute(cp, name, in);
88*f1fbf3c2SXin Li             else if (nameStr.equals(ConstantAttribute.tag))
89*f1fbf3c2SXin Li                 return new ConstantAttribute(cp, name, in);
90*f1fbf3c2SXin Li             else if (nameStr.equals(DeprecatedAttribute.tag))
91*f1fbf3c2SXin Li                 return new DeprecatedAttribute(cp, name, in);
92*f1fbf3c2SXin Li 
93*f1fbf3c2SXin Li         if (first < 'M')
94*f1fbf3c2SXin Li             if (nameStr.equals(EnclosingMethodAttribute.tag))
95*f1fbf3c2SXin Li                 return new EnclosingMethodAttribute(cp, name, in);
96*f1fbf3c2SXin Li             else if (nameStr.equals(ExceptionsAttribute.tag))
97*f1fbf3c2SXin Li                 return new ExceptionsAttribute(cp, name, in);
98*f1fbf3c2SXin Li             else if (nameStr.equals(InnerClassesAttribute.tag))
99*f1fbf3c2SXin Li                 return new InnerClassesAttribute(cp, name, in);
100*f1fbf3c2SXin Li             else if (nameStr.equals(LineNumberAttribute.tag))
101*f1fbf3c2SXin Li                 return new LineNumberAttribute(cp, name, in);
102*f1fbf3c2SXin Li             else if (nameStr.equals(LocalVariableAttribute.tag))
103*f1fbf3c2SXin Li                 return new LocalVariableAttribute(cp, name, in);
104*f1fbf3c2SXin Li             else if (nameStr.equals(LocalVariableTypeAttribute.tag))
105*f1fbf3c2SXin Li                 return new LocalVariableTypeAttribute(cp, name, in);
106*f1fbf3c2SXin Li 
107*f1fbf3c2SXin Li         if (first < 'S')
108*f1fbf3c2SXin Li             /* Note that the names of Annotations attributes begin with 'R'. */
109*f1fbf3c2SXin Li             if (nameStr.equals(MethodParametersAttribute.tag))
110*f1fbf3c2SXin Li                 return new MethodParametersAttribute(cp, name, in);
111*f1fbf3c2SXin Li             else if (nameStr.equals(NestHostAttribute.tag))
112*f1fbf3c2SXin Li                 return new NestHostAttribute(cp, name, in);
113*f1fbf3c2SXin Li             else if (nameStr.equals(NestMembersAttribute.tag))
114*f1fbf3c2SXin Li                 return new NestMembersAttribute(cp, name, in);
115*f1fbf3c2SXin Li             else if (nameStr.equals(AnnotationsAttribute.visibleTag)
116*f1fbf3c2SXin Li                      || nameStr.equals(AnnotationsAttribute.invisibleTag))
117*f1fbf3c2SXin Li                 // RuntimeVisibleAnnotations or RuntimeInvisibleAnnotations
118*f1fbf3c2SXin Li                 return new AnnotationsAttribute(cp, name, in);
119*f1fbf3c2SXin Li             else if (nameStr.equals(ParameterAnnotationsAttribute.visibleTag)
120*f1fbf3c2SXin Li                      || nameStr.equals(ParameterAnnotationsAttribute.invisibleTag))
121*f1fbf3c2SXin Li                 return new ParameterAnnotationsAttribute(cp, name, in);
122*f1fbf3c2SXin Li             else if (nameStr.equals(TypeAnnotationsAttribute.visibleTag)
123*f1fbf3c2SXin Li                      || nameStr.equals(TypeAnnotationsAttribute.invisibleTag))
124*f1fbf3c2SXin Li                 return new TypeAnnotationsAttribute(cp, name, in);
125*f1fbf3c2SXin Li 
126*f1fbf3c2SXin Li         if (first >= 'S')
127*f1fbf3c2SXin Li             if (nameStr.equals(SignatureAttribute.tag))
128*f1fbf3c2SXin Li                 return new SignatureAttribute(cp, name, in);
129*f1fbf3c2SXin Li             else if (nameStr.equals(SourceFileAttribute.tag))
130*f1fbf3c2SXin Li                 return new SourceFileAttribute(cp, name, in);
131*f1fbf3c2SXin Li             else if (nameStr.equals(SyntheticAttribute.tag))
132*f1fbf3c2SXin Li                 return new SyntheticAttribute(cp, name, in);
133*f1fbf3c2SXin Li             else if (nameStr.equals(StackMap.tag))
134*f1fbf3c2SXin Li                 return new StackMap(cp, name, in);
135*f1fbf3c2SXin Li             else if (nameStr.equals(StackMapTable.tag))
136*f1fbf3c2SXin Li                 return new StackMapTable(cp, name, in);
137*f1fbf3c2SXin Li 
138*f1fbf3c2SXin Li         return new AttributeInfo(cp, name, in);
139*f1fbf3c2SXin Li     }
140*f1fbf3c2SXin Li 
141*f1fbf3c2SXin Li     /**
142*f1fbf3c2SXin Li      * Returns an attribute name.
143*f1fbf3c2SXin Li      */
getName()144*f1fbf3c2SXin Li     public String getName() {
145*f1fbf3c2SXin Li         return constPool.getUtf8Info(name);
146*f1fbf3c2SXin Li     }
147*f1fbf3c2SXin Li 
148*f1fbf3c2SXin Li     /**
149*f1fbf3c2SXin Li      * Returns a constant pool table.
150*f1fbf3c2SXin Li      */
getConstPool()151*f1fbf3c2SXin Li     public ConstPool getConstPool() { return constPool; }
152*f1fbf3c2SXin Li 
153*f1fbf3c2SXin Li     /**
154*f1fbf3c2SXin Li      * Returns the length of this <code>attribute_info</code>
155*f1fbf3c2SXin Li      * structure.
156*f1fbf3c2SXin Li      * The returned value is <code>attribute_length + 6</code>.
157*f1fbf3c2SXin Li      */
length()158*f1fbf3c2SXin Li     public int length() {
159*f1fbf3c2SXin Li         return info.length + 6;
160*f1fbf3c2SXin Li     }
161*f1fbf3c2SXin Li 
162*f1fbf3c2SXin Li     /**
163*f1fbf3c2SXin Li      * Returns the <code>info</code> field
164*f1fbf3c2SXin Li      * of this <code>attribute_info</code> structure.
165*f1fbf3c2SXin Li      *
166*f1fbf3c2SXin Li      * <p>This method is not available if the object is an instance
167*f1fbf3c2SXin Li      * of <code>CodeAttribute</code>.
168*f1fbf3c2SXin Li      */
get()169*f1fbf3c2SXin Li     public byte[] get() { return info; }
170*f1fbf3c2SXin Li 
171*f1fbf3c2SXin Li     /**
172*f1fbf3c2SXin Li      * Sets the <code>info</code> field
173*f1fbf3c2SXin Li      * of this <code>attribute_info</code> structure.
174*f1fbf3c2SXin Li      *
175*f1fbf3c2SXin Li      * <p>This method is not available if the object is an instance
176*f1fbf3c2SXin Li      * of <code>CodeAttribute</code>.
177*f1fbf3c2SXin Li      */
set(byte[] newinfo)178*f1fbf3c2SXin Li     public void set(byte[] newinfo) { info = newinfo; }
179*f1fbf3c2SXin Li 
180*f1fbf3c2SXin Li     /**
181*f1fbf3c2SXin Li      * Makes a copy.  Class names are replaced according to the
182*f1fbf3c2SXin Li      * given <code>Map</code> object.
183*f1fbf3c2SXin Li      *
184*f1fbf3c2SXin Li      * @param newCp     the constant pool table used by the new copy.
185*f1fbf3c2SXin Li      * @param classnames        pairs of replaced and substituted
186*f1fbf3c2SXin Li      *                          class names.
187*f1fbf3c2SXin Li      */
copy(ConstPool newCp, Map<String,String> classnames)188*f1fbf3c2SXin Li     public AttributeInfo copy(ConstPool newCp, Map<String,String> classnames)
189*f1fbf3c2SXin Li     {
190*f1fbf3c2SXin Li         return new AttributeInfo(newCp, getName(), Arrays.copyOf(info, info.length));
191*f1fbf3c2SXin Li     }
192*f1fbf3c2SXin Li 
write(DataOutputStream out)193*f1fbf3c2SXin Li     void write(DataOutputStream out) throws IOException
194*f1fbf3c2SXin Li     {
195*f1fbf3c2SXin Li         out.writeShort(name);
196*f1fbf3c2SXin Li         out.writeInt(info.length);
197*f1fbf3c2SXin Li         if (info.length > 0)
198*f1fbf3c2SXin Li             out.write(info);
199*f1fbf3c2SXin Li     }
200*f1fbf3c2SXin Li 
getLength(List<AttributeInfo> attributes)201*f1fbf3c2SXin Li     static int getLength(List<AttributeInfo> attributes) {
202*f1fbf3c2SXin Li         int size = 0;
203*f1fbf3c2SXin Li 
204*f1fbf3c2SXin Li         for (AttributeInfo attr:attributes)
205*f1fbf3c2SXin Li             size += attr.length();
206*f1fbf3c2SXin Li 
207*f1fbf3c2SXin Li         return size;
208*f1fbf3c2SXin Li     }
209*f1fbf3c2SXin Li 
lookup(List<AttributeInfo> attributes, String name)210*f1fbf3c2SXin Li     static AttributeInfo lookup(List<AttributeInfo> attributes, String name) {
211*f1fbf3c2SXin Li         if (attributes == null)
212*f1fbf3c2SXin Li             return null;
213*f1fbf3c2SXin Li 
214*f1fbf3c2SXin Li         for (AttributeInfo ai:attributes)
215*f1fbf3c2SXin Li             if (ai.getName().equals(name))
216*f1fbf3c2SXin Li                 return ai;
217*f1fbf3c2SXin Li 
218*f1fbf3c2SXin Li         return null;            // no such attribute
219*f1fbf3c2SXin Li     }
220*f1fbf3c2SXin Li 
remove(List<AttributeInfo> attributes, String name)221*f1fbf3c2SXin Li     static synchronized AttributeInfo remove(List<AttributeInfo> attributes, String name) {
222*f1fbf3c2SXin Li         if (attributes == null)
223*f1fbf3c2SXin Li             return null;
224*f1fbf3c2SXin Li 
225*f1fbf3c2SXin Li         for (AttributeInfo ai:attributes)
226*f1fbf3c2SXin Li             if (ai.getName().equals(name))
227*f1fbf3c2SXin Li                 if (attributes.remove(ai))
228*f1fbf3c2SXin Li                     return ai;
229*f1fbf3c2SXin Li 
230*f1fbf3c2SXin Li         return null;
231*f1fbf3c2SXin Li     }
232*f1fbf3c2SXin Li 
writeAll(List<AttributeInfo> attributes, DataOutputStream out)233*f1fbf3c2SXin Li     static void writeAll(List<AttributeInfo> attributes, DataOutputStream out)
234*f1fbf3c2SXin Li         throws IOException
235*f1fbf3c2SXin Li     {
236*f1fbf3c2SXin Li         if (attributes == null)
237*f1fbf3c2SXin Li             return;
238*f1fbf3c2SXin Li 
239*f1fbf3c2SXin Li         for (AttributeInfo attr:attributes)
240*f1fbf3c2SXin Li             attr.write(out);
241*f1fbf3c2SXin Li     }
242*f1fbf3c2SXin Li 
copyAll(List<AttributeInfo> attributes, ConstPool cp)243*f1fbf3c2SXin Li     static List<AttributeInfo> copyAll(List<AttributeInfo> attributes, ConstPool cp) {
244*f1fbf3c2SXin Li         if (attributes == null)
245*f1fbf3c2SXin Li             return null;
246*f1fbf3c2SXin Li 
247*f1fbf3c2SXin Li         List<AttributeInfo> newList = new ArrayList<AttributeInfo>();
248*f1fbf3c2SXin Li         for (AttributeInfo attr:attributes)
249*f1fbf3c2SXin Li             newList.add(attr.copy(cp, null));
250*f1fbf3c2SXin Li 
251*f1fbf3c2SXin Li         return newList;
252*f1fbf3c2SXin Li     }
253*f1fbf3c2SXin Li 
254*f1fbf3c2SXin Li     /* The following two methods are used to implement
255*f1fbf3c2SXin Li      * ClassFile.renameClass().
256*f1fbf3c2SXin Li      * Only CodeAttribute, LocalVariableAttribute,
257*f1fbf3c2SXin Li      * AnnotationsAttribute, and SignatureAttribute
258*f1fbf3c2SXin Li      * override these methods.
259*f1fbf3c2SXin Li      */
renameClass(String oldname, String newname)260*f1fbf3c2SXin Li     void renameClass(String oldname, String newname) {}
renameClass(Map<String,String> classnames)261*f1fbf3c2SXin Li     void renameClass(Map<String,String> classnames) {}
262*f1fbf3c2SXin Li 
renameClass(List<AttributeInfo> attributes, String oldname, String newname)263*f1fbf3c2SXin Li     static void renameClass(List<AttributeInfo> attributes, String oldname, String newname) {
264*f1fbf3c2SXin Li         if (attributes == null)
265*f1fbf3c2SXin Li             return;
266*f1fbf3c2SXin Li 
267*f1fbf3c2SXin Li         for (AttributeInfo ai:attributes)
268*f1fbf3c2SXin Li             ai.renameClass(oldname, newname);
269*f1fbf3c2SXin Li     }
270*f1fbf3c2SXin Li 
renameClass(List<AttributeInfo> attributes, Map<String,String> classnames)271*f1fbf3c2SXin Li     static void renameClass(List<AttributeInfo> attributes, Map<String,String> classnames) {
272*f1fbf3c2SXin Li         if (attributes == null)
273*f1fbf3c2SXin Li             return;
274*f1fbf3c2SXin Li 
275*f1fbf3c2SXin Li         for (AttributeInfo ai:attributes)
276*f1fbf3c2SXin Li             ai.renameClass(classnames);
277*f1fbf3c2SXin Li     }
278*f1fbf3c2SXin Li 
getRefClasses(Map<String,String> classnames)279*f1fbf3c2SXin Li     void getRefClasses(Map<String,String> classnames) {}
280*f1fbf3c2SXin Li 
getRefClasses(List<AttributeInfo> attributes, Map<String,String> classnames)281*f1fbf3c2SXin Li     static void getRefClasses(List<AttributeInfo> attributes, Map<String,String> classnames) {
282*f1fbf3c2SXin Li         if (attributes == null)
283*f1fbf3c2SXin Li             return;
284*f1fbf3c2SXin Li 
285*f1fbf3c2SXin Li         for (AttributeInfo ai:attributes)
286*f1fbf3c2SXin Li             ai.getRefClasses(classnames);
287*f1fbf3c2SXin Li     }
288*f1fbf3c2SXin Li }
289