// © 2017 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html

#include "unicode/utypes.h"

#if !UCONFIG_NO_FORMATTING

// Allow implicit conversion from char16_t* to UnicodeString for this file:
// Helpful in toString methods and elsewhere.
#define UNISTR_FROM_STRING_EXPLICIT
#define UNISTR_FROM_CHAR_EXPLICIT

#include "uassert.h"
#include "number_patternstring.h"
#include "unicode/utf16.h"
#include "number_utils.h"
#include "number_roundingutils.h"
#include "number_mapper.h"

using namespace icu;
using namespace icu::number;
using namespace icu::number::impl;


void PatternParser::parseToPatternInfo(const UnicodeString& patternString, ParsedPatternInfo& patternInfo,
                                       UErrorCode& status) {
    patternInfo.consumePattern(patternString, status);
}

DecimalFormatProperties
PatternParser::parseToProperties(const UnicodeString& pattern, IgnoreRounding ignoreRounding,
                                 UErrorCode& status) {
    DecimalFormatProperties properties;
    parseToExistingPropertiesImpl(pattern, properties, ignoreRounding, status);
    return properties;
}

DecimalFormatProperties PatternParser::parseToProperties(const UnicodeString& pattern,
                                                         UErrorCode& status) {
    return parseToProperties(pattern, IGNORE_ROUNDING_NEVER, status);
}

void
PatternParser::parseToExistingProperties(const UnicodeString& pattern, DecimalFormatProperties& properties,
                                         IgnoreRounding ignoreRounding, UErrorCode& status) {
    parseToExistingPropertiesImpl(pattern, properties, ignoreRounding, status);
}


char16_t ParsedPatternInfo::charAt(int32_t flags, int32_t index) const {
    const Endpoints& endpoints = getEndpoints(flags);
    if (index < 0 || index >= endpoints.end - endpoints.start) {
        UPRV_UNREACHABLE_EXIT;
    }
    return pattern.charAt(endpoints.start + index);
}

int32_t ParsedPatternInfo::length(int32_t flags) const {
    return getLengthFromEndpoints(getEndpoints(flags));
}

int32_t ParsedPatternInfo::getLengthFromEndpoints(const Endpoints& endpoints) {
    return endpoints.end - endpoints.start;
}

UnicodeString ParsedPatternInfo::getString(int32_t flags) const {
    const Endpoints& endpoints = getEndpoints(flags);
    if (endpoints.start == endpoints.end) {
        return UnicodeString();
    }
    // Create a new UnicodeString
    return UnicodeString(pattern, endpoints.start, endpoints.end - endpoints.start);
}

const Endpoints& ParsedPatternInfo::getEndpoints(int32_t flags) const {
    bool prefix = (flags & AFFIX_PREFIX) != 0;
    bool isNegative = (flags & AFFIX_NEGATIVE_SUBPATTERN) != 0;
    bool padding = (flags & AFFIX_PADDING) != 0;
    if (isNegative && padding) {
        return negative.paddingEndpoints;
    } else if (padding) {
        return positive.paddingEndpoints;
    } else if (prefix && isNegative) {
        return negative.prefixEndpoints;
    } else if (prefix) {
        return positive.prefixEndpoints;
    } else if (isNegative) {
        return negative.suffixEndpoints;
    } else {
        return positive.suffixEndpoints;
    }
}

bool ParsedPatternInfo::positiveHasPlusSign() const {
    return positive.hasPlusSign;
}

bool ParsedPatternInfo::hasNegativeSubpattern() const {
    return fHasNegativeSubpattern;
}

bool ParsedPatternInfo::negativeHasMinusSign() const {
    return negative.hasMinusSign;
}

bool ParsedPatternInfo::hasCurrencySign() const {
    return positive.hasCurrencySign || (fHasNegativeSubpattern && negative.hasCurrencySign);
}

bool ParsedPatternInfo::containsSymbolType(AffixPatternType type, UErrorCode& status) const {
    return AffixUtils::containsType(pattern, type, status);
}

bool ParsedPatternInfo::hasBody() const {
    return positive.integerTotal > 0;
}

bool ParsedPatternInfo::currencyAsDecimal() const {
    return positive.hasCurrencyDecimal;
}

/////////////////////////////////////////////////////
/// BEGIN RECURSIVE DESCENT PARSER IMPLEMENTATION ///
/////////////////////////////////////////////////////

UChar32 ParsedPatternInfo::ParserState::peek() {
    if (offset == pattern.length()) {
        return -1;
    } else {
        return pattern.char32At(offset);
    }
}

UChar32 ParsedPatternInfo::ParserState::peek2() {
    if (offset == pattern.length()) {
        return -1;
    }
    int32_t cp1 = pattern.char32At(offset);
    int32_t offset2 = offset + U16_LENGTH(cp1);
    if (offset2 == pattern.length()) {
        return -1;
    }
    return pattern.char32At(offset2);
}

UChar32 ParsedPatternInfo::ParserState::next() {
    int32_t codePoint = peek();
    offset += U16_LENGTH(codePoint);
    return codePoint;
}

void ParsedPatternInfo::consumePattern(const UnicodeString& patternString, UErrorCode& status) {
    if (U_FAILURE(status)) { return; }
    this->pattern = patternString;

    // This class is not intended for writing twice!
    // Use move assignment to overwrite instead.
    U_ASSERT(state.offset == 0);

    // pattern := subpattern (';' subpattern)?
    currentSubpattern = &positive;
    consumeSubpattern(status);
    if (U_FAILURE(status)) { return; }
    if (state.peek() == u';') {
        state.next(); // consume the ';'
        // Don't consume the negative subpattern if it is empty (trailing ';')
        if (state.peek() != -1) {
            fHasNegativeSubpattern = true;
            currentSubpattern = &negative;
            consumeSubpattern(status);
            if (U_FAILURE(status)) { return; }
        }
    }
    if (state.peek() != -1) {
        state.toParseException(u"Found unquoted special character");
        status = U_UNQUOTED_SPECIAL;
    }
}

void ParsedPatternInfo::consumeSubpattern(UErrorCode& status) {
    // subpattern := literals? number exponent? literals?
    consumePadding(PadPosition::UNUM_PAD_BEFORE_PREFIX, status);
    if (U_FAILURE(status)) { return; }
    consumeAffix(currentSubpattern->prefixEndpoints, status);
    if (U_FAILURE(status)) { return; }
    consumePadding(PadPosition::UNUM_PAD_AFTER_PREFIX, status);
    if (U_FAILURE(status)) { return; }
    consumeFormat(status);
    if (U_FAILURE(status)) { return; }
    consumeExponent(status);
    if (U_FAILURE(status)) { return; }
    consumePadding(PadPosition::UNUM_PAD_BEFORE_SUFFIX, status);
    if (U_FAILURE(status)) { return; }
    consumeAffix(currentSubpattern->suffixEndpoints, status);
    if (U_FAILURE(status)) { return; }
    consumePadding(PadPosition::UNUM_PAD_AFTER_SUFFIX, status);
    if (U_FAILURE(status)) { return; }
}

void ParsedPatternInfo::consumePadding(PadPosition paddingLocation, UErrorCode& status) {
    if (state.peek() != u'*') {
        return;
    }
    if (currentSubpattern->hasPadding) {
        state.toParseException(u"Cannot have multiple pad specifiers");
        status = U_MULTIPLE_PAD_SPECIFIERS;
        return;
    }
    currentSubpattern->paddingLocation = paddingLocation;
    currentSubpattern->hasPadding = true;
    state.next(); // consume the '*'
    currentSubpattern->paddingEndpoints.start = state.offset;
    consumeLiteral(status);
    currentSubpattern->paddingEndpoints.end = state.offset;
}

void ParsedPatternInfo::consumeAffix(Endpoints& endpoints, UErrorCode& status) {
    // literals := { literal }
    endpoints.start = state.offset;
    while (true) {
        switch (state.peek()) {
            case u'#':
            case u'@':
            case u';':
            case u'*':
            case u'.':
            case u',':
            case u'0':
            case u'1':
            case u'2':
            case u'3':
            case u'4':
            case u'5':
            case u'6':
            case u'7':
            case u'8':
            case u'9':
            case -1:
                // Characters that cannot appear unquoted in a literal
                // break outer;
                goto after_outer;

            case u'%':
                currentSubpattern->hasPercentSign = true;
                break;

            case u'‰':
                currentSubpattern->hasPerMilleSign = true;
                break;

            case u'¤':
                currentSubpattern->hasCurrencySign = true;
                break;

            case u'-':
                currentSubpattern->hasMinusSign = true;
                break;

            case u'+':
                currentSubpattern->hasPlusSign = true;
                break;

            default:
                break;
        }
        consumeLiteral(status);
        if (U_FAILURE(status)) { return; }
    }
    after_outer:
    endpoints.end = state.offset;
}

void ParsedPatternInfo::consumeLiteral(UErrorCode& status) {
    if (state.peek() == -1) {
        state.toParseException(u"Expected unquoted literal but found EOL");
        status = U_PATTERN_SYNTAX_ERROR;
        return;
    } else if (state.peek() == u'\'') {
        state.next(); // consume the starting quote
        while (state.peek() != u'\'') {
            if (state.peek() == -1) {
                state.toParseException(u"Expected quoted literal but found EOL");
                status = U_PATTERN_SYNTAX_ERROR;
                return;
            } else {
                state.next(); // consume a quoted character
            }
        }
        state.next(); // consume the ending quote
    } else {
        // consume a non-quoted literal character
        state.next();
    }
}

void ParsedPatternInfo::consumeFormat(UErrorCode& status) {
    consumeIntegerFormat(status);
    if (U_FAILURE(status)) { return; }
    if (state.peek() == u'.') {
        state.next(); // consume the decimal point
        currentSubpattern->hasDecimal = true;
        currentSubpattern->widthExceptAffixes += 1;
        consumeFractionFormat(status);
        if (U_FAILURE(status)) { return; }
    } else if (state.peek() == u'¤') {
        // Check if currency is a decimal separator
        switch (state.peek2()) {
            case u'#':
            case u'0':
            case u'1':
            case u'2':
            case u'3':
            case u'4':
            case u'5':
            case u'6':
            case u'7':
            case u'8':
            case u'9':
                break;
            default:
                // Currency symbol followed by a non-numeric character;
                // treat as a normal affix.
                return;
        }
        // Currency symbol is followed by a numeric character;
        // treat as a decimal separator.
        currentSubpattern->hasCurrencySign = true;
        currentSubpattern->hasCurrencyDecimal = true;
        currentSubpattern->hasDecimal = true;
        currentSubpattern->widthExceptAffixes += 1;
        state.next(); // consume the symbol
        consumeFractionFormat(status);
        if (U_FAILURE(status)) { return; }
    }
}

void ParsedPatternInfo::consumeIntegerFormat(UErrorCode& status) {
    // Convenience reference:
    ParsedSubpatternInfo& result = *currentSubpattern;

    while (true) {
        switch (state.peek()) {
            case u',':
                result.widthExceptAffixes += 1;
                result.groupingSizes <<= 16;
                break;

            case u'#':
                if (result.integerNumerals > 0) {
                    state.toParseException(u"# cannot follow 0 before decimal point");
                    status = U_UNEXPECTED_TOKEN;
                    return;
                }
                result.widthExceptAffixes += 1;
                result.groupingSizes += 1;
                if (result.integerAtSigns > 0) {
                    result.integerTrailingHashSigns += 1;
                } else {
                    result.integerLeadingHashSigns += 1;
                }
                result.integerTotal += 1;
                break;

            case u'@':
                if (result.integerNumerals > 0) {
                    state.toParseException(u"Cannot mix 0 and @");
                    status = U_UNEXPECTED_TOKEN;
                    return;
                }
                if (result.integerTrailingHashSigns > 0) {
                    state.toParseException(u"Cannot nest # inside of a run of @");
                    status = U_UNEXPECTED_TOKEN;
                    return;
                }
                result.widthExceptAffixes += 1;
                result.groupingSizes += 1;
                result.integerAtSigns += 1;
                result.integerTotal += 1;
                break;

            case u'0':
            case u'1':
            case u'2':
            case u'3':
            case u'4':
            case u'5':
            case u'6':
            case u'7':
            case u'8':
            case u'9':
                if (result.integerAtSigns > 0) {
                    state.toParseException(u"Cannot mix @ and 0");
                    status = U_UNEXPECTED_TOKEN;
                    return;
                }
                result.widthExceptAffixes += 1;
                result.groupingSizes += 1;
                result.integerNumerals += 1;
                result.integerTotal += 1;
                if (!result.rounding.isZeroish() || state.peek() != u'0') {
                    result.rounding.appendDigit(static_cast<int8_t>(state.peek() - u'0'), 0, true);
                }
                break;

            default:
                goto after_outer;
        }
        state.next(); // consume the symbol
    }

    after_outer:
    // Disallow patterns with a trailing ',' or with two ',' next to each other
    auto grouping1 = static_cast<int16_t> (result.groupingSizes & 0xffff);
    auto grouping2 = static_cast<int16_t> ((result.groupingSizes >> 16) & 0xffff);
    auto grouping3 = static_cast<int16_t> ((result.groupingSizes >> 32) & 0xffff);
    if (grouping1 == 0 && grouping2 != -1) {
        state.toParseException(u"Trailing grouping separator is invalid");
        status = U_UNEXPECTED_TOKEN;
        return;
    }
    if (grouping2 == 0 && grouping3 != -1) {
        state.toParseException(u"Grouping width of zero is invalid");
        status = U_PATTERN_SYNTAX_ERROR;
        return;
    }
}

void ParsedPatternInfo::consumeFractionFormat(UErrorCode& status) {
    // Convenience reference:
    ParsedSubpatternInfo& result = *currentSubpattern;

    int32_t zeroCounter = 0;
    while (true) {
        switch (state.peek()) {
            case u'#':
                result.widthExceptAffixes += 1;
                result.fractionHashSigns += 1;
                result.fractionTotal += 1;
                zeroCounter++;
                break;

            case u'0':
            case u'1':
            case u'2':
            case u'3':
            case u'4':
            case u'5':
            case u'6':
            case u'7':
            case u'8':
            case u'9':
                if (result.fractionHashSigns > 0) {
                    state.toParseException(u"0 cannot follow # after decimal point");
                    status = U_UNEXPECTED_TOKEN;
                    return;
                }
                result.widthExceptAffixes += 1;
                result.fractionNumerals += 1;
                result.fractionTotal += 1;
                if (state.peek() == u'0') {
                    zeroCounter++;
                } else {
                    result.rounding
                            .appendDigit(static_cast<int8_t>(state.peek() - u'0'), zeroCounter, false);
                    zeroCounter = 0;
                }
                break;

            default:
                return;
        }
        state.next(); // consume the symbol
    }
}

void ParsedPatternInfo::consumeExponent(UErrorCode& status) {
    // Convenience reference:
    ParsedSubpatternInfo& result = *currentSubpattern;

    if (state.peek() != u'E') {
        return;
    }
    if ((result.groupingSizes & 0xffff0000L) != 0xffff0000L) {
        state.toParseException(u"Cannot have grouping separator in scientific notation");
        status = U_MALFORMED_EXPONENTIAL_PATTERN;
        return;
    }
    state.next(); // consume the E
    result.widthExceptAffixes++;
    if (state.peek() == u'+') {
        state.next(); // consume the +
        result.exponentHasPlusSign = true;
        result.widthExceptAffixes++;
    }
    while (state.peek() == u'0') {
        state.next(); // consume the 0
        result.exponentZeros += 1;
        result.widthExceptAffixes++;
    }
}

///////////////////////////////////////////////////
/// END RECURSIVE DESCENT PARSER IMPLEMENTATION ///
///////////////////////////////////////////////////

void PatternParser::parseToExistingPropertiesImpl(const UnicodeString& pattern,
                                                  DecimalFormatProperties& properties,
                                                  IgnoreRounding ignoreRounding, UErrorCode& status) {
    if (pattern.length() == 0) {
        // Backwards compatibility requires that we reset to the default values.
        // TODO: Only overwrite the properties that "saveToProperties" normally touches?
        properties.clear();
        return;
    }

    ParsedPatternInfo patternInfo;
    parseToPatternInfo(pattern, patternInfo, status);
    if (U_FAILURE(status)) { return; }
    patternInfoToProperties(properties, patternInfo, ignoreRounding, status);
}

void
PatternParser::patternInfoToProperties(DecimalFormatProperties& properties, ParsedPatternInfo& patternInfo,
                                       IgnoreRounding _ignoreRounding, UErrorCode& status) {
    // Translate from PatternParseResult to Properties.
    // Note that most data from "negative" is ignored per the specification of DecimalFormat.

    const ParsedSubpatternInfo& positive = patternInfo.positive;

    bool ignoreRounding;
    if (_ignoreRounding == IGNORE_ROUNDING_NEVER) {
        ignoreRounding = false;
    } else if (_ignoreRounding == IGNORE_ROUNDING_IF_CURRENCY) {
        ignoreRounding = positive.hasCurrencySign;
    } else {
        U_ASSERT(_ignoreRounding == IGNORE_ROUNDING_ALWAYS);
        ignoreRounding = true;
    }

    // Grouping settings
    auto grouping1 = static_cast<int16_t> (positive.groupingSizes & 0xffff);
    auto grouping2 = static_cast<int16_t> ((positive.groupingSizes >> 16) & 0xffff);
    auto grouping3 = static_cast<int16_t> ((positive.groupingSizes >> 32) & 0xffff);
    if (grouping2 != -1) {
        properties.groupingSize = grouping1;
        properties.groupingUsed = true;
    } else {
        properties.groupingSize = -1;
        properties.groupingUsed = false;
    }
    if (grouping3 != -1) {
        properties.secondaryGroupingSize = grouping2;
    } else {
        properties.secondaryGroupingSize = -1;
    }

    // For backwards compatibility, require that the pattern emit at least one min digit.
    int minInt, minFrac;
    if (positive.integerTotal == 0 && positive.fractionTotal > 0) {
        // patterns like ".##"
        minInt = 0;
        minFrac = uprv_max(1, positive.fractionNumerals);
    } else if (positive.integerNumerals == 0 && positive.fractionNumerals == 0) {
        // patterns like "#.##"
        minInt = 1;
        minFrac = 0;
    } else {
        minInt = positive.integerNumerals;
        minFrac = positive.fractionNumerals;
    }

    // Rounding settings
    // Don't set basic rounding when there is a currency sign; defer to CurrencyUsage
    if (positive.integerAtSigns > 0) {
        properties.minimumFractionDigits = -1;
        properties.maximumFractionDigits = -1;
        properties.roundingIncrement = 0.0;
        properties.minimumSignificantDigits = positive.integerAtSigns;
        properties.maximumSignificantDigits = positive.integerAtSigns + positive.integerTrailingHashSigns;
    } else if (!positive.rounding.isZeroish()) {
        if (!ignoreRounding) {
            properties.minimumFractionDigits = minFrac;
            properties.maximumFractionDigits = positive.fractionTotal;
            properties.roundingIncrement = positive.rounding.toDouble();
        } else {
            properties.minimumFractionDigits = -1;
            properties.maximumFractionDigits = -1;
            properties.roundingIncrement = 0.0;
        }
        properties.minimumSignificantDigits = -1;
        properties.maximumSignificantDigits = -1;
    } else {
        if (!ignoreRounding) {
            properties.minimumFractionDigits = minFrac;
            properties.maximumFractionDigits = positive.fractionTotal;
            properties.roundingIncrement = 0.0;
        } else {
            properties.minimumFractionDigits = -1;
            properties.maximumFractionDigits = -1;
            properties.roundingIncrement = 0.0;
        }
        properties.minimumSignificantDigits = -1;
        properties.maximumSignificantDigits = -1;
    }

    // If the pattern ends with a '.' then force the decimal point.
    if (positive.hasDecimal && positive.fractionTotal == 0) {
        properties.decimalSeparatorAlwaysShown = true;
    } else {
        properties.decimalSeparatorAlwaysShown = false;
    }

    // Persist the currency as decimal separator
    properties.currencyAsDecimal = positive.hasCurrencyDecimal;

    // Scientific notation settings
    if (positive.exponentZeros > 0) {
        properties.exponentSignAlwaysShown = positive.exponentHasPlusSign;
        properties.minimumExponentDigits = positive.exponentZeros;
        if (positive.integerAtSigns == 0) {
            // patterns without '@' can define max integer digits, used for engineering notation
            properties.minimumIntegerDigits = positive.integerNumerals;
            properties.maximumIntegerDigits = positive.integerTotal;
        } else {
            // patterns with '@' cannot define max integer digits
            properties.minimumIntegerDigits = 1;
            properties.maximumIntegerDigits = -1;
        }
    } else {
        properties.exponentSignAlwaysShown = false;
        properties.minimumExponentDigits = -1;
        properties.minimumIntegerDigits = minInt;
        properties.maximumIntegerDigits = -1;
    }

    // Compute the affix patterns (required for both padding and affixes)
    UnicodeString posPrefix = patternInfo.getString(AffixPatternProvider::AFFIX_PREFIX);
    UnicodeString posSuffix = patternInfo.getString(0);

    // Padding settings
    if (positive.hasPadding) {
        // The width of the positive prefix and suffix templates are included in the padding
        int paddingWidth = positive.widthExceptAffixes +
                           AffixUtils::estimateLength(posPrefix, status) +
                           AffixUtils::estimateLength(posSuffix, status);
        properties.formatWidth = paddingWidth;
        UnicodeString rawPaddingString = patternInfo.getString(AffixPatternProvider::AFFIX_PADDING);
        if (rawPaddingString.length() == 1) {
            properties.padString = rawPaddingString;
        } else if (rawPaddingString.length() == 2) {
            if (rawPaddingString.charAt(0) == u'\'') {
                properties.padString.setTo(u"'", -1);
            } else {
                properties.padString = rawPaddingString;
            }
        } else {
            properties.padString = UnicodeString(rawPaddingString, 1, rawPaddingString.length() - 2);
        }
        properties.padPosition = positive.paddingLocation;
    } else {
        properties.formatWidth = -1;
        properties.padString.setToBogus();
        properties.padPosition.nullify();
    }

    // Set the affixes
    // Always call the setter, even if the prefixes are empty, especially in the case of the
    // negative prefix pattern, to prevent default values from overriding the pattern.
    properties.positivePrefixPattern = posPrefix;
    properties.positiveSuffixPattern = posSuffix;
    if (patternInfo.fHasNegativeSubpattern) {
        properties.negativePrefixPattern = patternInfo.getString(
                AffixPatternProvider::AFFIX_NEGATIVE_SUBPATTERN | AffixPatternProvider::AFFIX_PREFIX);
        properties.negativeSuffixPattern = patternInfo.getString(
                AffixPatternProvider::AFFIX_NEGATIVE_SUBPATTERN);
    } else {
        properties.negativePrefixPattern.setToBogus();
        properties.negativeSuffixPattern.setToBogus();
    }

    // Set the magnitude multiplier
    if (positive.hasPercentSign) {
        properties.magnitudeMultiplier = 2;
    } else if (positive.hasPerMilleSign) {
        properties.magnitudeMultiplier = 3;
    } else {
        properties.magnitudeMultiplier = 0;
    }
}

///////////////////////////////////////////////////////////////////
/// End PatternStringParser.java; begin PatternStringUtils.java ///
///////////////////////////////////////////////////////////////////

// Determine whether a given roundingIncrement should be ignored for formatting
// based on the current maxFrac value (maximum fraction digits). For example a
// roundingIncrement of 0.01 should be ignored if maxFrac is 1, but not if maxFrac
// is 2 or more. Note that roundingIncrements are rounded in significance, so
// a roundingIncrement of 0.006 is treated like 0.01 for this determination, i.e.
// it should not be ignored if maxFrac is 2 or more (but a roundingIncrement of
// 0.005 is treated like 0.001 for significance). This is the reason for the
// initial doubling below.
// roundIncr must be non-zero.
bool PatternStringUtils::ignoreRoundingIncrement(double roundIncr, int32_t maxFrac) {
    if (maxFrac < 0) {
        return false;
    }
    int32_t frac = 0;
    roundIncr *= 2.0;
    for (frac = 0; frac <= maxFrac && roundIncr <= 1.0; frac++, roundIncr *= 10.0);
    return (frac > maxFrac);
}

UnicodeString PatternStringUtils::propertiesToPatternString(const DecimalFormatProperties& properties,
                                                            UErrorCode& status) {
    UnicodeString sb;

    // Convenience references
    // The uprv_min() calls prevent DoS
    int32_t dosMax = 100;
    int32_t grouping1 = uprv_max(0, uprv_min(properties.groupingSize, dosMax));
    int32_t grouping2 = uprv_max(0, uprv_min(properties.secondaryGroupingSize, dosMax));
    bool useGrouping = properties.groupingUsed;
    int32_t paddingWidth = uprv_min(properties.formatWidth, dosMax);
    NullableValue<PadPosition> paddingLocation = properties.padPosition;
    UnicodeString paddingString = properties.padString;
    int32_t minInt = uprv_max(0, uprv_min(properties.minimumIntegerDigits, dosMax));
    int32_t maxInt = uprv_min(properties.maximumIntegerDigits, dosMax);
    int32_t minFrac = uprv_max(0, uprv_min(properties.minimumFractionDigits, dosMax));
    int32_t maxFrac = uprv_min(properties.maximumFractionDigits, dosMax);
    int32_t minSig = uprv_min(properties.minimumSignificantDigits, dosMax);
    int32_t maxSig = uprv_min(properties.maximumSignificantDigits, dosMax);
    bool alwaysShowDecimal = properties.decimalSeparatorAlwaysShown;
    int32_t exponentDigits = uprv_min(properties.minimumExponentDigits, dosMax);
    bool exponentShowPlusSign = properties.exponentSignAlwaysShown;

    AutoAffixPatternProvider affixProvider(properties, status);

    // Prefixes
    sb.append(affixProvider.get().getString(AffixPatternProvider::AFFIX_POS_PREFIX));
    int32_t afterPrefixPos = sb.length();

    // Figure out the grouping sizes.
    if (!useGrouping) {
        grouping1 = 0;
        grouping2 = 0;
    } else if (grouping1 == grouping2) {
        grouping1 = 0;
    }
    int32_t groupingLength = grouping1 + grouping2 + 1;

    // Figure out the digits we need to put in the pattern.
    double roundingInterval = properties.roundingIncrement;
    UnicodeString digitsString;
    int32_t digitsStringScale = 0;
    if (maxSig != uprv_min(dosMax, -1)) {
        // Significant Digits.
        while (digitsString.length() < minSig) {
            digitsString.append(u'@');
        }
        while (digitsString.length() < maxSig) {
            digitsString.append(u'#');
        }
    } else if (roundingInterval != 0.0 && !ignoreRoundingIncrement(roundingInterval,maxFrac)) {
        // Rounding Interval.
        digitsStringScale = -roundingutils::doubleFractionLength(roundingInterval, nullptr);
        // TODO: Check for DoS here?
        DecimalQuantity incrementQuantity;
        incrementQuantity.setToDouble(roundingInterval);
        incrementQuantity.adjustMagnitude(-digitsStringScale);
        incrementQuantity.roundToMagnitude(0, kDefaultMode, status);
        UnicodeString str = incrementQuantity.toPlainString();
        if (str.charAt(0) == u'-') {
            // TODO: Unsupported operation exception or fail silently?
            digitsString.append(str, 1, str.length() - 1);
        } else {
            digitsString.append(str);
        }
    }
    while (digitsString.length() + digitsStringScale < minInt) {
        digitsString.insert(0, u'0');
    }
    while (-digitsStringScale < minFrac) {
        digitsString.append(u'0');
        digitsStringScale--;
    }

    // Write the digits to the string builder
    int32_t m0 = uprv_max(groupingLength, digitsString.length() + digitsStringScale);
    m0 = (maxInt != dosMax) ? uprv_max(maxInt, m0) - 1 : m0 - 1;
    int32_t mN = (maxFrac != dosMax) ? uprv_min(-maxFrac, digitsStringScale) : digitsStringScale;
    for (int32_t magnitude = m0; magnitude >= mN; magnitude--) {
        int32_t di = digitsString.length() + digitsStringScale - magnitude - 1;
        if (di < 0 || di >= digitsString.length()) {
            sb.append(u'#');
        } else {
            sb.append(digitsString.charAt(di));
        }
        // Decimal separator
        if (magnitude == 0 && (alwaysShowDecimal || mN < 0)) {
            if (properties.currencyAsDecimal) {
                sb.append(u'¤');
            } else {
                sb.append(u'.');
            }
        }
        if (!useGrouping) {
            continue;
        }
        // Least-significant grouping separator
        if (magnitude > 0 && magnitude == grouping1) {
            sb.append(u',');
        }
        // All other grouping separators
        if (magnitude > grouping1 && grouping2 > 0 && (magnitude - grouping1) % grouping2 == 0) {
            sb.append(u',');
        }
    }

    // Exponential notation
    if (exponentDigits != uprv_min(dosMax, -1)) {
        sb.append(u'E');
        if (exponentShowPlusSign) {
            sb.append(u'+');
        }
        for (int32_t i = 0; i < exponentDigits; i++) {
            sb.append(u'0');
        }
    }

    // Suffixes
    int32_t beforeSuffixPos = sb.length();
    sb.append(affixProvider.get().getString(AffixPatternProvider::AFFIX_POS_SUFFIX));

    // Resolve Padding
    if (paddingWidth > 0 && !paddingLocation.isNull()) {
        while (paddingWidth - sb.length() > 0) {
            sb.insert(afterPrefixPos, u'#');
            beforeSuffixPos++;
        }
        int32_t addedLength;
        switch (paddingLocation.get(status)) {
            case PadPosition::UNUM_PAD_BEFORE_PREFIX:
                addedLength = escapePaddingString(paddingString, sb, 0, status);
                sb.insert(0, u'*');
                afterPrefixPos += addedLength + 1;
                beforeSuffixPos += addedLength + 1;
                break;
            case PadPosition::UNUM_PAD_AFTER_PREFIX:
                addedLength = escapePaddingString(paddingString, sb, afterPrefixPos, status);
                sb.insert(afterPrefixPos, u'*');
                afterPrefixPos += addedLength + 1;
                beforeSuffixPos += addedLength + 1;
                break;
            case PadPosition::UNUM_PAD_BEFORE_SUFFIX:
                escapePaddingString(paddingString, sb, beforeSuffixPos, status);
                sb.insert(beforeSuffixPos, u'*');
                break;
            case PadPosition::UNUM_PAD_AFTER_SUFFIX:
                sb.append(u'*');
                escapePaddingString(paddingString, sb, sb.length(), status);
                break;
        }
        if (U_FAILURE(status)) { return sb; }
    }

    // Negative affixes
    // Ignore if the negative prefix pattern is "-" and the negative suffix is empty
    if (affixProvider.get().hasNegativeSubpattern()) {
        sb.append(u';');
        sb.append(affixProvider.get().getString(AffixPatternProvider::AFFIX_NEG_PREFIX));
        // Copy the positive digit format into the negative.
        // This is optional; the pattern is the same as if '#' were appended here instead.
        // NOTE: It is not safe to append the UnicodeString to itself, so we need to copy.
        // See https://unicode-org.atlassian.net/browse/ICU-13707
        UnicodeString copy(sb);
        sb.append(copy, afterPrefixPos, beforeSuffixPos - afterPrefixPos);
        sb.append(affixProvider.get().getString(AffixPatternProvider::AFFIX_NEG_SUFFIX));
    }

    return sb;
}

int PatternStringUtils::escapePaddingString(UnicodeString input, UnicodeString& output, int startIndex,
                                            UErrorCode& status) {
    (void) status;
    if (input.length() == 0) {
        input.setTo(kFallbackPaddingString, -1);
    }
    int startLength = output.length();
    if (input.length() == 1) {
        if (input.compare(u"'", -1) == 0) {
            output.insert(startIndex, u"''", -1);
        } else {
            output.insert(startIndex, input);
        }
    } else {
        output.insert(startIndex, u'\'');
        int offset = 1;
        for (int i = 0; i < input.length(); i++) {
            // it's okay to deal in chars here because the quote mark is the only interesting thing.
            char16_t ch = input.charAt(i);
            if (ch == u'\'') {
                output.insert(startIndex + offset, u"''", -1);
                offset += 2;
            } else {
                output.insert(startIndex + offset, ch);
                offset += 1;
            }
        }
        output.insert(startIndex + offset, u'\'');
    }
    return output.length() - startLength;
}

UnicodeString
PatternStringUtils::convertLocalized(const UnicodeString& input, const DecimalFormatSymbols& symbols,
                                     bool toLocalized, UErrorCode& status) {
    // Construct a table of strings to be converted between localized and standard.
    static constexpr int32_t LEN = 21;
    UnicodeString table[LEN][2];
    int standIdx = toLocalized ? 0 : 1;
    int localIdx = toLocalized ? 1 : 0;
    // TODO: Add approximately sign here?
    table[0][standIdx] = u"%";
    table[0][localIdx] = symbols.getConstSymbol(DecimalFormatSymbols::kPercentSymbol);
    table[1][standIdx] = u"‰";
    table[1][localIdx] = symbols.getConstSymbol(DecimalFormatSymbols::kPerMillSymbol);
    table[2][standIdx] = u".";
    table[2][localIdx] = symbols.getConstSymbol(DecimalFormatSymbols::kDecimalSeparatorSymbol);
    table[3][standIdx] = u",";
    table[3][localIdx] = symbols.getConstSymbol(DecimalFormatSymbols::kGroupingSeparatorSymbol);
    table[4][standIdx] = u"-";
    table[4][localIdx] = symbols.getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol);
    table[5][standIdx] = u"+";
    table[5][localIdx] = symbols.getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol);
    table[6][standIdx] = u";";
    table[6][localIdx] = symbols.getConstSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol);
    table[7][standIdx] = u"@";
    table[7][localIdx] = symbols.getConstSymbol(DecimalFormatSymbols::kSignificantDigitSymbol);
    table[8][standIdx] = u"E";
    table[8][localIdx] = symbols.getConstSymbol(DecimalFormatSymbols::kExponentialSymbol);
    table[9][standIdx] = u"*";
    table[9][localIdx] = symbols.getConstSymbol(DecimalFormatSymbols::kPadEscapeSymbol);
    table[10][standIdx] = u"#";
    table[10][localIdx] = symbols.getConstSymbol(DecimalFormatSymbols::kDigitSymbol);
    for (int i = 0; i < 10; i++) {
        table[11 + i][standIdx] = u'0' + i;
        table[11 + i][localIdx] = symbols.getConstDigitSymbol(i);
    }

    // Special case: quotes are NOT allowed to be in any localIdx strings.
    // Substitute them with '’' instead.
    for (int32_t i = 0; i < LEN; i++) {
        table[i][localIdx].findAndReplace(u'\'', u'’');
    }

    // Iterate through the string and convert.
    // State table:
    // 0 => base state
    // 1 => first char inside a quoted sequence in input and output string
    // 2 => inside a quoted sequence in input and output string
    // 3 => first char after a close quote in input string;
    // close quote still needs to be written to output string
    // 4 => base state in input string; inside quoted sequence in output string
    // 5 => first char inside a quoted sequence in input string;
    // inside quoted sequence in output string
    UnicodeString result;
    int state = 0;
    for (int offset = 0; offset < input.length(); offset++) {
        UChar ch = input.charAt(offset);

        // Handle a quote character (state shift)
        if (ch == u'\'') {
            if (state == 0) {
                result.append(u'\'');
                state = 1;
                continue;
            } else if (state == 1) {
                result.append(u'\'');
                state = 0;
                continue;
            } else if (state == 2) {
                state = 3;
                continue;
            } else if (state == 3) {
                result.append(u'\'');
                result.append(u'\'');
                state = 1;
                continue;
            } else if (state == 4) {
                state = 5;
                continue;
            } else {
                U_ASSERT(state == 5);
                result.append(u'\'');
                result.append(u'\'');
                state = 4;
                continue;
            }
        }

        if (state == 0 || state == 3 || state == 4) {
            for (auto& pair : table) {
                // Perform a greedy match on this symbol string
                UnicodeString temp = input.tempSubString(offset, pair[0].length());
                if (temp == pair[0]) {
                    // Skip ahead past this region for the next iteration
                    offset += pair[0].length() - 1;
                    if (state == 3 || state == 4) {
                        result.append(u'\'');
                        state = 0;
                    }
                    result.append(pair[1]);
                    goto continue_outer;
                }
            }
            // No replacement found. Check if a special quote is necessary
            for (auto& pair : table) {
                UnicodeString temp = input.tempSubString(offset, pair[1].length());
                if (temp == pair[1]) {
                    if (state == 0) {
                        result.append(u'\'');
                        state = 4;
                    }
                    result.append(ch);
                    goto continue_outer;
                }
            }
            // Still nothing. Copy the char verbatim. (Add a close quote if necessary)
            if (state == 3 || state == 4) {
                result.append(u'\'');
                state = 0;
            }
            result.append(ch);
        } else {
            U_ASSERT(state == 1 || state == 2 || state == 5);
            result.append(ch);
            state = 2;
        }
        continue_outer:;
    }
    // Resolve final quotes
    if (state == 3 || state == 4) {
        result.append(u'\'');
        state = 0;
    }
    if (state != 0) {
        // Malformed localized pattern: unterminated quote
        status = U_PATTERN_SYNTAX_ERROR;
    }
    return result;
}

void PatternStringUtils::patternInfoToStringBuilder(const AffixPatternProvider& patternInfo, bool isPrefix,
                                                    PatternSignType patternSignType,
                                                    bool approximately,
                                                    StandardPlural::Form plural,
                                                    bool perMilleReplacesPercent, UnicodeString& output) {

    // Should the output render '+' where '-' would normally appear in the pattern?
    bool plusReplacesMinusSign = (patternSignType == PATTERN_SIGN_TYPE_POS_SIGN)
        && !patternInfo.positiveHasPlusSign();

    // Should we use the affix from the negative subpattern?
    // (If not, we will use the positive subpattern.)
    bool useNegativeAffixPattern = patternInfo.hasNegativeSubpattern()
        && (patternSignType == PATTERN_SIGN_TYPE_NEG
            || (patternInfo.negativeHasMinusSign() && (plusReplacesMinusSign || approximately)));

    // Resolve the flags for the affix pattern.
    int flags = 0;
    if (useNegativeAffixPattern) {
        flags |= AffixPatternProvider::AFFIX_NEGATIVE_SUBPATTERN;
    }
    if (isPrefix) {
        flags |= AffixPatternProvider::AFFIX_PREFIX;
    }
    if (plural != StandardPlural::Form::COUNT) {
        U_ASSERT(plural == (AffixPatternProvider::AFFIX_PLURAL_MASK & plural));
        flags |= plural;
    }

    // Should we prepend a sign to the pattern?
    bool prependSign;
    if (!isPrefix || useNegativeAffixPattern) {
        prependSign = false;
    } else if (patternSignType == PATTERN_SIGN_TYPE_NEG) {
        prependSign = true;
    } else {
        prependSign = plusReplacesMinusSign || approximately;
    }

    // What symbols should take the place of the sign placeholder?
    const char16_t* signSymbols = u"-";
    if (approximately) {
        if (plusReplacesMinusSign) {
            signSymbols = u"~+";
        } else if (patternSignType == PATTERN_SIGN_TYPE_NEG) {
            signSymbols = u"~-";
        } else {
            signSymbols = u"~";
        }
    } else if (plusReplacesMinusSign) {
        signSymbols = u"+";
    }

    // Compute the number of tokens in the affix pattern (signSymbols is considered one token).
    int length = patternInfo.length(flags) + (prependSign ? 1 : 0);

    // Finally, set the result into the StringBuilder.
    output.remove();
    for (int index = 0; index < length; index++) {
        char16_t candidate;
        if (prependSign && index == 0) {
            candidate = u'-';
        } else if (prependSign) {
            candidate = patternInfo.charAt(flags, index - 1);
        } else {
            candidate = patternInfo.charAt(flags, index);
        }
        if (candidate == u'-') {
            if (u_strlen(signSymbols) == 1) {
                candidate = signSymbols[0];
            } else {
                output.append(signSymbols[0]);
                candidate = signSymbols[1];
            }
        }
        if (perMilleReplacesPercent && candidate == u'%') {
            candidate = u'‰';
        }
        output.append(candidate);
    }
}

PatternSignType PatternStringUtils::resolveSignDisplay(UNumberSignDisplay signDisplay, Signum signum) {
    switch (signDisplay) {
        case UNUM_SIGN_AUTO:
        case UNUM_SIGN_ACCOUNTING:
            switch (signum) {
                case SIGNUM_NEG:
                case SIGNUM_NEG_ZERO:
                    return PATTERN_SIGN_TYPE_NEG;
                case SIGNUM_POS_ZERO:
                case SIGNUM_POS:
                    return PATTERN_SIGN_TYPE_POS;
                default:
                    break;
            }
            break;

        case UNUM_SIGN_ALWAYS:
        case UNUM_SIGN_ACCOUNTING_ALWAYS:
            switch (signum) {
                case SIGNUM_NEG:
                case SIGNUM_NEG_ZERO:
                    return PATTERN_SIGN_TYPE_NEG;
                case SIGNUM_POS_ZERO:
                case SIGNUM_POS:
                    return PATTERN_SIGN_TYPE_POS_SIGN;
                default:
                    break;
            }
            break;

        case UNUM_SIGN_EXCEPT_ZERO:
        case UNUM_SIGN_ACCOUNTING_EXCEPT_ZERO:
            switch (signum) {
                case SIGNUM_NEG:
                    return PATTERN_SIGN_TYPE_NEG;
                case SIGNUM_NEG_ZERO:
                case SIGNUM_POS_ZERO:
                    return PATTERN_SIGN_TYPE_POS;
                case SIGNUM_POS:
                    return PATTERN_SIGN_TYPE_POS_SIGN;
                default:
                    break;
            }
            break;

        case UNUM_SIGN_NEGATIVE:
        case UNUM_SIGN_ACCOUNTING_NEGATIVE:
            switch (signum) {
                case SIGNUM_NEG:
                    return PATTERN_SIGN_TYPE_NEG;
                case SIGNUM_NEG_ZERO:
                case SIGNUM_POS_ZERO:
                case SIGNUM_POS:
                    return PATTERN_SIGN_TYPE_POS;
                default:
                    break;
            }
            break;

        case UNUM_SIGN_NEVER:
            return PATTERN_SIGN_TYPE_POS;

        default:
            break;
    }

    UPRV_UNREACHABLE_EXIT;
    return PATTERN_SIGN_TYPE_POS;
}

#endif /* #if !UCONFIG_NO_FORMATTING */
