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

// ** 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_$

$_body_$

#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()} {}

  // 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());
  }

  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(" }");
    }
  }

$_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 bool value = false;
};

template <class Storage>
struct EmbossReservedInternalIsGeneric$_name_$View<
    Generic$_name_$View<Storage>> {
  static constexpr 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);
}

// ** 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)) {
      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");
      }
    }


// ** write_read_only_field_to_text_stream ** //////////////////////////////////
    if (has_$_field_name_$().ValueOr(false) &&
        emboss_reserved_local_field_options.comments()) {
      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");
    }

// ** 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) {
    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.
  if ($_parameters_known_$ has_$_name_$().ValueOr(false) && $_size_$.Known() &&
      $_size_$.ValueOr(0) >= 0 && $_offset_$.Known() &&
      $_offset_$.ValueOr(0) >= 0) {
    return $_type_reader_$(
        $_parameter_values_$ backing_
            .template GetOffsetStorage<$_alignment_$, $_static_offset_$>(
                $_offset_$.ValueOrDefault(), $_size_$.ValueOrDefault()));
  } else {
    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 ** //////////////
  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 $_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 ** ////////////////////
  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);
    }

$_write_methods_$

   private:
    ::emboss::support::Maybe</**/ $_logical_type_$> MaybeRead() const {
      return $_read_value_$;
    }

    static constexpr bool ValueIsOk(
        $_logical_type_$ emboss_reserved_local_value) {
      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.
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_$::$_name_$;
      return true;
    }

// ** name_from_enum_case ** ///////////////////////////////////////////////////
      case $_enum_$::$_name_$: return "$_name_$";

// ** enum_is_known_case ** ////////////////////////////////////////////////////
      case $_enum_$::$_name_$: return true;

// ** enum_value ** ////////////////////////////////////////////////////////////
  $_name_$ = $_value_$,

// ** enum_using_statement ** //////////////////////////////////////////////////
  using $_name_$ = $_component_$;
