// 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 <cstdint>
#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(uint8_t new_value) const {
    TextOutputOptions result = *this;
    result.numeric_base_ = new_value;
    return result;
  }

  TextOutputOptions WithAllowPartialOutput(bool new_value) const {
    TextOutputOptions result = *this;
    result.allow_partial_output_ = 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_; }
  bool allow_partial_output() const { return allow_partial_output_; }

 private:
  ::std::string indent_;
  ::std::string current_indent_;
  bool comments_ = false;
  bool multiline_ = false;
  bool digit_grouping_ = false;
  bool allow_partial_output_ = 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) {
      if (!options.allow_partial_output() || (*array)[i].IsAggregate() ||
          (*array)[i].Ok()) {
        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);
      } else if (element_options.comments()) {
        stream->Write("\n");
        stream->Write(element_options.current_indent());
        stream->Write("# [");
        WriteIntegerToTextStream(i, stream, options.numeric_base(),
                                 options.digit_grouping());
        stream->Write("]: UNREADABLE");
      }
    }
    stream->Write("\n");
    stream->Write(options.current_indent());
    stream->Write("}");
  } else {
    stream->Write("{");
    bool skipped_unreadable = false;
    for (::std::size_t i = 0; i < array->ElementCount(); ++i) {
      if (!options.allow_partial_output() || (*array)[i].IsAggregate() ||
          (*array)[i].Ok()) {
        stream->Write(" ");
        if (i % 8 == 0 || skipped_unreadable) {
          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(",");
        }
        skipped_unreadable = false;
      } else {
        if (element_options.comments()) {
          stream->Write(" # ");
          if (i % 8 == 0) {
            stream->Write("[");
            WriteIntegerToTextStream(i, stream, options.numeric_base(),
                                     options.digit_grouping());
            stream->Write("]: ");
          }
          stream->Write("UNREADABLE\n");
        }
        skipped_unreadable = true;
      }
    }
    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_
