1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.dexgen.dex.file;
18 
19 import com.android.dexgen.rop.annotation.Annotations;
20 import com.android.dexgen.rop.cst.CstFieldRef;
21 import com.android.dexgen.util.AnnotatedOutput;
22 import com.android.dexgen.util.Hex;
23 import com.android.dexgen.util.ToHuman;
24 
25 /**
26  * Association of a field and its annotations.
27  */
28 public final class FieldAnnotationStruct
29         implements ToHuman, Comparable<FieldAnnotationStruct> {
30     /** {@code non-null;} the field in question */
31     private final CstFieldRef field;
32 
33     /** {@code non-null;} the associated annotations */
34     private AnnotationSetItem annotations;
35 
36     /**
37      * Constructs an instance.
38      *
39      * @param field {@code non-null;} the field in question
40      * @param annotations {@code non-null;} the associated annotations
41      */
FieldAnnotationStruct(CstFieldRef field, AnnotationSetItem annotations)42     public FieldAnnotationStruct(CstFieldRef field,
43             AnnotationSetItem annotations) {
44         if (field == null) {
45             throw new NullPointerException("field == null");
46         }
47 
48         if (annotations == null) {
49             throw new NullPointerException("annotations == null");
50         }
51 
52         this.field = field;
53         this.annotations = annotations;
54     }
55 
56     /** {@inheritDoc} */
hashCode()57     public int hashCode() {
58         return field.hashCode();
59     }
60 
61     /** {@inheritDoc} */
equals(Object other)62     public boolean equals(Object other) {
63         if (! (other instanceof FieldAnnotationStruct)) {
64             return false;
65         }
66 
67         return field.equals(((FieldAnnotationStruct) other).field);
68     }
69 
70     /** {@inheritDoc} */
compareTo(FieldAnnotationStruct other)71     public int compareTo(FieldAnnotationStruct other) {
72         return field.compareTo(other.field);
73     }
74 
75     /** {@inheritDoc} */
addContents(DexFile file)76     public void addContents(DexFile file) {
77         FieldIdsSection fieldIds = file.getFieldIds();
78         MixedItemSection wordData = file.getWordData();
79 
80         fieldIds.intern(field);
81         annotations = wordData.intern(annotations);
82     }
83 
84     /** {@inheritDoc} */
writeTo(DexFile file, AnnotatedOutput out)85     public void writeTo(DexFile file, AnnotatedOutput out) {
86         int fieldIdx = file.getFieldIds().indexOf(field);
87         int annotationsOff = annotations.getAbsoluteOffset();
88 
89         if (out.annotates()) {
90             out.annotate(0, "    " + field.toHuman());
91             out.annotate(4, "      field_idx:       " + Hex.u4(fieldIdx));
92             out.annotate(4, "      annotations_off: " +
93                     Hex.u4(annotationsOff));
94         }
95 
96         out.writeInt(fieldIdx);
97         out.writeInt(annotationsOff);
98     }
99 
100     /** {@inheritDoc} */
toHuman()101     public String toHuman() {
102         return field.toHuman() + ": " + annotations;
103     }
104 
105     /**
106      * Gets the field this item is for.
107      *
108      * @return {@code non-null;} the field
109      */
getField()110     public CstFieldRef getField() {
111         return field;
112     }
113 
114     /**
115      * Gets the associated annotations.
116      *
117      * @return {@code non-null;} the annotations
118      */
getAnnotations()119     public Annotations getAnnotations() {
120         return annotations.getAnnotations();
121     }
122 }
123