// © 2018 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.number;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Set;

import com.ibm.icu.impl.CacheBase;
import com.ibm.icu.impl.PatternProps;
import com.ibm.icu.impl.SoftCache;
import com.ibm.icu.impl.StringSegment;
import com.ibm.icu.impl.number.MacroProps;
import com.ibm.icu.impl.number.RoundingUtils;
import com.ibm.icu.number.NumberFormatter.DecimalSeparatorDisplay;
import com.ibm.icu.number.NumberFormatter.GroupingStrategy;
import com.ibm.icu.number.NumberFormatter.SignDisplay;
import com.ibm.icu.number.NumberFormatter.UnitWidth;
import com.ibm.icu.text.DecimalFormatSymbols;
import com.ibm.icu.text.NumberingSystem;
import com.ibm.icu.util.BytesTrie;
import com.ibm.icu.util.CharsTrie;
import com.ibm.icu.util.CharsTrieBuilder;
import com.ibm.icu.util.Currency;
import com.ibm.icu.util.Currency.CurrencyUsage;
import com.ibm.icu.util.MeasureUnit;
import com.ibm.icu.util.NoUnit;
import com.ibm.icu.util.StringTrieBuilder;

/**
 * @author sffc
 *
 */
class NumberSkeletonImpl {

    //////////////////////////////////////////////////////////////////////////////////////////
    // NOTE: For examples of how to add a new stem to the number skeleton parser, see:      //
    // https://github.com/unicode-org/icu/commit/a2a7982216b2348070dc71093775ac7195793d73   //
    // and                                                                                  //
    // https://github.com/unicode-org/icu/commit/6fe86f3934a8a5701034f648a8f7c5087e84aa28   //
    //////////////////////////////////////////////////////////////////////////////////////////

    /**
     * While parsing a skeleton, this enum records what type of option we expect to find next.
     */
    static enum ParseState {
        // Section 0: We expect whitespace or a stem, but not an option:
        STATE_NULL,

        // Section 1: We might accept an option, but it is not required:
        STATE_SCIENTIFIC,
        STATE_FRACTION_PRECISION,

        // Section 2: An option is required:
        STATE_INCREMENT_PRECISION,
        STATE_MEASURE_UNIT,
        STATE_PER_MEASURE_UNIT,
        STATE_IDENTIFIER_UNIT,
        STATE_UNIT_USAGE,
        STATE_CURRENCY_UNIT,
        STATE_INTEGER_WIDTH,
        STATE_NUMBERING_SYSTEM,
        STATE_SCALE,
    }

    /**
     * All possible stem literals have an entry in the StemEnum. The enum name is the kebab case stem
     * string literal written in upper snake case.
     *
     * @see StemToObject
     * @see #SERIALIZED_STEM_TRIE
     */
    static enum StemEnum {
        // Section 1: Stems that do not require an option:
        STEM_COMPACT_SHORT,
        STEM_COMPACT_LONG,
        STEM_SCIENTIFIC,
        STEM_ENGINEERING,
        STEM_NOTATION_SIMPLE,
        STEM_BASE_UNIT,
        STEM_PERCENT,
        STEM_PERMILLE,
        STEM_PERCENT_100, // concise-only
        STEM_PRECISION_INTEGER,
        STEM_PRECISION_UNLIMITED,
        STEM_PRECISION_CURRENCY_STANDARD,
        STEM_PRECISION_CURRENCY_CASH,
        STEM_ROUNDING_MODE_CEILING,
        STEM_ROUNDING_MODE_FLOOR,
        STEM_ROUNDING_MODE_DOWN,
        STEM_ROUNDING_MODE_UP,
        STEM_ROUNDING_MODE_HALF_EVEN,
        STEM_ROUNDING_MODE_HALF_DOWN,
        STEM_ROUNDING_MODE_HALF_UP,
        STEM_ROUNDING_MODE_UNNECESSARY,
        STEM_GROUP_OFF,
        STEM_GROUP_MIN2,
        STEM_GROUP_AUTO,
        STEM_GROUP_ON_ALIGNED,
        STEM_GROUP_THOUSANDS,
        STEM_LATIN,
        STEM_UNIT_WIDTH_NARROW,
        STEM_UNIT_WIDTH_SHORT,
        STEM_UNIT_WIDTH_FULL_NAME,
        STEM_UNIT_WIDTH_ISO_CODE,
        STEM_UNIT_WIDTH_FORMAL,
        STEM_UNIT_WIDTH_VARIANT,
        STEM_UNIT_WIDTH_HIDDEN,
        STEM_SIGN_AUTO,
        STEM_SIGN_ALWAYS,
        STEM_SIGN_NEVER,
        STEM_SIGN_ACCOUNTING,
        STEM_SIGN_ACCOUNTING_ALWAYS,
        STEM_SIGN_EXCEPT_ZERO,
        STEM_SIGN_ACCOUNTING_EXCEPT_ZERO,
        STEM_SIGN_NEGATIVE,
        STEM_SIGN_ACCOUNTING_NEGATIVE,
        STEM_DECIMAL_AUTO,
        STEM_DECIMAL_ALWAYS,

        // Section 2: Stems that DO require an option:
        STEM_PRECISION_INCREMENT,
        STEM_MEASURE_UNIT,
        STEM_PER_MEASURE_UNIT,
        STEM_UNIT,
        STEM_UNIT_USAGE,
        STEM_CURRENCY,
        STEM_INTEGER_WIDTH,
        STEM_NUMBERING_SYSTEM,
        STEM_SCALE,
    };

    /** Default wildcard char, accepted on input and printed in output */
    static final char WILDCARD_CHAR = '*';

    /** Alternative wildcard char, accept on input but not printed in output */
    static final char ALT_WILDCARD_CHAR = '+';

    /** Checks whether the char is a wildcard on input */
    static boolean isWildcardChar(char c) {
        return c == WILDCARD_CHAR || c == ALT_WILDCARD_CHAR;
    }

    /** For mapping from ordinal back to StemEnum in Java. */
    static final StemEnum[] STEM_ENUM_VALUES = StemEnum.values();

    /** A data structure for mapping from stem strings to the stem enum. Built at startup. */
    static final String SERIALIZED_STEM_TRIE = buildStemTrie();

    static String buildStemTrie() {
        CharsTrieBuilder b = new CharsTrieBuilder();

        // Section 1:
        b.add("compact-short", StemEnum.STEM_COMPACT_SHORT.ordinal());
        b.add("compact-long", StemEnum.STEM_COMPACT_LONG.ordinal());
        b.add("scientific", StemEnum.STEM_SCIENTIFIC.ordinal());
        b.add("engineering", StemEnum.STEM_ENGINEERING.ordinal());
        b.add("notation-simple", StemEnum.STEM_NOTATION_SIMPLE.ordinal());
        b.add("base-unit", StemEnum.STEM_BASE_UNIT.ordinal());
        b.add("percent", StemEnum.STEM_PERCENT.ordinal());
        b.add("permille", StemEnum.STEM_PERMILLE.ordinal());
        b.add("precision-integer", StemEnum.STEM_PRECISION_INTEGER.ordinal());
        b.add("precision-unlimited", StemEnum.STEM_PRECISION_UNLIMITED.ordinal());
        b.add("precision-currency-standard", StemEnum.STEM_PRECISION_CURRENCY_STANDARD.ordinal());
        b.add("precision-currency-cash", StemEnum.STEM_PRECISION_CURRENCY_CASH.ordinal());
        b.add("rounding-mode-ceiling", StemEnum.STEM_ROUNDING_MODE_CEILING.ordinal());
        b.add("rounding-mode-floor", StemEnum.STEM_ROUNDING_MODE_FLOOR.ordinal());
        b.add("rounding-mode-down", StemEnum.STEM_ROUNDING_MODE_DOWN.ordinal());
        b.add("rounding-mode-up", StemEnum.STEM_ROUNDING_MODE_UP.ordinal());
        b.add("rounding-mode-half-even", StemEnum.STEM_ROUNDING_MODE_HALF_EVEN.ordinal());
        b.add("rounding-mode-half-down", StemEnum.STEM_ROUNDING_MODE_HALF_DOWN.ordinal());
        b.add("rounding-mode-half-up", StemEnum.STEM_ROUNDING_MODE_HALF_UP.ordinal());
        b.add("rounding-mode-unnecessary", StemEnum.STEM_ROUNDING_MODE_UNNECESSARY.ordinal());
        b.add("group-off", StemEnum.STEM_GROUP_OFF.ordinal());
        b.add("group-min2", StemEnum.STEM_GROUP_MIN2.ordinal());
        b.add("group-auto", StemEnum.STEM_GROUP_AUTO.ordinal());
        b.add("group-on-aligned", StemEnum.STEM_GROUP_ON_ALIGNED.ordinal());
        b.add("group-thousands", StemEnum.STEM_GROUP_THOUSANDS.ordinal());
        b.add("latin", StemEnum.STEM_LATIN.ordinal());
        b.add("unit-width-narrow", StemEnum.STEM_UNIT_WIDTH_NARROW.ordinal());
        b.add("unit-width-short", StemEnum.STEM_UNIT_WIDTH_SHORT.ordinal());
        b.add("unit-width-full-name", StemEnum.STEM_UNIT_WIDTH_FULL_NAME.ordinal());
        b.add("unit-width-iso-code", StemEnum.STEM_UNIT_WIDTH_ISO_CODE.ordinal());
        b.add("unit-width-formal", StemEnum.STEM_UNIT_WIDTH_FORMAL.ordinal());
        b.add("unit-width-variant", StemEnum.STEM_UNIT_WIDTH_VARIANT.ordinal());
        b.add("unit-width-hidden", StemEnum.STEM_UNIT_WIDTH_HIDDEN.ordinal());
        b.add("sign-auto", StemEnum.STEM_SIGN_AUTO.ordinal());
        b.add("sign-always", StemEnum.STEM_SIGN_ALWAYS.ordinal());
        b.add("sign-never", StemEnum.STEM_SIGN_NEVER.ordinal());
        b.add("sign-accounting", StemEnum.STEM_SIGN_ACCOUNTING.ordinal());
        b.add("sign-accounting-always", StemEnum.STEM_SIGN_ACCOUNTING_ALWAYS.ordinal());
        b.add("sign-except-zero", StemEnum.STEM_SIGN_EXCEPT_ZERO.ordinal());
        b.add("sign-accounting-except-zero", StemEnum.STEM_SIGN_ACCOUNTING_EXCEPT_ZERO.ordinal());
        b.add("sign-negative", StemEnum.STEM_SIGN_NEGATIVE.ordinal());
        b.add("sign-accounting-negative", StemEnum.STEM_SIGN_ACCOUNTING_NEGATIVE.ordinal());
        b.add("decimal-auto", StemEnum.STEM_DECIMAL_AUTO.ordinal());
        b.add("decimal-always", StemEnum.STEM_DECIMAL_ALWAYS.ordinal());

        // Section 2:
        b.add("precision-increment", StemEnum.STEM_PRECISION_INCREMENT.ordinal());
        b.add("measure-unit", StemEnum.STEM_MEASURE_UNIT.ordinal());
        b.add("per-measure-unit", StemEnum.STEM_PER_MEASURE_UNIT.ordinal());
        b.add("unit", StemEnum.STEM_UNIT.ordinal());
        b.add("usage", StemEnum.STEM_UNIT_USAGE.ordinal());
        b.add("currency", StemEnum.STEM_CURRENCY.ordinal());
        b.add("integer-width", StemEnum.STEM_INTEGER_WIDTH.ordinal());
        b.add("numbering-system", StemEnum.STEM_NUMBERING_SYSTEM.ordinal());
        b.add("scale", StemEnum.STEM_SCALE.ordinal());

        // Section 3 (concise tokens):
        b.add("K", StemEnum.STEM_COMPACT_SHORT.ordinal());
        b.add("KK", StemEnum.STEM_COMPACT_LONG.ordinal());
        b.add("%", StemEnum.STEM_PERCENT.ordinal());
        b.add("%x100", StemEnum.STEM_PERCENT_100.ordinal());
        b.add(",_", StemEnum.STEM_GROUP_OFF.ordinal());
        b.add(",?", StemEnum.STEM_GROUP_MIN2.ordinal());
        b.add(",!", StemEnum.STEM_GROUP_ON_ALIGNED.ordinal());
        b.add("+!", StemEnum.STEM_SIGN_ALWAYS.ordinal());
        b.add("+_", StemEnum.STEM_SIGN_NEVER.ordinal());
        b.add("()", StemEnum.STEM_SIGN_ACCOUNTING.ordinal());
        b.add("()!", StemEnum.STEM_SIGN_ACCOUNTING_ALWAYS.ordinal());
        b.add("+?", StemEnum.STEM_SIGN_EXCEPT_ZERO.ordinal());
        b.add("()?", StemEnum.STEM_SIGN_ACCOUNTING_EXCEPT_ZERO.ordinal());
        b.add("+-", StemEnum.STEM_SIGN_NEGATIVE.ordinal());
        b.add("()-", StemEnum.STEM_SIGN_ACCOUNTING_NEGATIVE.ordinal());

        // Build the CharsTrie
        // TODO: Use SLOW or FAST here?
        return b.buildCharSequence(StringTrieBuilder.Option.FAST).toString();
    }

    /**
     * Utility class for methods that convert from StemEnum to corresponding objects or enums. This
     * applies to only the "Section 1" stems, those that are well-defined without an option.
     */
    static final class StemToObject {

        private static Notation notation(StemEnum stem) {
            switch (stem) {
            case STEM_COMPACT_SHORT:
                return Notation.compactShort();
            case STEM_COMPACT_LONG:
                return Notation.compactLong();
            case STEM_SCIENTIFIC:
                return Notation.scientific();
            case STEM_ENGINEERING:
                return Notation.engineering();
            case STEM_NOTATION_SIMPLE:
                return Notation.simple();
            default:
                throw new AssertionError();
            }
        }

        private static MeasureUnit unit(StemEnum stem) {
            switch (stem) {
            case STEM_BASE_UNIT:
                return NoUnit.BASE;
            case STEM_PERCENT:
                return NoUnit.PERCENT;
            case STEM_PERMILLE:
                return NoUnit.PERMILLE;
            default:
                throw new AssertionError();
            }
        }

        private static Precision precision(StemEnum stem) {
            switch (stem) {
            case STEM_PRECISION_INTEGER:
                return Precision.integer();
            case STEM_PRECISION_UNLIMITED:
                return Precision.unlimited();
            case STEM_PRECISION_CURRENCY_STANDARD:
                return Precision.currency(CurrencyUsage.STANDARD);
            case STEM_PRECISION_CURRENCY_CASH:
                return Precision.currency(CurrencyUsage.CASH);
            default:
                throw new AssertionError();
            }
        }

        private static RoundingMode roundingMode(StemEnum stem) {
            switch (stem) {
            case STEM_ROUNDING_MODE_CEILING:
                return RoundingMode.CEILING;
            case STEM_ROUNDING_MODE_FLOOR:
                return RoundingMode.FLOOR;
            case STEM_ROUNDING_MODE_DOWN:
                return RoundingMode.DOWN;
            case STEM_ROUNDING_MODE_UP:
                return RoundingMode.UP;
            case STEM_ROUNDING_MODE_HALF_EVEN:
                return RoundingMode.HALF_EVEN;
            case STEM_ROUNDING_MODE_HALF_DOWN:
                return RoundingMode.HALF_DOWN;
            case STEM_ROUNDING_MODE_HALF_UP:
                return RoundingMode.HALF_UP;
            case STEM_ROUNDING_MODE_UNNECESSARY:
                return RoundingMode.UNNECESSARY;
            default:
                throw new AssertionError();
            }
        }

        private static GroupingStrategy groupingStrategy(StemEnum stem) {
            switch (stem) {
            case STEM_GROUP_OFF:
                return GroupingStrategy.OFF;
            case STEM_GROUP_MIN2:
                return GroupingStrategy.MIN2;
            case STEM_GROUP_AUTO:
                return GroupingStrategy.AUTO;
            case STEM_GROUP_ON_ALIGNED:
                return GroupingStrategy.ON_ALIGNED;
            case STEM_GROUP_THOUSANDS:
                return GroupingStrategy.THOUSANDS;
            default:
                return null; // for objects, throw; for enums, return null
            }
        }

        private static UnitWidth unitWidth(StemEnum stem) {
            switch (stem) {
            case STEM_UNIT_WIDTH_NARROW:
                return UnitWidth.NARROW;
            case STEM_UNIT_WIDTH_SHORT:
                return UnitWidth.SHORT;
            case STEM_UNIT_WIDTH_FULL_NAME:
                return UnitWidth.FULL_NAME;
            case STEM_UNIT_WIDTH_ISO_CODE:
                return UnitWidth.ISO_CODE;
            case STEM_UNIT_WIDTH_FORMAL:
                return UnitWidth.FORMAL;
            case STEM_UNIT_WIDTH_VARIANT:
                return UnitWidth.VARIANT;
            case STEM_UNIT_WIDTH_HIDDEN:
                return UnitWidth.HIDDEN;
            default:
                return null; // for objects, throw; for enums, return null
            }
        }

        private static SignDisplay signDisplay(StemEnum stem) {
            switch (stem) {
            case STEM_SIGN_AUTO:
                return SignDisplay.AUTO;
            case STEM_SIGN_ALWAYS:
                return SignDisplay.ALWAYS;
            case STEM_SIGN_NEVER:
                return SignDisplay.NEVER;
            case STEM_SIGN_ACCOUNTING:
                return SignDisplay.ACCOUNTING;
            case STEM_SIGN_ACCOUNTING_ALWAYS:
                return SignDisplay.ACCOUNTING_ALWAYS;
            case STEM_SIGN_EXCEPT_ZERO:
                return SignDisplay.EXCEPT_ZERO;
            case STEM_SIGN_ACCOUNTING_EXCEPT_ZERO:
                return SignDisplay.ACCOUNTING_EXCEPT_ZERO;
            case STEM_SIGN_NEGATIVE:
                return SignDisplay.NEGATIVE;
            case STEM_SIGN_ACCOUNTING_NEGATIVE:
                return SignDisplay.ACCOUNTING_NEGATIVE;
            default:
                return null; // for objects, throw; for enums, return null
            }
        }

        private static DecimalSeparatorDisplay decimalSeparatorDisplay(StemEnum stem) {
            switch (stem) {
            case STEM_DECIMAL_AUTO:
                return DecimalSeparatorDisplay.AUTO;
            case STEM_DECIMAL_ALWAYS:
                return DecimalSeparatorDisplay.ALWAYS;
            default:
                return null; // for objects, throw; for enums, return null
            }
        }
    }

    /**
     * Utility class for methods that convert from enums to stem strings. More complex object conversions
     * take place in ObjectToStemString.
     */
    static final class EnumToStemString {

        private static void roundingMode(RoundingMode value, StringBuilder sb) {
            switch (value) {
            case CEILING:
                sb.append("rounding-mode-ceiling");
                break;
            case FLOOR:
                sb.append("rounding-mode-floor");
                break;
            case DOWN:
                sb.append("rounding-mode-down");
                break;
            case UP:
                sb.append("rounding-mode-up");
                break;
            case HALF_EVEN:
                sb.append("rounding-mode-half-even");
                break;
            case HALF_DOWN:
                sb.append("rounding-mode-half-down");
                break;
            case HALF_UP:
                sb.append("rounding-mode-half-up");
                break;
            case UNNECESSARY:
                sb.append("rounding-mode-unnecessary");
                break;
            default:
                throw new AssertionError();
            }
        }

        private static void groupingStrategy(GroupingStrategy value, StringBuilder sb) {
            switch (value) {
            case OFF:
                sb.append("group-off");
                break;
            case MIN2:
                sb.append("group-min2");
                break;
            case AUTO:
                sb.append("group-auto");
                break;
            case ON_ALIGNED:
                sb.append("group-on-aligned");
                break;
            case THOUSANDS:
                sb.append("group-thousands");
                break;
            default:
                throw new AssertionError();
            }
        }

        private static void unitWidth(UnitWidth value, StringBuilder sb) {
            switch (value) {
            case NARROW:
                sb.append("unit-width-narrow");
                break;
            case SHORT:
                sb.append("unit-width-short");
                break;
            case FULL_NAME:
                sb.append("unit-width-full-name");
                break;
            case ISO_CODE:
                sb.append("unit-width-iso-code");
                break;
            case FORMAL:
                sb.append("unit-width-formal");
                break;
            case VARIANT:
                sb.append("unit-width-variant");
                break;
            case HIDDEN:
                sb.append("unit-width-hidden");
                break;
            default:
                throw new AssertionError();
            }
        }

        private static void signDisplay(SignDisplay value, StringBuilder sb) {
            switch (value) {
            case AUTO:
                sb.append("sign-auto");
                break;
            case ALWAYS:
                sb.append("sign-always");
                break;
            case NEVER:
                sb.append("sign-never");
                break;
            case ACCOUNTING:
                sb.append("sign-accounting");
                break;
            case ACCOUNTING_ALWAYS:
                sb.append("sign-accounting-always");
                break;
            case EXCEPT_ZERO:
                sb.append("sign-except-zero");
                break;
            case ACCOUNTING_EXCEPT_ZERO:
                sb.append("sign-accounting-except-zero");
                break;
            case NEGATIVE:
                sb.append("sign-negative");
                break;
            case ACCOUNTING_NEGATIVE:
                sb.append("sign-accounting-negative");
                break;
            default:
                throw new AssertionError();
            }
        }

        private static void decimalSeparatorDisplay(DecimalSeparatorDisplay value, StringBuilder sb) {
            switch (value) {
            case AUTO:
                sb.append("decimal-auto");
                break;
            case ALWAYS:
                sb.append("decimal-always");
                break;
            default:
                throw new AssertionError();
            }
        }
    }

    ///// ENTRYPOINT FUNCTIONS /////

    /** Cache for parsed skeleton strings. */
    private static final CacheBase<String, UnlocalizedNumberFormatter, Void> cache = new SoftCache<String, UnlocalizedNumberFormatter, Void>() {
        @Override
        protected UnlocalizedNumberFormatter createInstance(String skeletonString, Void unused) {
            return create(skeletonString);
        }
    };

    /**
     * Gets the number formatter for the given number skeleton string from the cache, creating it if it
     * does not exist in the cache.
     *
     * @param skeletonString
     *            A number skeleton string, possibly not in its shortest form.
     * @return An UnlocalizedNumberFormatter with behavior defined by the given skeleton string.
     */
    public static UnlocalizedNumberFormatter getOrCreate(String skeletonString) {
        // TODO: This does not currently check the cache for the normalized form of the skeleton.
        // A new cache implementation would be required for that to work.
        return cache.getInstance(skeletonString, null);
    }

    /**
     * Creates a NumberFormatter corresponding to the given skeleton string.
     *
     * @param skeletonString
     *            A number skeleton string, possibly not in its shortest form.
     * @return An UnlocalizedNumberFormatter with behavior defined by the given skeleton string.
     */
    public static UnlocalizedNumberFormatter create(String skeletonString) {
        MacroProps macros = parseSkeleton(skeletonString);
        return NumberFormatter.with().macros(macros);
    }

    /**
     * Create a skeleton string corresponding to the given NumberFormatter.
     *
     * @param macros
     *            The NumberFormatter options object.
     * @return A skeleton string in normalized form.
     */
    public static String generate(MacroProps macros) {
        StringBuilder sb = new StringBuilder();
        generateSkeleton(macros, sb);
        return sb.toString();
    }

    ///// MAIN PARSING FUNCTIONS /////

    /**
     * Converts from a skeleton string to a MacroProps. This method contains the primary parse loop.
     */
    private static MacroProps parseSkeleton(String skeletonString) {
        // Add a trailing whitespace to the end of the skeleton string to make code cleaner.
        skeletonString += " ";

        MacroProps macros = new MacroProps();
        StringSegment segment = new StringSegment(skeletonString, false);
        CharsTrie stemTrie = new CharsTrie(SERIALIZED_STEM_TRIE, 0);
        ParseState stem = ParseState.STATE_NULL;
        int offset = 0;

        // Primary skeleton parse loop:
        while (offset < segment.length()) {
            int cp = segment.codePointAt(offset);
            boolean isTokenSeparator = PatternProps.isWhiteSpace(cp);
            boolean isOptionSeparator = (cp == '/');

            if (!isTokenSeparator && !isOptionSeparator) {
                // Non-separator token; consume it.
                offset += Character.charCount(cp);
                if (stem == ParseState.STATE_NULL) {
                    // We are currently consuming a stem.
                    // Go to the next state in the stem trie.
                    stemTrie.nextForCodePoint(cp);
                }
                continue;
            }

            // We are looking at a token or option separator.
            // If the segment is nonempty, parse it and reset the segment.
            // Otherwise, make sure it is a valid repeating separator.
            if (offset != 0) {
                segment.setLength(offset);
                if (stem == ParseState.STATE_NULL) {
                    // The first separator after the start of a token. Parse it as a stem.
                    stem = parseStem(segment, stemTrie, macros);
                    stemTrie.reset();
                } else {
                    // A separator after the first separator of a token. Parse it as an option.
                    stem = parseOption(stem, segment, macros);
                }
                segment.resetLength();

                // Consume the segment:
                segment.adjustOffset(offset);
                offset = 0;

            } else if (stem != ParseState.STATE_NULL) {
                // A separator ('/' or whitespace) following an option separator ('/')
                segment.setLength(Character.charCount(cp)); // for error message
                throw new SkeletonSyntaxException("Unexpected separator character", segment);

            } else {
                // Two spaces in a row; this is OK.
            }

            // Does the current stem forbid options?
            if (isOptionSeparator && stem == ParseState.STATE_NULL) {
                segment.setLength(Character.charCount(cp)); // for error message
                throw new SkeletonSyntaxException("Unexpected option separator", segment);
            }

            // Does the current stem require an option?
            if (isTokenSeparator && stem != ParseState.STATE_NULL) {
                switch (stem) {
                case STATE_INCREMENT_PRECISION:
                case STATE_MEASURE_UNIT:
                case STATE_PER_MEASURE_UNIT:
                case STATE_IDENTIFIER_UNIT:
                case STATE_UNIT_USAGE:
                case STATE_CURRENCY_UNIT:
                case STATE_INTEGER_WIDTH:
                case STATE_NUMBERING_SYSTEM:
                case STATE_SCALE:
                    segment.setLength(Character.charCount(cp)); // for error message
                    throw new SkeletonSyntaxException("Stem requires an option", segment);
                default:
                    break;
                }
                stem = ParseState.STATE_NULL;
            }

            // Consume the separator:
            segment.adjustOffset(Character.charCount(cp));
        }
        assert stem == ParseState.STATE_NULL;
        return macros;
    }

    /**
     * Given that the current segment represents a stem, parse it and save the result.
     *
     * @return The next state after parsing this stem, corresponding to what subset of options to expect.
     */
    private static ParseState parseStem(StringSegment segment, CharsTrie stemTrie, MacroProps macros) {
        // First check for "blueprint" stems, which start with a "signal char"
        switch (segment.charAt(0)) {
        case '.':
            checkNull(macros.precision, segment);
            BlueprintHelpers.parseFractionStem(segment, macros);
            return ParseState.STATE_FRACTION_PRECISION;
        case '@':
            checkNull(macros.precision, segment);
            BlueprintHelpers.parseDigitsStem(segment, macros);
            return ParseState.STATE_NULL;
        case 'E':
            checkNull(macros.notation, segment);
            BlueprintHelpers.parseScientificStem(segment, macros);
            return ParseState.STATE_NULL;
        case '0':
            checkNull(macros.integerWidth, segment);
            BlueprintHelpers.parseIntegerStem(segment, macros);
            return ParseState.STATE_NULL;
        }

        // Now look at the stemsTrie, which is already be pointing at our stem.
        BytesTrie.Result stemResult = stemTrie.current();

        if (stemResult != BytesTrie.Result.INTERMEDIATE_VALUE
                && stemResult != BytesTrie.Result.FINAL_VALUE) {
            throw new SkeletonSyntaxException("Unknown stem", segment);
        }

        StemEnum stem = STEM_ENUM_VALUES[stemTrie.getValue()];
        switch (stem) {

        // Stems with meaning on their own, not requiring an option:

        case STEM_COMPACT_SHORT:
        case STEM_COMPACT_LONG:
        case STEM_SCIENTIFIC:
        case STEM_ENGINEERING:
        case STEM_NOTATION_SIMPLE:
            checkNull(macros.notation, segment);
            macros.notation = StemToObject.notation(stem);
            switch (stem) {
            case STEM_SCIENTIFIC:
            case STEM_ENGINEERING:
                return ParseState.STATE_SCIENTIFIC; // allows for scientific options
            default:
                return ParseState.STATE_NULL;
            }

        case STEM_BASE_UNIT:
        case STEM_PERCENT:
        case STEM_PERMILLE:
            checkNull(macros.unit, segment);
            macros.unit = StemToObject.unit(stem);
            return ParseState.STATE_NULL;

        case STEM_PERCENT_100:
            checkNull(macros.scale, segment);
            checkNull(macros.unit, segment);
            macros.scale = Scale.powerOfTen(2);
            macros.unit = NoUnit.PERCENT;
            return ParseState.STATE_NULL;

        case STEM_PRECISION_INTEGER:
        case STEM_PRECISION_UNLIMITED:
        case STEM_PRECISION_CURRENCY_STANDARD:
        case STEM_PRECISION_CURRENCY_CASH:
            checkNull(macros.precision, segment);
            macros.precision = StemToObject.precision(stem);
            switch (stem) {
            case STEM_PRECISION_INTEGER:
                return ParseState.STATE_FRACTION_PRECISION; // allows for "precision-integer/@##"
            default:
                return ParseState.STATE_NULL;
            }

        case STEM_ROUNDING_MODE_CEILING:
        case STEM_ROUNDING_MODE_FLOOR:
        case STEM_ROUNDING_MODE_DOWN:
        case STEM_ROUNDING_MODE_UP:
        case STEM_ROUNDING_MODE_HALF_EVEN:
        case STEM_ROUNDING_MODE_HALF_DOWN:
        case STEM_ROUNDING_MODE_HALF_UP:
        case STEM_ROUNDING_MODE_UNNECESSARY:
            checkNull(macros.roundingMode, segment);
            macros.roundingMode = StemToObject.roundingMode(stem);
            return ParseState.STATE_NULL;

        case STEM_GROUP_OFF:
        case STEM_GROUP_MIN2:
        case STEM_GROUP_AUTO:
        case STEM_GROUP_ON_ALIGNED:
        case STEM_GROUP_THOUSANDS:
            checkNull(macros.grouping, segment);
            macros.grouping = StemToObject.groupingStrategy(stem);
            return ParseState.STATE_NULL;

        case STEM_LATIN:
            checkNull(macros.symbols, segment);
            macros.symbols = NumberingSystem.LATIN;
            return ParseState.STATE_NULL;

        case STEM_UNIT_WIDTH_NARROW:
        case STEM_UNIT_WIDTH_SHORT:
        case STEM_UNIT_WIDTH_FULL_NAME:
        case STEM_UNIT_WIDTH_ISO_CODE:
        case STEM_UNIT_WIDTH_FORMAL:
        case STEM_UNIT_WIDTH_VARIANT:
        case STEM_UNIT_WIDTH_HIDDEN:
            checkNull(macros.unitWidth, segment);
            macros.unitWidth = StemToObject.unitWidth(stem);
            return ParseState.STATE_NULL;

        case STEM_SIGN_AUTO:
        case STEM_SIGN_ALWAYS:
        case STEM_SIGN_NEVER:
        case STEM_SIGN_ACCOUNTING:
        case STEM_SIGN_ACCOUNTING_ALWAYS:
        case STEM_SIGN_EXCEPT_ZERO:
        case STEM_SIGN_ACCOUNTING_EXCEPT_ZERO:
        case STEM_SIGN_NEGATIVE:
        case STEM_SIGN_ACCOUNTING_NEGATIVE:
            checkNull(macros.sign, segment);
            macros.sign = StemToObject.signDisplay(stem);
            return ParseState.STATE_NULL;

        case STEM_DECIMAL_AUTO:
        case STEM_DECIMAL_ALWAYS:
            checkNull(macros.decimal, segment);
            macros.decimal = StemToObject.decimalSeparatorDisplay(stem);
            return ParseState.STATE_NULL;

        // Stems requiring an option:

        case STEM_PRECISION_INCREMENT:
            checkNull(macros.precision, segment);
            return ParseState.STATE_INCREMENT_PRECISION;

        case STEM_MEASURE_UNIT:
            checkNull(macros.unit, segment);
            return ParseState.STATE_MEASURE_UNIT;

        case STEM_PER_MEASURE_UNIT:
            // In C++, STEM_CURRENCY's checks mark perUnit as "seen". Here we do
            // the inverse: checking that macros.unit is not set to a currency.
            if (macros.unit instanceof Currency) {
                throw new SkeletonSyntaxException("Duplicated setting", segment);
            }
            checkNull(macros.perUnit, segment);
            return ParseState.STATE_PER_MEASURE_UNIT;

        case STEM_UNIT:
            checkNull(macros.unit, segment);
            checkNull(macros.perUnit, segment);
            return ParseState.STATE_IDENTIFIER_UNIT;

        case STEM_UNIT_USAGE:
            checkNull(macros.usage, segment);
            return ParseState.STATE_UNIT_USAGE;

        case STEM_CURRENCY:
            checkNull(macros.unit, segment);
            checkNull(macros.perUnit, segment);
            return ParseState.STATE_CURRENCY_UNIT;

        case STEM_INTEGER_WIDTH:
            checkNull(macros.integerWidth, segment);
            return ParseState.STATE_INTEGER_WIDTH;

        case STEM_NUMBERING_SYSTEM:
            checkNull(macros.symbols, segment);
            return ParseState.STATE_NUMBERING_SYSTEM;

        case STEM_SCALE:
            checkNull(macros.scale, segment);
            return ParseState.STATE_SCALE;

        default:
            throw new AssertionError();
        }
    }

    /**
     * Given that the current segment represents an option, parse it and save the result.
     *
     * @return The next state after parsing this option, corresponding to what subset of options to
     *         expect next.
     */
    private static ParseState parseOption(ParseState stem, StringSegment segment, MacroProps macros) {

        ///// Required options: /////

        switch (stem) {
        case STATE_CURRENCY_UNIT:
            BlueprintHelpers.parseCurrencyOption(segment, macros);
            return ParseState.STATE_NULL;
        case STATE_MEASURE_UNIT:
            BlueprintHelpers.parseMeasureUnitOption(segment, macros);
            return ParseState.STATE_NULL;
        case STATE_PER_MEASURE_UNIT:
            BlueprintHelpers.parseMeasurePerUnitOption(segment, macros);
            return ParseState.STATE_NULL;
        case STATE_IDENTIFIER_UNIT:
            BlueprintHelpers.parseIdentifierUnitOption(segment, macros);
            return ParseState.STATE_NULL;
        case STATE_UNIT_USAGE:
            BlueprintHelpers.parseUnitUsageOption(segment, macros);
            return ParseState.STATE_NULL;
        case STATE_INCREMENT_PRECISION:
            BlueprintHelpers.parseIncrementOption(segment, macros);
            return ParseState.STATE_NULL;
        case STATE_INTEGER_WIDTH:
            BlueprintHelpers.parseIntegerWidthOption(segment, macros);
            return ParseState.STATE_NULL;
        case STATE_NUMBERING_SYSTEM:
            BlueprintHelpers.parseNumberingSystemOption(segment, macros);
            return ParseState.STATE_NULL;
        case STATE_SCALE:
            BlueprintHelpers.parseScaleOption(segment, macros);
            return ParseState.STATE_NULL;
        default:
            break;
        }

        ///// Non-required options: /////

        // Scientific options
        switch (stem) {
        case STATE_SCIENTIFIC:
            if (BlueprintHelpers.parseExponentWidthOption(segment, macros)) {
                return ParseState.STATE_SCIENTIFIC;
            }
            if (BlueprintHelpers.parseExponentSignOption(segment, macros)) {
                return ParseState.STATE_SCIENTIFIC;
            }
            break;
        default:
            break;
        }

        // Frac-sig option
        switch (stem) {
        case STATE_FRACTION_PRECISION:
            if (BlueprintHelpers.parseFracSigOption(segment, macros)) {
                return ParseState.STATE_NULL;
            }
            break;
        default:
            break;
        }

        // Unknown option
        throw new SkeletonSyntaxException("Invalid option", segment);
    }

    ///// MAIN SKELETON GENERATION FUNCTION /////

    /**
     * Main skeleton generator function. Appends the normalized skeleton for the MacroProps to the given
     * StringBuilder.
     */
    private static void generateSkeleton(MacroProps macros, StringBuilder sb) {
        // Supported options
        if (macros.notation != null && GeneratorHelpers.notation(macros, sb)) {
            sb.append(' ');
        }
        if (macros.unit != null && GeneratorHelpers.unit(macros, sb)) {
            sb.append(' ');
        }
        if (macros.usage != null && GeneratorHelpers.usage(macros, sb)) {
            sb.append(' ');
        }
        if (macros.precision != null && GeneratorHelpers.precision(macros, sb)) {
            sb.append(' ');
        }
        if (macros.roundingMode != null && GeneratorHelpers.roundingMode(macros, sb)) {
            sb.append(' ');
        }
        if (macros.grouping != null && GeneratorHelpers.grouping(macros, sb)) {
            sb.append(' ');
        }
        if (macros.integerWidth != null && GeneratorHelpers.integerWidth(macros, sb)) {
            sb.append(' ');
        }
        if (macros.symbols != null && GeneratorHelpers.symbols(macros, sb)) {
            sb.append(' ');
        }
        if (macros.unitWidth != null && GeneratorHelpers.unitWidth(macros, sb)) {
            sb.append(' ');
        }
        if (macros.sign != null && GeneratorHelpers.sign(macros, sb)) {
            sb.append(' ');
        }
        if (macros.decimal != null && GeneratorHelpers.decimal(macros, sb)) {
            sb.append(' ');
        }
        if (macros.scale != null && GeneratorHelpers.scale(macros, sb)) {
            sb.append(' ');
        }

        // Unsupported options
        if (macros.padder != null) {
            throw new UnsupportedOperationException(
                    "Cannot generate number skeleton with custom padder");
        }
        if (macros.unitDisplayCase != null && !macros.unitDisplayCase.isEmpty()) {
            throw new UnsupportedOperationException(
                    "Cannot generate number skeleton with custom unit display case");
        }
        if (macros.affixProvider != null) {
            throw new UnsupportedOperationException(
                    "Cannot generate number skeleton with custom affix provider");
        }
        if (macros.rules != null) {
            throw new UnsupportedOperationException(
                    "Cannot generate number skeleton with custom plural rules");
        }

        // Remove the trailing space
        if (sb.length() > 0) {
            sb.setLength(sb.length() - 1);
        }
    }

    ///// BLUEPRINT HELPER FUNCTIONS /////

    /**
     * Utility class for methods for processing stems and options that cannot be interpreted literally.
     */
    static final class BlueprintHelpers {

        /** @return Whether we successfully found and parsed an exponent width option. */
        private static boolean parseExponentWidthOption(StringSegment segment, MacroProps macros) {
            if (!isWildcardChar(segment.charAt(0))) {
                return false;
            }
            int offset = 1;
            int minExp = 0;
            for (; offset < segment.length(); offset++) {
                if (segment.charAt(offset) == 'e') {
                    minExp++;
                } else {
                    break;
                }
            }
            if (offset < segment.length()) {
                return false;
            }
            // Use the public APIs to enforce bounds checking
            macros.notation = ((ScientificNotation) macros.notation).withMinExponentDigits(minExp);
            return true;
        }

        private static void generateExponentWidthOption(int minExponentDigits, StringBuilder sb) {
            sb.append(WILDCARD_CHAR);
            appendMultiple(sb, 'e', minExponentDigits);
        }

        /** @return Whether we successfully found and parsed an exponent sign option. */
        private static boolean parseExponentSignOption(StringSegment segment, MacroProps macros) {
            // Get the sign display type out of the CharsTrie data structure.
            // TODO: Make this more efficient (avoid object allocation)? It shouldn't be very hot code.
            CharsTrie tempStemTrie = new CharsTrie(SERIALIZED_STEM_TRIE, 0);
            BytesTrie.Result result = tempStemTrie.next(segment, 0, segment.length());
            if (result != BytesTrie.Result.INTERMEDIATE_VALUE
                    && result != BytesTrie.Result.FINAL_VALUE) {
                return false;
            }
            SignDisplay sign = StemToObject.signDisplay(STEM_ENUM_VALUES[tempStemTrie.getValue()]);
            if (sign == null) {
                return false;
            }
            macros.notation = ((ScientificNotation) macros.notation).withExponentSignDisplay(sign);
            return true;
        }

        private static void parseCurrencyOption(StringSegment segment, MacroProps macros) {
            String currencyCode = segment.subSequence(0, segment.length()).toString();
            Currency currency;
            try {
                currency = Currency.getInstance(currencyCode);
            } catch (IllegalArgumentException e) {
                // Not 3 ascii chars
                throw new SkeletonSyntaxException("Invalid currency", segment, e);
            }
            macros.unit = currency;
        }

        private static void generateCurrencyOption(Currency currency, StringBuilder sb) {
            sb.append(currency.getCurrencyCode());
        }

        // "measure-unit/" is deprecated in favour of "unit/".
        private static void parseMeasureUnitOption(StringSegment segment, MacroProps macros) {
            // NOTE: The category (type) of the unit is guaranteed to be a valid subtag (alphanumeric)
            // http://unicode.org/reports/tr35/#Validity_Data
            int firstHyphen = 0;
            while (firstHyphen < segment.length() && segment.charAt(firstHyphen) != '-') {
                firstHyphen++;
            }
            if (firstHyphen == segment.length()) {
                throw new SkeletonSyntaxException("Invalid measure unit option", segment);
            }
            String type = segment.subSequence(0, firstHyphen).toString();
            String subType = segment.subSequence(firstHyphen + 1, segment.length()).toString();
            Set<MeasureUnit> units = MeasureUnit.getAvailable(type);
            for (MeasureUnit unit : units) {
                if (subType.equals(unit.getSubtype())) {
                    macros.unit = unit;
                    return;
                }
            }
            throw new SkeletonSyntaxException("Unknown measure unit", segment);
        }

        // "per-measure-unit/" is deprecated in favour of "unit/".
        private static void parseMeasurePerUnitOption(StringSegment segment, MacroProps macros) {
            // A little bit of a hack: save the current unit (numerator), call the main measure unit
            // parsing code, put back the numerator unit, and put the new unit into per-unit.
            MeasureUnit numerator = macros.unit;
            parseMeasureUnitOption(segment, macros);
            macros.perUnit = macros.unit;
            macros.unit = numerator;
        }

        /**
         * Parses unit identifiers like "meter-per-second" and "foot-and-inch", as
         * specified via a "unit/" concise skeleton.
         */
        private static void parseIdentifierUnitOption(StringSegment segment, MacroProps macros) {
            try {
                macros.unit = MeasureUnit.forIdentifier(segment.asString());
            } catch (IllegalArgumentException e) {
                throw new SkeletonSyntaxException("Invalid unit stem", segment);
            }
        }

        private static void parseUnitUsageOption(StringSegment segment, MacroProps macros) {
            macros.usage = segment.asString();
            // We do not do any validation of the usage string: it depends on the
            // unitPreferenceData in the units resources.
        }

        private static void parseFractionStem(StringSegment segment, MacroProps macros) {
            assert segment.charAt(0) == '.';
            int offset = 1;
            int minFrac = 0;
            int maxFrac;
            for (; offset < segment.length(); offset++) {
                if (segment.charAt(offset) == '0') {
                    minFrac++;
                } else {
                    break;
                }
            }
            if (offset < segment.length()) {
                if (isWildcardChar(segment.charAt(offset))) {
                    maxFrac = -1;
                    offset++;
                } else {
                    maxFrac = minFrac;
                    for (; offset < segment.length(); offset++) {
                        if (segment.charAt(offset) == '#') {
                            maxFrac++;
                        } else {
                            break;
                        }
                    }
                }
            } else {
                maxFrac = minFrac;
            }
            if (offset < segment.length()) {
                throw new SkeletonSyntaxException("Invalid fraction stem", segment);
            }
            // Use the public APIs to enforce bounds checking
            if (maxFrac == -1) {
                if (minFrac == 0) {
                    macros.precision = Precision.unlimited();
                } else {
                    macros.precision = Precision.minFraction(minFrac);
                }
            } else {
                macros.precision = Precision.minMaxFraction(minFrac, maxFrac);
            }
        }

        private static void generateFractionStem(int minFrac, int maxFrac, StringBuilder sb) {
            if (minFrac == 0 && maxFrac == 0) {
                sb.append("precision-integer");
                return;
            }
            sb.append('.');
            appendMultiple(sb, '0', minFrac);
            if (maxFrac == -1) {
                sb.append(WILDCARD_CHAR);
            } else {
                appendMultiple(sb, '#', maxFrac - minFrac);
            }
        }

        private static void parseDigitsStem(StringSegment segment, MacroProps macros) {
            assert segment.charAt(0) == '@';
            int offset = 0;
            int minSig = 0;
            int maxSig;
            for (; offset < segment.length(); offset++) {
                if (segment.charAt(offset) == '@') {
                    minSig++;
                } else {
                    break;
                }
            }
            if (offset < segment.length()) {
                if (isWildcardChar(segment.charAt(offset))) {
                    maxSig = -1;
                    offset++;
                } else {
                    maxSig = minSig;
                    for (; offset < segment.length(); offset++) {
                        if (segment.charAt(offset) == '#') {
                            maxSig++;
                        } else {
                            break;
                        }
                    }
                }
            } else {
                maxSig = minSig;
            }
            if (offset < segment.length()) {
                throw new SkeletonSyntaxException("Invalid significant digits stem", segment);
            }
            // Use the public APIs to enforce bounds checking
            if (maxSig == -1) {
                macros.precision = Precision.minSignificantDigits(minSig);
            } else {
                macros.precision = Precision.minMaxSignificantDigits(minSig, maxSig);
            }
        }

        private static void generateDigitsStem(int minSig, int maxSig, StringBuilder sb) {
            appendMultiple(sb, '@', minSig);
            if (maxSig == -1) {
                sb.append(WILDCARD_CHAR);
            } else {
                appendMultiple(sb, '#', maxSig - minSig);
            }
        }

        private static void parseScientificStem(StringSegment segment, MacroProps macros) {
            assert(segment.charAt(0) == 'E');
            block:
            {
                int offset = 1;
                if (segment.length() == offset) {
                    break block;
                }
                boolean isEngineering = false;
                if (segment.charAt(offset) == 'E') {
                    isEngineering = true;
                    offset++;
                    if (segment.length() == offset) {
                        break block;
                    }
                }
                SignDisplay signDisplay = SignDisplay.AUTO;
                if (segment.charAt(offset) == '+') {
                    offset++;
                    if (segment.length() == offset) {
                        break block;
                    }
                    if (segment.charAt(offset) == '!') {
                        signDisplay = SignDisplay.ALWAYS;
                    } else if (segment.charAt(offset) == '?') {
                        signDisplay = SignDisplay.EXCEPT_ZERO;
                    } else {
                        // NOTE: Other sign displays are not included because they aren't useful in this context
                        break block;
                    }
                    offset++;
                    if (segment.length() == offset) {
                        break block;
                    }
                }
                int minDigits = 0;
                for (; offset < segment.length(); offset++) {
                    if (segment.charAt(offset) != '0') {
                        break block;
                    }
                    minDigits++;
                }
                macros.notation = (isEngineering ? Notation.engineering() : Notation.scientific())
                    .withExponentSignDisplay(signDisplay)
                    .withMinExponentDigits(minDigits);
                return;
            }
            throw new SkeletonSyntaxException("Invalid scientific stem", segment);
        }

        private static void parseIntegerStem(StringSegment segment, MacroProps macros) {
            assert(segment.charAt(0) == '0');
            int offset = 1;
            for (; offset < segment.length(); offset++) {
                if (segment.charAt(offset) != '0') {
                    offset--;
                    break;
                }
            }
            if (offset < segment.length()) {
                 throw new SkeletonSyntaxException("Invalid integer stem", segment);
            }
            macros.integerWidth = IntegerWidth.zeroFillTo(offset);
            return;
        }

        /** @return Whether we successfully found and parsed a frac-sig option. */
        private static boolean parseFracSigOption(StringSegment segment, MacroProps macros) {
            if (segment.charAt(0) != '@') {
                return false;
            }
            int offset = 0;
            int minSig = 0;
            int maxSig;
            for (; offset < segment.length(); offset++) {
                if (segment.charAt(offset) == '@') {
                    minSig++;
                } else {
                    break;
                }
            }
            // For the frac-sig option, there must be minSig or maxSig but not both.
            // Valid: @+, @@+, @@@+
            // Valid: @#, @##, @###
            // Invalid: @, @@, @@@
            // Invalid: @@#, @@##, @@@#
            if (offset < segment.length()) {
                if (isWildcardChar(segment.charAt(offset))) {
                    maxSig = -1;
                    offset++;
                } else if (minSig > 1) {
                    // @@#, @@##, @@@#
                    throw new SkeletonSyntaxException("Invalid digits option for fraction rounder",
                            segment);
                } else {
                    maxSig = minSig;
                    for (; offset < segment.length(); offset++) {
                        if (segment.charAt(offset) == '#') {
                            maxSig++;
                        } else {
                            break;
                        }
                    }
                }
            } else {
                // @, @@, @@@
                throw new SkeletonSyntaxException("Invalid digits option for fraction rounder", segment);
            }
            if (offset < segment.length()) {
                throw new SkeletonSyntaxException("Invalid digits option for fraction rounder", segment);
            }

            FractionPrecision oldRounder = (FractionPrecision) macros.precision;
            if (maxSig == -1) {
                macros.precision = oldRounder.withMinDigits(minSig);
            } else {
                macros.precision = oldRounder.withMaxDigits(maxSig);
            }
            return true;
        }

        private static void parseIncrementOption(StringSegment segment, MacroProps macros) {
            // Call segment.subSequence() because segment.toString() doesn't create a clean string.
            String str = segment.subSequence(0, segment.length()).toString();
            BigDecimal increment;
            try {
                increment = new BigDecimal(str);
            } catch (NumberFormatException e) {
                throw new SkeletonSyntaxException("Invalid rounding increment", segment, e);
            }
            macros.precision = Precision.increment(increment);
        }

        private static void generateIncrementOption(BigDecimal increment, StringBuilder sb) {
            sb.append(increment.toPlainString());
        }

        private static void parseIntegerWidthOption(StringSegment segment, MacroProps macros) {
            int offset = 0;
            int minInt = 0;
            int maxInt;
            if (isWildcardChar(segment.charAt(0))) {
                maxInt = -1;
                offset++;
            } else {
                maxInt = 0;
            }
            for (; offset < segment.length(); offset++) {
                if (maxInt != -1 && segment.charAt(offset) == '#') {
                    maxInt++;
                } else {
                    break;
                }
            }
            if (offset < segment.length()) {
                for (; offset < segment.length(); offset++) {
                    if (segment.charAt(offset) == '0') {
                        minInt++;
                    } else {
                        break;
                    }
                }
            }
            if (maxInt != -1) {
                maxInt += minInt;
            }
            if (offset < segment.length()) {
                throw new SkeletonSyntaxException("Invalid integer width stem", segment);
            }
            // Use the public APIs to enforce bounds checking
            if (maxInt == -1) {
                macros.integerWidth = IntegerWidth.zeroFillTo(minInt);
            } else {
                macros.integerWidth = IntegerWidth.zeroFillTo(minInt).truncateAt(maxInt);
            }
        }

        private static void generateIntegerWidthOption(int minInt, int maxInt, StringBuilder sb) {
            if (maxInt == -1) {
                sb.append(WILDCARD_CHAR);
            } else {
                appendMultiple(sb, '#', maxInt - minInt);
            }
            appendMultiple(sb, '0', minInt);
        }

        private static void parseNumberingSystemOption(StringSegment segment, MacroProps macros) {
            String nsName = segment.subSequence(0, segment.length()).toString();
            NumberingSystem ns = NumberingSystem.getInstanceByName(nsName);
            if (ns == null) {
                throw new SkeletonSyntaxException("Unknown numbering system", segment);
            }
            macros.symbols = ns;
        }

        private static void generateNumberingSystemOption(NumberingSystem ns, StringBuilder sb) {
            sb.append(ns.getName());
        }

        private static void parseScaleOption(StringSegment segment, MacroProps macros) {
            // Call segment.subSequence() because segment.toString() doesn't create a clean string.
            String str = segment.subSequence(0, segment.length()).toString();
            BigDecimal bd;
            try {
                bd = new BigDecimal(str);
            } catch (NumberFormatException e) {
                throw new SkeletonSyntaxException("Invalid scale", segment, e);
            }
            // NOTE: If bd is a power of ten, the Scale API optimizes it for us.
            macros.scale = Scale.byBigDecimal(bd);
        }

        private static void generateScaleOption(Scale scale, StringBuilder sb) {
            BigDecimal bd = scale.arbitrary;
            if (bd == null) {
                bd = BigDecimal.ONE;
            }
            bd = bd.scaleByPowerOfTen(scale.magnitude);
            sb.append(bd.toPlainString());
        }
    }

    ///// STEM GENERATION HELPER FUNCTIONS /////

    /**
     * Utility class for methods for generating a token corresponding to each macro-prop. Each method
     * returns whether or not a token was written to the string builder.
     */
    static final class GeneratorHelpers {

        private static boolean notation(MacroProps macros, StringBuilder sb) {
            if (macros.notation instanceof CompactNotation) {
                if (macros.notation == Notation.compactLong()) {
                    sb.append("compact-long");
                    return true;
                } else if (macros.notation == Notation.compactShort()) {
                    sb.append("compact-short");
                    return true;
                } else {
                    // Compact notation generated from custom data (not supported in skeleton)
                    // The other compact notations are literals
                    throw new UnsupportedOperationException(
                            "Cannot generate number skeleton with custom compact data");
                }
            } else if (macros.notation instanceof ScientificNotation) {
                ScientificNotation impl = (ScientificNotation) macros.notation;
                if (impl.engineeringInterval == 3) {
                    sb.append("engineering");
                } else {
                    sb.append("scientific");
                }
                if (impl.minExponentDigits > 1) {
                    sb.append('/');
                    BlueprintHelpers.generateExponentWidthOption(impl.minExponentDigits, sb);
                }
                if (impl.exponentSignDisplay != SignDisplay.AUTO) {
                    sb.append('/');
                    EnumToStemString.signDisplay(impl.exponentSignDisplay, sb);
                }
                return true;
            } else {
                assert macros.notation instanceof SimpleNotation;
                // Default value is not shown in normalized form
                return false;
            }
        }

        private static boolean unit(MacroProps macros, StringBuilder sb) {
            MeasureUnit unit = macros.unit;
            if (macros.perUnit != null) {
                if (macros.unit instanceof Currency || macros.perUnit instanceof Currency) {
                    throw new UnsupportedOperationException(
                        "Cannot generate number skeleton with currency unit and per-unit");
                }
                unit = unit.product(macros.perUnit.reciprocal());
            }
            if (unit instanceof Currency) {
                sb.append("currency/");
                BlueprintHelpers.generateCurrencyOption((Currency)unit, sb);
                return true;
            } else if (unit.equals(MeasureUnit.PERCENT)) {
                sb.append("percent");
                return true;
            } else if (unit.equals(MeasureUnit.PERMILLE)) {
                sb.append("permille");
                return true;
            } else {
                sb.append("unit/");
                sb.append(unit.getIdentifier());
                return true;
            }
        }

        private static boolean usage(MacroProps macros, StringBuilder sb) {
            if (macros.usage != null  && macros.usage.length() > 0) {
                sb.append("usage/");
                sb.append(macros.usage);

                return true;
            }
            return false;
        }

        private static boolean precision(MacroProps macros, StringBuilder sb) {
            if (macros.precision instanceof Precision.InfiniteRounderImpl) {
                sb.append("precision-unlimited");
            } else if (macros.precision instanceof Precision.FractionRounderImpl) {
                Precision.FractionRounderImpl impl = (Precision.FractionRounderImpl) macros.precision;
                BlueprintHelpers.generateFractionStem(impl.minFrac, impl.maxFrac, sb);
            } else if (macros.precision instanceof Precision.SignificantRounderImpl) {
                Precision.SignificantRounderImpl impl = (Precision.SignificantRounderImpl) macros.precision;
                BlueprintHelpers.generateDigitsStem(impl.minSig, impl.maxSig, sb);
            } else if (macros.precision instanceof Precision.FracSigRounderImpl) {
                Precision.FracSigRounderImpl impl = (Precision.FracSigRounderImpl) macros.precision;
                BlueprintHelpers.generateFractionStem(impl.minFrac, impl.maxFrac, sb);
                sb.append('/');
                if (impl.minSig == -1) {
                    BlueprintHelpers.generateDigitsStem(1, impl.maxSig, sb);
                } else {
                    BlueprintHelpers.generateDigitsStem(impl.minSig, -1, sb);
                }
            } else if (macros.precision instanceof Precision.IncrementRounderImpl) {
                Precision.IncrementRounderImpl impl = (Precision.IncrementRounderImpl) macros.precision;
                sb.append("precision-increment/");
                BlueprintHelpers.generateIncrementOption(impl.increment, sb);
            } else {
                assert macros.precision instanceof Precision.CurrencyRounderImpl;
                Precision.CurrencyRounderImpl impl = (Precision.CurrencyRounderImpl) macros.precision;
                if (impl.usage == CurrencyUsage.STANDARD) {
                    sb.append("precision-currency-standard");
                } else {
                    sb.append("precision-currency-cash");
                }
            }

            // NOTE: Always return true for rounding because the default value depends on other options.
            return true;
        }

        private static boolean roundingMode(MacroProps macros, StringBuilder sb) {
            if (macros.roundingMode == RoundingUtils.DEFAULT_ROUNDING_MODE) {
                return false; // Default value
            }
            EnumToStemString.roundingMode(macros.roundingMode, sb);
            return true;
        }

        private static boolean grouping(MacroProps macros, StringBuilder sb) {
            if (macros.grouping instanceof GroupingStrategy) {
                if (macros.grouping == GroupingStrategy.AUTO) {
                    return false; // Default value
                }
                EnumToStemString.groupingStrategy((GroupingStrategy) macros.grouping, sb);
                return true;
            } else {
                throw new UnsupportedOperationException(
                        "Cannot generate number skeleton with custom Grouper");
            }
        }

        private static boolean integerWidth(MacroProps macros, StringBuilder sb) {
            if (macros.integerWidth.equals(IntegerWidth.DEFAULT)) {
                return false; // Default
            }
            sb.append("integer-width/");
            BlueprintHelpers.generateIntegerWidthOption(macros.integerWidth.minInt,
                    macros.integerWidth.maxInt,
                    sb);
            return true;
        }

        private static boolean symbols(MacroProps macros, StringBuilder sb) {
            if (macros.symbols instanceof NumberingSystem) {
                NumberingSystem ns = (NumberingSystem) macros.symbols;
                if (ns.getName().equals("latn")) {
                    sb.append("latin");
                } else {
                    sb.append("numbering-system/");
                    BlueprintHelpers.generateNumberingSystemOption(ns, sb);
                }
                return true;
            } else {
                assert macros.symbols instanceof DecimalFormatSymbols;
                throw new UnsupportedOperationException(
                        "Cannot generate number skeleton with custom DecimalFormatSymbols");
            }
        }

        private static boolean unitWidth(MacroProps macros, StringBuilder sb) {
            if (macros.unitWidth == UnitWidth.SHORT) {
                return false; // Default value
            }
            EnumToStemString.unitWidth(macros.unitWidth, sb);
            return true;
        }

        private static boolean sign(MacroProps macros, StringBuilder sb) {
            if (macros.sign == SignDisplay.AUTO) {
                return false; // Default value
            }
            EnumToStemString.signDisplay(macros.sign, sb);
            return true;
        }

        private static boolean decimal(MacroProps macros, StringBuilder sb) {
            if (macros.decimal == DecimalSeparatorDisplay.AUTO) {
                return false; // Default value
            }
            EnumToStemString.decimalSeparatorDisplay(macros.decimal, sb);
            return true;
        }

        private static boolean scale(MacroProps macros, StringBuilder sb) {
            if (!macros.scale.isValid()) {
                return false; // Default value
            }
            sb.append("scale/");
            BlueprintHelpers.generateScaleOption(macros.scale, sb);
            return true;
        }

    }

    ///// OTHER UTILITY FUNCTIONS /////

    private static void checkNull(Object value, CharSequence content) {
        if (value != null) {
            throw new SkeletonSyntaxException("Duplicated setting", content);
        }
    }

    private static void appendMultiple(StringBuilder sb, int cp, int count) {
        for (int i = 0; i < count; i++) {
            sb.appendCodePoint(cp);
        }
    }
}
