1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage com.android.dx.dex.file;
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.annotation.Annotations;
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.annotation.AnnotationsList;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstFieldRef;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.rop.cst.CstMethodRef;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.AnnotatedOutput;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport com.android.dx.util.Hex;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.io.PrintWriter;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList;
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Collections;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Per-class directory of annotations.
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic final class AnnotationsDirectoryItem extends OffsettedItem {
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** the required alignment for instances of this class */
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ALIGNMENT = 4;
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** write size of this class's header, in bytes */
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int HEADER_SIZE = 16;
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** write size of a list element, in bytes */
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final int ELEMENT_SIZE = 8;
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} the class-level annotations, if any */
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private AnnotationSetItem classAnnotations;
45de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
4699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} the annotated fields, if any */
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private ArrayList<FieldAnnotationStruct> fieldAnnotations;
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
4999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} the annotated methods, if any */
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private ArrayList<MethodAnnotationStruct> methodAnnotations;
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
5299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project    /** {@code null-ok;} the annotated parameters, if any */
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private ArrayList<ParameterAnnotationStruct> parameterAnnotations;
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs an empty instance.
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public AnnotationsDirectoryItem() {
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        super(ALIGNMENT, -1);
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        classAnnotations = null;
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fieldAnnotations = null;
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methodAnnotations = null;
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parameterAnnotations = null;
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
66de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public ItemType itemType() {
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return ItemType.TYPE_ANNOTATIONS_DIRECTORY_ITEM;
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns whether this item is empty (has no contents).
75de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
7699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code true} if this item is empty, or {@code false}
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * if not
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isEmpty() {
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (classAnnotations == null) &&
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (fieldAnnotations == null) &&
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (methodAnnotations == null) &&
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (parameterAnnotations == null);
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns whether this item is a candidate for interning. The only
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * interning candidates are ones that <i>only</i> have a non-null
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * set of class annotations, with no other lists.
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
9199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code true} if this is an interning candidate, or
9299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code false} if not
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isInternable() {
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (classAnnotations != null) &&
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (fieldAnnotations == null) &&
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (methodAnnotations == null) &&
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (parameterAnnotations == null);
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int hashCode() {
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (classAnnotations == null) {
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return 0;
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
107de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return classAnnotations.hashCode();
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
110de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@inheritDoc}
113de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p><b>Note:</b>: This throws an exception if this item is not
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * internable.</p>
116de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #isInternable
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int compareTo0(OffsettedItem other) {
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (! isInternable()) {
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new UnsupportedOperationException("uninternable instance");
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        AnnotationsDirectoryItem otherDirectory =
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (AnnotationsDirectoryItem) other;
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return classAnnotations.compareTo(otherDirectory.classAnnotations);
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the direct annotations on this instance. These are annotations
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * made on the class, per se, as opposed to on one of its members.
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * It is only valid to call this method at most once per instance.
134de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
13599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param annotations {@code non-null;} annotations to set for this class
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void setClassAnnotations(Annotations annotations) {
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (annotations == null) {
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException("annotations == null");
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
141de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (classAnnotations != null) {
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new UnsupportedOperationException(
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "class annotations already set");
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        classAnnotations = new AnnotationSetItem(annotations);
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds a field annotations item to this instance.
152de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
15399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param field {@code non-null;} field in question
15499409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param annotations {@code non-null;} associated annotations to add
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addFieldAnnotations(CstFieldRef field,
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Annotations annotations) {
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (fieldAnnotations == null) {
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            fieldAnnotations = new ArrayList<FieldAnnotationStruct>();
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
161de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        fieldAnnotations.add(new FieldAnnotationStruct(field,
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        new AnnotationSetItem(annotations)));
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds a method annotations item to this instance.
168de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
16999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param method {@code non-null;} method in question
17099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param annotations {@code non-null;} associated annotations to add
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addMethodAnnotations(CstMethodRef method,
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Annotations annotations) {
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodAnnotations == null) {
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodAnnotations = new ArrayList<MethodAnnotationStruct>();
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        methodAnnotations.add(new MethodAnnotationStruct(method,
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        new AnnotationSetItem(annotations)));
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Adds a parameter annotations item to this instance.
184de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
18599409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param method {@code non-null;} method in question
18699409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param list {@code non-null;} associated list of annotation sets to add
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addParameterAnnotations(CstMethodRef method,
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            AnnotationsList list) {
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (parameterAnnotations == null) {
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            parameterAnnotations = new ArrayList<ParameterAnnotationStruct>();
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        parameterAnnotations.add(new ParameterAnnotationStruct(method, list));
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the method annotations for a given method, if any. This is
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * meant for use by debugging / dumping code.
200de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
20199409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param method {@code non-null;} the method
20299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the method annotations, if any
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public Annotations getMethodAnnotations(CstMethodRef method) {
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodAnnotations == null) {
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
208de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (MethodAnnotationStruct item : methodAnnotations) {
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (item.getMethod().equals(method)) {
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return item.getAnnotations();
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return null;
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets the parameter annotations for a given method, if any. This is
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * meant for use by debugging / dumping code.
221de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
22299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param method {@code non-null;} the method
22399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code null-ok;} the parameter annotations, if any
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public AnnotationsList getParameterAnnotations(CstMethodRef method) {
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (parameterAnnotations == null) {
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (ParameterAnnotationStruct item : parameterAnnotations) {
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (item.getMethod().equals(method)) {
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return item.getAnnotationsList();
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return null;
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
238de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addContents(DexFile file) {
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        MixedItemSection wordData = file.getWordData();
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (classAnnotations != null) {
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            classAnnotations = wordData.intern(classAnnotations);
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (fieldAnnotations != null) {
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (FieldAnnotationStruct item : fieldAnnotations) {
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                item.addContents(file);
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodAnnotations != null) {
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (MethodAnnotationStruct item : methodAnnotations) {
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                item.addContents(file);
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
258de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (parameterAnnotations != null) {
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (ParameterAnnotationStruct item : parameterAnnotations) {
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                item.addContents(file);
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String toHuman() {
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        throw new RuntimeException("unsupported");
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected void place0(Section addedTo, int offset) {
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // We just need to set the write size here.
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int elementCount = listSize(fieldAnnotations)
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            + listSize(methodAnnotations) + listSize(parameterAnnotations);
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        setWriteSize(HEADER_SIZE + (elementCount * ELEMENT_SIZE));
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /** {@inheritDoc} */
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    protected void writeTo0(DexFile file, AnnotatedOutput out) {
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean annotates = out.annotates();
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int classOff = OffsettedItem.getAbsoluteOffsetOr0(classAnnotations);
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int fieldsSize = listSize(fieldAnnotations);
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int methodsSize = listSize(methodAnnotations);
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int parametersSize = listSize(parameterAnnotations);
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (annotates) {
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.annotate(0, offsetString() + " annotations directory");
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.annotate(4, "  class_annotations_off: " + Hex.u4(classOff));
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.annotate(4, "  fields_size:           " +
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Hex.u4(fieldsSize));
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.annotate(4, "  methods_size:          " +
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Hex.u4(methodsSize));
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.annotate(4, "  parameters_size:       " +
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    Hex.u4(parametersSize));
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out.writeInt(classOff);
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out.writeInt(fieldsSize);
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out.writeInt(methodsSize);
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        out.writeInt(parametersSize);
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (fieldsSize != 0) {
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Collections.sort(fieldAnnotations);
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (annotates) {
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                out.annotate(0, "  fields:");
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (FieldAnnotationStruct item : fieldAnnotations) {
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                item.writeTo(file, out);
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodsSize != 0) {
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Collections.sort(methodAnnotations);
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (annotates) {
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                out.annotate(0, "  methods:");
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (MethodAnnotationStruct item : methodAnnotations) {
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                item.writeTo(file, out);
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (parametersSize != 0) {
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Collections.sort(parameterAnnotations);
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (annotates) {
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                out.annotate(0, "  parameters:");
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (ParameterAnnotationStruct item : parameterAnnotations) {
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                item.writeTo(file, out);
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
33999409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * Gets the list size of the given list, or {@code 0} if given
34099409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * {@code null}.
341de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
34299409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param list {@code null-ok;} the list in question
34399409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @return {@code >= 0;} its size
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static int listSize(ArrayList<?> list) {
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (list == null) {
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return 0;
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return list.size();
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Prints out the contents of this instance, in a debugging-friendly
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * way. This is meant to be called from {@link ClassDefItem#debugPrint}.
356de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro     *
35799409883d9c4c0ffb49b070ce307bb33a9dfe9f1The Android Open Source Project     * @param out {@code non-null;} where to output to
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*package*/ void debugPrint(PrintWriter out) {
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (classAnnotations != null) {
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.println("  class annotations: " + classAnnotations);
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (fieldAnnotations != null) {
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.println("  field annotations:");
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (FieldAnnotationStruct item : fieldAnnotations) {
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                out.println("    " + item.toHuman());
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (methodAnnotations != null) {
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.println("  method annotations:");
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (MethodAnnotationStruct item : methodAnnotations) {
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                out.println("    " + item.toHuman());
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
377de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (parameterAnnotations != null) {
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            out.println("  parameter annotations:");
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            for (ParameterAnnotationStruct item : parameterAnnotations) {
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                out.println("    " + item.toHuman());
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
384de75089fb7216d19e9c22cce4dc62a49513477d3Carl Shapiro    }
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
386