12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */
2f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// © 2016 and later: Unicode, Inc. and others.
3f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License
42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/*
52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *******************************************************************************
65a559d08b74c555d7f997b51acd311b7a8756d26Fredrik Roubert * Copyright (C) 2007-2016, International Business Machines Corporation and
72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * others. All Rights Reserved.
82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *******************************************************************************
92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */
102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.text;
122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.io.IOException;
142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.io.NotSerializableException;
152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.io.ObjectInputStream;
162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.io.ObjectOutputStream;
172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.io.ObjectStreamException;
182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.io.Serializable;
192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.text.ParseException;
202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.ArrayList;
212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Collection;
222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Collections;
232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.HashSet;
242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Iterator;
252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.LinkedHashSet;
262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.List;
272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Locale;
282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.Set;
292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.TreeSet;
302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.regex.Pattern;
312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.impl.PluralRulesLoader;
332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.Output;
342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.ULocale;
352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/**
372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Defines rules for mapping non-negative numeric values onto a small set of keywords.
392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </p>
402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Rules are constructed from a text description, consisting of a series of keywords and conditions. The {@link #select}
422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * method examines each condition in order and returns the keyword for the first condition that matches the number. If
432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * none match, {@link #KEYWORD_OTHER} is returned.
442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </p>
452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * A PluralRules object is immutable. It contains caches for sample values, but those are synchronized.
472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * PluralRules is Serializable so that it can be used in formatters, which are serializable.
492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </p>
502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * For more information, details, and tips for writing rules, see the <a
522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * href="http://www.unicode.org/draft/reports/tr35/tr35.html#Language_Plural_Rules">LDML spec, C.11 Language Plural
532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Rules</a>
542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </p>
552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Examples:
572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </p>
58f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert *
592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <pre>
602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * &quot;one: n is 1; few: n in 2..4&quot;
612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </pre>
622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This defines two rules, for 'one' and 'few'. The condition for 'one' is "n is 1" which means that the number must be
642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * equal to 1 for this condition to pass. The condition for 'few' is "n in 2..4" which means that the number must be
652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * between 2 and 4 inclusive - and be an integer - for this condition to pass. All other numbers are assigned the
662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * keyword "other" by the default rule.
672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </p>
68f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert *
692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <pre>
702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * &quot;zero: n is 0; one: n is 1; zero: n mod 100 in 1..19&quot;
712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </pre>
722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This illustrates that the same keyword can be defined multiple times. Each rule is examined in order, and the first
742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * keyword whose condition passes is the one returned. Also notes that a modulus is applied to n in the last rule. Thus
752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * its condition holds for 119, 219, 319...
762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </p>
77f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert *
782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <pre>
792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * &quot;one: n is 1; few: n mod 10 in 2..4 and n mod 100 not in 12..14&quot;
802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </pre>
812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * This illustrates conjunction and negation. The condition for 'few' has two parts, both of which must be met:
832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * "n mod 10 in 2..4" and "n mod 100 not in 12..14". The first part applies a modulus to n before the test as in the
842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * previous example. The second part applies a different modulus and also uses negation, thus it matches all numbers
852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * _not_ in 12, 13, 14, 112, 113, 114, 212, 213, 214...
862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </p>
872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Syntax:
892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </p>
902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <pre>
912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * rules         = rule (';' rule)*
922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * rule          = keyword ':' condition
932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * keyword       = &lt;identifier&gt;
942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * condition     = and_condition ('or' and_condition)*
952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * and_condition = relation ('and' relation)*
962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * relation      = not? expr not? rel not? range_list
972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * expr          = ('n' | 'i' | 'f' | 'v' | 't') (mod value)?
982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * not           = 'not' | '!'
992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * rel           = 'in' | 'is' | '=' | '≠' | 'within'
1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * mod           = 'mod' | '%'
1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * range_list    = (range | value) (',' range_list)*
1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * value         = digit+
1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * digit         = 0|1|2|3|4|5|6|7|8|9
1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * range         = value'..'value
1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </pre>
1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>Each <b>not</b> term inverts the meaning; however, there should not be more than one of them.</p>
1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The i, f, t, and v values are defined as follows:
1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </p>
1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <ul>
1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>i to be the integer digits.</li>
1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>f to be the visible decimal digits, as an integer.</li>
1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>t to be the visible decimal digits—without trailing zeros—as an integer.</li>
1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>v to be the number of visible fraction digits.</li>
1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <li>j is defined to only match integers. That is j is 3 fails if v != 0 (eg for 3.1 or 3.0).</li>
1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </ul>
1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Examples are in the following table:
1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </p>
1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <table border='1' style="border-collapse:collapse">
1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tbody>
1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr>
1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th>n</th>
1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th>i</th>
1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th>f</th>
1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <th>v</th>
1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr>
1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr>
1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1.0</td>
1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1</td>
1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td align="right">0</td>
1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1</td>
1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr>
1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr>
1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1.00</td>
1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1</td>
1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td align="right">0</td>
1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>2</td>
1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr>
1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr>
1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1.3</td>
1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1</td>
1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td align="right">3</td>
1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1</td>
1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr>
1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr>
1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1.03</td>
1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1</td>
1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td align="right">3</td>
1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>2</td>
1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr>
1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <tr>
1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1.23</td>
1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>1</td>
1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td align="right">23</td>
1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <td>2</td>
1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tr>
1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </tbody>
1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </table>
1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * An "identifier" is a sequence of characters that do not have the Unicode Pattern_Syntax or Pattern_White_Space
1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * properties.
1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>
1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * The difference between 'in' and 'within' is that 'in' only includes integers in the specified range, while 'within'
1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * includes all values. Using 'within' with a range_list consisting entirely of values is the same as using 'in' (it's
1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * not an error).
1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </p>
1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */
1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic class PluralRules implements Serializable {
1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static final UnicodeSet ALLOWED_ID = new UnicodeSet("[a-z]").freeze();
1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // TODO Remove RulesList by moving its API and fields into PluralRules.
1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
17693cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
177836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final String CATEGORY_SEPARATOR = ";  ";
1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
18393cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
184836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final String KEYWORD_RULE_SEPARATOR = ": ";
1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static final long serialVersionUID = 1;
1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private final RuleList rules;
1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private final transient Set<String> keywords;
1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Provides a factory for returning plural rules
196f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert     *
1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
19893cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
199836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
2002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
2022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static abstract class Factory {
2032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
2042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Sole constructor
2052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
20693cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
207836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
2082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
2092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
2102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        protected Factory() {
2112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
2142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Provides access to the predefined <code>PluralRules</code> for a given locale and the plural type.
215f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert         *
2162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * <p>
2172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * ICU defines plural rules for many locales based on CLDR <i>Language Plural Rules</i>. For these predefined
2182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * rules, see CLDR page at http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
219f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert         *
2202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @param locale
2212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *            The locale for which a <code>PluralRules</code> object is returned.
2222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @param type
2232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *            The plural type (e.g., cardinal or ordinal).
2242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @return The predefined <code>PluralRules</code> object for this locale. If there's no predefined rules for
2252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *         this locale, the rules for the closest parent in the locale hierarchy that has one will be returned.
2262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *         The final fallback always returns the default rules.
2272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
22893cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
229836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
2302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
2312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
2322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public abstract PluralRules forLocale(ULocale locale, PluralType type);
2332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
2352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Utility for getting CARDINAL rules.
2362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @param locale the locale
2372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @return plural rules.
2382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
23993cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
240836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
2412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
2422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
2432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final PluralRules forLocale(ULocale locale) {
2442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return forLocale(locale, PluralType.CARDINAL);
2452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
2482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Returns the locales for which there is plurals data.
249f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert         *
2502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
25193cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
252836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
2532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
2542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
2552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public abstract ULocale[] getAvailableULocales();
2562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
2582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Returns the 'functionally equivalent' locale with respect to plural rules. Calling PluralRules.forLocale with
259bfab1e7fec36dff93fb980c546ad64a565faf9fcPaul Duffin         * the functionally equivalent locale, and with the provided locale, returns rules that behave the same. <br>
2602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * All locales with the same functionally equivalent locale have plural rules that behave the same. This is not
2612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * exaustive; there may be other locales whose plural rules behave the same that do not have the same equivalent
2622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * locale.
263f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert         *
2642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @param locale
2652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *            the locale to check
2662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @param isAvailable
267bfab1e7fec36dff93fb980c546ad64a565faf9fcPaul Duffin         *            if not null and of length &gt; 0, this will hold 'true' at index 0 if locale is directly defined
2682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *            (without fallback) as having plural rules
2692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @return the functionally-equivalent locale
2702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
27193cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
272836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
2732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
2742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
2752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public abstract ULocale getFunctionalEquivalent(ULocale locale, boolean[] isAvailable);
2762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
2782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Returns the default factory.
2792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
28093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
281836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
2822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
2832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
2842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public static PluralRulesLoader getDefaultFactory() {
2852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return PluralRulesLoader.loader;
2862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
2872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
2892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Returns whether or not there are overrides.
2902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
29193cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
292836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
2932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
2942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
2952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public abstract boolean hasOverride(ULocale locale);
2962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
2972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // Standard keywords.
2982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
2992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Common name for the 'zero' plural form.
3012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final String KEYWORD_ZERO = "zero";
3032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Common name for the 'singular' plural form.
3062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final String KEYWORD_ONE = "one";
3082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Common name for the 'dual' plural form.
3112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final String KEYWORD_TWO = "two";
3132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Common name for the 'paucal' or other special plural form.
3162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final String KEYWORD_FEW = "few";
3182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Common name for the arabic (11 to 99) plural form.
3212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final String KEYWORD_MANY = "many";
3232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Common name for the default plural form.  This name is returned
3262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * for values to which no other form in the rule applies.  It
3272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * can additionally be assigned rules of its own.
3282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final String KEYWORD_OTHER = "other";
3302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Value returned by {@link #getUniqueKeywordValue} when there is no
3332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * unique value to return.
3342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final double NO_UNIQUE_VALUE = -0.00123456777;
3362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Type of plurals and PluralRules.
3392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public enum PluralType {
3412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
3422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Plural rules for cardinal numbers: 1 file vs. 2 files.
3432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
3442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        CARDINAL,
3452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
3462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Plural rules for ordinal numbers: 1st file, 2nd file, 3rd file, 4th file, etc.
3472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
3482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        ORDINAL
3492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    };
3502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /*
3522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The default constraint that is always satisfied.
3532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static final Constraint NO_CONSTRAINT = new Constraint() {
3552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private static final long serialVersionUID = 9163464945387899416L;
3562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
357f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
3582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean isFulfilled(FixedDecimal n) {
3592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return true;
3602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
3612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
362f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
3632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean isLimited(SampleType sampleType) {
3642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return false;
3652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
3662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
367f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
3682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String toString() {
3692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return "";
3702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
3712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    };
3722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
374f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert     *
3752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static final Rule DEFAULT_RULE = new Rule("other", NO_CONSTRAINT, null, null);
3772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Parses a plural rules description and returns a PluralRules.
3802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param description the rule description.
3812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @throws ParseException if the description cannot be parsed.
3822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *    The exception index is typically not set, it will be -1.
3832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static PluralRules parseDescription(String description)
3852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throws ParseException {
3862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        description = description.trim();
3882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return description.length() == 0 ? DEFAULT : new PluralRules(parseRuleChain(description));
3892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
3902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
3912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
3922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Creates a PluralRules from a description if it is parsable,
3932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * otherwise returns null.
3942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param description the rule description.
3952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return the PluralRules
3962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
3972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static PluralRules createRules(String description) {
3982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        try {
3992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return parseDescription(description);
4002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } catch(Exception e) {
4012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return null;
4022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
4042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
4062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The default rules that accept any number and return
4072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * {@link #KEYWORD_OTHER}.
4082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
4092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final PluralRules DEFAULT = new PluralRules(new RuleList().addRule(DEFAULT_RULE));
4102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private enum Operand {
4122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        n,
4132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        i,
4142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        f,
4152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        t,
4162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        v,
4172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        w,
4182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /* deprecated */
4192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        j;
4202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
4212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
4232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
42493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
425836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
4262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
4272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
4282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static class FixedDecimal extends Number implements Comparable<FixedDecimal> {
4292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private static final long serialVersionUID = -4756200506571685661L;
4302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
4312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
43293cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
433836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
4342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
4352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
4362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final double source;
4372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
4382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
43993cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
440836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
4412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
4422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
4432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final int visibleDecimalDigitCount;
4442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
4452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
44693cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
447836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
4482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
4492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
4502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final int visibleDecimalDigitCountWithoutTrailingZeros;
4512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
4522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
45393cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
454836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
4552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
4562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
4572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final long decimalDigits;
4582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
4592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
46093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
461836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
4622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
4632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
4642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final long decimalDigitsWithoutTrailingZeros;
4652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
4662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
46793cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
468836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
4692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
4702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
4712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final long integerValue;
4722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
4732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
47493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
475836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
4762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
4772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
4782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final boolean hasIntegerValue;
4792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
4802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
48193cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
482836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
4832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
4842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
4852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final boolean isNegative;
4862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final int baseFactor;
4872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
4892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
49093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
491836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
4922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
4932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
4942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public double getSource() {
4952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return source;
4962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
4972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
4982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
4992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
50093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
501836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
5022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
5032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
5042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public int getVisibleDecimalDigitCount() {
5052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return visibleDecimalDigitCount;
5062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
5072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
5092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
51093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
511836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
5122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
5132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
5142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public int getVisibleDecimalDigitCountWithoutTrailingZeros() {
5152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return visibleDecimalDigitCountWithoutTrailingZeros;
5162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
5172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
5192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
52093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
521836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
5222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
5232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
5242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public long getDecimalDigits() {
5252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return decimalDigits;
5262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
5272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
5292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
53093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
531836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
5322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
5332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
5342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public long getDecimalDigitsWithoutTrailingZeros() {
5352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return decimalDigitsWithoutTrailingZeros;
5362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
5372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
5392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
54093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
541836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
5422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
5432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
5442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public long getIntegerValue() {
5452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return integerValue;
5462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
5472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
5492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
55093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
551836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
5522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
5532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
5542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean isHasIntegerValue() {
5552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return hasIntegerValue;
5562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
5572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
5592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
56093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
561836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
5622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
5632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
5642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean isNegative() {
5652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return isNegative;
5662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
5672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
5692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
57093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
571836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
5722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
5732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
5742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public int getBaseFactor() {
5752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return baseFactor;
5762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
5772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        static final long MAX = (long)1E18;
5792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
5802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
5812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
5822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @param n is the original number
5832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @param v number of digits to the right of the decimal place. e.g 1.00 = 2 25. = 0
5842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @param f Corresponds to f in the plural rules grammar.
5852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         *   The digits to the right of the decimal place as an integer. e.g 1.10 = 10
58693cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
587836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
5882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
5892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
5902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public FixedDecimal(double n, int v, long f) {
5912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            isNegative = n < 0;
5922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            source = isNegative ? -n : n;
5932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            visibleDecimalDigitCount = v;
5942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            decimalDigits = f;
595f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert            integerValue = n > MAX
596f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert                    ? MAX
5972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            : (long)n;
5982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            hasIntegerValue = source == integerValue;
5992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // check values. TODO make into unit test.
600f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert            //
6012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            //            long visiblePower = (int) Math.pow(10, v);
6022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            //            if (fractionalDigits > visiblePower) {
6032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            //                throw new IllegalArgumentException();
6042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            //            }
6052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            //            double fraction = intValue + (fractionalDigits / (double) visiblePower);
6062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            //            if (fraction != source) {
6072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            //                double diff = Math.abs(fraction - source)/(Math.abs(fraction) + Math.abs(source));
6082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            //                if (diff > 0.00000001d) {
6092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            //                    throw new IllegalArgumentException();
6102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            //                }
6112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            //            }
6122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (f == 0) {
6132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                decimalDigitsWithoutTrailingZeros = 0;
6142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                visibleDecimalDigitCountWithoutTrailingZeros = 0;
6152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            } else {
6162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                long fdwtz = f;
6172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                int trimmedCount = v;
6182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                while ((fdwtz%10) == 0) {
6192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    fdwtz /= 10;
6202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    --trimmedCount;
6212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
6222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                decimalDigitsWithoutTrailingZeros = fdwtz;
6232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                visibleDecimalDigitCountWithoutTrailingZeros = trimmedCount;
6242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
6252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            baseFactor = (int) Math.pow(10, v);
6262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
6292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
63093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
631836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
6322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
6332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
6342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public FixedDecimal(double n, int v) {
6352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this(n,v,getFractionalDigits(n, v));
6362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private static int getFractionalDigits(double n, int v) {
6392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (v == 0) {
6402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return 0;
6412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            } else {
6422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (n < 0) {
6432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    n = -n;
6442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
6452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                int baseFactor = (int) Math.pow(10, v);
6462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                long scaled = Math.round(n * baseFactor);
6472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return (int) (scaled % baseFactor);
6482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
6492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
6522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
65393cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
654836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
6552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
6562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
6572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public FixedDecimal(double n) {
6582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this(n, decimals(n));
6592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
6622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
66393cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
664836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
6652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
6662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
6672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public FixedDecimal(long n) {
6682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this(n,0);
6692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
6702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
6712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private static final long MAX_INTEGER_PART = 1000000000;
6722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
6732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Return a guess as to the number of decimals that would be displayed. This is only a guess; callers should
6742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * always supply the decimals explicitly if possible. Currently, it is up to 6 decimals (without trailing zeros).
6752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Returns 0 for infinities and nans.
6762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
67793cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
678836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
679f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert         *
6802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
6812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
6822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public static int decimals(double n) {
6832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // Ugly...
6842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (Double.isInfinite(n) || Double.isNaN(n)) {
6852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return 0;
6862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
6872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (n < 0) {
6882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                n = -n;
6892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
6902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (n == Math.floor(n)) {
6912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return 0;
6922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
6932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (n < MAX_INTEGER_PART) {
6942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                long temp = (long)(n * 1000000) % 1000000; // get 6 decimals
6952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                for (int mask = 10, digits = 6; digits > 0; mask *= 10, --digits) {
6962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if ((temp % mask) != 0) {
6972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        return digits;
6982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
6992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
7002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return 0;
7012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            } else {
7022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                String buf = String.format(Locale.ENGLISH, "%1.15e", n);
7032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                int ePos = buf.lastIndexOf('e');
7042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                int expNumPos = ePos + 1;
7052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (buf.charAt(expNumPos) == '+') {
7062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    expNumPos++;
7072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
7082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                String exponentStr = buf.substring(expNumPos);
7092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                int exponent = Integer.parseInt(exponentStr);
7102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                int numFractionDigits = ePos - 2 - exponent;
7112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (numFractionDigits < 0) {
7122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    return 0;
7132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
7142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                for (int i=ePos-1; numFractionDigits > 0; --i) {
7152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if (buf.charAt(i) != '0') {
7162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        break;
7172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
718f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert                    --numFractionDigits;
7192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
7202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return numFractionDigits;
7212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
7222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
7232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
7242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
7252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
72693cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
727836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
7282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
7292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
7302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public FixedDecimal (String n) {
7312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // Ugly, but for samples we don't care.
7322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this(Double.parseDouble(n), getVisibleFractionCount(n));
7332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
7342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
7352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private static int getVisibleFractionCount(String value) {
7362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            value = value.trim();
7372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            int decimalPos = value.indexOf('.') + 1;
7382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (decimalPos == 0) {
7392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return 0;
7402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            } else {
7412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return value.length() - decimalPos;
7422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
7432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
7442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
7452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
7462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
74793cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
748836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
7492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
7502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
7512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public double get(Operand operand) {
7522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            switch(operand) {
7532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            default: return source;
7542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case i: return integerValue;
7552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case f: return decimalDigits;
7562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case t: return decimalDigitsWithoutTrailingZeros;
7572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case v: return visibleDecimalDigitCount;
7582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case w: return visibleDecimalDigitCountWithoutTrailingZeros;
7592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
7602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
7612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
7622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
7632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
76493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
765836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
7662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
7672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
7682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public static Operand getOperand(String t) {
7692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return Operand.valueOf(t);
7702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
7712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
7722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
7732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * We're not going to care about NaN.
7742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
77593cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
776836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
7772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
778f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
7792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
7802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public int compareTo(FixedDecimal other) {
7812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (integerValue != other.integerValue) {
7822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return integerValue < other.integerValue ? -1 : 1;
7832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
7842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (source != other.source) {
7852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return source < other.source ? -1 : 1;
7862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
7872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (visibleDecimalDigitCount != other.visibleDecimalDigitCount) {
7882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return visibleDecimalDigitCount < other.visibleDecimalDigitCount ? -1 : 1;
7892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
7902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            long diff = decimalDigits - other.decimalDigits;
7912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (diff != 0) {
7922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return diff < 0 ? -1 : 1;
7932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
7942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return 0;
7952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
7962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
7972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
7982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
79993cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
800836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
8012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
8022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
8032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Override
8042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean equals(Object arg0) {
8052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (arg0 == null) {
8062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return false;
8072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
8082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (arg0 == this) {
8092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return true;
8102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
8112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (!(arg0 instanceof FixedDecimal)) {
8122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return false;
8132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
8142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            FixedDecimal other = (FixedDecimal)arg0;
8152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return source == other.source && visibleDecimalDigitCount == other.visibleDecimalDigitCount && decimalDigits == other.decimalDigits;
8162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
8172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
8182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
8192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
82093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
821836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
8222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
8232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
8242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Override
8252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public int hashCode() {
8262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // TODO Auto-generated method stub
8272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return (int)(decimalDigits + 37 * (visibleDecimalDigitCount + (int)(37 * source)));
8282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
8292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
8302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
8312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
83293cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
833836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
8342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
8352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
8362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Override
8372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String toString() {
8382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return String.format("%." + visibleDecimalDigitCount + "f", source);
8392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
8402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
8412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
8422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
84393cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
844836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
8452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
8462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
8472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean hasIntegerValue() {
8482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return hasIntegerValue;
8492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
8502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
8512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
8522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
85393cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
854836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
8552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
8562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
8572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Override
8582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public int intValue() {
8592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // TODO Auto-generated method stub
8602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return (int)integerValue;
8612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
8622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
8632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
8642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
86593cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
866836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
8672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
8682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
8692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Override
8702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public long longValue() {
8712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return integerValue;
8722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
8732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
8742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
8752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
87693cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
877836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
8782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
8792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
8802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Override
8812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public float floatValue() {
8822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return (float) source;
8832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
8842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
8852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
8862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
88793cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
888836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
8892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
8902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
8912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Override
8922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public double doubleValue() {
8932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return isNegative ? -source : source;
8942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
8952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
8962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
8972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
89893cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
899836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
9002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
9012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
9022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public long getShiftedValue() {
9032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return integerValue * baseFactor + decimalDigits;
9042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
9062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private void writeObject(
9072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                ObjectOutputStream out)
9082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        throws IOException {
9092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new NotSerializableException();
9102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
9122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private void readObject(ObjectInputStream in
9132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                ) throws IOException, ClassNotFoundException {
9142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new NotSerializableException();
9152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
9172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
9182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
9192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Selection parameter for either integer-only or decimal-only.
9202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
92193cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
922836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
9232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
9242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
9252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public enum SampleType {
9262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
9272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
928836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
9292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
9302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
9312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        INTEGER,
9322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
9332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
934836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
9352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
9362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
9372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        DECIMAL
9382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
9392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
9402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
9412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * A range of NumberInfo that includes all values with the same visibleFractionDigitCount.
9422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
94393cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
944836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
9452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
9462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
9472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static class FixedDecimalRange {
9482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
9492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
95093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
951836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
9522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
9532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
9542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final FixedDecimal start;
9552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
9562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
95793cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
958836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
9592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
9602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
9612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final FixedDecimal end;
9622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
9632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
96493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
965836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
9662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
9672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
9682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public FixedDecimalRange(FixedDecimal start, FixedDecimal end) {
9692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (start.visibleDecimalDigitCount != end.visibleDecimalDigitCount) {
9702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                throw new IllegalArgumentException("Ranges must have the same number of visible decimals: " + start + "~" + end);
9712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
9722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.start = start;
9732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.end = end;
9742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
9762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
97793cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
978836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
9792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
9802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
9812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Override
9822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String toString() {
9832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return start + (end == start ? "" : "~" + end);
9842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
9852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
9862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
9872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
9882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * A list of NumberInfo that includes all values with the same visibleFractionDigitCount.
9892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
99093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
991836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
9922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
9932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
9942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static class FixedDecimalSamples {
9952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
9962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
99793cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
998836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
9992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
10002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
10012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final SampleType sampleType;
10022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
10032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
100493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
1005836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
10062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
10072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
10082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final Set<FixedDecimalRange> samples;
10092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
10102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
101193cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
1012836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
10132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
10142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
10152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public final boolean bounded;
10162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
10172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * The samples must be immutable.
10182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @param sampleType
10192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @param samples
10202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
10212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private FixedDecimalSamples(SampleType sampleType, Set<FixedDecimalRange> samples, boolean bounded) {
10222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            super();
10232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.sampleType = sampleType;
10242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.samples = samples;
10252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.bounded = bounded;
10262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
10272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /*
10282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Parse a list of the form described in CLDR. The source must be trimmed.
10292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
10302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        static FixedDecimalSamples parse(String source) {
10312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            SampleType sampleType2;
10322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            boolean bounded2 = true;
10332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            boolean haveBound = false;
10342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            Set<FixedDecimalRange> samples2 = new LinkedHashSet<FixedDecimalRange>();
10352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
10362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (source.startsWith("integer")) {
10372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                sampleType2 = SampleType.INTEGER;
10382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            } else if (source.startsWith("decimal")) {
10392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                sampleType2 = SampleType.DECIMAL;
10402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            } else {
10412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                throw new IllegalArgumentException("Samples must start with 'integer' or 'decimal'");
10422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
10432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            source = source.substring(7).trim(); // remove both
10442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
10452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (String range : COMMA_SEPARATED.split(source)) {
10462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (range.equals("…") || range.equals("...")) {
10472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    bounded2 = false;
10482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    haveBound = true;
10492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    continue;
10502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
10512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (haveBound) {
10522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    throw new IllegalArgumentException("Can only have … at the end of samples: " + range);
10532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
10542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                String[] rangeParts = TILDE_SEPARATED.split(range);
10552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                switch (rangeParts.length) {
1056f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert                case 1:
10572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    FixedDecimal sample = new FixedDecimal(rangeParts[0]);
10582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    checkDecimal(sampleType2, sample);
10592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    samples2.add(new FixedDecimalRange(sample, sample));
10602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    break;
10612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                case 2:
10622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    FixedDecimal start = new FixedDecimal(rangeParts[0]);
10632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    FixedDecimal end = new FixedDecimal(rangeParts[1]);
10642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    checkDecimal(sampleType2, start);
10652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    checkDecimal(sampleType2, end);
10662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    samples2.add(new FixedDecimalRange(start, end));
10672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    break;
10682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                default: throw new IllegalArgumentException("Ill-formed number range: " + range);
10692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
10702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
10712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return new FixedDecimalSamples(sampleType2, Collections.unmodifiableSet(samples2), bounded2);
10722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
10732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
10742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private static void checkDecimal(SampleType sampleType2, FixedDecimal sample) {
10752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if ((sampleType2 == SampleType.INTEGER) != (sample.getVisibleDecimalDigitCount() == 0)) {
1076f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert                throw new IllegalArgumentException("Ill-formed number range: " + sample);
10772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
10782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
10792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
10802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
10812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
108293cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
1083836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
10842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
10852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
10862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public Set<Double> addSamples(Set<Double> result) {
10872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (FixedDecimalRange item : samples) {
10882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // we have to convert to longs so we don't get strange double issues
10892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                long startDouble = item.start.getShiftedValue();
10902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                long endDouble = item.end.getShiftedValue();
10912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
10922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                for (long d = startDouble; d <= endDouble; d += 1) {
10932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    result.add(d/(double)item.start.baseFactor);
10942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
10952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
10962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return result;
10972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
10982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
10992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
11002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
110193cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
1102836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
11032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
11042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
11052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Override
11062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String toString() {
11072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            StringBuilder b = new StringBuilder("@").append(sampleType.toString().toLowerCase(Locale.ENGLISH));
11082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            boolean first = true;
11092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (FixedDecimalRange item : samples) {
11102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (first) {
11112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    first = false;
11122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                } else {
11132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    b.append(",");
11142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
11152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                b.append(' ').append(item);
11162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
11172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (!bounded) {
11182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                b.append(", …");
11192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
11202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return b.toString();
11212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
11222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
11242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
112593cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
1126836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
11272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
11282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
11292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public Set<FixedDecimalRange> getSamples() {
11302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return samples;
11312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
11322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
11342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
113593cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller         * @hide original deprecated declaration
1136836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
11372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
11382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
11392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public void getStartEndSamples(Set<FixedDecimal> target) {
11402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (FixedDecimalRange item : samples) {
11412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                target.add(item.start);
11422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                target.add(item.end);
11432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
11442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
11452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
11462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /*
11482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * A constraint on a number.
11492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
11502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private interface Constraint extends Serializable {
11512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /*
11522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Returns true if the number fulfills the constraint.
11532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @param n the number to test, >= 0.
11542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
11552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        boolean isFulfilled(FixedDecimal n);
11562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /*
11582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Returns false if an unlimited number of values fulfills the
11592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * constraint.
11602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
11612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        boolean isLimited(SampleType sampleType);
11622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
11632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static class SimpleTokenizer {
11652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        static final UnicodeSet BREAK_AND_IGNORE = new UnicodeSet(0x09, 0x0a, 0x0c, 0x0d, 0x20, 0x20).freeze();
11662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        static final UnicodeSet BREAK_AND_KEEP = new UnicodeSet('!', '!', '%', '%', ',', ',', '.', '.', '=', '=').freeze();
11672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        static String[] split(String source) {
11682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            int last = -1;
11692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            List<String> result = new ArrayList<String>();
11702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (int i = 0; i < source.length(); ++i) {
11712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                char ch = source.charAt(i);
11722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (BREAK_AND_IGNORE.contains(ch)) {
11732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if (last >= 0) {
11742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        result.add(source.substring(last,i));
11752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        last = -1;
11762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
11772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                } else if (BREAK_AND_KEEP.contains(ch)) {
11782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if (last >= 0) {
11792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        result.add(source.substring(last,i));
11802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
11812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    result.add(source.substring(i,i+1));
11822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    last = -1;
11832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                } else if (last < 0) {
11842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    last = i;
11852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
11862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
11872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (last >= 0) {
11882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result.add(source.substring(last));
11892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
11902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return result.toArray(new String[result.size()]);
11912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
11922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
11932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
11942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /*
11952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * syntax:
11962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * condition :       or_condition
11972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                   and_condition
11982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * or_condition :    and_condition 'or' condition
11992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * and_condition :   relation
12002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                   relation 'and' relation
12012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * relation :        in_relation
12022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                   within_relation
12032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * in_relation :     not? expr not? in not? range
12042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * within_relation : not? expr not? 'within' not? range
12052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * not :             'not'
12062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                   '!'
12072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * expr :            'n'
12082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                   'n' mod value
12092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * mod :             'mod'
12102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                   '%'
12112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * in :              'in'
12122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                   'is'
12132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                   '='
12142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *                   '≠'
12152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * value :           digit+
12162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * digit :           0|1|2|3|4|5|6|7|8|9
12172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * range :           value'..'value
12182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
12192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static Constraint parseConstraint(String description)
12202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throws ParseException {
12212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
12222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        Constraint result = null;
12232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        String[] or_together = OR_SEPARATED.split(description);
12242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < or_together.length; ++i) {
12252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            Constraint andConstraint = null;
12262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            String[] and_together = AND_SEPARATED.split(or_together[i]);
12272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (int j = 0; j < and_together.length; ++j) {
12282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                Constraint newConstraint = NO_CONSTRAINT;
12292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
12302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                String condition = and_together[j].trim();
12312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                String[] tokens = SimpleTokenizer.split(condition);
12322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
12332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                int mod = 0;
12342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                boolean inRange = true;
12352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                boolean integersOnly = true;
12362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                double lowBound = Long.MAX_VALUE;
12372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                double highBound = Long.MIN_VALUE;
12382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                long[] vals = null;
12392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
12402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                int x = 0;
12412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                String t = tokens[x++];
12422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                boolean hackForCompatibility = false;
12432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                Operand operand;
12442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                try {
12452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    operand = FixedDecimal.getOperand(t);
12462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                } catch (Exception e) {
12472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    throw unexpected(t, condition);
12482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
12492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (x < tokens.length) {
12502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    t = tokens[x++];
12512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if ("mod".equals(t) || "%".equals(t)) {
12522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        mod = Integer.parseInt(tokens[x++]);
12532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        t = nextToken(tokens, x++, condition);
12542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
12552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if ("not".equals(t)) {
12562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        inRange = !inRange;
12572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        t = nextToken(tokens, x++, condition);
12582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        if ("=".equals(t)) {
12592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            throw unexpected(t, condition);
12602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        }
12612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    } else if ("!".equals(t)) {
12622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        inRange = !inRange;
12632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        t = nextToken(tokens, x++, condition);
12642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        if (!"=".equals(t)) {
12652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            throw unexpected(t, condition);
12662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        }
12672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
12682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if ("is".equals(t) || "in".equals(t) || "=".equals(t)) {
12692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        hackForCompatibility = "is".equals(t);
12702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        if (hackForCompatibility && !inRange) {
12712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            throw unexpected(t, condition);
12722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        }
12732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        t = nextToken(tokens, x++, condition);
12742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    } else if ("within".equals(t)) {
12752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        integersOnly = false;
12762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        t = nextToken(tokens, x++, condition);
12772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    } else {
12782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        throw unexpected(t, condition);
12792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
12802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if ("not".equals(t)) {
12812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        if (!hackForCompatibility && !inRange) {
12822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            throw unexpected(t, condition);
12832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        }
12842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        inRange = !inRange;
12852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        t = nextToken(tokens, x++, condition);
12862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
12872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
12882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    List<Long> valueList = new ArrayList<Long>();
12892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
12902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    // the token t is always one item ahead
12912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    while (true) {
12922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        long low = Long.parseLong(t);
12932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        long high = low;
12942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        if (x < tokens.length) {
12952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            t = nextToken(tokens, x++, condition);
12962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            if (t.equals(".")) {
12972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                t = nextToken(tokens, x++, condition);
12982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                if (!t.equals(".")) {
12992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                    throw unexpected(t, condition);
13002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                }
13012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                t = nextToken(tokens, x++, condition);
13022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                high = Long.parseLong(t);
13032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                if (x < tokens.length) {
13042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                    t = nextToken(tokens, x++, condition);
13052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                    if (!t.equals(",")) { // adjacent number: 1 2
13062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                        // no separator, fail
13072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                        throw unexpected(t, condition);
1308f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert                                    }
13092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                }
13102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            } else if (!t.equals(",")) { // adjacent number: 1 2
13112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                // no separator, fail
13122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                                throw unexpected(t, condition);
13132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            }
13142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        }
13152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        // at this point, either we are out of tokens, or t is ','
13162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        if (low > high) {
13172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            throw unexpected(low + "~" + high, condition);
13182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        } else if (mod != 0 && high >= mod) {
13192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            throw unexpected(high + ">mod=" + mod, condition);
13202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        }
13212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        valueList.add(low);
13222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        valueList.add(high);
13232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        lowBound = Math.min(lowBound, low);
13242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        highBound = Math.max(highBound, high);
13252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        if (x >= tokens.length) {
13262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            break;
13272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        }
13282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        t = nextToken(tokens, x++, condition);
13292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
13302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
13312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if (t.equals(",")) {
13322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        throw unexpected(t, condition);
13332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
13342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
13352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if (valueList.size() == 2) {
13362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        vals = null;
13372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    } else {
13382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        vals = new long[valueList.size()];
13392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        for (int k = 0; k < vals.length; ++k) {
13402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            vals[k] = valueList.get(k);
13412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        }
13422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
13432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
13442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    // Hack to exclude "is not 1,2"
13452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if (lowBound != highBound && hackForCompatibility && !inRange) {
13462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        throw unexpected("is not <range>", condition);
13472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
13482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
13492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    newConstraint =
13502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            new RangeConstraint(mod, inRange, operand, integersOnly, lowBound, highBound, vals);
13512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
13522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
13532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (andConstraint == null) {
13542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    andConstraint = newConstraint;
13552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                } else {
13562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    andConstraint = new AndConstraint(andConstraint,
13572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            newConstraint);
13582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
13592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
13602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
13612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (result == null) {
13622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result = andConstraint;
13632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            } else {
13642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result = new OrConstraint(result, andConstraint);
13652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
13662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
13672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return result;
13682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
13692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
13702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static final Pattern AT_SEPARATED = Pattern.compile("\\s*\\Q\\E@\\s*");
13712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static final Pattern OR_SEPARATED = Pattern.compile("\\s*or\\s*");
13722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static final Pattern AND_SEPARATED = Pattern.compile("\\s*and\\s*");
13732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static final Pattern COMMA_SEPARATED = Pattern.compile("\\s*,\\s*");
13742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static final Pattern DOTDOT_SEPARATED = Pattern.compile("\\s*\\Q..\\E\\s*");
13752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static final Pattern TILDE_SEPARATED = Pattern.compile("\\s*~\\s*");
13762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    static final Pattern SEMI_SEPARATED = Pattern.compile("\\s*;\\s*");
13772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
13782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
13792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /* Returns a parse exception wrapping the token and context strings. */
13802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static ParseException unexpected(String token, String context) {
13812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return new ParseException("unexpected token '" + token +
13822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                "' in '" + context + "'", -1);
13832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
13842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
13852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /*
13862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the token at x if available, else throws a parse exception.
13872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
13882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static String nextToken(String[] tokens, int x, String context)
13892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throws ParseException {
13902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (x < tokens.length) {
13912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return tokens[x];
13922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
13932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        throw new ParseException("missing token at end of '" + context + "'", -1);
13942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
13952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
13962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /*
13972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Syntax:
13982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * rule : keyword ':' condition
13992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * keyword: <identifier>
14002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
14012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static Rule parseRule(String description) throws ParseException {
14022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (description.length() == 0) {
14032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return DEFAULT_RULE;
14042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
14052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        description = description.toLowerCase(Locale.ENGLISH);
14072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int x = description.indexOf(':');
14092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (x == -1) {
14102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new ParseException("missing ':' in rule description '" +
14112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    description + "'", 0);
14122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
14132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        String keyword = description.substring(0, x).trim();
14152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (!isValidKeyword(keyword)) {
14162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new ParseException("keyword '" + keyword +
14172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    " is not valid", 0);
14182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
14192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        description = description.substring(x+1).trim();
14212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        String[] constraintOrSamples = AT_SEPARATED.split(description);
14222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        boolean sampleFailure = false;
14232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        FixedDecimalSamples integerSamples = null, decimalSamples = null;
14242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        switch (constraintOrSamples.length) {
14252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case 1: break;
1426f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        case 2:
14272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            integerSamples = FixedDecimalSamples.parse(constraintOrSamples[1]);
14282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (integerSamples.sampleType == SampleType.DECIMAL) {
14292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                decimalSamples = integerSamples;
14302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                integerSamples = null;
14312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
14322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
14332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case 3:
14342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            integerSamples = FixedDecimalSamples.parse(constraintOrSamples[1]);
14352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            decimalSamples = FixedDecimalSamples.parse(constraintOrSamples[2]);
14362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (integerSamples.sampleType != SampleType.INTEGER || decimalSamples.sampleType != SampleType.DECIMAL) {
14372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                throw new IllegalArgumentException("Must have @integer then @decimal in " + description);
14382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
14392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
1440f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        default:
14412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new IllegalArgumentException("Too many samples in " + description);
14422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
14432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (sampleFailure) {
14442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new IllegalArgumentException("Ill-formed samples—'@' characters.");
14452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
14462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // 'other' is special, and must have no rules; all other keywords must have rules.
14482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        boolean isOther = keyword.equals("other");
14492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isOther != (constraintOrSamples[0].length() == 0)) {
14502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new IllegalArgumentException("The keyword 'other' must have no constraints, just samples.");
14512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
14522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        Constraint constraint;
14542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (isOther) {
14552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            constraint = NO_CONSTRAINT;
14562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } else {
14572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            constraint = parseConstraint(constraintOrSamples[0]);
14582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
14592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return new Rule(keyword, constraint, integerSamples, decimalSamples);
14602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
14612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /*
14642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Syntax:
14652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * rules : rule
14662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *         rule ';' rules
14672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
14682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static RuleList parseRuleChain(String description)
14692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throws ParseException {
14702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        RuleList result = new RuleList();
14712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // remove trailing ;
1472f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        if (description.endsWith(";")) {
14732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            description = description.substring(0,description.length()-1);
14742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
14752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        String[] rules = SEMI_SEPARATED.split(description);
14762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (int i = 0; i < rules.length; ++i) {
14772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            Rule rule = parseRule(rules[i].trim());
14782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result.hasExplicitBoundingInfo |= rule.integerSamples != null || rule.decimalSamples != null;
14792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result.addRule(rule);
14802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
14812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return result.finish();
14822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
14832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /*
14852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * An implementation of Constraint representing a modulus,
14862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * a range of values, and include/exclude. Provides lots of
14872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * convenience factory methods.
14882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
14892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static class RangeConstraint implements Constraint, Serializable {
14902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private static final long serialVersionUID = 1;
14912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
14922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final int mod;
14932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final boolean inRange;
14942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final boolean integersOnly;
14952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final double lowerBound;
14962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final double upperBound;
14972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final long[] range_list;
14982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final Operand operand;
14992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
15002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        RangeConstraint(int mod, boolean inRange, Operand operand, boolean integersOnly,
15012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                double lowBound, double highBound, long[] vals) {
15022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.mod = mod;
15032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.inRange = inRange;
15042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.integersOnly = integersOnly;
15052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.lowerBound = lowBound;
15062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.upperBound = highBound;
15072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.range_list = vals;
15082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.operand = operand;
15092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
15102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1511f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
15122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean isFulfilled(FixedDecimal number) {
15132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            double n = number.get(operand);
15142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if ((integersOnly && (n - (long)n) != 0.0
15152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    || operand == Operand.j && number.visibleDecimalDigitCount != 0)) {
15162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return !inRange;
15172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
15182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (mod != 0) {
15192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                n = n % mod;    // java % handles double numerator the way we want
15202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
15212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            boolean test = n >= lowerBound && n <= upperBound;
15222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (test && range_list != null) {
15232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                test = false;
15242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                for (int i = 0; !test && i < range_list.length; i += 2) {
15252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    test = n >= range_list[i] && n <= range_list[i+1];
15262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
15272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
15282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return inRange == test;
15292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
15302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1531f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
15322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean isLimited(SampleType sampleType) {
15332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            boolean valueIsZero = lowerBound == upperBound && lowerBound == 0d;
1534f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert            boolean hasDecimals =
15352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    (operand == Operand.v || operand == Operand.w || operand == Operand.f || operand == Operand.t)
15362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    && inRange != valueIsZero; // either NOT f = zero or f = non-zero
15372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            switch (sampleType) {
1538f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert            case INTEGER:
15392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return hasDecimals // will be empty
15402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        || (operand == Operand.n || operand == Operand.i || operand == Operand.j)
1541f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert                        && mod == 0
15422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        && inRange;
15432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
15442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            case DECIMAL:
15452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return  (!hasDecimals || operand == Operand.n || operand == Operand.j)
15462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        && (integersOnly || lowerBound == upperBound)
1547f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert                        && mod == 0
15482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        && inRange;
15492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
15502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return false;
15512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
15522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1553f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
15542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String toString() {
15552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            StringBuilder result = new StringBuilder();
15562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result.append(operand);
15572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (mod != 0) {
15582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result.append(" % ").append(mod);
15592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
15602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            boolean isList = lowerBound != upperBound;
15612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result.append(
15622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    !isList ? (inRange ? " = " : " != ")
15632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                            : integersOnly ? (inRange ? " = " : " != ")
1564f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert                                    : (inRange ? " within " : " not within ")
15652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    );
15662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (range_list != null) {
15672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                for (int i = 0; i < range_list.length; i += 2) {
15682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    addRange(result, range_list[i], range_list[i+1], i != 0);
15692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
15702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            } else {
15712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                addRange(result, lowerBound, upperBound, false);
15722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
15732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return result.toString();
15742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
15752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
15762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
15772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static void addRange(StringBuilder result, double lb, double ub, boolean addSeparator) {
15782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (addSeparator) {
15792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result.append(",");
15802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
15812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (lb == ub) {
15822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result.append(format(lb));
15832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } else {
15842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result.append(format(lb) + ".." + format(ub));
15852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
15862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
15872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
15882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static String format(double lb) {
15892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        long lbi = (long) lb;
15902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return lb == lbi ? String.valueOf(lbi) : String.valueOf(lb);
15912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
15922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
15932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /* Convenience base class for and/or constraints. */
15942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static abstract class BinaryConstraint implements Constraint,
15952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    Serializable {
15962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private static final long serialVersionUID = 1;
15972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        protected final Constraint a;
15982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        protected final Constraint b;
15992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
16002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        protected BinaryConstraint(Constraint a, Constraint b) {
16012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.a = a;
16022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.b = b;
16032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
16052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
16062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /* A constraint representing the logical and of two constraints. */
16072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static class AndConstraint extends BinaryConstraint {
16082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private static final long serialVersionUID = 7766999779862263523L;
16092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
16102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        AndConstraint(Constraint a, Constraint b) {
16112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            super(a, b);
16122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1614f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
16152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean isFulfilled(FixedDecimal n) {
1616f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert            return a.isFulfilled(n)
16172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    && b.isFulfilled(n);
16182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1620f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
16212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean isLimited(SampleType sampleType) {
16222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // we ignore the case where both a and b are unlimited but no values
16232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // satisfy both-- we still consider this 'unlimited'
1624f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert            return a.isLimited(sampleType)
16252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    || b.isLimited(sampleType);
16262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1628f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
16292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String toString() {
16302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return a.toString() + " and " + b.toString();
16312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
16332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
16342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /* A constraint representing the logical or of two constraints. */
16352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static class OrConstraint extends BinaryConstraint {
16362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private static final long serialVersionUID = 1405488568664762222L;
16372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
16382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        OrConstraint(Constraint a, Constraint b) {
16392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            super(a, b);
16402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1642f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
16432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean isFulfilled(FixedDecimal n) {
1644f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert            return a.isFulfilled(n)
16452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    || b.isFulfilled(n);
16462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1648f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
16492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean isLimited(SampleType sampleType) {
1650f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert            return a.isLimited(sampleType)
16512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    && b.isLimited(sampleType);
16522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1654f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
16552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String toString() {
16562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return a.toString() + " or " + b.toString();
16572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
16592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
16602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /*
16612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Implementation of Rule that uses a constraint.
16622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Provides 'and' and 'or' to combine constraints.  Immutable.
16632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
16642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static class Rule implements Serializable {
1665f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        // TODO - Findbugs: Class android.icu.text.PluralRules$Rule defines non-transient
1666f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        // non-serializable instance field integerSamples. See ticket#10494.
16672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private static final long serialVersionUID = 1;
16682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final String keyword;
16692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final Constraint constraint;
16702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final FixedDecimalSamples integerSamples;
16712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final FixedDecimalSamples decimalSamples;
16722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
16732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public Rule(String keyword, Constraint constraint, FixedDecimalSamples integerSamples, FixedDecimalSamples decimalSamples) {
16742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.keyword = keyword;
16752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.constraint = constraint;
16762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.integerSamples = integerSamples;
16772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            this.decimalSamples = decimalSamples;
16782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
16802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @SuppressWarnings("unused")
16812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public Rule and(Constraint c) {
16822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return new Rule(keyword, new AndConstraint(constraint, c), integerSamples, decimalSamples);
16832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
16852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @SuppressWarnings("unused")
16862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public Rule or(Constraint c) {
16872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return new Rule(keyword, new OrConstraint(constraint, c), integerSamples, decimalSamples);
16882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
16902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String getKeyword() {
16912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return keyword;
16922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
16942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean appliesTo(FixedDecimal n) {
16952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return constraint.isFulfilled(n);
16962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
16972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
16982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean isLimited(SampleType sampleType) {
16992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return constraint.isLimited(sampleType);
17002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
17012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1702f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
17032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String toString() {
1704f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert            return keyword + ": " + constraint.toString()
17052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    + (integerSamples == null ? "" : " " + integerSamples.toString())
17062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    + (decimalSamples == null ? "" : " " + decimalSamples.toString());
17072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
17082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
17092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
17102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * @deprecated This API is ICU internal only.
1711836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
17122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
17132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Deprecated
17142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Override
17152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public int hashCode() {
17162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return keyword.hashCode() ^ constraint.hashCode();
17172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
17182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
17192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String getConstraint() {
17202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return constraint.toString();
17212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
17222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
17232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
17242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static class RuleList implements Serializable {
17252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private boolean hasExplicitBoundingInfo = false;
17262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private static final long serialVersionUID = 1;
17272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private final List<Rule> rules = new ArrayList<Rule>();
17282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
17292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public RuleList addRule(Rule nextRule) {
17302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            String keyword = nextRule.getKeyword();
17312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (Rule rule : rules) {
17322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (keyword.equals(rule.getKeyword())) {
17332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    throw new IllegalArgumentException("Duplicate keyword: " + keyword);
17342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
17352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
17362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            rules.add(nextRule);
17372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return this;
17382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
17392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
17402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public RuleList finish() throws ParseException {
17412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // make sure that 'other' is present, and at the end.
17422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            Rule otherRule = null;
17432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (Iterator<Rule> it = rules.iterator(); it.hasNext();) {
17442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                Rule rule = it.next();
17452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if ("other".equals(rule.getKeyword())) {
17462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    otherRule = rule;
17472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    it.remove();
17482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
17492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
17502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (otherRule == null) {
17512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                otherRule = parseRule("other:"); // make sure we have always have an 'other' a rule
17522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
17532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            rules.add(otherRule);
17542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return this;
17552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
17562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
17572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private Rule selectRule(FixedDecimal n) {
17582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (Rule rule : rules) {
17592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (rule.appliesTo(n)) {
17602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    return rule;
17612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
17622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
17632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return null;
17642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
17652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
17662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String select(FixedDecimal n) {
17672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (Double.isInfinite(n.source) || Double.isNaN(n.source)) {
17682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return KEYWORD_OTHER;
17692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
17702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            Rule r = selectRule(n);
17712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return r.getKeyword();
17722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
17732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
17742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public Set<String> getKeywords() {
17752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            Set<String> result = new LinkedHashSet<String>();
17762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (Rule rule : rules) {
17772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                result.add(rule.getKeyword());
17782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
17792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // since we have explict 'other', we don't need this.
17802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            //result.add(KEYWORD_OTHER);
17812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return result;
17822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
17832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
17842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean isLimited(String keyword, SampleType sampleType) {
17852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (hasExplicitBoundingInfo) {
17862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                FixedDecimalSamples mySamples = getDecimalSamples(keyword, sampleType);
17872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return mySamples == null ? true : mySamples.bounded;
17882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
17892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
17902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return computeLimited(keyword, sampleType);
17912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
17922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
17932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean computeLimited(String keyword, SampleType sampleType) {
17942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // if all rules with this keyword are limited, it's limited,
17952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // and if there's no rule with this keyword, it's unlimited
17962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            boolean result = false;
17972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (Rule rule : rules) {
17982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (keyword.equals(rule.getKeyword())) {
17992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    if (!rule.isLimited(sampleType)) {
18002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                        return false;
18012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    }
18022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    result = true;
18032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
18042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
18052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return result;
18062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
18072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1808f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert        @Override
18092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String toString() {
18102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            StringBuilder builder = new StringBuilder();
18112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (Rule rule : rules) {
18122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (builder.length() != 0) {
18132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    builder.append(CATEGORY_SEPARATOR);
18142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
18152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                builder.append(rule);
18162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
18172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return builder.toString();
18182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
18192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
18202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public String getRules(String keyword) {
18212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (Rule rule : rules) {
18222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (rule.getKeyword().equals(keyword)) {
18232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    return rule.getConstraint();
18242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
18252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
18262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return null;
18272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
18282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
18292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public boolean select(FixedDecimal sample, String keyword) {
18302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (Rule rule : rules) {
18312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (rule.getKeyword().equals(keyword) && rule.appliesTo(sample)) {
18322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    return true;
18332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
18342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
18352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return false;
18362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
18372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
18382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public FixedDecimalSamples getDecimalSamples(String keyword, SampleType sampleType) {
18392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (Rule rule : rules) {
18402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (rule.getKeyword().equals(keyword)) {
18412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    return sampleType == SampleType.INTEGER ? rule.integerSamples : rule.decimalSamples;
18422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
18432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
18442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return null;
18452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
18462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
18472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
18482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @SuppressWarnings("unused")
18492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private boolean addConditional(Set<FixedDecimal> toAddTo, Set<FixedDecimal> others, double trial) {
18502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        boolean added;
18512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        FixedDecimal toAdd = new FixedDecimal(trial);
18522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (!toAddTo.contains(toAdd) && !others.contains(toAdd)) {
18532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            others.add(toAdd);
18542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            added = true;
18552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } else {
18562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            added = false;
18572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
18582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return added;
18592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
18602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
18612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
18622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
18632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // -------------------------------------------------------------------------
18642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // Static class methods.
18652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // -------------------------------------------------------------------------
18662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
18672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
18682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Provides access to the predefined cardinal-number <code>PluralRules</code> for a given
18692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * locale.
18702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Same as forLocale(locale, PluralType.CARDINAL).
18712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
18722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <p>ICU defines plural rules for many locales based on CLDR <i>Language Plural Rules</i>.
18732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * For these predefined rules, see CLDR page at
18742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
18752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
18762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param locale The locale for which a <code>PluralRules</code> object is
18772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   returned.
18782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The predefined <code>PluralRules</code> object for this locale.
18792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   If there's no predefined rules for this locale, the rules
18802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   for the closest parent in the locale hierarchy that has one will
18812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   be returned.  The final fallback always returns the default
18822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   rules.
18832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
18842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static PluralRules forLocale(ULocale locale) {
18852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return Factory.getDefaultFactory().forLocale(locale, PluralType.CARDINAL);
18862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
18872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
18882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
18892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Provides access to the predefined cardinal-number <code>PluralRules</code> for a given
18905a559d08b74c555d7f997b51acd311b7a8756d26Fredrik Roubert     * {@link java.util.Locale}.
18912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Same as forLocale(locale, PluralType.CARDINAL).
18922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
18932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <p>ICU defines plural rules for many locales based on CLDR <i>Language Plural Rules</i>.
18942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * For these predefined rules, see CLDR page at
18952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
18962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
18975a559d08b74c555d7f997b51acd311b7a8756d26Fredrik Roubert     * @param locale The locale for which a <code>PluralRules</code> object is
18982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   returned.
18992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The predefined <code>PluralRules</code> object for this locale.
19002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   If there's no predefined rules for this locale, the rules
19012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   for the closest parent in the locale hierarchy that has one will
19022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   be returned.  The final fallback always returns the default
19032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   rules.
19042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
19052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static PluralRules forLocale(Locale locale) {
19062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return forLocale(ULocale.forLocale(locale));
19072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
19082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
19092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
19102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Provides access to the predefined <code>PluralRules</code> for a given
19112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * locale and the plural type.
19122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
19132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <p>ICU defines plural rules for many locales based on CLDR <i>Language Plural Rules</i>.
19142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * For these predefined rules, see CLDR page at
19152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
19162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
19172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param locale The locale for which a <code>PluralRules</code> object is
19182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   returned.
19192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param type The plural type (e.g., cardinal or ordinal).
19202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The predefined <code>PluralRules</code> object for this locale.
19212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   If there's no predefined rules for this locale, the rules
19222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   for the closest parent in the locale hierarchy that has one will
19232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   be returned.  The final fallback always returns the default
19242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   rules.
19252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
19262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static PluralRules forLocale(ULocale locale, PluralType type) {
19272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return Factory.getDefaultFactory().forLocale(locale, type);
19282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
19292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
19302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
19312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Provides access to the predefined <code>PluralRules</code> for a given
19325a559d08b74c555d7f997b51acd311b7a8756d26Fredrik Roubert     * {@link java.util.Locale} and the plural type.
19332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
19342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * <p>ICU defines plural rules for many locales based on CLDR <i>Language Plural Rules</i>.
19352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * For these predefined rules, see CLDR page at
19362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
19372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
19385a559d08b74c555d7f997b51acd311b7a8756d26Fredrik Roubert     * @param locale The locale for which a <code>PluralRules</code> object is
19392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   returned.
19402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param type The plural type (e.g., cardinal or ordinal).
19412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The predefined <code>PluralRules</code> object for this locale.
19422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   If there's no predefined rules for this locale, the rules
19432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   for the closest parent in the locale hierarchy that has one will
19442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   be returned.  The final fallback always returns the default
19452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *   rules.
19462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
19472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static PluralRules forLocale(Locale locale, PluralType type) {
19482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return forLocale(ULocale.forLocale(locale), type);
19492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
19502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
19512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /*
19522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Checks whether a token is a valid keyword.
19532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
19542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param token the token to be checked
19552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return true if the token is a valid keyword.
19562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
19572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private static boolean isValidKeyword(String token) {
19582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return ALLOWED_ID.containsAll(token);
19592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
19602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
19612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /*
19622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Creates a new <code>PluralRules</code> object.  Immutable.
19632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
19642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private PluralRules(RuleList rules) {
19652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        this.rules = rules;
19662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        this.keywords = Collections.unmodifiableSet(rules.getKeywords());
19672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
19682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
19692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
19702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
197193cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
1972836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
19732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
19742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
19752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Override
19762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public int hashCode() {
19772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return rules.hashCode();
19782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
19792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
19802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Given a number, returns the keyword of the first rule that applies to
19812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * the number.
19822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
19832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param number The number for which the rule has to be determined.
19842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The keyword of the selected rule.
19852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
19862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public String select(double number) {
19872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return rules.select(new FixedDecimal(number));
19882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
19892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
19902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
19912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Given a number, returns the keyword of the first rule that applies to
19922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * the number.
19932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
19942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param number The number for which the rule has to be determined.
19952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The keyword of the selected rule.
19962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
199793cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
1998836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
19992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
20002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
20012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public String select(double number, int countVisibleFractionDigits, long fractionaldigits) {
20022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return rules.select(new FixedDecimal(number, countVisibleFractionDigits, fractionaldigits));
20032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
20042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
20052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
20062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Given a number information, returns the keyword of the first rule that applies to
20072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * the number.
20082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
200998d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert     * @param number The number information for which the rule has to be determined.
20102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The keyword of the selected rule.
20112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
201293cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
2013836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
20142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
20152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
201698d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert    public String select(FixedDecimal number) {
201798d264ec1d3841aef62c0e0293c929c23c08c5c5Fredrik Roubert        return rules.select(number);
20182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
20192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
20202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
20212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Given a number information, and keyword, return whether the keyword would match the number.
20222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
20232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param sample The number information for which the rule has to be determined.
20242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param keyword The keyword to filter on
20252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
202693cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
2027836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
20282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
20292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
20302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public boolean matches(FixedDecimal sample, String keyword) {
20312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return rules.select(sample, keyword);
20322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
20332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
20342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
20352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns a set of all rule keywords used in this <code>PluralRules</code>
20362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * object.  The rule "other" is always present by default.
20372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
20382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The set of keywords.
20392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
20402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public Set<String> getKeywords() {
20412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return keywords;
20422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
20432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
20442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
20452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the unique value that this keyword matches, or {@link #NO_UNIQUE_VALUE}
20462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * if the keyword matches multiple values or is not defined for this PluralRules.
20472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
20482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param keyword the keyword to check for a unique value
20492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return The unique value for the keyword, or NO_UNIQUE_VALUE.
20502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
20512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public double getUniqueKeywordValue(String keyword) {
20522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        Collection<Double> values = getAllKeywordValues(keyword);
20532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (values != null && values.size() == 1) {
20542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return values.iterator().next();
20552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
20562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return NO_UNIQUE_VALUE;
20572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
20582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
20592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
20602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns all the values that trigger this keyword, or null if the number of such
20612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * values is unlimited.
20622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
20632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param keyword the keyword
20642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return the values that trigger this keyword, or null.  The returned collection
20652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * is immutable. It will be empty if the keyword is not defined.
20662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
20672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public Collection<Double> getAllKeywordValues(String keyword) {
20682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return getAllKeywordValues(keyword, SampleType.INTEGER);
20692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
20702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
20712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
20722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns all the values that trigger this keyword, or null if the number of such
20732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * values is unlimited.
20742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
20752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param keyword the keyword
20762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param type the type of samples requested, INTEGER or DECIMAL
20772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return the values that trigger this keyword, or null.  The returned collection
20782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * is immutable. It will be empty if the keyword is not defined.
2079f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert     *
20802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
208193cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
2082836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
20832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
20842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
20852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public Collection<Double> getAllKeywordValues(String keyword, SampleType type) {
20862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (!isLimited(keyword, type)) {
20872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return null;
20882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
20892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        Collection<Double> samples = getSamples(keyword, type);
20902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return samples == null ? null : Collections.unmodifiableCollection(samples);
20912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
20922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
20932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
20942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns a list of integer values for which select() would return that keyword,
20952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * or null if the keyword is not defined. The returned collection is unmodifiable.
20962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The returned list is not complete, and there might be additional values that
20972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * would return the keyword.
20982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
20992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param keyword the keyword to test
21002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return a list of values matching the keyword.
21012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
21022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public Collection<Double> getSamples(String keyword) {
21032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return getSamples(keyword, SampleType.INTEGER);
21042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
21052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
21062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
21072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns a list of values for which select() would return that keyword,
21082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * or null if the keyword is not defined.
21092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The returned collection is unmodifiable.
21102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The returned list is not complete, and there might be additional values that
21112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * would return the keyword. The keyword might be defined, and yet have an empty set of samples,
21122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * IF there are samples for the other sampleType.
21132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
21142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param keyword the keyword to test
21152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param sampleType the type of samples requested, INTEGER or DECIMAL
21162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return a list of values matching the keyword.
21172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated ICU internal only
211893cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
2119836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
21202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
21212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
21222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public Collection<Double> getSamples(String keyword, SampleType sampleType) {
21232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (!keywords.contains(keyword)) {
21242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return null;
21252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
21262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        Set<Double> result = new TreeSet<Double>();
21272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
21282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (rules.hasExplicitBoundingInfo) {
21292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            FixedDecimalSamples samples = rules.getDecimalSamples(keyword, sampleType);
21302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return samples == null ? Collections.unmodifiableSet(result)
21312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    : Collections.unmodifiableSet(samples.addSamples(result));
21322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
21332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
21342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // hack in case the rule is created without explicit samples
21352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int maxCount = isLimited(keyword, sampleType) ? Integer.MAX_VALUE : 20;
21362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
21372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        switch (sampleType) {
21382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case INTEGER:
21392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (int i = 0; i < 200; ++i) {
21402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (!addSample(keyword, i, maxCount, result)) {
21412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    break;
21422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
21432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
21442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            addSample(keyword, 1000000, maxCount, result); // hack for Welsh
21452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
21462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        case DECIMAL:
21472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            for (int i = 0; i < 2000; ++i) {
21482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (!addSample(keyword, new FixedDecimal(i/10d, 1), maxCount, result)) {
21492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    break;
21502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
21512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
21522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            addSample(keyword, new FixedDecimal(1000000d, 1), maxCount, result); // hack for Welsh
21532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            break;
21542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
21552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return result.size() == 0 ? null : Collections.unmodifiableSet(result);
21562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
21572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
21582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
21592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
216093cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
2161836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
21622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
21632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
21642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public boolean addSample(String keyword, Number sample, int maxCount, Set<Double> result) {
21652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        String selectedKeyword = sample instanceof FixedDecimal ? select((FixedDecimal)sample) : select(sample.doubleValue());
21662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (selectedKeyword.equals(keyword)) {
21672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            result.add(sample.doubleValue());
21682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (--maxCount < 0) {
21692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return false;
21702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
21712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
21722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return true;
21732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
21742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
21752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
21762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns a list of values for which select() would return that keyword,
21772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * or null if the keyword is not defined or no samples are available.
21782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The returned collection is unmodifiable.
21792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * The returned list is not complete, and there might be additional values that
21802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * would return the keyword.
21812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
21822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param keyword the keyword to test
21832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param sampleType the type of samples requested, INTEGER or DECIMAL
21842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return a list of values matching the keyword.
21852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
218693cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
2187836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
21882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
21892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
21902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public FixedDecimalSamples getDecimalSamples(String keyword, SampleType sampleType) {
21912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return rules.getDecimalSamples(keyword, sampleType);
21922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
21932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
21942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
21952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the set of locales for which PluralRules are known.
21962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return the set of locales for which PluralRules are known, as a list
2197836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
21982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
21992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static ULocale[] getAvailableULocales() {
22002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return Factory.getDefaultFactory().getAvailableULocales();
22012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
22022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
22032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
22042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the 'functionally equivalent' locale with respect to
22052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * plural rules.  Calling PluralRules.forLocale with the functionally equivalent
22062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * locale, and with the provided locale, returns rules that behave the same.
2207bfab1e7fec36dff93fb980c546ad64a565faf9fcPaul Duffin     * <br>
22082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * All locales with the same functionally equivalent locale have
22092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * plural rules that behave the same.  This is not exaustive;
22102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * there may be other locales whose plural rules behave the same
22112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * that do not have the same equivalent locale.
22122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *
22132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param locale the locale to check
2214bfab1e7fec36dff93fb980c546ad64a565faf9fcPaul Duffin     * @param isAvailable if not null and of length &gt; 0, this will hold 'true' at
22152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * index 0 if locale is directly defined (without fallback) as having plural rules
22162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return the functionally-equivalent locale
2217836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
22182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
22192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static ULocale getFunctionalEquivalent(ULocale locale, boolean[] isAvailable) {
22202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return Factory.getDefaultFactory().getFunctionalEquivalent(locale, isAvailable);
22212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
22222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
22232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
22242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * {@inheritDoc}
22252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2226f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert    @Override
22272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public String toString() {
22282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return rules.toString();
22292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
22302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
22312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
22322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * {@inheritDoc}
22332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
2234f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert    @Override
22352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public boolean equals(Object rhs) {
22362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return rhs instanceof PluralRules && equals((PluralRules)rhs);
22372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
22382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
22392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
22402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns true if rhs is equal to this.
22412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param rhs the PluralRules to compare to.
22422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return true if this and rhs are equal.
22432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
22442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    // TODO Optimize this
22452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public boolean equals(PluralRules rhs) {
22462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return rhs != null && toString().equals(rhs.toString());
22472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
22482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
22492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
22502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Status of the keyword for the rules, given a set of explicit values.
2251f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert     *
2252836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
22532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
22542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public enum KeywordStatus {
22552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
22562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * The keyword is not valid for the rules.
2257f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert         *
2258836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
22592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
22602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        INVALID,
22612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
22622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * The keyword is valid, but unused (it is covered by the explicit values, OR has no values for the given {@link SampleType}).
2263f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert         *
2264836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
22652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
22662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        SUPPRESSED,
22672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
22682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * The keyword is valid, used, and has a single possible value (before considering explicit values).
2269f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert         *
2270836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
22712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
22722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        UNIQUE,
22732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
22742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * The keyword is valid, used, not unique, and has a finite set of values.
2275f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert         *
2276836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
22772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
22782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        BOUNDED,
22792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
22802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * The keyword is valid but not bounded; there indefinitely many matching values.
2281f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert         *
2282836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller         * @hide draft / provisional / internal are hidden on Android
22832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
22842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        UNBOUNDED
22852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
22862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
22872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
22882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Find the status for the keyword, given a certain set of explicit values.
2289f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert     *
22902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param keyword
22912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            the particular keyword (call rules.getKeywords() to get the valid ones)
22922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param offset
22932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            the offset used, or 0.0d if not. Internally, the offset is subtracted from each explicit value before
22942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            checking against the keyword values.
22952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param explicits
22962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            a set of Doubles that are used explicitly (eg [=0], "[=1]"). May be empty or null.
22972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param uniqueValue
22982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            If non null, set to the unique value.
22992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return the KeywordStatus
2300836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
23012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
23022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public KeywordStatus getKeywordStatus(String keyword, int offset, Set<Double> explicits,
23032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            Output<Double> uniqueValue) {
23042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return getKeywordStatus(keyword, offset, explicits, uniqueValue, SampleType.INTEGER);
23052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
23062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
23072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Find the status for the keyword, given a certain set of explicit values.
2308f86f25d102340da66b9c7cb6b2d5ecdc0de43ecfFredrik Roubert     *
23092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param keyword
23102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            the particular keyword (call rules.getKeywords() to get the valid ones)
23112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param offset
23122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            the offset used, or 0.0d if not. Internally, the offset is subtracted from each explicit value before
23132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            checking against the keyword values.
23142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param explicits
23152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            a set of Doubles that are used explicitly (eg [=0], "[=1]"). May be empty or null.
23162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param sampleType
23172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            request KeywordStatus relative to INTEGER or DECIMAL values
23182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @param uniqueValue
23192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     *            If non null, set to the unique value.
23202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @return the KeywordStatus
23212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
232293cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
2323836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
23242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
23252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
23262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public KeywordStatus getKeywordStatus(String keyword, int offset, Set<Double> explicits,
23272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            Output<Double> uniqueValue, SampleType sampleType) {
23282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (uniqueValue != null) {
23292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            uniqueValue.value = null;
23302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
23312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (!keywords.contains(keyword)) {
23332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return KeywordStatus.INVALID;
23342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
23352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (!isLimited(keyword, sampleType)) {
23372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return KeywordStatus.UNBOUNDED;
23382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
23392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        Collection<Double> values = getSamples(keyword, sampleType);
23412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        int originalSize = values.size();
23432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (explicits == null) {
23452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            explicits = Collections.emptySet();
23462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
23472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // Quick check on whether there are multiple elements
23492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (originalSize > explicits.size()) {
23512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if (originalSize == 1) {
23522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                if (uniqueValue != null) {
23532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    uniqueValue.value = values.iterator().next();
23542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                }
23552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                return KeywordStatus.UNIQUE;
23562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
23572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return KeywordStatus.BOUNDED;
23582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
23592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // Compute if the quick test is insufficient.
23612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        HashSet<Double> subtractedSet = new HashSet<Double>(values);
23632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        for (Double explicit : explicits) {
23642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            subtractedSet.remove(explicit - offset);
23652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
23662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (subtractedSet.size() == 0) {
23672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return KeywordStatus.SUPPRESSED;
23682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
23692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        if (uniqueValue != null && subtractedSet.size() == 1) {
23712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            uniqueValue.value = subtractedSet.iterator().next();
23722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
23732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return originalSize == 1 ? KeywordStatus.UNIQUE : KeywordStatus.BOUNDED;
23752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
23762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
23782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated This API is ICU internal only.
237993cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
2380836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
23812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
23822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
23832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public String getRules(String keyword) {
23842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return rules.getRules(keyword);
23852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
23862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private void writeObject(
23882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            ObjectOutputStream out)
23892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                    throws IOException {
23902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        throw new NotSerializableException();
23912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
23922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private void readObject(ObjectInputStream in
23942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            ) throws IOException, ClassNotFoundException {
23952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        throw new NotSerializableException();
23962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
23972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
23982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private Object writeReplace() throws ObjectStreamException {
23992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return new PluralRulesSerialProxy(toString());
24002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
24012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
24022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
24032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated internal
240493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
2405836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
24062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
24072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
24082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public int compareTo(PluralRules other) {
24092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return toString().compareTo(other.toString());
24102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
24112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
24122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
24132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated internal
241493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
2415836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
24162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
24172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
24182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public Boolean isLimited(String keyword) {
24192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return rules.isLimited(keyword, SampleType.INTEGER);
24202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
24212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
24222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
24232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated internal
242493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
2425836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
24262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
24272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
24282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public boolean isLimited(String keyword, SampleType sampleType) {
24292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return rules.isLimited(keyword, sampleType);
24302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
24312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
24322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
24332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * @deprecated internal
243493cf604e9dd0525f15bc0a7450b2a35f3884c298Neil Fuller     * @hide original deprecated declaration
2435836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller     * @hide draft / provisional / internal are hidden on Android
24362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
24372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Deprecated
24382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public boolean computeLimited(String keyword, SampleType sampleType) {
24392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return rules.computeLimited(keyword, sampleType);
24402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
24412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller}
2442