// Copyright 2019 Google LLC
//
// 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.

// This header contains functionality related to Emboss text output.
#ifndef EMBOSS_RUNTIME_CPP_EMBOSS_TEXT_UTIL_H_
#define EMBOSS_RUNTIME_CPP_EMBOSS_TEXT_UTIL_H_

#include <array>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <limits>
#include <sstream>
#include <string>
#include <vector>

#include "runtime/cpp/emboss_defines.h"

namespace emboss {

// TextOutputOptions are used to configure text output.  Typically, one can just
// use a default TextOutputOptions() (for compact output) or MultilineText()
// (for reasonable formatted output).
class TextOutputOptions final {
 public:
  TextOutputOptions() = default;

  TextOutputOptions PlusOneIndent() const {
    TextOutputOptions result = *this;
    result.current_indent_ += indent();
    return result;
  }

  TextOutputOptions Multiline(bool new_value) const {
    TextOutputOptions result = *this;
    result.multiline_ = new_value;
    return result;
  }

  TextOutputOptions WithIndent(::std::string new_value) const {
    TextOutputOptions result = *this;
    result.indent_ = ::std::move(new_value);
    return result;
  }

  TextOutputOptions WithComments(bool new_value) const {
    TextOutputOptions result = *this;
    result.comments_ = new_value;
    return result;
  }

  TextOutputOptions WithDigitGrouping(bool new_value) const {
    TextOutputOptions result = *this;
    result.digit_grouping_ = new_value;
    return result;
  }

  TextOutputOptions WithNumericBase(int new_value) const {
    TextOutputOptions result = *this;
    result.numeric_base_ = new_value;
    return result;
  }

  ::std::string current_indent() const { return current_indent_; }
  ::std::string indent() const { return indent_; }
  bool multiline() const { return multiline_; }
  bool digit_grouping() const { return digit_grouping_; }
  bool comments() const { return comments_; }
  ::std::uint8_t numeric_base() const { return numeric_base_; }

 private:
  ::std::string indent_;
  ::std::string current_indent_;
  bool comments_ = false;
  bool multiline_ = false;
  bool digit_grouping_ = false;
  ::std::uint8_t numeric_base_ = 10;
};

namespace support {

// TextOutputStream puts a stream-like interface onto a std::string, for use by
// DumpToTextStream.  It is used by UpdateFromText().
class TextOutputStream final {
 public:
  inline explicit TextOutputStream() = default;

  inline void Write(const ::std::string &text) {
    text_.write(text.data(), text.size());
  }

  inline void Write(const char *text) { text_.write(text, strlen(text)); }

  inline void Write(const char c) { text_.put(c); }

  inline ::std::string Result() { return text_.str(); }

 private:
  ::std::ostringstream text_;
};

// DecodeInteger decodes an integer from a string.  This is very similar to the
// many, many existing integer decode routines in the world, except that a) it
// accepts integers in any Emboss format, and b) it can run in environments that
// do not support std::istream or Google's number conversion routines.
//
// Ideally, this would be replaced by someone else's code.
template <class IntType>
bool DecodeInteger(const ::std::string &text, IntType *result) {
  IntType accumulator = 0;
  IntType base = 10;
  bool negative = false;
  unsigned offset = 0;
  if (::std::is_signed<IntType>::value && text.size() >= 1 + offset &&
      text[offset] == '-') {
    negative = true;
    offset += 1;
  }
  if (text.size() >= 2 + offset && text[offset] == '0') {
    if (text[offset + 1] == 'x' || text[offset + 1] == 'X') {
      base = 16;
      offset += 2;
    } else if (text[offset + 1] == 'b' || text[offset + 1] == 'B') {
      base = 2;
      offset += 2;
    }
  }
  // "", "0x", "0b", "-", "-0x", and "-0b" are not valid numbers.
  if (offset == text.size()) return false;
  for (; offset < text.size(); ++offset) {
    char c = text[offset];
    IntType digit = 0;
    if (c == '_') {
      if (offset == 0) {
        return false;
      }
      continue;
    } else if (c >= '0' && c <= '9') {
      digit = c - '0';
    } else if (c >= 'A' && c <= 'F') {
      digit = c - 'A' + 10;
    } else if (c >= 'a' && c <= 'f') {
      digit = c - 'a' + 10;
    } else {
      return false;
    }
    if (digit >= base) {
      return false;
    }
    if (negative) {
      if (accumulator <
          (::std::numeric_limits<IntType>::min() + digit) / base) {
        return false;
      }
      accumulator = accumulator * base - digit;
    } else {
      if (accumulator >
          (::std::numeric_limits<IntType>::max() - digit) / base) {
        return false;
      }
      accumulator = accumulator * base + digit;
    }
  }
  *result = accumulator;
  return true;
}

template <class Stream>
bool DiscardWhitespace(Stream *stream) {
  char c;
  bool in_comment = false;
  do {
    if (!stream->Read(&c)) return true;
    if (c == '#') in_comment = true;
    if (c == '\r' || c == '\n') in_comment = false;
  } while (in_comment || c == ' ' || c == '\t' || c == '\n' || c == '\r');
  return stream->Unread(c);
}

template <class Stream>
bool ReadToken(Stream *stream, ::std::string *token) {
  ::std::vector<char> result;
  char c;
  if (!DiscardWhitespace(stream)) return false;
  if (!stream->Read(&c)) {
    *token = "";
    return true;
  }

  const char *const punctuation = ":{}[],";
  if (strchr(punctuation, c) != nullptr) {
    *token = ::std::string(1, c);
    return true;
  } else {
    // TODO(bolms): Only allow alphanumeric characters here?
    do {
      result.push_back(c);
      if (!stream->Read(&c)) {
        *token = ::std::string(&result[0], result.size());
        return true;
      }
    } while (c != ' ' && c != '\t' && c != '\n' && c != '\r' && c != '#' &&
             strchr(punctuation, c) == nullptr);
    if (!stream->Unread(c)) return false;
    *token = ::std::string(&result[0], result.size());
    return true;
  }
}

template <class Stream, class View>
bool ReadIntegerFromTextStream(View *view, Stream *stream) {
  ::std::string token;
  if (!::emboss::support::ReadToken(stream, &token)) return false;
  if (token.empty()) return false;
  typename View::ValueType value;
  if (!::emboss::support::DecodeInteger(token, &value)) return false;
  return view->TryToWrite(value);
}

// WriteIntegerToTextStream encodes the given value in base 2, 10, or 16, with
// or without digit group separators ('_'), and then calls stream->Write() with
// a char * argument that is a C-style null-terminated string of the encoded
// number.
//
// As with DecodeInteger, above, it would be nice to be able to replace this
// with someone else's code, but I (bolms@) was unable to find anything in
// standard C++ that would encode numbers in binary, nothing that would add
// digit separators to hex numbers, and nothing that would use '_' for digit
// separators.
template <class Stream, typename IntegralType>
void WriteIntegerToTextStream(IntegralType value, Stream *stream,
                              ::std::uint8_t base, bool digit_grouping) {
  static_assert(::std::numeric_limits<
                    typename ::std::remove_cv<IntegralType>::type>::is_integer,
                "WriteIntegerToTextStream only supports integer types.");
  static_assert(
      !::std::is_same<bool,
                      typename ::std::remove_cv<IntegralType>::type>::value,
      "WriteIntegerToTextStream only supports integer types.");
  EMBOSS_CHECK(base == 10 || base == 2 || base == 16);
  const char *const digits = "0123456789abcdef";
  const int grouping = base == 10 ? 3 : base == 16 ? 4 : 8;
  // The maximum size 32-bit number is -2**31, which is:
  //
  // -0b10000000_00000000_00000000_00000000  (38 chars)
  // -2_147_483_648  (14 chars)
  // -0x8000_0000  (12 chars)
  //
  // Likewise, the maximum size 8-bit number is -128, which is:
  // -0b10000000  (11 chars)
  // -128  (4 chars)
  // -0x80  (5 chars)
  //
  // Binary with separators is always the longest value: 9 chars per 8 bits,
  // minus 1 char for the '_' that does not appear at the front of the number,
  // plus 2 chars for "0b", plus 1 char for '-', plus 1 extra char for the
  // trailing '\0', which is (sizeof value) * CHAR_BIT * 9 / 8 - 1 + 2 + 1 + 1.
  const int buffer_size = (sizeof value) * CHAR_BIT * 9 / 8 + 3;
  char buffer[buffer_size];
  buffer[buffer_size - 1] = '\0';
  int next_char = buffer_size - 2;
  if (value == 0) {
    EMBOSS_DCHECK_GE(next_char, 0);
    buffer[next_char] = digits[0];
    --next_char;
  }
  int sign = value < 0 ? -1 : 1;
  int digit_count = 0;
  auto buffer_char = [&](char c) {
    EMBOSS_DCHECK_GE(next_char, 0);
    buffer[next_char] = c;
    --next_char;
  };
  if (value < 0) {
    if (value == ::std::numeric_limits<decltype(value)>::lowest()) {
      // The minimum negative two's-complement value has no corresponding
      // positive value, so 'value = -value' is not useful in that case.
      // Instead, we do some trickery to buffer the lowest-order digit here.
      auto digit = -(value + 1) % base + 1;
      value = -(value + 1) / base;
      if (digit == base) {
        digit = 0;
        ++value;
      }
      buffer_char(digits[digit]);
      ++digit_count;
    } else {
      value = -value;
    }
  }
  while (value > 0) {
    if (digit_count && digit_count % grouping == 0 && digit_grouping) {
      buffer_char('_');
    }
    buffer_char(digits[value % base]);
    value /= base;
    ++digit_count;
  }
  if (base == 16) {
    buffer_char('x');
    buffer_char('0');
  } else if (base == 2) {
    buffer_char('b');
    buffer_char('0');
  }
  if (sign < 0) {
    buffer_char('-');
  }

  stream->Write(buffer + 1 + next_char);
}

// Writes an integer value in the base given in options, plus an optional
// comment with the same value in a second base.  This is used for the common
// output format of IntView, UIntView, and BcdView.
template <class Stream, class View>
void WriteIntegerViewToTextStream(View *view, Stream *stream,
                                  const TextOutputOptions &options) {
  WriteIntegerToTextStream(view->Read(), stream, options.numeric_base(),
                           options.digit_grouping());
  if (options.comments()) {
    stream->Write("  # ");
    WriteIntegerToTextStream(view->Read(), stream,
                             options.numeric_base() == 10 ? 16 : 10,
                             options.digit_grouping());
  }
}

// The TextOutputOptions parameter is present so that it can be passed in by
// generated code that uses the same form for WriteBooleanViewToTextStream,
// WriteIntegerViewToTextStream, and WriteEnumViewToTextStream.
template <class Stream, class View>
void WriteBooleanViewToTextStream(View *view, Stream *stream,
                                  const TextOutputOptions &) {
  if (view->Read()) {
    stream->Write("true");
  } else {
    stream->Write("false");
  }
}

// FloatConstants holds various masks for working with IEEE754-compatible
// floating-point values at a bit level.  These are mostly used here to
// implement text format for NaNs, preserving the NaN payload so that the text
// format can (in theory) provide a bit-exact round-trip through the text
// format.
template <class Float>
struct FloatConstants;

template <>
struct FloatConstants<float> {
  static_assert(sizeof(float) == 4, "Emboss requires 32-bit float.");
  using MatchingIntegerType = ::std::uint32_t;
  static constexpr MatchingIntegerType kMantissaMask() { return 0x7fffffU; }
  static constexpr MatchingIntegerType kExponentMask() { return 0x7f800000U; }
  static constexpr MatchingIntegerType kSignMask() { return 0x80000000U; }
  static constexpr int kPrintfPrecision() { return 9; }
  static constexpr const char *kScanfFormat() { return "%f%n"; }
};

template <>
struct FloatConstants<double> {
  static_assert(sizeof(double) == 8, "Emboss requires 64-bit double.");
  using MatchingIntegerType = ::std::uint64_t;
  static constexpr MatchingIntegerType kMantissaMask() {
    return 0xfffffffffffffUL;
  }
  static constexpr MatchingIntegerType kExponentMask() {
    return 0x7ff0000000000000UL;
  }
  static constexpr MatchingIntegerType kSignMask() {
    return 0x8000000000000000UL;
  }
  static constexpr int kPrintfPrecision() { return 17; }
  static constexpr const char *kScanfFormat() { return "%lf%n"; }
};

// Decodes a floating-point number from text.
template <class Float>
bool DecodeFloat(const ::std::string &token, Float *result) {
  // The state of the world for reading floating-point values is somewhat better
  // than the situation for writing them, but there are still a few bits that
  // are underspecified.  This function is the mirror of WriteFloatToTextStream,
  // below, so it specifically decodes infinities and NaNs in the formats that
  // Emboss uses.
  //
  // Because of the use of scanf here, this function accepts hex floating-point
  // values (0xh.hhhhpeee) *on some systems*.  TODO(bolms): make hex float
  // support universal.

  using UInt = typename FloatConstants<Float>::MatchingIntegerType;

  if (token.empty()) return false;

  // First, check for negative.
  bool negative = token[0] == '-';

  // Second, check for NaN.
  ::std::size_t i = token[0] == '-' || token[0] == '+' ? 1 : 0;
  if (token.size() >= i + 3 && (token[i] == 'N' || token[i] == 'n') &&
      (token[i + 1] == 'A' || token[i + 1] == 'a') &&
      (token[i + 2] == 'N' || token[i + 2] == 'n')) {
    UInt nan_payload;
    if (token.size() >= i + 4) {
      if (token[i + 3] == '(' && token[token.size() - 1] == ')') {
        if (!DecodeInteger(token.substr(i + 4, token.size() - i - 5),
                           &nan_payload)) {
          return false;
        }
      } else {
        // NaN may not be followed by trailing characters other than a
        // ()-enclosed payload.
        return false;
      }
    } else {
      // If no specific NaN was given, take a default NaN from the C++ standard
      // library.  Technically, a conformant C++ implementation might not have
      // quiet_NaN(), but any IEEE754-based implementation should.
      //
      // It is tempting to just write the default NaN directly into the view and
      // return success, but "-NaN" should be have its sign bit set, and there
      // is no direct way to set the sign bit of a NaN, so there are fewer code
      // paths if we extract the default NaN payload, then use it in the
      // reconstruction step, below.
      Float default_nan = ::std::numeric_limits<Float>::quiet_NaN();
      UInt bits;
      ::std::memcpy(&bits, &default_nan, sizeof(bits));
      nan_payload = bits & FloatConstants<Float>::kMantissaMask();
    }
    if (nan_payload == 0) {
      // "NaN" with a payload of zero is actually the bit pattern for infinity;
      // "NaN(0)" should not be an alias for "Inf".
      return false;
    }
    if (nan_payload & (FloatConstants<Float>::kExponentMask() |
                       FloatConstants<Float>::kSignMask())) {
      // The payload must be small enough to fit in the payload space; it must
      // not overflow into the exponent or sign bits.
      //
      // Note that the DecodeInteger call which decoded the payload will return
      // false if the payload would overflow the `UInt` type, so cases like
      // "NaN(0x10000000000000000000000000000)" -- which are so big that they no
      // longer interfere with the sign or exponent -- are caught above.
      return false;
    }
    UInt bits = FloatConstants<Float>::kExponentMask();
    bits |= nan_payload;
    if (negative) {
      bits |= FloatConstants<Float>::kSignMask();
    }
    ::std::memcpy(result, &bits, sizeof(bits));
    return true;
  }

  // If the value is not NaN, check for infinity.
  if (token.size() >= i + 3 && (token[i] == 'I' || token[i] == 'i') &&
      (token[i + 1] == 'N' || token[i + 1] == 'n') &&
      (token[i + 2] == 'F' || token[i + 2] == 'f')) {
    if (token.size() > i + 3) {
      // Infinity must be exactly "Inf" or "-Inf" (case insensitive).  There
      // must not be trailing characters.
      return false;
    }
    // As with quiet_NaN(), a conforming C++ implementation might not have
    // infinity(), but an IEEE 754-based implementation should.
    if (negative) {
      *result = -::std::numeric_limits<Float>::infinity();
      return true;
    } else {
      *result = ::std::numeric_limits<Float>::infinity();
      return true;
    }
  }

  // For non-NaN, non-Inf values, use the C scanf function, mirroring the use of
  // printf for writing the value, below.
  int chars_used = -1;
  if (::std::sscanf(token.c_str(), FloatConstants<Float>::kScanfFormat(),
                    result, &chars_used) < 1) {
    return false;
  }
  if (chars_used < 0 ||
      static_cast</**/ ::std::size_t>(chars_used) < token.size()) {
    return false;
  }
  return true;
}

// Decodes a floating-point number from a text stream and writes it to the
// specified view.
template <class Stream, class View>
bool ReadFloatFromTextStream(View *view, Stream *stream) {
  ::std::string token;
  if (!ReadToken(stream, &token)) return false;
  typename View::ValueType value;
  if (!DecodeFloat(token, &value)) return false;
  return view->TryToWrite(value);
}

template <class Stream, class Float>
void WriteFloatToTextStream(Float n, Stream *stream,
                            const TextOutputOptions &options) {
  static_assert(::std::is_same<Float, float>::value ||
                    ::std::is_same<Float, double>::value,
                "WriteFloatToTextStream can only write float or double.");
  // The state of the world w.r.t. rendering floating-points as decimal text is,
  // ca. 2018, less than ideal.
  //
  // In C++ land, there is actually no stable facility in the standard library
  // until to_chars() in C++17 -- which is not actually implemented yet in
  // libc++.  to_string(), the printf() family, and the iostreams system all
  // respect the current locale.  In most programs, the locale is permanently
  // left on "C", but this is not guaranteed.  to_string() also uses a fixed and
  // rather unfortunate format.
  //
  // For integers, I (bolms@) chose to just implement custom read and write
  // routines, but those routines are quite small and straightforward compared
  // to floating point conversion.  Even writing correct output is difficult,
  // and writing correct and minimal output is the subject of a number of
  // academic papers.
  //
  // For the moment, I'm just using snprintf("%.*g", 17, n), which is guaranteed
  // to be read back as the same number, but can be longer than strictly
  // necessary.
  //
  // TODO(bolms): Import a modified version of the double-to-string conversion
  // from Swift's standard library, which appears to be best implementation
  // currently available.

  if (::std::isnan(n)) {
    // The printf format for NaN is just "NaN".  In the interests of keeping
    // things bit-exact, Emboss prints the exact NaN.
    typename FloatConstants<Float>::MatchingIntegerType bits;
    ::std::memcpy(&bits, &n, sizeof(bits));
    ::std::uint64_t nan_payload = bits & FloatConstants<Float>::kMantissaMask();
    ::std::uint64_t nan_sign = bits & FloatConstants<Float>::kSignMask();
    if (nan_sign) {
      // NaN still has a sign bit, which is generally treated differently from
      // the payload.  There is no real "standard" text format for NaNs, but
      // "-NaN" appears to be a common way of indicating a NaN with the sign bit
      // set.
      stream->Write("-NaN(");
    } else {
      stream->Write("NaN(");
    }
    // NaN payloads are always dumped in hex.  Note that Emboss is treating the
    // is_quiet/is_signal bit as just another bit in the payload.
    WriteIntegerToTextStream(nan_payload, stream, 16, options.digit_grouping());
    stream->Write(")");
    return;
  }

  if (::std::isinf(n)) {
    if (n < 0.0) {
      stream->Write("-Inf");
    } else {
      stream->Write("Inf");
    }
    return;
  }

  // TODO(bolms): Should the current numeric base be honored here?  Should there
  // be a separate Float numeric base?
  ::std::array<char, 30> buffer;
  // TODO(bolms): Figure out how to get ::std::snprintf to work on
  // microcontroller builds.
  ::std::size_t snprintf_result = static_cast</**/ ::std::size_t>(::snprintf(
      &(buffer[0]), buffer.size(), "%.*g",
      FloatConstants<Float>::kPrintfPrecision(), static_cast<double>(n)));
  (void)snprintf_result;  // Unused if EMBOSS_CHECK_LE is compiled out.
  EMBOSS_CHECK_LE(snprintf_result, buffer.size());
  stream->Write(&buffer[0]);

  // TODO(bolms): Support digit grouping.
}

template <class Stream, class View>
void WriteEnumViewToTextStream(View *view, Stream *stream,
                               const TextOutputOptions &options) {
  const char *name = TryToGetNameFromEnum(view->Read());
  if (name != nullptr) {
    stream->Write(name);
  }
  // If the enum value has no known name, then write its numeric value
  // instead.  If it does have a known name, and comments are enabled on the
  // output, then write the numeric value as a comment.
  if (name == nullptr || options.comments()) {
    if (name != nullptr) stream->Write("  # ");
    WriteIntegerToTextStream(
        static_cast<
            typename ::std::underlying_type<typename View::ValueType>::type>(
            view->Read()),
        stream, options.numeric_base(), options.digit_grouping());
  }
}

// Updates an array from a text stream.  For an array of integers, the most
// basic form of the text format looks like:
//
// { 0, 1, 2 }
//
// However, the following are all acceptable and equivalent:
//
// { 0, 1, 2, }
// {0 1 2}
// { [2]: 2, [1]: 1, [0]: 0 }
// {[2]:2, [0]:0, 1}
//
// Formally, the array must be contained within braces ("{}").  Elements are
// represented as an optional index surrounded by brackets ("[]") followed by
// the text format of the element, followed by a single optional comma (",").
// If no index is present for the first element, the index 0 will be used.  If
// no index is present for any elements after the first, the index one greater
// than the previous index will be used.
template <class Array, class Stream>
bool ReadArrayFromTextStream(Array *array, Stream *stream) {
  // The text format allows any given index to be set more than once.  In
  // theory, this function could track indices and fail if an index were
  // double-set, but doing so would require quite a bit of overhead, and
  // O(array->ElementCount()) extra space in the worst case.  It does not seem
  // worth it to impose the runtime cost here.
  ::std::size_t index = 0;
  ::std::string brace;
  // Read out the opening brace.
  if (!ReadToken(stream, &brace)) return false;
  if (brace != "{") return false;
  for (;;) {
    char c;
    // Check for a closing brace; if present, success.
    if (!DiscardWhitespace(stream)) return false;
    if (!stream->Read(&c)) return false;
    if (c == '}') return true;

    // If the element has an index, read it.
    if (c == '[') {
      ::std::string index_text;
      if (!ReadToken(stream, &index_text)) return false;
      if (!::emboss::support::DecodeInteger(index_text, &index)) return false;
      ::std::string closing_bracket;
      if (!ReadToken(stream, &closing_bracket)) return false;
      if (closing_bracket != "]") return false;
      ::std::string colon;
      if (!ReadToken(stream, &colon)) return false;
      if (colon != ":") return false;
    } else {
      if (!stream->Unread(c)) return false;
    }

    // Read the element.
    if (index >= array->ElementCount()) return false;
    if (!(*array)[index].UpdateFromTextStream(stream)) return false;
    ++index;

    // If there is a trailing comma, discard it.
    if (!DiscardWhitespace(stream)) return false;
    if (!stream->Read(&c)) return false;
    if (c != ',') {
      if (c != '}') return false;
      if (!stream->Unread(c)) return false;
    }
  }
}

// Writes an array to a text stream.  This writes the array in a format
// compatible with ReadArrayFromTextStream, above.  For multiline output, writes
// one element per line.
//
// TODO(bolms): Make the output for arrays of small elements (like bytes) much
// more compact.
//
// This will require several support functions like `MaxTextLength` on every
// view type, and will substantially increase the number of tests required for
// this function, but will make arrays of small elements much more readable.
template <class Array, class Stream>
void WriteArrayToTextStream(Array *array, Stream *stream,
                            const TextOutputOptions &options) {
  TextOutputOptions element_options = options.PlusOneIndent();
  if (options.multiline()) {
    stream->Write("{");
    WriteShorthandArrayCommentToTextStream(array, stream, element_options);
    for (::std::size_t i = 0; i < array->ElementCount(); ++i) {
      stream->Write("\n");
      stream->Write(element_options.current_indent());
      stream->Write("[");
      // TODO(bolms): Put padding in here so that array elements start at the
      // same column.
      //
      // TODO(bolms): (Maybe) figure out how to get padding to work so that
      // elements with comments can have their comments align to the same
      // column.
      WriteIntegerToTextStream(i, stream, options.numeric_base(),
                               options.digit_grouping());
      stream->Write("]: ");
      (*array)[i].WriteToTextStream(stream, element_options);
    }
    stream->Write("\n");
    stream->Write(options.current_indent());
    stream->Write("}");
  } else {
    stream->Write("{");
    for (::std::size_t i = 0; i < array->ElementCount(); ++i) {
      stream->Write(" ");
      if (i % 8 == 0) {
        stream->Write("[");
        WriteIntegerToTextStream(i, stream, options.numeric_base(),
                                 options.digit_grouping());
        stream->Write("]: ");
      }
      (*array)[i].WriteToTextStream(stream, element_options);
      if (i < array->ElementCount() - 1) {
        stream->Write(",");
      }
    }
    stream->Write(" }");
  }
}

// TextStream puts a stream-like interface onto a std::string, for use by
// UpdateFromTextStream.  It is used by UpdateFromText().
class TextStream final {
 public:
  // This template handles std::string, std::string_view, and absl::string_view.
  template <class String>
  inline explicit TextStream(const String &text)
      : text_(text.data()), length_(text.size()) {}

  inline explicit TextStream(const char *text)
      : text_(text), length_(strlen(text)) {}

  inline TextStream(const char *text, ::std::size_t length)
      : text_(text), length_(length) {}

  inline bool Read(char *result) {
    if (index_ >= length_) return false;
    *result = text_[index_];
    ++index_;
    return true;
  }

  inline bool Unread(char c) {
    if (index_ < 1) return false;
    if (text_[index_ - 1] != c) return false;
    --index_;
    return true;
  }

 private:
  // It would be nice to use string_view here, but that's not available until
  // C++17.
  const char *text_ = nullptr;
  ::std::size_t length_ = 0;
  ::std::size_t index_ = 0;
};

}  // namespace support

// Returns a TextOutputOptions set for reasonable multi-line text output.
static inline TextOutputOptions MultilineText() {
  return TextOutputOptions()
      .Multiline(true)
      .WithIndent("  ")
      .WithComments(true)
      .WithDigitGrouping(true);
}

// TODO(bolms): Add corresponding ReadFromText*() verbs which enforce the
// constraint that all of a field's dependencies must be present in the text
// before the field itself is set.
template <typename EmbossViewType>
inline bool UpdateFromText(const EmbossViewType &view,
                           const ::std::string &text) {
  auto text_stream = support::TextStream{text};
  return view.UpdateFromTextStream(&text_stream);
}

template <typename EmbossViewType>
inline ::std::string WriteToString(const EmbossViewType &view,
                                   TextOutputOptions options) {
  support::TextOutputStream text_stream;
  view.WriteToTextStream(&text_stream, options);
  return text_stream.Result();
}

template <typename EmbossViewType>
inline ::std::string WriteToString(const EmbossViewType &view) {
  return WriteToString(view, TextOutputOptions());
}

}  // namespace emboss

#endif  // EMBOSS_RUNTIME_CPP_EMBOSS_TEXT_UTIL_H_
