// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// @dart=2.9

import 'dart:collection';
import 'dart:math';

import 'package:intl/intl.dart';
import 'package:intl/number_symbols.dart';
import 'package:intl/number_symbols_data.dart';

import 'intl_stream.dart';

part 'compact_number_format.dart';

// ignore_for_file: constant_identifier_names

/// The function that we pass internally to NumberFormat to get
/// the appropriate pattern (e.g. currency)
typedef _PatternGetter = String Function(NumberSymbols);

/// Provides the ability to format a number in a locale-specific way.
///
/// The format is specified as a pattern using a subset of the ICU formatting
/// patterns.
///
/// - `0` A single digit
/// - `#` A single digit, omitted if the value is zero
/// - `.` Decimal separator
/// - `-` Minus sign
/// - `,` Grouping separator
/// - `E` Separates mantissa and expontent
/// - `+` - Before an exponent, to say it should be prefixed with a plus sign.
/// - `%` - In prefix or suffix, multiply by 100 and show as percentage
/// - `‰ (\u2030)` In prefix or suffix, multiply by 1000 and show as per mille
/// - `¤ (\u00A4)` Currency sign, replaced by currency name
/// - `'` Used to quote special characters
/// - `;` Used to separate the positive and negative patterns (if both present)
///
/// For example,
///
///       var f = NumberFormat("###.0#", "en_US");
///       print(f.format(12.345));
///           ==> 12.34
///
/// If the locale is not specified, it will default to the current locale. If
/// the format is not specified it will print in a basic format with at least
/// one integer digit and three fraction digits.
///
/// There are also standard patterns available via the special constructors.
/// e.g.
///
///       var percent = NumberFormat.percentPattern("ar"); var
///       eurosInUSFormat = NumberFormat.currency(locale: "en_US",
///           symbol: "€");
///
/// There are several such constructors available, though some of them are
/// limited. For example, at the moment, scientificPattern prints only as
/// equivalent to "#E0" and does not take into account significant digits.
class NumberFormat {
  /// Variables to determine how number printing behaves.
  String _negativePrefix;
  String _positivePrefix;
  String _negativeSuffix;
  String _positiveSuffix;

  /// How many numbers in a group when using punctuation to group digits in
  /// large numbers. e.g. in en_US: "1,000,000" has a grouping size of 3 digits
  /// between commas.
  int _groupingSize;

  /// In some formats the last grouping size may be different than previous
  /// ones, e.g. Hindi.
  int _finalGroupingSize;

  /// Set to true if the format has explicitly set the grouping size.
  bool _decimalSeparatorAlwaysShown;
  bool _useSignForPositiveExponent;
  bool _useExponentialNotation;

  /// Explicitly store if we are a currency format, and so should use the
  /// appropriate number of decimal digits for a currency.
  // TODO(alanknight): Handle currency formats which are specified in a raw
  /// pattern, not using one of the currency constructors.
  bool _isForCurrency;

  int maximumIntegerDigits;
  int minimumIntegerDigits;
  int maximumFractionDigits;
  int minimumFractionDigits;
  int minimumExponentDigits;
  int _significantDigits;

  ///  How many significant digits should we print.
  ///
  ///  Note that if significantDigitsInUse is the default false, this
  ///  will be ignored.
  int get significantDigits => _significantDigits;
  set significantDigits(int x) {
    _significantDigits = x;
    significantDigitsInUse = true;
  }

  bool significantDigitsInUse = false;

  /// For percent and permille, what are we multiplying by in order to
  /// get the printed value, e.g. 100 for percent.
  int _multiplier;

  /// How many digits are there in the [_multiplier].
  int _multiplierDigits;

  /// Stores the pattern used to create this format. This isn't used, but
  /// is helpful in debugging.
  String _pattern;

  /// The locale in which we print numbers.
  final String _locale;

  /// Caches the symbols used for our locale.
  NumberSymbols _symbols;

  /// The name of the currency to print, in ISO 4217 form.
  String currencyName;

  /// The symbol to be used when formatting this as currency.
  ///
  /// For example, "$", "US$", or "€".
  String _currencySymbol;

  /// The symbol to be used when formatting this as currency.
  ///
  /// For example, "$", "US$", or "€".
  String get currencySymbol => _currencySymbol;

  /// The number of decimal places to use when formatting.
  ///
  /// If this is not explicitly specified in the constructor, then for
  /// currencies we use the default value for the currency if the name is given,
  /// otherwise we use the value from the pattern for the locale.
  ///
  /// So, for example,
  ///       NumberFormat.currency(name: 'USD', decimalDigits: 7)
  /// will format with 7 decimal digits, because that's what we asked for. But
  ///       NumberFormat.currency(locale: 'en_US', name: 'JPY')
  /// will format with zero, because that's the default for JPY, and the
  /// currency's default takes priority over the locale's default.
  ///       NumberFormat.currency(locale: 'en_US')
  /// will format with two, which is the default for that locale.
  ///
  int get decimalDigits => _decimalDigits;

  int _decimalDigits;

  /// Transient internal state in which to build up the result of the format
  /// operation. We can have this be just an instance variable because Dart is
  /// single-threaded and unless we do an asynchronous operation in the process
  /// of formatting then there will only ever be one number being formatted
  /// at a time. In languages with threads we'd need to pass this on the stack.
  final StringBuffer _buffer = StringBuffer();

  /// Create a number format that prints using [newPattern] as it applies in
  /// [locale].
  factory NumberFormat([String newPattern, String locale]) =>
      NumberFormat._forPattern(locale, (x) => newPattern);

  /// Create a number format that prints as DECIMAL_PATTERN.
  NumberFormat.decimalPattern([String locale])
      : this._forPattern(locale, (x) => x.DECIMAL_PATTERN);

  /// Create a number format that prints as PERCENT_PATTERN.
  NumberFormat.percentPattern([String locale])
      : this._forPattern(locale, (x) => x.PERCENT_PATTERN);

  /// Create a number format that prints as PERCENT_PATTERN.
  NumberFormat.decimalPercentPattern({String locale, int decimalDigits})
      : this._forPattern(locale, (x) => x.PERCENT_PATTERN,
            decimalDigits: decimalDigits);

  /// Create a number format that prints as SCIENTIFIC_PATTERN.
  NumberFormat.scientificPattern([String locale])
      : this._forPattern(locale, (x) => x.SCIENTIFIC_PATTERN);

  /// A regular expression to validate currency names are exactly three
  /// alphabetic characters.
  static final _checkCurrencyName = RegExp(r'^[a-zA-Z]{3}$');

  /// Create a number format that prints as CURRENCY_PATTERN. (Deprecated:
  /// prefer NumberFormat.currency)
  ///
  /// If provided,
  /// use [currencyNameOrSymbol] in place of the default currency name. e.g.
  ///       var eurosInCurrentLocale = NumberFormat
  ///           .currencyPattern(Intl.defaultLocale, "€");
  @Deprecated('Use NumberFormat.currency')
  factory NumberFormat.currencyPattern(
      [String locale, String currencyNameOrSymbol]) {
    // If it looks like an iso4217 name, pass as name, otherwise as symbol.
    if (currencyNameOrSymbol != null &&
        _checkCurrencyName.hasMatch(currencyNameOrSymbol)) {
      return NumberFormat.currency(locale: locale, name: currencyNameOrSymbol);
    } else {
      return NumberFormat.currency(
          locale: locale, symbol: currencyNameOrSymbol);
    }
  }

  /// Create a [NumberFormat] that formats using the locale's CURRENCY_PATTERN.
  ///
  /// If [locale] is not specified, it will use the current default locale.
  ///
  /// If [name] is specified, the currency with that ISO 4217 name will be used.
  /// Otherwise we will use the default currency name for the current locale. If
  /// no [symbol] is specified, we will use the currency name in the formatted
  /// result. e.g.
  ///       var f = NumberFormat.currency(locale: 'en_US', name: 'EUR')
  /// will format currency like "EUR1.23". If we did not specify the name, it
  /// would format like "USD1.23".
  ///
  /// If [symbol] is used, then that symbol will be used in formatting instead
  /// of the name. e.g.
  ///       var eurosInCurrentLocale = NumberFormat.currency(symbol: "€");
  /// will format like "€1.23". Otherwise it will use the currency name.
  /// If this is not explicitly specified in the constructor, then for
  /// currencies we use the default value for the currency if the name is given,
  /// otherwise we use the value from the pattern for the locale.
  ///
  /// If [decimalDigits] is specified, numbers will format with that many digits
  /// after the decimal place. If it's not, they will use the default for the
  /// currency in [name], and the default currency for [locale] if the currency
  /// name is not specified. e.g.
  ///       NumberFormat.currency(name: 'USD', decimalDigits: 7)
  /// will format with 7 decimal digits, because that's what we asked for. But
  ///       NumberFormat.currency(locale: 'en_US', name: 'JPY')
  /// will format with zero, because that's the default for JPY, and the
  /// currency's default takes priority over the locale's default.
  ///       NumberFormat.currency(locale: 'en_US')
  /// will format with two, which is the default for that locale.
  ///
  /// The [customPattern] parameter can be used to specify a particular
  /// format. This is useful if you have your own locale data which includes
  /// unsupported formats (e.g. accounting format for currencies.)
  // TODO(alanknight): Should we allow decimalDigits on other numbers.
  NumberFormat.currency(
      {String locale,
      String name,
      String symbol,
      int decimalDigits,
      String customPattern})
      : this._forPattern(locale, (x) => customPattern ?? x.CURRENCY_PATTERN,
            name: name,
            currencySymbol: symbol,
            decimalDigits: decimalDigits,
            isForCurrency: true);

  /// Creates a [NumberFormat] for currencies, using the simple symbol for the
  /// currency if one is available (e.g. $, €), so it should only be used if the
  /// short currency symbol will be unambiguous.
  ///
  /// If [locale] is not specified, it will use the current default locale.
  ///
  /// If [name] is specified, the currency with that ISO 4217 name will be used.
  /// Otherwise we will use the default currency name for the current locale. We
  /// will assume that the symbol for this is well known in the locale and
  /// unambiguous. If you format CAD in an en_US locale using this format it
  /// will display as "$", which may be confusing to the user.
  ///
  /// If [decimalDigits] is specified, numbers will format with that many digits
  /// after the decimal place. If it's not, they will use the default for the
  /// currency in [name], and the default currency for [locale] if the currency
  /// name is not specified. e.g.
  ///       NumberFormat.simpleCurrency(name: 'USD', decimalDigits: 7)
  /// will format with 7 decimal digits, because that's what we asked for. But
  ///       NumberFormat.simpleCurrency(locale: 'en_US', name: 'JPY')
  /// will format with zero, because that's the default for JPY, and the
  /// currency's default takes priority over the locale's default.
  ///       NumberFormat.simpleCurrency(locale: 'en_US')
  /// will format with two, which is the default for that locale.
  factory NumberFormat.simpleCurrency(
      {String locale, String name, int decimalDigits}) {
    return NumberFormat._forPattern(locale, (x) => x.CURRENCY_PATTERN,
        name: name,
        decimalDigits: decimalDigits,
        lookupSimpleCurrencySymbol: true,
        isForCurrency: true);
  }

  /// Returns the simple currency symbol for given currency code, or
  /// [currencyCode] if no simple symbol is listed.
  ///
  /// The simple currency symbol is generally short, and the same or related to
  /// what is used in countries having the currency as an official symbol. It
  /// may be a symbol character, or may have letters, or both. It may be
  /// different according to the locale: for example, for an Arabic locale it
  /// may consist of Arabic letters, but for a French locale consist of Latin
  /// letters. It will not be unique: for example, "$" can appear for both USD
  /// and CAD.
  ///
  /// (The current implementation is the same for all locales, but this is
  /// temporary and callers shouldn't rely on it.)
  String simpleCurrencySymbol(String currencyCode) =>
      _simpleCurrencySymbols[currencyCode] ?? currencyCode;

  /// A map from currency names to the simple name/symbol.
  ///
  /// The simple currency symbol is generally short, and the same or related to
  /// what is used in countries having the currency as an official symbol. It
  /// may be a symbol character, or may have letters, or both. It may be
  /// different according to the locale: for example, for an Arabic locale it
  /// may consist of Arabic letters, but for a French locale consist of Latin
  /// letters. It will not be unique: for example, "$" can appear for both USD
  /// and CAD.
  ///
  /// (The current implementation is the same for all locales, but this is
  /// temporary and callers shouldn't rely on it.)
  static final Map<String, String> _simpleCurrencySymbols = {
    'AFN': 'Af.',
    'TOP': r'T$',
    'MGA': 'Ar',
    'THB': '\u0e3f',
    'PAB': 'B/.',
    'ETB': 'Birr',
    'VEF': 'Bs',
    'BOB': 'Bs',
    'GHS': 'GHS',
    'CRC': '\u20a1',
    'NIO': r'C$',
    'GMD': 'GMD',
    'MKD': 'din',
    'BHD': 'din',
    'DZD': 'din',
    'IQD': 'din',
    'JOD': 'din',
    'KWD': 'din',
    'LYD': 'din',
    'RSD': 'din',
    'TND': 'din',
    'AED': 'dh',
    'MAD': 'dh',
    'STD': 'Db',
    'BSD': r'$',
    'FJD': r'$',
    'GYD': r'$',
    'KYD': r'$',
    'LRD': r'$',
    'SBD': r'$',
    'SRD': r'$',
    'AUD': r'$',
    'BBD': r'$',
    'BMD': r'$',
    'BND': r'$',
    'BZD': r'$',
    'CAD': r'$',
    'HKD': r'$',
    'JMD': r'$',
    'NAD': r'$',
    'NZD': r'$',
    'SGD': r'$',
    'TTD': r'$',
    'TWD': r'NT$',
    'USD': r'$',
    'XCD': r'$',
    'VND': '\u20ab',
    'AMD': 'Dram',
    'CVE': 'CVE',
    'EUR': '\u20ac',
    'AWG': 'Afl.',
    'HUF': 'Ft',
    'BIF': 'FBu',
    'CDF': 'FrCD',
    'CHF': 'CHF',
    'DJF': 'Fdj',
    'GNF': 'FG',
    'RWF': 'RF',
    'XOF': 'CFA',
    'XPF': 'FCFP',
    'KMF': 'CF',
    'XAF': 'FCFA',
    'HTG': 'HTG',
    'PYG': 'Gs',
    'UAH': '\u20b4',
    'PGK': 'PGK',
    'LAK': '\u20ad',
    'CZK': 'K\u010d',
    'SEK': 'kr',
    'ISK': 'kr',
    'DKK': 'kr',
    'NOK': 'kr',
    'HRK': 'kn',
    'MWK': 'MWK',
    'ZMK': 'ZWK',
    'AOA': 'Kz',
    'MMK': 'K',
    'GEL': 'GEL',
    'LVL': 'Ls',
    'ALL': 'Lek',
    'HNL': 'L',
    'SLL': 'SLL',
    'MDL': 'MDL',
    'RON': 'RON',
    'BGN': 'lev',
    'SZL': 'SZL',
    'TRY': 'TL',
    'LTL': 'Lt',
    'LSL': 'LSL',
    'AZN': 'man.',
    'BAM': 'KM',
    'MZN': 'MTn',
    'NGN': '\u20a6',
    'ERN': 'Nfk',
    'BTN': 'Nu.',
    'MRO': 'MRO',
    'MOP': 'MOP',
    'CUP': r'$',
    'CUC': r'$',
    'ARS': r'$',
    'CLF': 'UF',
    'CLP': r'$',
    'COP': r'$',
    'DOP': r'$',
    'MXN': r'$',
    'PHP': '\u20b1',
    'UYU': r'$',
    'FKP': '£',
    'GIP': '£',
    'SHP': '£',
    'EGP': 'E£',
    'LBP': 'L£',
    'SDG': 'SDG',
    'SSP': 'SSP',
    'GBP': '£',
    'SYP': '£',
    'BWP': 'P',
    'GTQ': 'Q',
    'ZAR': 'R',
    'BRL': r'R$',
    'OMR': 'Rial',
    'QAR': 'Rial',
    'YER': 'Rial',
    'IRR': 'Rial',
    'KHR': 'Riel',
    'MYR': 'RM',
    'SAR': 'Riyal',
    'BYR': 'BYR',
    'RUB': 'руб.',
    'MUR': 'Rs',
    'SCR': 'SCR',
    'LKR': 'Rs',
    'NPR': 'Rs',
    'INR': '\u20b9',
    'PKR': 'Rs',
    'IDR': 'Rp',
    'ILS': '\u20aa',
    'KES': 'Ksh',
    'SOS': 'SOS',
    'TZS': 'TSh',
    'UGX': 'UGX',
    'PEN': 'S/.',
    'KGS': 'KGS',
    'UZS': 'so\u02bcm',
    'TJS': 'Som',
    'BDT': '\u09f3',
    'WST': 'WST',
    'KZT': '\u20b8',
    'MNT': '\u20ae',
    'VUV': 'VUV',
    'KPW': '\u20a9',
    'KRW': '\u20a9',
    'JPY': '¥',
    'CNY': '¥',
    'PLN': 'z\u0142',
    'MVR': 'Rf',
    'NLG': 'NAf',
    'ZMW': 'ZK',
    'ANG': 'ƒ',
    'TMT': 'TMT',
  };

  /// Create a number format that prints in a pattern we get from
  /// the [getPattern] function using the locale [locale].
  ///
  /// The [currencySymbol] can either be specified directly, or we can pass a
  /// function [computeCurrencySymbol] that will compute it later, given other
  /// information, typically the verified locale.
  NumberFormat._forPattern(String locale, _PatternGetter getPattern,
      {String name,
      String currencySymbol,
      int decimalDigits,
      bool lookupSimpleCurrencySymbol = false,
      bool isForCurrency = false})
      : _locale = Intl.verifiedLocale(locale, localeExists),
        _isForCurrency = isForCurrency {
    _symbols = numberFormatSymbols[_locale];
    _localeZero = _symbols.ZERO_DIGIT.codeUnitAt(0);
    _zeroOffset = _localeZero - _zero;
    currencyName = name ?? _symbols.DEF_CURRENCY_CODE;

    _currencySymbol = currencySymbol;
    if (_currencySymbol == null && lookupSimpleCurrencySymbol) {
      _currencySymbol = _simpleCurrencySymbols[currencyName];
    }
    _currencySymbol ??= currencyName;

    var pattern = getPattern(symbols);

    // Save pattern with spaces converted to hard spaces, just for debugging.
    _pattern = pattern?.replaceAll(' ', '\u00a0');

    var result = _NumberFormatParser.parse(symbols, pattern, _isForCurrency,
        _currencySymbol, currencyName, decimalDigits);

    _positivePrefix = result.positivePrefix;
    _negativePrefix = result.negativePrefix;
    _positiveSuffix = result.positiveSuffix;
    _negativeSuffix = result.negativeSuffix;

    _multiplier = result.multiplier;
    _multiplierDigits = result.multiplierDigits;

    _useExponentialNotation = result.useExponentialNotation;
    minimumExponentDigits = result.minimumExponentDigits;

    maximumIntegerDigits = result.maximumIntegerDigits;
    minimumIntegerDigits = result.minimumIntegerDigits;
    maximumFractionDigits = result.maximumFractionDigits;
    minimumFractionDigits = result.minimumFractionDigits;

    _groupingSize = result.groupingSize;
    _finalGroupingSize = result.finalGroupingSize;

    _useSignForPositiveExponent = result.useSignForPositiveExponent;
    _decimalSeparatorAlwaysShown = result.decimalSeparatorAlwaysShown;

    _decimalDigits = result.decimalDigits;
  }

  /// A number format for compact representations, e.g. "1.2M" instead
  /// of "1,200,000".
  factory NumberFormat.compact({String locale}) {
    return _CompactNumberFormat(
        locale: locale,
        formatType: _CompactFormatType.COMPACT_DECIMAL_SHORT_PATTERN);
  }

  /// A number format for "long" compact representations, e.g. "1.2 million"
  /// instead of of "1,200,000".
  factory NumberFormat.compactLong({String locale}) {
    return _CompactNumberFormat(
        locale: locale,
        formatType: _CompactFormatType.COMPACT_DECIMAL_LONG_PATTERN);
  }

  /// A number format for compact currency representations, e.g. "$1.2M" instead
  /// of "$1,200,000", and which will automatically determine a currency symbol
  /// based on the currency name or the locale. See
  /// [NumberFormat.simpleCurrency].
  factory NumberFormat.compactSimpleCurrency(
      {String locale, String name, int decimalDigits}) {
    return _CompactNumberFormat(
        locale: locale,
        formatType: _CompactFormatType.COMPACT_DECIMAL_SHORT_CURRENCY_PATTERN,
        name: name,
        getPattern: (symbols) => symbols.CURRENCY_PATTERN,
        decimalDigits: decimalDigits,
        lookupSimpleCurrencySymbol: true,
        isForCurrency: true);
  }

  /// A number format for compact currency representations, e.g. "$1.2M" instead
  /// of "$1,200,000".
  factory NumberFormat.compactCurrency(
      {String locale, String name, String symbol, int decimalDigits}) {
    return _CompactNumberFormat(
        locale: locale,
        formatType: _CompactFormatType.COMPACT_DECIMAL_SHORT_CURRENCY_PATTERN,
        name: name,
        getPattern: (symbols) => symbols.CURRENCY_PATTERN,
        currencySymbol: symbol,
        decimalDigits: decimalDigits,
        isForCurrency: true);
  }

  /// Return the locale code in which we operate, e.g. 'en_US' or 'pt'.
  String get locale => _locale;

  /// Return true if the locale exists, or if it is null. The null case
  /// is interpreted to mean that we use the default locale.
  static bool localeExists(localeName) {
    if (localeName == null) return false;
    return numberFormatSymbols.containsKey(localeName);
  }

  /// Return the symbols which are used in our locale. Cache them to avoid
  /// repeated lookup.
  NumberSymbols get symbols => _symbols;

  /// Format [number] according to our pattern and return the formatted string.
  String format(number) {
    if (_isNaN(number)) return symbols.NAN;
    if (_isInfinite(number)) return '${_signPrefix(number)}${symbols.INFINITY}';

    _add(_signPrefix(number));
    _formatNumber(number.abs());
    _add(_signSuffix(number));

    var result = _buffer.toString();
    _buffer.clear();
    return result;
  }

  /// Parse the number represented by the string. If it's not
  /// parseable, throws a [FormatException].
  num parse(String text) => _NumberParser(this, text).value;

  /// Format the main part of the number in the form dictated by the pattern.
  void _formatNumber(number) {
    if (_useExponentialNotation) {
      _formatExponential(number);
    } else {
      _formatFixed(number);
    }
  }

  /// Format the number in exponential notation.
  void _formatExponential(num number) {
    if (number == 0.0) {
      _formatFixed(number);
      _formatExponent(0);
      return;
    }

    var exponent = (log(number) / _ln10).floor();
    var mantissa = number / pow(10.0, exponent);

    if (maximumIntegerDigits > 1 &&
        maximumIntegerDigits > minimumIntegerDigits) {
      // A repeating range is defined; adjust to it as follows.
      // If repeat == 3, we have 6,5,4=>3; 3,2,1=>0; 0,-1,-2=>-3;
      // -3,-4,-5=>-6, etc. This takes into account that the
      // exponent we have here is off by one from what we expect;
      // it is for the format 0.MMMMMx10^n.
      while ((exponent % maximumIntegerDigits) != 0) {
        mantissa *= 10;
        exponent--;
      }
    } else {
      // No repeating range is defined, use minimum integer digits.
      if (minimumIntegerDigits < 1) {
        exponent++;
        mantissa /= 10;
      } else {
        exponent -= minimumIntegerDigits - 1;
        mantissa *= pow(10, minimumIntegerDigits - 1);
      }
    }
    _formatFixed(mantissa);
    _formatExponent(exponent);
  }

  /// Format the exponent portion, e.g. in "1.3e-5" the "e-5".
  void _formatExponent(num exponent) {
    _add(symbols.EXP_SYMBOL);
    if (exponent < 0) {
      exponent = -exponent;
      _add(symbols.MINUS_SIGN);
    } else if (_useSignForPositiveExponent) {
      _add(symbols.PLUS_SIGN);
    }
    _pad(minimumExponentDigits, exponent.toString());
  }

  /// Used to test if we have exceeded integer limits.
  // TODO(alanknight): Do we have a MaxInt constant we could use instead?
  static final _maxInt = 1 is double ? pow(2, 52) : 1.0e300.floor();
  static final _maxDigits = (log(_maxInt) / log(10)).ceil();

  /// Helpers to check numbers that don't conform to the [num] interface,
  /// e.g. Int64
  bool _isInfinite(number) => number is num ? number.isInfinite : false;
  bool _isNaN(number) => number is num ? number.isNaN : false;

  /// Helper to get the floor of a number which might not be num. This should
  /// only ever be called with an argument which is positive, or whose abs()
  ///  is negative. The second case is the maximum negative value on a
  ///  fixed-length integer. Since they are integers, they are also their own
  ///  floor.
  dynamic _floor(dynamic number) {
    if (number.isNegative && !number.abs().isNegative) {
      throw ArgumentError(
          'Internal error: expected positive number, got $number');
    }
    return (number is num) ? number.floor() : number ~/ 1;
  }

  /// Helper to round a number which might not be num.
  dynamic _round(dynamic number) {
    if (number is num) {
      if (number.isInfinite) {
        return _maxInt;
      } else {
        return number.round();
      }
    } else if (number.remainder(1) == 0) {
      // Not a normal number, but int-like, e.g. Int64
      return number;
    } else {
      // TODO(alanknight): Do this more efficiently. If IntX  had floor and
      // round we could avoid this.
      var basic = _floor(number);
      var fraction = (number - basic).toDouble().round();
      return fraction == 0 ? number : number + fraction;
    }
  }

  // Return the number of digits left of the decimal place in [number].
  static int numberOfIntegerDigits(number) {
    var simpleNumber = number.toDouble().abs();
    // It's unfortunate that we have to do this, but we get precision errors
    // that affect the result if we use logs, e.g. 1000000
    if (simpleNumber < 10) return 1;
    if (simpleNumber < 100) return 2;
    if (simpleNumber < 1000) return 3;
    if (simpleNumber < 10000) return 4;
    if (simpleNumber < 100000) return 5;
    if (simpleNumber < 1000000) return 6;
    if (simpleNumber < 10000000) return 7;
    if (simpleNumber < 100000000) return 8;
    if (simpleNumber < 1000000000) return 9;
    if (simpleNumber < 10000000000) return 10;
    if (simpleNumber < 100000000000) return 11;
    if (simpleNumber < 1000000000000) return 12;
    if (simpleNumber < 10000000000000) return 13;
    if (simpleNumber < 100000000000000) return 14;
    if (simpleNumber < 1000000000000000) return 15;
    if (simpleNumber < 10000000000000000) return 16;
    // We're past the point where being off by one on the number of digits
    // will affect the pattern, so now we can use logs.
    return max(1, (log(simpleNumber) / _ln10).ceil());
  }

  int _fractionDigitsAfter(int remainingSignificantDigits) =>
      max(0, remainingSignificantDigits);

  /// Format the basic number portion, including the fractional digits.
  void _formatFixed(dynamic number) {
    dynamic integerPart;
    int fractionPart;
    int extraIntegerDigits;
    var fractionDigits = maximumFractionDigits;

    var power = 0;
    int digitMultiplier;

    if (_isInfinite(number)) {
      integerPart = number.toInt();
      extraIntegerDigits = 0;
      fractionPart = 0;
    } else {
      // We have three possible pieces. First, the basic integer part. If this
      // is a percent or permille, the additional 2 or 3 digits. Finally the
      // fractional part.
      // We avoid multiplying the number because it might overflow if we have
      // a fixed-size integer type, so we extract each of the three as an
      // integer pieces.
      integerPart = _floor(number);
      var fraction = number - integerPart;
      if (fraction.toInt() != 0) {
        // If the fractional part leftover is > 1, presumbly the number
        // was too big for a fixed-size integer, so leave it as whatever
        // it was - the obvious thing is a double.
        integerPart = number;
        fraction = 0;
      }

      /// If we have significant digits, recalculate the number of fraction
      /// digits based on that.
      if (significantDigitsInUse) {
        var integerLength = numberOfIntegerDigits(integerPart);
        var remainingSignificantDigits =
            significantDigits - _multiplierDigits - integerLength;
        fractionDigits = _fractionDigitsAfter(remainingSignificantDigits);
        if (remainingSignificantDigits < 0) {
          // We may have to round.
          var divideBy = pow(10, integerLength - significantDigits);
          integerPart = (integerPart / divideBy).round() * divideBy;
        }
      }
      power = pow(10, fractionDigits);
      digitMultiplier = power * _multiplier;

      // Multiply out to the number of decimal places and the percent, then
      // round. For fixed-size integer types this should always be zero, so
      // multiplying is OK.
      var remainingDigits = _round(fraction * digitMultiplier).toInt();
      // However, in rounding we may overflow into the main digits.
      if (remainingDigits >= digitMultiplier) {
        integerPart++;
        remainingDigits -= digitMultiplier;
      }
      // Separate out the extra integer parts from the fraction part.
      extraIntegerDigits = remainingDigits ~/ power;
      fractionPart = remainingDigits % power;
    }

    var integerDigits = _integerDigits(integerPart, extraIntegerDigits);
    var digitLength = integerDigits.length;
    var fractionPresent =
        fractionDigits > 0 && (minimumFractionDigits > 0 || fractionPart > 0);

    if (_hasIntegerDigits(integerDigits)) {
      // Add the padding digits to the regular digits so that we get grouping.
      var padding = '0' * (minimumIntegerDigits - digitLength);
      integerDigits = '$padding$integerDigits';
      digitLength = integerDigits.length;
      for (var i = 0; i < digitLength; i++) {
        _addDigit(integerDigits.codeUnitAt(i));
        _group(digitLength, i);
      }
    } else if (!fractionPresent) {
      // If neither fraction nor integer part exists, just print zero.
      _addZero();
    }

    _decimalSeparator(fractionPresent);
    _formatFractionPart((fractionPart + power).toString());
  }

  /// Compute the raw integer digits which will then be printed with
  /// grouping and translated to localized digits.
  String _integerDigits(integerPart, extraIntegerDigits) {
    // If the integer part is larger than the maximum integer size
    // (2^52 on Javascript, 2^63 on the VM) it will lose precision,
    // so pad out the rest of it with zeros.
    var paddingDigits = '';
    if (integerPart is num && integerPart > _maxInt) {
      var howManyDigitsTooBig = (log(integerPart) / _ln10).ceil() - _maxDigits;
      num divisor = pow(10, howManyDigitsTooBig).round();
      // pow() produces 0 if the result is too large for a 64-bit int.
      // If that happens, use a floating point divisor instead.
      if (divisor == 0) divisor = pow(10.0, howManyDigitsTooBig);
      paddingDigits = '0' * howManyDigitsTooBig.toInt();
      integerPart = (integerPart / divisor).truncate();
    }

    var extra = extraIntegerDigits == 0 ? '' : extraIntegerDigits.toString();
    var intDigits = _mainIntegerDigits(integerPart);
    var paddedExtra =
        intDigits.isEmpty ? extra : extra.padLeft(_multiplierDigits, '0');
    return '$intDigits$paddedExtra$paddingDigits';
  }

  /// The digit string of the integer part. This is the empty string if the
  /// integer part is zero and otherwise is the toString() of the integer
  /// part, stripping off any minus sign.
  String _mainIntegerDigits(integer) {
    if (integer == 0) return '';
    var digits = integer.toString();
    if (significantDigitsInUse && digits.length > significantDigits) {
      digits = digits.substring(0, significantDigits) +
          ''.padLeft(digits.length - significantDigits, '0');
    }
    // If we have a fixed-length int representation, it can have a negative
    // number whose negation is also negative, e.g. 2^-63 in 64-bit.
    // Remove the minus sign.
    return digits.startsWith('-') ? digits.substring(1) : digits;
  }

  /// Format the part after the decimal place in a fixed point number.
  void _formatFractionPart(String fractionPart) {
    var fractionLength = fractionPart.length;
    while (fractionPart.codeUnitAt(fractionLength - 1) == _zero &&
        fractionLength > minimumFractionDigits + 1) {
      fractionLength--;
    }
    for (var i = 1; i < fractionLength; i++) {
      _addDigit(fractionPart.codeUnitAt(i));
    }
  }

  /// Print the decimal separator if appropriate.
  void _decimalSeparator(bool fractionPresent) {
    if (_decimalSeparatorAlwaysShown || fractionPresent) {
      _add(symbols.DECIMAL_SEP);
    }
  }

  /// Return true if we have a main integer part which is printable, either
  /// because we have digits left of the decimal point (this may include digits
  /// which have been moved left because of percent or permille formatting),
  /// or because the minimum number of printable digits is greater than 1.
  bool _hasIntegerDigits(String digits) =>
      digits.isNotEmpty || minimumIntegerDigits > 0;

  /// A group of methods that provide support for writing digits and other
  /// required characters into [_buffer] easily.
  void _add(String x) {
    _buffer.write(x);
  }

  void _addZero() {
    _buffer.write(symbols.ZERO_DIGIT);
  }

  void _addDigit(int x) {
    _buffer.writeCharCode(x + _zeroOffset);
  }

  void _pad(int numberOfDigits, String basic) {
    if (_zeroOffset == 0) {
      _buffer.write(basic.padLeft(numberOfDigits, '0'));
    } else {
      _slowPad(numberOfDigits, basic);
    }
  }

  /// Print padding up to [numberOfDigits] above what's included in [basic].
  void _slowPad(int numberOfDigits, String basic) {
    for (var i = 0; i < numberOfDigits - basic.length; i++) {
      _add(symbols.ZERO_DIGIT);
    }
    for (var i = 0; i < basic.length; i++) {
      _addDigit(basic.codeUnitAt(i));
    }
  }

  /// We are printing the digits of the number from left to right. We may need
  /// to print a thousands separator or other grouping character as appropriate
  /// to the locale. So we find how many places we are from the end of the number
  /// by subtracting our current [position] from the [totalLength] and printing
  /// the separator character every [_groupingSize] digits, with the final
  /// grouping possibly being of a different size, [_finalGroupingSize].
  void _group(int totalLength, int position) {
    var distanceFromEnd = totalLength - position;
    if (distanceFromEnd <= 1 || _groupingSize <= 0) return;
    if (distanceFromEnd == _finalGroupingSize + 1) {
      _add(symbols.GROUP_SEP);
    } else if ((distanceFromEnd > _finalGroupingSize) &&
        (distanceFromEnd - _finalGroupingSize) % _groupingSize == 1) {
      _add(symbols.GROUP_SEP);
    }
  }

  /// The code point for the character '0'.
  static const _zero = 48;

  /// The code point for the locale's zero digit.
  ///
  ///  Initialized when the locale is set.
  int _localeZero = 0;

  /// The difference between our zero and '0'.
  ///
  /// In other words, a constant _localeZero - _zero. Initialized when
  /// the locale is set.
  int _zeroOffset = 0;

  /// Returns the prefix for [x] based on whether it's positive or negative.
  /// In en_US this would be '' and '-' respectively.
  String _signPrefix(x) => x.isNegative ? _negativePrefix : _positivePrefix;

  /// Returns the suffix for [x] based on wether it's positive or negative.
  /// In en_US there are no suffixes for positive or negative.
  String _signSuffix(x) => x.isNegative ? _negativeSuffix : _positiveSuffix;

  /// Explicitly turn off any grouping (e.g. by thousands) in this format.
  ///
  /// This is used in compact number formatting, where we
  /// omit the normal grouping. Best to know what you're doing if you call it.
  void turnOffGrouping() {
    _groupingSize = 0;
    _finalGroupingSize = 0;
  }

  String toString() => 'NumberFormat($_locale, $_pattern)';
}

///  A one-time object for parsing a particular numeric string. One-time here
/// means an instance can only parse one string. This is implemented by
/// transforming from a locale-specific format to one that the system can parse,
/// then calls the system parsing methods on it.
class _NumberParser {
  /// The format for which we are parsing.
  final NumberFormat format;

  /// The text we are parsing.
  final String text;

  /// What we use to iterate over the input text.
  final IntlStream input;

  /// The result of parsing [text] according to [format]. Automatically
  /// populated in the constructor.
  num value;

  /// The symbols used by our format.
  NumberSymbols get symbols => format.symbols;

  /// Where we accumulate the normalized representation of the number.
  final StringBuffer _normalized = StringBuffer();

  /// Did we see something that indicates this is, or at least might be,
  /// a positive number.
  bool gotPositive = false;

  /// Did we see something that indicates this is, or at least might be,
  /// a negative number.
  bool gotNegative = false;

  /// Did we see the required positive suffix at the end. Should
  /// match [gotPositive].
  bool gotPositiveSuffix = false;

  /// Did we see the required negative suffix at the end. Should
  /// match [gotNegative].
  bool gotNegativeSuffix = false;

  /// Should we stop parsing before hitting the end of the string.
  bool done = false;

  /// Have we already skipped over any required prefixes.
  bool prefixesSkipped = false;

  /// If the number is percent or permill, what do we divide by at the end.
  int scale = 1;

  String get _positivePrefix => format._positivePrefix;
  String get _negativePrefix => format._negativePrefix;
  String get _positiveSuffix => format._positiveSuffix;
  String get _negativeSuffix => format._negativeSuffix;
  int get _zero => NumberFormat._zero;
  int get _localeZero => format._localeZero;

  ///  Create a new [_NumberParser] on which we can call parse().
  _NumberParser(this.format, this.text) : input = IntlStream(text) {
    scale = format._multiplier;
    value = parse();
  }

  ///  The strings we might replace with functions that return the replacement
  /// values. They are functions because we might need to check something
  /// in the context. Note that the ordering is important here. For example,
  /// `symbols.PERCENT` might be " %", and we must handle that before we
  /// look at an individual space.
  Map<String, Function> get replacements =>
      _replacements ??= _initializeReplacements();

  Map<String, Function> _replacements;

  Map<String, Function> _initializeReplacements() => {
        symbols.DECIMAL_SEP: () => '.',
        symbols.EXP_SYMBOL: () => 'E',
        symbols.GROUP_SEP: handleSpace,
        symbols.PERCENT: () {
          scale = _NumberFormatParser._PERCENT_SCALE;
          return '';
        },
        symbols.PERMILL: () {
          scale = _NumberFormatParser._PER_MILLE_SCALE;
          return '';
        },
        ' ': handleSpace,
        '\u00a0': handleSpace,
        '+': () => '+',
        '-': () => '-',
      };

  void invalidFormat() =>
      throw FormatException('Invalid number: ${input.contents}');

  /// Replace a space in the number with the normalized form. If space is not
  /// a significant character (normally grouping) then it's just invalid. If it
  /// is the grouping character, then it's only valid if it's followed by a
  /// digit. e.g. '$12 345.00'
  void handleSpace() =>
      groupingIsNotASpaceOrElseItIsSpaceFollowedByADigit ? '' : invalidFormat();

  /// Determine if a space is a valid character in the number. See
  /// [handleSpace].
  bool get groupingIsNotASpaceOrElseItIsSpaceFollowedByADigit {
    if (symbols.GROUP_SEP != '\u00a0' || symbols.GROUP_SEP != ' ') return true;
    var peeked = input.peek(symbols.GROUP_SEP.length + 1);
    return asDigit(peeked[peeked.length - 1]) != null;
  }

  /// Turn [char] into a number representing a digit, or null if it doesn't
  /// represent a digit in this locale.
  int asDigit(String char) {
    var charCode = char.codeUnitAt(0);
    var digitValue = charCode - _localeZero;
    if (digitValue >= 0 && digitValue < 10) {
      return digitValue;
    } else {
      return null;
    }
  }

  /// Check to see if the input begins with either the positive or negative
  /// prefixes. Set the [gotPositive] and [gotNegative] variables accordingly.
  void checkPrefixes({bool skip = false}) {
    bool checkPrefix(String prefix) =>
        prefix.isNotEmpty && input.startsWith(prefix);

    // TODO(alanknight): There's a faint possibility of a bug here where
    // a positive prefix is followed by a negative prefix that's also a valid
    // part of the number, but that seems very unlikely.
    if (checkPrefix(_positivePrefix)) gotPositive = true;
    if (checkPrefix(_negativePrefix)) gotNegative = true;

    // The positive prefix might be a substring of the negative, in
    // which case both would match.
    if (gotPositive && gotNegative) {
      if (_positivePrefix.length > _negativePrefix.length) {
        gotNegative = false;
      } else if (_negativePrefix.length > _positivePrefix.length) {
        gotPositive = false;
      }
    }
    if (skip) {
      if (gotPositive) input.read(_positivePrefix.length);
      if (gotNegative) input.read(_negativePrefix.length);
    }
  }

  /// If the rest of our input is either the positive or negative suffix,
  /// set [gotPositiveSuffix] or [gotNegativeSuffix] accordingly.
  void checkSuffixes() {
    var remainder = input.rest();
    if (remainder == _positiveSuffix) gotPositiveSuffix = true;
    if (remainder == _negativeSuffix) gotNegativeSuffix = true;
  }

  /// We've encountered a character that's not a digit. Go through our
  /// replacement rules looking for how to handle it. If we see something
  /// that's not a digit and doesn't have a replacement, then we're done
  /// and the number is probably invalid.
  void processNonDigit() {
    // It might just be a prefix that we haven't skipped. We don't want to
    // skip them initially because they might also be semantically meaningful,
    // e.g. leading %. So we allow them through the loop, but only once.
    var foundAnInterpretation = false;
    if (input.index == 0 && !prefixesSkipped) {
      prefixesSkipped = true;
      checkPrefixes(skip: true);
      foundAnInterpretation = true;
    }

    for (var key in replacements.keys) {
      if (input.startsWith(key)) {
        _normalized.write(replacements[key]());
        input.read(key.length);
        return;
      }
    }
    // We haven't found either of these things, this seems invalid.
    if (!foundAnInterpretation) {
      done = true;
    }
  }

  /// Parse [text] and return the resulting number. Throws [FormatException]
  /// if we can't parse it.
  num parse() {
    if (text == symbols.NAN) return 0.0 / 0.0;
    if (text == '$_positivePrefix${symbols.INFINITY}$_positiveSuffix') {
      return 1.0 / 0.0;
    }
    if (text == '$_negativePrefix${symbols.INFINITY}$_negativeSuffix') {
      return -1.0 / 0.0;
    }

    checkPrefixes();
    var parsed = parseNumber(input);

    if (gotPositive && !gotPositiveSuffix) invalidNumber();
    if (gotNegative && !gotNegativeSuffix) invalidNumber();
    if (!input.atEnd()) invalidNumber();

    return parsed;
  }

  /// The number is invalid, throw a [FormatException].
  void invalidNumber() =>
      throw FormatException('Invalid Number: ${input.contents}');

  /// Parse the number portion of the input, i.e. not any prefixes or suffixes,
  /// and assuming NaN and Infinity are already handled.
  num parseNumber(IntlStream input) {
    if (gotNegative) {
      _normalized.write('-');
    }
    while (!done && !input.atEnd()) {
      var digit = asDigit(input.peek());
      if (digit != null) {
        _normalized.writeCharCode(_zero + digit);
        input.next();
      } else {
        processNonDigit();
      }
      checkSuffixes();
    }

    var normalizedText = _normalized.toString();
    num parsed = int.tryParse(normalizedText);
    parsed ??= double.parse(normalizedText);
    return parsed / scale;
  }
}

/// Output of [_NumberFormatParser.parse].
///
/// Everything needed to initialize a [NumberFormat].
class _NumberFormatParseResult {
  String negativePrefix;
  String positivePrefix = '';
  String negativeSuffix = '';
  String positiveSuffix = '';

  int multiplier = 1;
  int get multiplierDigits => (log(multiplier) / _ln10).round();

  int minimumExponentDigits = 0;

  int maximumIntegerDigits = 40;
  int minimumIntegerDigits = 1;
  int maximumFractionDigits = 3;
  int minimumFractionDigits = 0;

  int groupingSize = 3;
  int finalGroupingSize = 3;

  bool decimalSeparatorAlwaysShown = false;
  bool useSignForPositiveExponent = false;
  bool useExponentialNotation = false;

  int decimalDigits;

  // [decimalDigits] is both input and output of parsing.
  _NumberFormatParseResult(NumberSymbols symbols, this.decimalDigits) {
    negativePrefix = symbols.MINUS_SIGN;
  }
}

/// Private class that parses the numeric formatting pattern and sets the
/// variables in [format] to appropriate values. Instances of this are
/// transient and store parsing state in instance variables, so can only be used
/// to parse a single pattern.
class _NumberFormatParser {
  /// The special characters in the pattern language. All others are treated
  /// as literals.
  static const _PATTERN_SEPARATOR = ';';
  static const _QUOTE = "'";
  static const _PATTERN_DIGIT = '#';
  static const _PATTERN_ZERO_DIGIT = '0';
  static const _PATTERN_GROUPING_SEPARATOR = ',';
  static const _PATTERN_DECIMAL_SEPARATOR = '.';
  static const _PATTERN_CURRENCY_SIGN = '\u00A4';
  static const _PATTERN_PER_MILLE = '\u2030';
  static const _PER_MILLE_SCALE = 1000;
  static const _PATTERN_PERCENT = '%';
  static const _PERCENT_SCALE = 100;
  static const _PATTERN_EXPONENT = 'E';
  static const _PATTERN_PLUS = '+';

  /// The format whose state we are setting.
  final NumberSymbols symbols;

  /// The pattern we are parsing.
  final _StringIterator pattern;

  /// Whether this is a currency.
  final bool isForCurrency;

  /// We can be passed a specific currency symbol, regardless of the locale.
  final String currencySymbol;

  final String currencyName;

  // The result being constructed.
  final _NumberFormatParseResult result;

  bool groupingSizeSetExplicitly = false;

  /// Create a new [_NumberFormatParser] for a particular [NumberFormat] and
  /// [input] pattern.
  ///
  /// [decimalDigits] is optional, if specified it overrides the default.
  _NumberFormatParser(this.symbols, String input, this.isForCurrency,
      this.currencySymbol, this.currencyName, int decimalDigits)
      : result = _NumberFormatParseResult(symbols, decimalDigits),
        pattern = _iterator(input) {
    pattern.moveNext();
  }

  static _NumberFormatParseResult parse(
          NumberSymbols symbols,
          String input,
          bool isForCurrency,
          String currencySymbol,
          String currencyName,
          int decimalDigits) =>
      input == null
          ? _NumberFormatParseResult(symbols, decimalDigits)
          : (_NumberFormatParser(symbols, input, isForCurrency, currencySymbol,
                  currencyName, decimalDigits)
                .._parse())
              .result;

  /// For currencies, the default number of decimal places to use in
  /// formatting. Defaults to two for non-currencies or currencies where it's
  /// not specified.
  int get _defaultDecimalDigits =>
      currencyFractionDigits[currencyName.toUpperCase()] ??
      currencyFractionDigits['DEFAULT'];

  /// Parse the input pattern and update [result].
  void _parse() {
    result.positivePrefix = _parseAffix();
    var trunk = _parseTrunk();
    result.positiveSuffix = _parseAffix();
    // If we have separate positive and negative patterns, now parse the
    // the negative version.
    if (pattern.current == _NumberFormatParser._PATTERN_SEPARATOR) {
      pattern.moveNext();
      result.negativePrefix = _parseAffix();
      // Skip over the negative trunk, verifying that it's identical to the
      // positive trunk.
      for (var each in _iterable(trunk)) {
        if (pattern.current != each && pattern.current != null) {
          throw FormatException(
              'Positive and negative trunks must be the same', trunk);
        }
        pattern.moveNext();
      }
      result.negativeSuffix = _parseAffix();
    } else {
      // If no negative affix is specified, they share the same positive affix.
      result.negativePrefix = result.negativePrefix + result.positivePrefix;
      result.negativeSuffix = result.positiveSuffix + result.negativeSuffix;
    }

    if (isForCurrency) {
      result.decimalDigits ??= _defaultDecimalDigits;
    }
    if (result.decimalDigits != null) {
      result.minimumFractionDigits = result.decimalDigits;
      result.maximumFractionDigits = result.decimalDigits;
    }
  }

  /// Variable used in parsing prefixes and suffixes to keep track of
  /// whether or not we are in a quoted region.
  bool inQuote = false;

  /// Parse a prefix or suffix and return the prefix/suffix string. Note that
  /// this also may modify the state of [format].
  String _parseAffix() {
    var affix = StringBuffer();
    inQuote = false;
    while (parseCharacterAffix(affix) && pattern.moveNext()) {}
    return affix.toString();
  }

  /// Parse an individual character as part of a prefix or suffix.  Return true
  /// if we should continue to look for more affix characters, and false if
  /// we have reached the end.
  bool parseCharacterAffix(StringBuffer affix) {
    var ch = pattern.current;
    if (ch == null) return false;
    if (ch == _QUOTE) {
      if (pattern.peek == _QUOTE) {
        pattern.moveNext();
        affix.write(_QUOTE); // 'don''t'
      } else {
        inQuote = !inQuote;
      }
      return true;
    }

    if (inQuote) {
      affix.write(ch);
    } else {
      switch (ch) {
        case _PATTERN_DIGIT:
        case _PATTERN_ZERO_DIGIT:
        case _PATTERN_GROUPING_SEPARATOR:
        case _PATTERN_DECIMAL_SEPARATOR:
        case _PATTERN_SEPARATOR:
          return false;
        case _PATTERN_CURRENCY_SIGN:
          // TODO(alanknight): Handle the local/global/portable currency signs
          affix.write(currencySymbol);
          break;
        case _PATTERN_PERCENT:
          if (result.multiplier != 1 && result.multiplier != _PERCENT_SCALE) {
            throw const FormatException('Too many percent/permill');
          }
          result.multiplier = _PERCENT_SCALE;
          affix.write(symbols.PERCENT);
          break;
        case _PATTERN_PER_MILLE:
          if (result.multiplier != 1 && result.multiplier != _PER_MILLE_SCALE) {
            throw const FormatException('Too many percent/permill');
          }
          result.multiplier = _PER_MILLE_SCALE;
          affix.write(symbols.PERMILL);
          break;
        default:
          affix.write(ch);
      }
    }
    return true;
  }

  /// Variables used in [_parseTrunk] and [parseTrunkCharacter].
  var decimalPos = -1;
  var digitLeftCount = 0;
  var zeroDigitCount = 0;
  var digitRightCount = 0;
  var groupingCount = -1;

  /// Parse the "trunk" portion of the pattern, the piece that doesn't include
  /// positive or negative prefixes or suffixes.
  String _parseTrunk() {
    var loop = true;
    var trunk = StringBuffer();
    while (pattern.current != null && loop) {
      loop = parseTrunkCharacter(trunk);
    }

    if (zeroDigitCount == 0 && digitLeftCount > 0 && decimalPos >= 0) {
      // Handle '###.###' and '###.' and '.###'
      // Handle '.###'
      var n = decimalPos == 0 ? 1 : decimalPos;
      digitRightCount = digitLeftCount - n;
      digitLeftCount = n - 1;
      zeroDigitCount = 1;
    }

    // Do syntax checking on the digits.
    if (decimalPos < 0 && digitRightCount > 0 ||
        decimalPos >= 0 &&
            (decimalPos < digitLeftCount ||
                decimalPos > digitLeftCount + zeroDigitCount) ||
        groupingCount == 0) {
      throw FormatException('Malformed pattern "${pattern.input}"');
    }
    var totalDigits = digitLeftCount + zeroDigitCount + digitRightCount;

    result.maximumFractionDigits =
        decimalPos >= 0 ? totalDigits - decimalPos : 0;
    if (decimalPos >= 0) {
      result.minimumFractionDigits =
          digitLeftCount + zeroDigitCount - decimalPos;
      if (result.minimumFractionDigits < 0) {
        result.minimumFractionDigits = 0;
      }
    }

    // The effectiveDecimalPos is the position the decimal is at or would be at
    // if there is no decimal. Note that if decimalPos<0, then digitTotalCount
    // == digitLeftCount + zeroDigitCount.
    var effectiveDecimalPos = decimalPos >= 0 ? decimalPos : totalDigits;
    result.minimumIntegerDigits = effectiveDecimalPos - digitLeftCount;
    if (result.useExponentialNotation) {
      result.maximumIntegerDigits =
          digitLeftCount + result.minimumIntegerDigits;

      // In exponential display, we need to at least show something.
      if (result.maximumFractionDigits == 0 &&
          result.minimumIntegerDigits == 0) {
        result.minimumIntegerDigits = 1;
      }
    }

    result.finalGroupingSize = max(0, groupingCount);
    if (!groupingSizeSetExplicitly) {
      result.groupingSize = result.finalGroupingSize;
    }
    result.decimalSeparatorAlwaysShown =
        decimalPos == 0 || decimalPos == totalDigits;

    return trunk.toString();
  }

  /// Parse an individual character of the trunk. Return true if we should
  /// continue to look for additional trunk characters or false if we have
  /// reached the end.
  bool parseTrunkCharacter(trunk) {
    var ch = pattern.current;
    switch (ch) {
      case _PATTERN_DIGIT:
        if (zeroDigitCount > 0) {
          digitRightCount++;
        } else {
          digitLeftCount++;
        }
        if (groupingCount >= 0 && decimalPos < 0) {
          groupingCount++;
        }
        break;
      case _PATTERN_ZERO_DIGIT:
        if (digitRightCount > 0) {
          throw FormatException('Unexpected "0" in pattern "${pattern.input}');
        }
        zeroDigitCount++;
        if (groupingCount >= 0 && decimalPos < 0) {
          groupingCount++;
        }
        break;
      case _PATTERN_GROUPING_SEPARATOR:
        if (groupingCount > 0) {
          groupingSizeSetExplicitly = true;
          result.groupingSize = groupingCount;
        }
        groupingCount = 0;
        break;
      case _PATTERN_DECIMAL_SEPARATOR:
        if (decimalPos >= 0) {
          throw FormatException(
              'Multiple decimal separators in pattern "$pattern"');
        }
        decimalPos = digitLeftCount + zeroDigitCount + digitRightCount;
        break;
      case _PATTERN_EXPONENT:
        trunk.write(ch);
        if (result.useExponentialNotation) {
          throw FormatException(
              'Multiple exponential symbols in pattern "$pattern"');
        }
        result.useExponentialNotation = true;
        result.minimumExponentDigits = 0;

        // exponent pattern can have a optional '+'.
        pattern.moveNext();
        var nextChar = pattern.current;
        if (nextChar == _PATTERN_PLUS) {
          trunk.write(pattern.current);
          pattern.moveNext();
          result.useSignForPositiveExponent = true;
        }

        // Use lookahead to parse out the exponential part
        // of the pattern, then jump into phase 2.
        while (pattern.current == _PATTERN_ZERO_DIGIT) {
          trunk.write(pattern.current);
          pattern.moveNext();
          result.minimumExponentDigits++;
        }

        if ((digitLeftCount + zeroDigitCount) < 1 ||
            result.minimumExponentDigits < 1) {
          throw FormatException('Malformed exponential pattern "$pattern"');
        }
        return false;
      default:
        return false;
    }
    trunk.write(ch);
    pattern.moveNext();
    return true;
  }
}

/// Returns an [Iterable] on the string as a list of substrings.
Iterable<String> _iterable(String s) => _StringIterable(s);

/// Return an iterator on the string as a list of substrings.
Iterator<String> _iterator(String s) => _StringIterator(s);

// TODO(nweiz): remove this when issue 3780 is fixed.
/// Provides an Iterable that wraps [_iterator] so it can be used in a `for`
/// loop.
class _StringIterable extends IterableBase<String> {
  final Iterator<String> iterator;

  _StringIterable(String s) : iterator = _iterator(s);
}

/// Provides an iterator over a string as a list of substrings, and also
/// gives us a lookahead of one via the [peek] method.
class _StringIterator implements Iterator<String> {
  final String input;
  int nextIndex = 0;
  String _current;

  _StringIterator(input) : input = _validate(input);

  String get current => _current;

  bool moveNext() {
    if (nextIndex >= input.length) {
      _current = null;
      return false;
    }
    _current = input[nextIndex++];
    return true;
  }

  String get peek => nextIndex >= input.length ? null : input[nextIndex];

  Iterator<String> get iterator => this;

  static String _validate(input) {
    if (input is! String) throw ArgumentError(input);
    return input;
  }
}

/// Used primarily for currency formatting, this number-like class stores
/// millionths of a currency unit, typically as an Int64.
///
/// It supports no operations other than being used for Intl number formatting.
abstract class MicroMoney {
  factory MicroMoney(micros) => _MicroMoney(micros);
}

/// Used primarily for currency formatting, this stores millionths of a
/// currency unit, typically as an Int64.
///
/// This private class provides the operations needed by the formatting code.
class _MicroMoney implements MicroMoney {
  final dynamic _micros;
  _MicroMoney(this._micros);
  static const _multiplier = 1000000;

  dynamic get _integerPart => _micros ~/ _multiplier;
  int get _fractionPart => (this - _integerPart)._micros.toInt().abs();

  bool get isNegative => _micros.isNegative;

  _MicroMoney abs() => isNegative ? _MicroMoney(_micros.abs()) : this;

  // Note that if this is done in a general way there's a risk of integer
  // overflow on JS when multiplying out the [other] parameter, which may be
  // an Int64. In formatting we only ever subtract out our own integer part.
  _MicroMoney operator -(other) {
    if (other is _MicroMoney) return _MicroMoney(_micros - other._micros);
    return _MicroMoney(_micros - (other * _multiplier));
  }

  _MicroMoney operator +(other) {
    if (other is _MicroMoney) return _MicroMoney(_micros + other._micros);
    return _MicroMoney(_micros + (other * _multiplier));
  }

  _MicroMoney operator ~/(divisor) {
    if (divisor is! int) {
      throw ArgumentError.value(
          divisor, 'divisor', '_MicroMoney ~/ only supports int arguments.');
    }
    return _MicroMoney((_integerPart ~/ divisor) * _multiplier);
  }

  _MicroMoney operator *(other) {
    if (other is! int) {
      throw ArgumentError.value(
          other, 'other', '_MicroMoney * only supports int arguments.');
    }
    return _MicroMoney(
        (_integerPart * other) * _multiplier + (_fractionPart * other));
  }

  /// Note that this only really supports remainder from an int,
  /// not division by another MicroMoney
  _MicroMoney remainder(other) {
    if (other is! int) {
      throw ArgumentError.value(
          other, 'other', '_MicroMoney.remainder only supports int arguments.');
    }
    return _MicroMoney(_micros.remainder(other * _multiplier));
  }

  double toDouble() => _micros.toDouble() / _multiplier;

  int toInt() => _integerPart.toInt();

  String toString() {
    var beforeDecimal = '$_integerPart';
    var decimalPart = '';
    var fractionPart = _fractionPart;
    if (fractionPart != 0) {
      decimalPart = '.$fractionPart';
    }
    return '$beforeDecimal$decimalPart';
  }
}

final _ln10 = log(10);
