// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/strings/internal/charconv_parse.h"

#include <cassert>
#include <cstddef>
#include <cstdint>
#include <limits>

#include "absl/strings/charconv.h"
#include "absl/strings/internal/memutil.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace {

// ParseFloat<10> will read the first 19 significant digits of the mantissa.
// This number was chosen for multiple reasons.
//
// (a) First, for whatever integer type we choose to represent the mantissa, we
// want to choose the largest possible number of decimal digits for that integer
// type.  We are using uint64_t, which can express any 19-digit unsigned
// integer.
//
// (b) Second, we need to parse enough digits that the binary value of any
// mantissa we capture has more bits of resolution than the mantissa
// representation in the target float.  Our algorithm requires at least 3 bits
// of headway, but 19 decimal digits give a little more than that.
//
// The following static assertions verify the above comments:
constexpr int kDecimalMantissaDigitsMax = 19;

static_assert(std::numeric_limits<uint64_t>::digits10 ==
                  kDecimalMantissaDigitsMax,
              "(a) above");

// IEEE doubles, which we assume in Abseil, have 53 binary bits of mantissa.
static_assert(std::numeric_limits<double>::is_iec559, "IEEE double assumed");
static_assert(std::numeric_limits<double>::radix == 2, "IEEE double fact");
static_assert(std::numeric_limits<double>::digits == 53, "IEEE double fact");

// The lowest valued 19-digit decimal mantissa we can read still contains
// sufficient information to reconstruct a binary mantissa.
static_assert(1000000000000000000u > (uint64_t{1} << (53 + 3)), "(b) above");

// ParseFloat<16> will read the first 15 significant digits of the mantissa.
//
// Because a base-16-to-base-2 conversion can be done exactly, we do not need
// to maximize the number of scanned hex digits to improve our conversion.  What
// is required is to scan two more bits than the mantissa can represent, so that
// we always round correctly.
//
// (One extra bit does not suffice to perform correct rounding, since a number
// exactly halfway between two representable floats has unique rounding rules,
// so we need to differentiate between a "halfway between" number and a "closer
// to the larger value" number.)
constexpr int kHexadecimalMantissaDigitsMax = 15;

// The minimum number of significant bits that will be read from
// kHexadecimalMantissaDigitsMax hex digits.  We must subtract by three, since
// the most significant digit can be a "1", which only contributes a single
// significant bit.
constexpr int kGuaranteedHexadecimalMantissaBitPrecision =
    4 * kHexadecimalMantissaDigitsMax - 3;

static_assert(kGuaranteedHexadecimalMantissaBitPrecision >
                  std::numeric_limits<double>::digits + 2,
              "kHexadecimalMantissaDigitsMax too small");

// We also impose a limit on the number of significant digits we will read from
// an exponent, to avoid having to deal with integer overflow.  We use 9 for
// this purpose.
//
// If we read a 9 digit exponent, the end result of the conversion will
// necessarily be infinity or zero, depending on the sign of the exponent.
// Therefore we can just drop extra digits on the floor without any extra
// logic.
constexpr int kDecimalExponentDigitsMax = 9;
static_assert(std::numeric_limits<int>::digits10 >= kDecimalExponentDigitsMax,
              "int type too small");

// To avoid incredibly large inputs causing integer overflow for our exponent,
// we impose an arbitrary but very large limit on the number of significant
// digits we will accept.  The implementation refuses to match a string with
// more consecutive significant mantissa digits than this.
constexpr int kDecimalDigitLimit = 50000000;

// Corresponding limit for hexadecimal digit inputs.  This is one fourth the
// amount of kDecimalDigitLimit, since each dropped hexadecimal digit requires
// a binary exponent adjustment of 4.
constexpr int kHexadecimalDigitLimit = kDecimalDigitLimit / 4;

// The largest exponent we can read is 999999999 (per
// kDecimalExponentDigitsMax), and the largest exponent adjustment we can get
// from dropped mantissa digits is 2 * kDecimalDigitLimit, and the sum of these
// comfortably fits in an integer.
//
// We count kDecimalDigitLimit twice because there are independent limits for
// numbers before and after the decimal point.  (In the case where there are no
// significant digits before the decimal point, there are independent limits for
// post-decimal-point leading zeroes and for significant digits.)
static_assert(999999999 + 2 * kDecimalDigitLimit <
                  std::numeric_limits<int>::max(),
              "int type too small");
static_assert(999999999 + 2 * (4 * kHexadecimalDigitLimit) <
                  std::numeric_limits<int>::max(),
              "int type too small");

// Returns true if the provided bitfield allows parsing an exponent value
// (e.g., "1.5e100").
bool AllowExponent(chars_format flags) {
  bool fixed = (flags & chars_format::fixed) == chars_format::fixed;
  bool scientific =
      (flags & chars_format::scientific) == chars_format::scientific;
  return scientific || !fixed;
}

// Returns true if the provided bitfield requires an exponent value be present.
bool RequireExponent(chars_format flags) {
  bool fixed = (flags & chars_format::fixed) == chars_format::fixed;
  bool scientific =
      (flags & chars_format::scientific) == chars_format::scientific;
  return scientific && !fixed;
}

const int8_t kAsciiToInt[256] = {
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0,  1,  2,  3,  4,  5,  6,  7,  8,
    9,  -1, -1, -1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    -1, -1, -1, -1, -1, -1, -1, -1, -1};

// Returns true if `ch` is a digit in the given base
template <int base>
bool IsDigit(char ch);

// Converts a valid `ch` to its digit value in the given base.
template <int base>
unsigned ToDigit(char ch);

// Returns true if `ch` is the exponent delimiter for the given base.
template <int base>
bool IsExponentCharacter(char ch);

// Returns the maximum number of significant digits we will read for a float
// in the given base.
template <int base>
constexpr int MantissaDigitsMax();

// Returns the largest consecutive run of digits we will accept when parsing a
// number in the given base.
template <int base>
constexpr int DigitLimit();

// Returns the amount the exponent must be adjusted by for each dropped digit.
// (For decimal this is 1, since the digits are in base 10 and the exponent base
// is also 10, but for hexadecimal this is 4, since the digits are base 16 but
// the exponent base is 2.)
template <int base>
constexpr int DigitMagnitude();

template <>
bool IsDigit<10>(char ch) {
  return ch >= '0' && ch <= '9';
}
template <>
bool IsDigit<16>(char ch) {
  return kAsciiToInt[static_cast<unsigned char>(ch)] >= 0;
}

template <>
unsigned ToDigit<10>(char ch) {
  return static_cast<unsigned>(ch - '0');
}
template <>
unsigned ToDigit<16>(char ch) {
  return static_cast<unsigned>(kAsciiToInt[static_cast<unsigned char>(ch)]);
}

template <>
bool IsExponentCharacter<10>(char ch) {
  return ch == 'e' || ch == 'E';
}

template <>
bool IsExponentCharacter<16>(char ch) {
  return ch == 'p' || ch == 'P';
}

template <>
constexpr int MantissaDigitsMax<10>() {
  return kDecimalMantissaDigitsMax;
}
template <>
constexpr int MantissaDigitsMax<16>() {
  return kHexadecimalMantissaDigitsMax;
}

template <>
constexpr int DigitLimit<10>() {
  return kDecimalDigitLimit;
}
template <>
constexpr int DigitLimit<16>() {
  return kHexadecimalDigitLimit;
}

template <>
constexpr int DigitMagnitude<10>() {
  return 1;
}
template <>
constexpr int DigitMagnitude<16>() {
  return 4;
}

// Reads decimal digits from [begin, end) into *out.  Returns the number of
// digits consumed.
//
// After max_digits has been read, keeps consuming characters, but no longer
// adjusts *out.  If a nonzero digit is dropped this way, *dropped_nonzero_digit
// is set; otherwise, it is left unmodified.
//
// If no digits are matched, returns 0 and leaves *out unchanged.
//
// ConsumeDigits does not protect against overflow on *out; max_digits must
// be chosen with respect to type T to avoid the possibility of overflow.
template <int base, typename T>
ptrdiff_t ConsumeDigits(const char* begin, const char* end,
                        ptrdiff_t max_digits, T* out,
                        bool* dropped_nonzero_digit) {
  if (base == 10) {
    assert(max_digits <= std::numeric_limits<T>::digits10);
  } else if (base == 16) {
    assert(max_digits * 4 <= std::numeric_limits<T>::digits);
  }
  const char* const original_begin = begin;

  // Skip leading zeros, but only if *out is zero.
  // They don't cause an overflow so we don't have to count them for
  // `max_digits`.
  while (!*out && end != begin && *begin == '0') ++begin;

  T accumulator = *out;
  const char* significant_digits_end =
      (end - begin > max_digits) ? begin + max_digits : end;
  while (begin < significant_digits_end && IsDigit<base>(*begin)) {
    // Do not guard against *out overflow; max_digits was chosen to avoid this.
    // Do assert against it, to detect problems in debug builds.
    auto digit = static_cast<T>(ToDigit<base>(*begin));
    assert(accumulator * base >= accumulator);
    accumulator *= base;
    assert(accumulator + digit >= accumulator);
    accumulator += digit;
    ++begin;
  }
  bool dropped_nonzero = false;
  while (begin < end && IsDigit<base>(*begin)) {
    dropped_nonzero = dropped_nonzero || (*begin != '0');
    ++begin;
  }
  if (dropped_nonzero && dropped_nonzero_digit != nullptr) {
    *dropped_nonzero_digit = true;
  }
  *out = accumulator;
  return begin - original_begin;
}

// Returns true if `v` is one of the chars allowed inside parentheses following
// a NaN.
bool IsNanChar(char v) {
  return (v == '_') || (v >= '0' && v <= '9') || (v >= 'a' && v <= 'z') ||
         (v >= 'A' && v <= 'Z');
}

// Checks the range [begin, end) for a strtod()-formatted infinity or NaN.  If
// one is found, sets `out` appropriately and returns true.
bool ParseInfinityOrNan(const char* begin, const char* end,
                        strings_internal::ParsedFloat* out) {
  if (end - begin < 3) {
    return false;
  }
  switch (*begin) {
    case 'i':
    case 'I': {
      // An infinity string consists of the characters "inf" or "infinity",
      // case insensitive.
      if (strings_internal::memcasecmp(begin + 1, "nf", 2) != 0) {
        return false;
      }
      out->type = strings_internal::FloatType::kInfinity;
      if (end - begin >= 8 &&
          strings_internal::memcasecmp(begin + 3, "inity", 5) == 0) {
        out->end = begin + 8;
      } else {
        out->end = begin + 3;
      }
      return true;
    }
    case 'n':
    case 'N': {
      // A NaN consists of the characters "nan", case insensitive, optionally
      // followed by a parenthesized sequence of zero or more alphanumeric
      // characters and/or underscores.
      if (strings_internal::memcasecmp(begin + 1, "an", 2) != 0) {
        return false;
      }
      out->type = strings_internal::FloatType::kNan;
      out->end = begin + 3;
      // NaN is allowed to be followed by a parenthesized string, consisting of
      // only the characters [a-zA-Z0-9_].  Match that if it's present.
      begin += 3;
      if (begin < end && *begin == '(') {
        const char* nan_begin = begin + 1;
        while (nan_begin < end && IsNanChar(*nan_begin)) {
          ++nan_begin;
        }
        if (nan_begin < end && *nan_begin == ')') {
          // We found an extra NaN specifier range
          out->subrange_begin = begin + 1;
          out->subrange_end = nan_begin;
          out->end = nan_begin + 1;
        }
      }
      return true;
    }
    default:
      return false;
  }
}
}  // namespace

namespace strings_internal {

template <int base>
strings_internal::ParsedFloat ParseFloat(const char* begin, const char* end,
                                         chars_format format_flags) {
  strings_internal::ParsedFloat result;

  // Exit early if we're given an empty range.
  if (begin == end) return result;

  // Handle the infinity and NaN cases.
  if (ParseInfinityOrNan(begin, end, &result)) {
    return result;
  }

  const char* const mantissa_begin = begin;
  while (begin < end && *begin == '0') {
    ++begin;  // skip leading zeros
  }
  uint64_t mantissa = 0;

  ptrdiff_t exponent_adjustment = 0;
  bool mantissa_is_inexact = false;
  ptrdiff_t pre_decimal_digits = ConsumeDigits<base>(
      begin, end, MantissaDigitsMax<base>(), &mantissa, &mantissa_is_inexact);
  begin += pre_decimal_digits;
  ptrdiff_t digits_left;
  if (pre_decimal_digits >= DigitLimit<base>()) {
    // refuse to parse pathological inputs
    return result;
  } else if (pre_decimal_digits > MantissaDigitsMax<base>()) {
    // We dropped some non-fraction digits on the floor.  Adjust our exponent
    // to compensate.
    exponent_adjustment = pre_decimal_digits - MantissaDigitsMax<base>();
    digits_left = 0;
  } else {
    digits_left = MantissaDigitsMax<base>() - pre_decimal_digits;
  }
  if (begin < end && *begin == '.') {
    ++begin;
    if (mantissa == 0) {
      // If we haven't seen any nonzero digits yet, keep skipping zeros.  We
      // have to adjust the exponent to reflect the changed place value.
      const char* begin_zeros = begin;
      while (begin < end && *begin == '0') {
        ++begin;
      }
      ptrdiff_t zeros_skipped = begin - begin_zeros;
      if (zeros_skipped >= DigitLimit<base>()) {
        // refuse to parse pathological inputs
        return result;
      }
      exponent_adjustment -= zeros_skipped;
    }
    ptrdiff_t post_decimal_digits = ConsumeDigits<base>(
        begin, end, digits_left, &mantissa, &mantissa_is_inexact);
    begin += post_decimal_digits;

    // Since `mantissa` is an integer, each significant digit we read after
    // the decimal point requires an adjustment to the exponent. "1.23e0" will
    // be stored as `mantissa` == 123 and `exponent` == -2 (that is,
    // "123e-2").
    if (post_decimal_digits >= DigitLimit<base>()) {
      // refuse to parse pathological inputs
      return result;
    } else if (post_decimal_digits > digits_left) {
      exponent_adjustment -= digits_left;
    } else {
      exponent_adjustment -= post_decimal_digits;
    }
  }
  // If we've found no mantissa whatsoever, this isn't a number.
  if (mantissa_begin == begin) {
    return result;
  }
  // A bare "." doesn't count as a mantissa either.
  if (begin - mantissa_begin == 1 && *mantissa_begin == '.') {
    return result;
  }

  if (mantissa_is_inexact) {
    // We dropped significant digits on the floor.  Handle this appropriately.
    if (base == 10) {
      // If we truncated significant decimal digits, store the full range of the
      // mantissa for future big integer math for exact rounding.
      result.subrange_begin = mantissa_begin;
      result.subrange_end = begin;
    } else if (base == 16) {
      // If we truncated hex digits, reflect this fact by setting the low
      // ("sticky") bit.  This allows for correct rounding in all cases.
      mantissa |= 1;
    }
  }
  result.mantissa = mantissa;

  const char* const exponent_begin = begin;
  result.literal_exponent = 0;
  bool found_exponent = false;
  if (AllowExponent(format_flags) && begin < end &&
      IsExponentCharacter<base>(*begin)) {
    bool negative_exponent = false;
    ++begin;
    if (begin < end && *begin == '-') {
      negative_exponent = true;
      ++begin;
    } else if (begin < end && *begin == '+') {
      ++begin;
    }
    const char* const exponent_digits_begin = begin;
    // Exponent is always expressed in decimal, even for hexadecimal floats.
    begin += ConsumeDigits<10>(begin, end, kDecimalExponentDigitsMax,
                               &result.literal_exponent, nullptr);
    if (begin == exponent_digits_begin) {
      // there were no digits where we expected an exponent.  We failed to read
      // an exponent and should not consume the 'e' after all.  Rewind 'begin'.
      found_exponent = false;
      begin = exponent_begin;
    } else {
      found_exponent = true;
      if (negative_exponent) {
        result.literal_exponent = -result.literal_exponent;
      }
    }
  }

  if (!found_exponent && RequireExponent(format_flags)) {
    // Provided flags required an exponent, but none was found.  This results
    // in a failure to scan.
    return result;
  }

  if (result.mantissa > 0) {
    const ptrdiff_t exponent = result.literal_exponent +
                               (DigitMagnitude<base>() * exponent_adjustment);

    if (exponent < (std::numeric_limits<int>::min)() ||
        exponent > (std::numeric_limits<int>::max)()) {
      // We cannot store the exponent in int. Fail by returning a result with
      // end default-initialized to nullptr.
      return result;
    }

    result.exponent = static_cast<int>(exponent);
  } else {
    result.exponent = 0;
  }
  result.end = begin;

  // Success!
  result.type = strings_internal::FloatType::kNumber;

  return result;
}

template ParsedFloat ParseFloat<10>(const char* begin, const char* end,
                                    chars_format format_flags);
template ParsedFloat ParseFloat<16>(const char* begin, const char* end,
                                    chars_format format_flags);

}  // namespace strings_internal
ABSL_NAMESPACE_END
}  // namespace absl
