1917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/* 2917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Copyright (C) 2007 The Android Open Source Project 3917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 4917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Licensed under the Apache License, Version 2.0 (the "License"); 5917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * you may not use this file except in compliance with the License. 6917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * You may obtain a copy of the License at 7917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 8917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * http://www.apache.org/licenses/LICENSE-2.0 9917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 10917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Unless required by applicable law or agreed to in writing, software 11917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * distributed under the License is distributed on an "AS IS" BASIS, 12917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * See the License for the specific language governing permissions and 14917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * limitations under the License. 15917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 16917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 17917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpackage com.android.dexgen.rop.annotation; 18917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 19917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.rop.cst.CstType; 20917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport com.android.dexgen.util.MutabilityControl; 21917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 22917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.util.Collection; 23917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.util.Collections; 24917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.util.Iterator; 25917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulimport java.util.TreeMap; 26917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 27917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul/** 28917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * List of {@link Annotation} instances. 29917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 30917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgulpublic final class Annotations extends MutabilityControl 31917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul implements Comparable<Annotations> { 32917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} immutable empty instance */ 33917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static final Annotations EMPTY = new Annotations(); 34917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 35917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul static { 36917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul EMPTY.setImmutable(); 37917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 38917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 39917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@code non-null;} map from types to annotations */ 40917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul private final TreeMap<CstType, Annotation> annotations; 41917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 42917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 43917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an immutable instance which is the combination of the 44917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * two given instances. The two instances must contain disjoint sets 45917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * of types. 46917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 47917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param a1 {@code non-null;} an instance 48917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param a2 {@code non-null;} the other instance 49917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the combination 50917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @throws IllegalArgumentException thrown if there is a duplicate type 51917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 52917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static Annotations combine(Annotations a1, Annotations a2) { 53917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Annotations result = new Annotations(); 54917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 55917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.addAll(a1); 56917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.addAll(a2); 57917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.setImmutable(); 58917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 59917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return result; 60917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 61917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 62917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 63917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an immutable instance which is the combination of the 64917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * given instance with the given additional annotation. The latter's 65917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * type must not already appear in the former. 66917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 67917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param annotations {@code non-null;} the instance to augment 68917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param annotation {@code non-null;} the additional annotation 69917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the combination 70917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @throws IllegalArgumentException thrown if there is a duplicate type 71917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 72917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public static Annotations combine(Annotations annotations, 73917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Annotation annotation) { 74917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Annotations result = new Annotations(); 75917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 76917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.addAll(annotations); 77917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.add(annotation); 78917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul result.setImmutable(); 79917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 80917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return result; 81917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 82917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 83917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 84917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Constructs an empty instance. 85917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 86917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Annotations() { 87917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul annotations = new TreeMap<CstType, Annotation>(); 88917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 89917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 90917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 91917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul @Override 92917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int hashCode() { 93917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return annotations.hashCode(); 94917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 95917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 96917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 97917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul @Override 98917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public boolean equals(Object other) { 99917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (! (other instanceof Annotations)) { 100917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return false; 101917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 102917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 103917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Annotations otherAnnotations = (Annotations) other; 104917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 105917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return annotations.equals(otherAnnotations.annotations); 106917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 107917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 108917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 109917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int compareTo(Annotations other) { 110917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Iterator<Annotation> thisIter = annotations.values().iterator(); 111917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Iterator<Annotation> otherIter = other.annotations.values().iterator(); 112917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 113917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul while (thisIter.hasNext() && otherIter.hasNext()) { 114917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Annotation thisOne = thisIter.next(); 115917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul Annotation otherOne = otherIter.next(); 116917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 117917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul int result = thisOne.compareTo(otherOne); 118917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (result != 0) { 119917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return result; 120917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 121917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 122917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 123917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (thisIter.hasNext()) { 124917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return 1; 125917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } else if (otherIter.hasNext()) { 126917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return -1; 127917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 128917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 129917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return 0; 130917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 131917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 132917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** {@inheritDoc} */ 133917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public String toString() { 134917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul StringBuilder sb = new StringBuilder(); 135917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul boolean first = true; 136917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 137917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul sb.append("annotations{"); 138917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 139917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (Annotation a : annotations.values()) { 140917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (first) { 141917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul first = false; 142917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } else { 143917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul sb.append(", "); 144917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 145917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul sb.append(a.toHuman()); 146917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 147917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 148917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul sb.append("}"); 149917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return sb.toString(); 150917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 151917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 152917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 153917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the number of elements in this instance. 154917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 155917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code >= 0;} the size 156917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 157917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public int size() { 158917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return annotations.size(); 159917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 160917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 161917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 162917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Adds an element to this instance. There must not already be an 163917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * element of the same type. 164917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 165917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param annotation {@code non-null;} the element to add 166917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @throws IllegalArgumentException thrown if there is a duplicate type 167917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 168917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public void add(Annotation annotation) { 169917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throwIfImmutable(); 170917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 171917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (annotation == null) { 172917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("annotation == null"); 173917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 174917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 175917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul CstType type = annotation.getType(); 176917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 177917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (annotations.containsKey(type)) { 178917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new IllegalArgumentException("duplicate type: " + 179917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul type.toHuman()); 180917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 181917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 182917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul annotations.put(type, annotation); 183917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 184917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 185917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 186917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Adds all of the elements of the given instance to this one. The 187917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * instances must not have any duplicate types. 188917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 189917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @param toAdd {@code non-null;} the annotations to add 190917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @throws IllegalArgumentException thrown if there is a duplicate type 191917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 192917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public void addAll(Annotations toAdd) { 193917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throwIfImmutable(); 194917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 195917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul if (toAdd == null) { 196917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul throw new NullPointerException("toAdd == null"); 197917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 198917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 199917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul for (Annotation a : toAdd.annotations.values()) { 200917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul add(a); 201917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 202917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 203917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul 204917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul /** 205917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * Gets the set of annotations contained in this instance. The 206917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * result is always unmodifiable. 207917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * 208917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul * @return {@code non-null;} the set of annotations 209917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul */ 210917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul public Collection<Annotation> getAnnotations() { 211917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul return Collections.unmodifiableCollection(annotations.values()); 212917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul } 213917cb222329ee8c035c3ffaf947e4265761b9367Piotr Gurgul} 214