// 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.

// -*- mode: C++ -*-
// vim: set filetype=cpp:

// Fragments of C++ code used by the Emboss C++ code generator.  Anything before
// the first template is ignored.  The names between ** ** are used as template
// names.  See code_template.py for more details.  Local variable names are
// prefixed with `emboss_reserved_local_` to avoid conflicting with struct field
// names.

// clang-format off

// ** outline ** ///////////////////////////////////////////////////////////////
/**
 * Generated by the Emboss compiler.  DO NOT EDIT!
 */
#ifndef ${header_guard}
#define ${header_guard}
#include <stdint.h>
#include <string.h>

#include <algorithm>
#include <ostream>
#include <type_traits>
#include <utility>

#include "runtime/cpp/emboss_cpp_util.h"

${includes}

/* NOLINTBEGIN */
${body}
/* NOLINTEND */

#endif  // ${header_guard}


// ** include ** ///////////////////////////////////////////////////////////////
#include "${file_name}"


// ** body ** //////////////////////////////////////////////////////////////////
${type_declarations}
${type_definitions}
${method_definitions}


// ** namespace_wrap ** ////////////////////////////////////////////////////////
namespace ${component} {
${body}
}  // namespace ${component}


// ** structure_view_declaration ** ////////////////////////////////////////////
template <class Storage>
class Generic${name}View;


// ** structure_view_class ** //////////////////////////////////////////////////
template <class View>
struct EmbossReservedInternalIsGeneric${name}View;

template <class Storage>
class Generic${name}View final {
 public:
  Generic${name}View() : backing_() {}
  explicit Generic${name}View(
      ${constructor_parameters} Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes) ${parameter_initializers}
        ${initialize_parameters_initialized_true} {}

  // Views over compatible backing storage should be freely assignable.
  template <typename OtherStorage>
  Generic${name}View(
      const Generic${name}View<OtherStorage> &emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()}
        ${parameter_copy_initializers} {}

  // Allow pass-through construction of backing_, but only if there is at least
  // one argument, and, if exactly one argument, that argument is not a
  // (possibly c/v/ref-qualified) Generic${name}View.
  //
  // Explicitly ruling out overloads that might match the copy or move
  // constructor is necessary in order for the copy and move constructors to be
  // reliably found during overload resolution.
  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGeneric${name}View<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit Generic${name}View(
      ${constructor_parameters} Arg &&emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(
            emboss_reserved_local_arg)) ${parameter_initializers}
        ${initialize_parameters_initialized_true} {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit Generic${name}View(
      ${constructor_parameters} Arg0 &&emboss_reserved_local_arg0,
      Arg1 &&emboss_reserved_local_arg1, Args &&... emboss_reserved_local_args)
      : backing_(::std::forward<Arg0>(emboss_reserved_local_arg0),
                 ::std::forward<Arg1>(emboss_reserved_local_arg1),
                 ::std::forward<Args>(
                     emboss_reserved_local_args)...) ${parameter_initializers}
        ${initialize_parameters_initialized_true} {}

  template <typename OtherStorage>
  Generic${name}View<Storage> &operator=(
      const Generic${name}View<OtherStorage> &emboss_reserved_local_other) {
    backing_ = emboss_reserved_local_other.BackingStorage();
    return *this;
  }

  ${enum_usings}

  bool Ok() const {
    if (!IsComplete()) return false;
${parameter_ok_checks}
${field_ok_checks}
${requires_check}
    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeIn${units}().Ok() &&
           backing_.SizeIn${units}() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeIn${units}().UncheckedRead());
  }
${size_method}

  template <typename OtherStorage>
  bool Equals(
      Generic${name}View<OtherStorage> emboss_reserved_local_other) const {
    ${equals_method_body} return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      Generic${name}View<OtherStorage> emboss_reserved_local_other) const {
    ${unchecked_equals_method_body} return true;
  }
  // (Unchecked)CopyFrom copies the number of bytes included in the other view,
  // and ignores the size of the current view.  Even if they differ before
  // copying, the destination view's size should match the source view's size
  // after copying, because any fields used in the calculation of the
  // destination view's size should be updated by the copy.
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      Generic${name}View<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeIn${units}().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      Generic${name}View<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeIn${units}().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      Generic${name}View<OtherStorage> emboss_reserved_local_other) const {
      return emboss_reserved_local_other.Ok() && backing_.TryToCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeIn${units}().Read());
  }

${text_stream_methods}

  static constexpr bool IsAggregate() { return true; }

${field_method_declarations}

 private:
  Storage backing_;
  ${parameter_fields}
  ${parameters_initialized_flag}

  // This is a bit of a hack to handle Equals() and UncheckedEquals() between
  // views with different underlying storage -- otherwise, structs with
  // anonymous members run into access violations.
  //
  // TODO(bolms): Revisit this once the special-case code for anonymous members
  // is replaced by explicit read/write virtual fields in the IR.
  template <class OtherStorage>
  friend class Generic${name}View;
};
using ${name}View =
    Generic${name}View</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ${name}Writer =
    Generic${name}View</**/ ::emboss::support::ReadWriteContiguousBuffer>;

template <class View>
struct EmbossReservedInternalIsGeneric${name}View {
  static constexpr const bool value = false;
};

template <class Storage>
struct EmbossReservedInternalIsGeneric${name}View<
    Generic${name}View<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline Generic${name}View<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
Make${name}View(${constructor_parameters} T &&emboss_reserved_local_arg) {
  return Generic${name}View<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<decltype(
              *::std::declval<T>()->data())>::type,
          1, 0>>(
      ${forwarded_parameters} ::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline Generic${name}View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
Make${name}View(${constructor_parameters} T *emboss_reserved_local_data,
                 ::std::size_t emboss_reserved_local_size) {
  return Generic${name}View</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      ${forwarded_parameters} emboss_reserved_local_data,
      emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline Generic${name}View<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAligned${name}View(
    ${constructor_parameters} T *emboss_reserved_local_data,
    ::std::size_t emboss_reserved_local_size) {
  return Generic${name}View<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      ${forwarded_parameters} emboss_reserved_local_data,
      emboss_reserved_local_size);
}

// ** struct_text_stream ** ////////////////////////////////////////////////////
  template <class Stream>
  bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) const {
    ::std::string emboss_reserved_local_brace;
    if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                      &emboss_reserved_local_brace))
      return false;
    if (emboss_reserved_local_brace != "{") return false;
    for (;;) {
      ::std::string emboss_reserved_local_name;
      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                        &emboss_reserved_local_name))
        return false;
      if (emboss_reserved_local_name == ",")
        if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                          &emboss_reserved_local_name))
          return false;
      if (emboss_reserved_local_name == "}") return true;
      ::std::string emboss_reserved_local_colon;
      if (!::emboss::support::ReadToken(emboss_reserved_local_stream,
                                        &emboss_reserved_local_colon))
        return false;
      if (emboss_reserved_local_colon != ":") return false;
${decode_fields}
      // decode_fields will `continue` if it successfully finds a field.
      return false;
    }
  }

  template <class Stream>
  void WriteToTextStream(
      Stream *emboss_reserved_local_stream,
      ::emboss::TextOutputOptions emboss_reserved_local_options) const {
    ::emboss::TextOutputOptions emboss_reserved_local_field_options =
        emboss_reserved_local_options.PlusOneIndent();
    if (emboss_reserved_local_options.multiline()) {
      emboss_reserved_local_stream->Write("{\n");
    } else {
      emboss_reserved_local_stream->Write("{");
    }
    bool emboss_reserved_local_wrote_field = false;
${write_fields}
    // Avoid unused variable warnings for empty structures:
    (void)emboss_reserved_local_wrote_field;
    if (emboss_reserved_local_options.multiline()) {
      emboss_reserved_local_stream->Write(
          emboss_reserved_local_options.current_indent());
      emboss_reserved_local_stream->Write("}");
    } else {
      emboss_reserved_local_stream->Write(" }");
    }
  }


// ** decode_field ** //////////////////////////////////////////////////////////
      // If the field name matches ${field_name}, handle it, otherwise fall
      // through to the next field.
      if (emboss_reserved_local_name == "${field_name}") {
        // TODO(bolms): How should missing optional fields be handled?
        if (!${field_name}().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

// ** write_field_to_text_stream ** ////////////////////////////////////////////
    if (has_${field_name}().ValueOr(false)) {
      // Don't try to read the field if `allow_partial_output` is set and the
      // field can't be `Read()`.  Aggregates should still be visited, even if
      // they are not `Ok()` overall, since submembers may still be `Ok()`.
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          ${field_name}().IsAggregate() || ${field_name}().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        } else {
          if (emboss_reserved_local_wrote_field) {
            emboss_reserved_local_stream->Write(",");
          }
          emboss_reserved_local_stream->Write(" ");
        }
        emboss_reserved_local_stream->Write("${field_name}: ");
        ${field_name}().WriteToTextStream(emboss_reserved_local_stream,
                                           emboss_reserved_local_field_options);
        emboss_reserved_local_wrote_field = true;
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write("\n");
        }
      } else if (emboss_reserved_local_field_options.allow_partial_output() &&
                 emboss_reserved_local_field_options.comments() &&
                 !${field_name}().IsAggregate() && !${field_name}().Ok()) {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write("# ${field_name}: UNREADABLE\n");
      }
    }

// ** write_read_only_field_to_text_stream ** //////////////////////////////////
    if (has_${field_name}().ValueOr(false) &&
        emboss_reserved_local_field_options.comments()) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          ${field_name}().IsAggregate() || ${field_name}().Ok()) {
        emboss_reserved_local_stream->Write(
            emboss_reserved_local_field_options.current_indent());
        // TODO(bolms): When there are multiline read-only fields, add an option
        // to TextOutputOptions to add `# ` to the current indent and use it
        // here, so that subsequent lines are also commented out.
        emboss_reserved_local_stream->Write("# ${field_name}: ");
        ${field_name}().WriteToTextStream(emboss_reserved_local_stream,
                                           emboss_reserved_local_field_options);
        emboss_reserved_local_stream->Write("\n");
      } else {
        if (emboss_reserved_local_field_options.multiline()) {
          emboss_reserved_local_stream->Write(
              emboss_reserved_local_field_options.current_indent());
        }
        emboss_reserved_local_stream->Write("# ${field_name}: UNREADABLE\n");
      }
    }

// ** constant_structure_size_method ** ////////////////////////////////////////
  static constexpr ::std::size_t SizeIn${units}() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeIn${units}().Read());
  }
  static constexpr bool SizeIsKnown() {
    return IntrinsicSizeIn${units}().Ok();
  }

// ** runtime_structure_size_method ** /////////////////////////////////////////
  ::std::size_t SizeIn${units}() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeIn${units}().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeIn${units}().Ok(); }


// ** ok_method_test ** ////////////////////////////////////////////////////////
    // If we don't have enough information to determine whether ${field} is
    // present in the structure, then structure.Ok() should be false.
    if (!has_${field}.Known()) return false;
    // If ${field} is present, but not Ok(), then structure.Ok() should be
    // false.  If ${field} is not present, it does not matter whether it is
    // Ok().
    if (has_${field}.ValueOrDefault() && !${field}.Ok()) return false;


// ** equals_method_test ** ////////////////////////////////////////////////////
    // If this->${field} is not equal to emboss_reserved_local_other.${field},
    // then the structures are not equal.

    // If either structure's has_${field} is unknown, then default to not
    // Equals().
    //
    // TODO(bolms): Should Equals() return Maybe<bool> and/or return true for
    // non-Ok()-but-equivalent structures?
    if (!has_${field}.Known()) return false;
    if (!emboss_reserved_local_other.has_${field}.Known()) return false;

    // If one side has ${field} but the other side does not, then the fields
    // are not equal.  We use ValueOrDefault() instead of Value() since Value()
    // is more complex and non-constexpr, and we already know that
    // has_${field}.Known() is true for both structures.
    if (emboss_reserved_local_other.has_${field}.ValueOrDefault() &&
        !has_${field}.ValueOrDefault())
      return false;
    if (has_${field}.ValueOrDefault() &&
        !emboss_reserved_local_other.has_${field}.ValueOrDefault())
      return false;

    // If both sides have ${field}, then check that their Equals() returns
    // true.
    if (emboss_reserved_local_other.has_${field}.ValueOrDefault() &&
        has_${field}.ValueOrDefault() &&
        !${field}.Equals(emboss_reserved_local_other.${field}))
      return false;


// ** unchecked_equals_method_test ** //////////////////////////////////////////
    // The contract for UncheckedEquals() is that the caller must assure that
    // both views are Ok() (which implies that has_${field}.Known() is true),
    // and UncheckedEquals() will never perform any assertion checks (which
    // implies that UncheckedEquals() cannot call has_${field}.Value()).

    // If this->has_${field} but !emboss_reserved_local_other.has_${field}, or
    // vice versa, then the structures are not equal.  If neither structure
    // has_${field}, then ${field} is considered equal.
    if (emboss_reserved_local_other.has_${field}.ValueOr(false) &&
        !has_${field}.ValueOr(false))
      return false;
    if (has_${field}.ValueOr(false) &&
        !emboss_reserved_local_other.has_${field}.ValueOr(false))
      return false;

    // If ${field} is present in both structures, then check its equality.
    if (emboss_reserved_local_other.has_${field}.ValueOr(false) &&
        has_${field}.ValueOr(false) &&
        !${field}.UncheckedEquals(emboss_reserved_local_other.${field}))
      return false;


// ** structure_view_type ** ///////////////////////////////////////////////////
${namespace}::Generic${name}View<typename ${buffer_type}>


// ** external_view_type ** ////////////////////////////////////////////////////
${namespace}::${name}View<
    /**/ ::emboss::support::FixedSizeViewParameters<${bits}, ${validator}>,
    typename ${buffer_type}>


// ** enum_view_type ** ////////////////////////////////////////////////////////
${support_namespace}::EnumView<
    /**/ ${enum_type},
    ::emboss::support::FixedSizeViewParameters<${bits}, ${validator}>,
    typename ${buffer_type}>


// ** array_view_adapter ** ////////////////////////////////////////////////////
${support_namespace}::GenericArrayView<
    typename ${element_view_type}, typename ${buffer_type}, ${element_size},
    ${addressable_unit_size} ${element_view_parameter_types}>


// ** structure_field_validator ** /////////////////////////////////////////////
struct ${name} {
  template <typename ValueType>
  static constexpr bool ValueIsOk(ValueType emboss_reserved_local_value) {
    (void)emboss_reserved_local_value;  // Silence -Wunused-parameter
    return (${expression}).ValueOrDefault();
  }
};


// ** structure_single_field_method_declarations ** ////////////////////////////
 ${visibility}:
  typename ${type_reader} ${name}() const;
  ::emboss::support::Maybe<bool> has_${name}() const;


// ** structure_single_field_method_definitions ** /////////////////////////////
template <class Storage>
inline typename ${type_reader} Generic${parent_type}View<Storage>::${name}()
    const {
  // If it's not possible to read the location of this field, provide a view
  // into a null storage -- the only safe methods to call on it will be Ok() and
  // IsComplete(), but it is necessary to return a view so that client code can
  // call those methods at all.  Similarly, if the end of the field would come
  // before the start, we provide a null storage, though arguably we should
  // not.
${parameter_subexpressions}
  if (${parameters_known} has_${name}().ValueOr(false)) {
${size_and_offset_subexpressions}
    auto emboss_reserved_local_size = ${size};
    auto emboss_reserved_local_offset = ${offset};
    if (emboss_reserved_local_size.Known() &&
        emboss_reserved_local_size.ValueOr(0) >= 0 &&
        emboss_reserved_local_offset.Known() &&
        emboss_reserved_local_offset.ValueOr(0) >= 0) {
        return ${type_reader}(
                ${parameter_values} backing_
                        .template GetOffsetStorage<${alignment},
                                                   ${static_offset}>(
                                emboss_reserved_local_offset.ValueOrDefault(),
                                emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ${type_reader}();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
Generic${parent_type}View<Storage>::has_${name}() const {
  return ${field_exists};
}


// ** structure_single_const_virtual_field_method_declarations ** //////////////
 ${visibility}:
  class ${virtual_view_type_name} final {
   public:
    using ValueType = ${logical_type};

    constexpr ${virtual_view_type_name}() {}
    ${virtual_view_type_name}(const ${virtual_view_type_name} &) = default;
    ${virtual_view_type_name}(${virtual_view_type_name} &&) = default;
    ${virtual_view_type_name} &operator=(const ${virtual_view_type_name} &) =
        default;
    ${virtual_view_type_name} &operator=(${virtual_view_type_name} &&) =
        default;
    ~${virtual_view_type_name}() = default;

    static constexpr ${logical_type} Read();
    static constexpr ${logical_type} UncheckedRead();
    static constexpr bool Ok() { return true; }
    template <class Stream>
    void WriteToTextStream(Stream *emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions
                               &emboss_reserved_local_options) const {
      ::emboss::support::${write_to_text_stream_function}(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }
  };

  static constexpr ${virtual_view_type_name} ${name}() {
    return ${virtual_view_type_name}();
  }
  static constexpr ::emboss::support::Maybe<bool> has_${name}() {
    return ::emboss::support::Maybe<bool>(true);
  }


// ** structure_single_const_virtual_field_method_definitions ** ///////////////
namespace ${parent_type} {
inline constexpr ${logical_type} ${name}() {
  return ${read_value}.ValueOrDefault();
}
}  // namespace ${parent_type}

template <class Storage>
inline constexpr ${logical_type}
Generic${parent_type}View<Storage>::${virtual_view_type_name}::Read() {
  return ${parent_type}::${name}();
}

template <class Storage>
inline constexpr ${logical_type}
Generic${parent_type}View<
    Storage>::${virtual_view_type_name}::UncheckedRead() {
  return ${parent_type}::${name}();
}

// ** structure_single_virtual_field_method_declarations ** ////////////////////
 ${visibility}:
  class ${virtual_view_type_name} final {
   public:
    using ValueType = ${logical_type};

    explicit ${virtual_view_type_name}(
        const Generic${parent_type}View &emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    ${virtual_view_type_name}() = delete;
    ${virtual_view_type_name}(const ${virtual_view_type_name} &) = default;
    ${virtual_view_type_name}(${virtual_view_type_name} &&) = default;
    ${virtual_view_type_name} &operator=(const ${virtual_view_type_name} &) =
        default;
    ${virtual_view_type_name} &operator=(${virtual_view_type_name} &&) =
        default;
    ~${virtual_view_type_name}() = default;

    ${logical_type} Read() const {
      EMBOSS_CHECK(view_.has_${name}().ValueOr(false));
      auto emboss_reserved_local_value = MaybeRead();
      EMBOSS_CHECK(emboss_reserved_local_value.Known());
      EMBOSS_CHECK(ValueIsOk(emboss_reserved_local_value.ValueOrDefault()));
      return emboss_reserved_local_value.ValueOrDefault();
    }
    ${logical_type} UncheckedRead() const {
      // UncheckedRead() on a virtual still calls Ok() on its dependencies;
      // i.e., it still does some bounds checking.  This is because of a subtle
      // case, illustrated by the example below:
      //
      //     # .emb
      //     struct Foo:
      //       0 [+1]    UInt  x
      //       if x != 0:
      //         1 [+1]  UInt  y
      //       let x_and_y = x != 0 && y != 0
      //
      //     // .cc
      //     std::array<char, 1> buffer = {0};
      //     const auto view = MakeFooView(&buffer);
      //     assert(!view.x_and_y().UncheckedRead());
      //
      // Without the checks for Ok(), the implementation of UncheckedRead()
      // looks something like:
      //
      //     bool UncheckedRead() const {
      //       return And(view_.x().UncheckedRead(),
      //                  view_.y().UncheckedRead()).ValueOrDefault();
      //     }
      //
      // Unfortunately, even if x().UncheckedRead() is false, this will call
      // UncheckedRead() on y(), which will segfault.
      //
      // TODO(bolms): Figure out a way to minimize bounds checking, instead of
      // just always checking here.
      return MaybeRead().ValueOrDefault();
    }
    // Ok() can be false if some dependency is unreadable, *or* if there is an
    // error somewhere in the arithmetic -- say, division by zero.
    bool Ok() const {
      auto emboss_reserved_local_value = MaybeRead();
      return emboss_reserved_local_value.Known() &&
             ValueIsOk(emboss_reserved_local_value.ValueOrDefault());
    }
    template <class Stream>
    void WriteToTextStream(Stream *emboss_reserved_local_stream,
                           const ::emboss::TextOutputOptions
                               &emboss_reserved_local_options) const {
      ::emboss::support::${write_to_text_stream_function}(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }

${write_methods}

   private:
    ::emboss::support::Maybe</**/ ${logical_type}> MaybeRead() const {
${read_subexpressions}
      return ${read_value};
    }

    static constexpr bool ValueIsOk(
        ${logical_type} emboss_reserved_local_value) {
      (void)emboss_reserved_local_value;  // Silence -Wunused-parameter
      return ${value_is_ok}.ValueOr(false);
    }

    const Generic${parent_type}View view_;
  };
  ${virtual_view_type_name} ${name}() const;
  ::emboss::support::Maybe<bool> has_${name}() const;


// ** structure_single_virtual_field_write_methods ** //////////////////////////
    bool TryToWrite(${logical_type} emboss_reserved_local_value) {
      const auto emboss_reserved_local_maybe_new_value = ${transform};
      if (!CouldWriteValue(emboss_reserved_local_value)) return false;
      return view_.${destination}.TryToWrite(
          emboss_reserved_local_maybe_new_value.ValueOrDefault());
    }
    void Write(${logical_type} emboss_reserved_local_value) {
      const bool result = TryToWrite(emboss_reserved_local_value);
      (void)result;
      EMBOSS_CHECK(result);
    }
    void UncheckedWrite(${logical_type} emboss_reserved_local_value) {
      view_.${destination}.UncheckedWrite((${transform}).ValueOrDefault());
    }
    bool CouldWriteValue(${logical_type} emboss_reserved_local_value) {
      if (!ValueIsOk(emboss_reserved_local_value)) return false;
      const auto emboss_reserved_local_maybe_new_value = ${transform};
      if (!emboss_reserved_local_maybe_new_value.Known()) return false;
      return view_.${destination}.CouldWriteValue(
          emboss_reserved_local_maybe_new_value.ValueOrDefault());
    }
    template <class Stream>
    bool UpdateFromTextStream(Stream *emboss_reserved_local_stream) {
      return ::emboss::support::ReadIntegerFromTextStream(
          this, emboss_reserved_local_stream);
    }


// ** structure_single_virtual_field_method_definitions ** /////////////////////
template <class Storage>
inline typename Generic${parent_type}View<Storage>::${virtual_view_type_name}
Generic${parent_type}View<Storage>::${name}() const {
  return
      typename Generic${parent_type}View<Storage>::${virtual_view_type_name}(
          *this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
Generic${parent_type}View<Storage>::has_${name}() const {
  return ${field_exists};
}


// ** structure_single_field_indirect_method_declarations ** ///////////////////
 ${visibility}:
  // The "this->" is required for (some versions of?) GCC.
  auto ${name}() const -> decltype(this->${aliased_field}) {
   return has_${name}().ValueOrDefault() ? ${aliased_field}
                                          : decltype(this->${aliased_field})();
  }
  ::emboss::support::Maybe<bool> has_${name}() const;


// ** struct_single_field_indirect_method_definitions ** ///////////////////////
template <class Storage>
inline ::emboss::support::Maybe<bool>
Generic${parent_type}View<Storage>::has_${name}() const {
  return ${field_exists};
}


// ** structure_single_parameter_field_method_declarations ** //////////////////
 private:
  // TODO(bolms): Is there any harm if these are public methods?
  constexpr ::emboss::support::MaybeConstantView</**/ ${logical_type}>
  ${name}() const {
    return parameters_initialized_
               ? ::emboss::support::MaybeConstantView</**/ ${logical_type}>(
                     ${name}_)
               : ::emboss::support::MaybeConstantView</**/ ${logical_type}>();
  }
  constexpr ::emboss::support::Maybe<bool> has_${name}() const {
    return ::emboss::support::Maybe<bool>(parameters_initialized_);
  }


// ** enum_declaration ** //////////////////////////////////////////////////////
enum class ${enum} : ${enum_type};


// ** enum_definition ** ///////////////////////////////////////////////////////
enum class ${enum} : ${enum_type} {
${enum_values}
};

// This setup (ab)uses the fact that C++ templates can be defined in many
// translation units, but will be collapsed to a single definition at link time
// (or no definition, if no client code instantiates the template).
//
// Emboss could accomplish almost the same result by generating multiple .cc
// files (one per function), but Bazel doesn't have great support for specifying
// "the output of this rule is an indeterminate number of files, all of which
// should be used as input to this other rule," which would be necessary to
// generate all the .cc files and then build and link them into a library.
// ** enum_traits ** ///////////////////////////////////////////////////////////
template <class Enum>
class EnumTraits;

template <>
class EnumTraits<${enum}> final {
 public:
  static bool TryToGetEnumFromName(const char *emboss_reserved_local_name,
                                   ${enum} *emboss_reserved_local_result) {
    if (emboss_reserved_local_name == nullptr) return false;
    // TODO(bolms): The generated code here would be much more efficient for
    // large enums if the mapping were performed using a prefix trie rather than
    // repeated strcmp().
${enum_from_name_cases}
    return false;
  }

  static const char *TryToGetNameFromEnum(
      ${enum} emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
${name_from_enum_cases}
      default: return nullptr;
    }
  }

  static bool EnumIsKnown(${enum} emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
${enum_is_known_cases}
      default:
        return false;
    }
  }

  static ::std::ostream &SendToOstream(::std::ostream &emboss_reserved_local_os,
                                       ${enum} emboss_reserved_local_value) {
    const char *emboss_reserved_local_name =
        TryToGetNameFromEnum(emboss_reserved_local_value);
    if (emboss_reserved_local_name == nullptr) {
      emboss_reserved_local_os
          << static_cast</**/ ::std::underlying_type<${enum}>::type>(
                 emboss_reserved_local_value);
    } else {
      emboss_reserved_local_os << emboss_reserved_local_name;
    }
    return emboss_reserved_local_os;
  }
};

// These functions are intended to be found via ADL.
static inline bool TryToGetEnumFromName(
    const char *emboss_reserved_local_name,
    ${enum} *emboss_reserved_local_result) {
  return EnumTraits<${enum}>::TryToGetEnumFromName(
      emboss_reserved_local_name, emboss_reserved_local_result);
}

static inline const char *TryToGetNameFromEnum(
    ${enum} emboss_reserved_local_value) {
  return EnumTraits<${enum}>::TryToGetNameFromEnum(
      emboss_reserved_local_value);
}

static inline bool EnumIsKnown(${enum} emboss_reserved_local_value) {
  return EnumTraits<${enum}>::EnumIsKnown(emboss_reserved_local_value);
}

static inline ::std::ostream &operator<<(
    ::std::ostream &emboss_reserved_local_os,
    ${enum} emboss_reserved_local_value) {
  return EnumTraits<${enum}>::SendToOstream(emboss_reserved_local_os,
                                             emboss_reserved_local_value);
}

// ** enum_from_name_case ** ///////////////////////////////////////////////////
    if (!strcmp("${name}", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = ${enum}::${value};
      return true;
    }

// ** name_from_enum_case ** ///////////////////////////////////////////////////
      case ${enum}::${value}: return "${name}";

// ** enum_is_known_case ** ////////////////////////////////////////////////////
      case ${enum}::${name}: return true;

// ** enum_value ** ////////////////////////////////////////////////////////////
  ${name} = ${value},

// ** enum_using_statement ** //////////////////////////////////////////////////
  using ${name} = ${component};
