1/* GENERATED SOURCE. DO NOT MODIFY. */
2/*
3 *******************************************************************************
4 * Copyright (C) 2008-2015, Google, International Business Machines Corporation and
5 * others. All Rights Reserved.
6 *******************************************************************************
7 */
8package android.icu.text;
9
10import java.util.Arrays;
11import java.util.EnumSet;
12
13import android.icu.impl.StandardPlural;
14import android.icu.util.Freezable;
15import android.icu.util.Output;
16
17/**
18 * Utility class for returning the plural category for a range of numbers, such as 1–5, so that appropriate messages can
19 * be chosen. The rules for determining this value vary widely across locales.
20 *
21 * @author markdavis
22 * @deprecated This API is ICU internal only.
23 * @hide Only a subset of ICU is exposed in Android
24 * @hide draft / provisional / internal are hidden on Android
25 */
26@Deprecated
27public final class PluralRanges implements Freezable<PluralRanges>, Comparable<PluralRanges> {
28
29    private volatile boolean isFrozen;
30    private Matrix matrix = new Matrix();
31    private boolean[] explicit = new boolean[StandardPlural.COUNT];
32
33    /**
34     * Constructor
35     *
36     * @deprecated This API is ICU internal only.
37     * @hide draft / provisional / internal are hidden on Android
38     */
39    @Deprecated
40    public PluralRanges() {
41    }
42
43    /**
44     * Internal class for mapping from two StandardPluralCategories values to another.
45     */
46    private static final class Matrix implements Comparable<Matrix>, Cloneable {
47        private byte[] data = new byte[StandardPlural.COUNT * StandardPlural.COUNT];
48        {
49            for (int i = 0; i < data.length; ++i) {
50                data[i] = -1;
51            }
52        }
53
54        Matrix() {
55        }
56
57        /**
58         * Internal method for setting.
59         */
60        @SuppressWarnings("unused")
61        void set(StandardPlural start, StandardPlural end, StandardPlural result) {
62            data[start.ordinal() * StandardPlural.COUNT + end.ordinal()] = result == null ? (byte) -1
63                    : (byte) result.ordinal();
64        }
65
66        /**
67         * Internal method for setting; throws exception if already set.
68         */
69        void setIfNew(StandardPlural start, StandardPlural end,
70                StandardPlural result) {
71            byte old = data[start.ordinal() * StandardPlural.COUNT + end.ordinal()];
72            if (old >= 0) {
73                throw new IllegalArgumentException("Previously set value for <" + start + ", " + end + ", "
74                        + StandardPlural.VALUES.get(old) + ">");
75            }
76            data[start.ordinal() * StandardPlural.COUNT + end.ordinal()] = result == null ? (byte) -1
77                    : (byte) result.ordinal();
78        }
79
80        /**
81         * Internal method for getting.
82         */
83        StandardPlural get(StandardPlural start, StandardPlural end) {
84            byte result = data[start.ordinal() * StandardPlural.COUNT + end.ordinal()];
85            return result < 0 ? null : StandardPlural.VALUES.get(result);
86        }
87
88        /**
89         * Internal method to see if <*,end> values are all the same.
90         */
91        @SuppressWarnings("unused")
92        StandardPlural endSame(StandardPlural end) {
93            StandardPlural first = null;
94            for (StandardPlural start : StandardPlural.VALUES) {
95                StandardPlural item = get(start, end);
96                if (item == null) {
97                    continue;
98                }
99                if (first == null) {
100                    first = item;
101                    continue;
102                }
103                if (first != item) {
104                    return null;
105                }
106            }
107            return first;
108        }
109
110        /**
111         * Internal method to see if <start,*> values are all the same.
112         */
113        @SuppressWarnings("unused")
114        StandardPlural startSame(StandardPlural start,
115                EnumSet<StandardPlural> endDone, Output<Boolean> emit) {
116            emit.value = false;
117            StandardPlural first = null;
118            for (StandardPlural end : StandardPlural.VALUES) {
119                StandardPlural item = get(start, end);
120                if (item == null) {
121                    continue;
122                }
123                if (first == null) {
124                    first = item;
125                    continue;
126                }
127                if (first != item) {
128                    return null;
129                }
130                // only emit if we didn't cover with the 'end' values
131                if (!endDone.contains(end)) {
132                    emit.value = true;
133                }
134            }
135            return first;
136        }
137
138        @Override
139        public int hashCode() {
140            int result = 0;
141            for (int i = 0; i < data.length; ++i) {
142                result = result * 37 + data[i];
143            }
144            return result;
145        }
146
147        @Override
148        public boolean equals(Object other) {
149            if (!(other instanceof Matrix)) {
150                return false;
151            }
152            return 0 == compareTo((Matrix) other);
153        }
154
155        public int compareTo(Matrix o) {
156            for (int i = 0; i < data.length; ++i) {
157                int diff = data[i] - o.data[i];
158                if (diff != 0) {
159                    return diff;
160                }
161            }
162            return 0;
163        }
164
165        @Override
166        public Matrix clone() {
167            Matrix result = new Matrix();
168            result.data = data.clone();
169            return result;
170        }
171
172        @Override
173        public String toString() {
174            StringBuilder result = new StringBuilder();
175            for (StandardPlural i : StandardPlural.values()) {
176                for (StandardPlural j : StandardPlural.values()) {
177                    StandardPlural x = get(i, j);
178                    if (x != null) {
179                        result.append(i + " & " + j + " → " + x + ";\n");
180                    }
181                }
182            }
183            return result.toString();
184        }
185    }
186
187    /**
188     * Internal method for building. If the start or end are null, it means everything of that type.
189     *
190     * @param rangeStart
191     *            plural category for the start of the range
192     * @param rangeEnd
193     *            plural category for the end of the range
194     * @param result
195     *            the resulting plural category
196     * @deprecated This API is ICU internal only.
197     * @hide draft / provisional / internal are hidden on Android
198     */
199    @Deprecated
200    public void add(StandardPlural rangeStart, StandardPlural rangeEnd,
201            StandardPlural result) {
202        if (isFrozen) {
203            throw new UnsupportedOperationException();
204        }
205        explicit[result.ordinal()] = true;
206        if (rangeStart == null) {
207            for (StandardPlural rs : StandardPlural.values()) {
208                if (rangeEnd == null) {
209                    for (StandardPlural re : StandardPlural.values()) {
210                        matrix.setIfNew(rs, re, result);
211                    }
212                } else {
213                    explicit[rangeEnd.ordinal()] = true;
214                    matrix.setIfNew(rs, rangeEnd, result);
215                }
216            }
217        } else if (rangeEnd == null) {
218            explicit[rangeStart.ordinal()] = true;
219            for (StandardPlural re : StandardPlural.values()) {
220                matrix.setIfNew(rangeStart, re, result);
221            }
222        } else {
223            explicit[rangeStart.ordinal()] = true;
224            explicit[rangeEnd.ordinal()] = true;
225            matrix.setIfNew(rangeStart, rangeEnd, result);
226        }
227    }
228
229    /**
230     * Returns the appropriate plural category for a range from start to end. If there is no available data, then
231     * 'end' is returned as an implicit value. (Such an implicit value can be tested for with {@link #isExplicit}.)
232     *
233     * @param start
234     *            plural category for the start of the range
235     * @param end
236     *            plural category for the end of the range
237     * @return the resulting plural category, or 'end' if there is no data.
238     * @deprecated This API is ICU internal only.
239     * @hide draft / provisional / internal are hidden on Android
240     */
241    @Deprecated
242    public StandardPlural get(StandardPlural start, StandardPlural end) {
243        StandardPlural result = matrix.get(start, end);
244        return result == null ? end : result;
245    }
246
247    /**
248     * Returns whether the appropriate plural category for a range from start to end
249     * is explicitly in the data (vs given an implicit value). See also {@link #get}.
250     *
251     * @param start
252     *            plural category for the start of the range
253     * @param end
254     *            plural category for the end of the range
255     * @return whether the value for (start,end) is explicit or not.
256     * @deprecated This API is ICU internal only.
257     * @hide draft / provisional / internal are hidden on Android
258     */
259    @Deprecated
260    public boolean isExplicit(StandardPlural start, StandardPlural end) {
261        return matrix.get(start, end) != null;
262    }
263
264    /**
265     * Internal method to determines whether the StandardPluralCategories was explicitly used in any add statement.
266     *
267     * @param count
268     *            plural category to test
269     * @return true if set
270     * @deprecated This API is ICU internal only.
271     * @hide draft / provisional / internal are hidden on Android
272     */
273    @Deprecated
274    public boolean isExplicitlySet(StandardPlural count) {
275        return explicit[count.ordinal()];
276    }
277
278    /**
279     * {@inheritDoc}
280     * @deprecated This API is ICU internal only.
281     * @hide draft / provisional / internal are hidden on Android
282     */
283    @Deprecated
284    @Override
285    public boolean equals(Object other) {
286        if (this == other) {
287            return true;
288        }
289        if (!(other instanceof PluralRanges)) {
290            return false;
291        }
292        PluralRanges otherPR = (PluralRanges)other;
293        return matrix.equals(otherPR.matrix) && Arrays.equals(explicit, otherPR.explicit);
294    }
295
296    /**
297     * {@inheritDoc}
298     * @deprecated This API is ICU internal only.
299     * @hide draft / provisional / internal are hidden on Android
300     */
301    @Override
302    @Deprecated
303    public int hashCode() {
304        return matrix.hashCode();
305    }
306
307    /**
308     * {@inheritDoc}
309     * @deprecated This API is ICU internal only.
310     * @hide draft / provisional / internal are hidden on Android
311     */
312    @Deprecated
313    public int compareTo(PluralRanges that) {
314        return matrix.compareTo(that.matrix);
315    }
316
317    /**
318     * {@inheritDoc}
319     * @deprecated This API is ICU internal only.
320     * @hide draft / provisional / internal are hidden on Android
321     */
322    @Deprecated
323    public boolean isFrozen() {
324        return isFrozen;
325    }
326
327    /**
328     * {@inheritDoc}
329     * @deprecated This API is ICU internal only.
330     * @hide draft / provisional / internal are hidden on Android
331     */
332    @Deprecated
333    public PluralRanges freeze() {
334        isFrozen = true;
335        return this;
336    }
337
338    /**
339     * {@inheritDoc}
340     * @deprecated This API is ICU internal only.
341     * @hide draft / provisional / internal are hidden on Android
342     */
343    @Deprecated
344    public PluralRanges cloneAsThawed() {
345        PluralRanges result = new PluralRanges();
346        result.explicit = explicit.clone();
347        result.matrix = matrix.clone();
348        return result;
349    }
350
351    /**
352     * {@inheritDoc}
353     * @deprecated This API is ICU internal only.
354     * @hide draft / provisional / internal are hidden on Android
355     */
356    @Override
357    @Deprecated
358    public String toString() {
359        return matrix.toString();
360    }
361}