/**
 * Generated by the Emboss compiler.  DO NOT EDIT!
 */
#ifndef TESTDATA_PARAMETERS_EMB_H_
#define TESTDATA_PARAMETERS_EMB_H_
#include <stdint.h>
#include <string.h>

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

#include "runtime/cpp/emboss_cpp_util.h"
#include "runtime/cpp/emboss_enum_view.h"
#include "runtime/cpp/emboss_prelude.h"
#include "runtime/cpp/emboss_text_util.h"

/* NOLINTBEGIN */
namespace emboss {
namespace test {
enum class Product : ::std::uint64_t;

enum class MessageId : ::std::uint64_t;

namespace MultiVersion {}  // namespace MultiVersion

template <class Storage>
class GenericMultiVersionView;

namespace Axes {}  // namespace Axes

template <class Storage>
class GenericAxesView;

namespace AxisPair {}  // namespace AxisPair

template <class Storage>
class GenericAxisPairView;

namespace AxesEnvelope {}  // namespace AxesEnvelope

template <class Storage>
class GenericAxesEnvelopeView;

enum class AxisType : ::std::int64_t;

namespace Axis {}  // namespace Axis

template <class Storage>
class GenericAxisView;

namespace Config {}  // namespace Config

template <class Storage>
class GenericConfigView;

namespace ConfigVX {
namespace EmbossReservedAnonymousField1 {

}  // namespace EmbossReservedAnonymousField1

template <class Storage>
class GenericEmbossReservedAnonymousField1View;

}  // namespace ConfigVX

template <class Storage>
class GenericConfigVXView;

namespace StructWithUnusedParameter {}  // namespace StructWithUnusedParameter

template <class Storage>
class GenericStructWithUnusedParameterView;

namespace StructContainingStructWithUnusedParameter {

}  // namespace StructContainingStructWithUnusedParameter

template <class Storage>
class GenericStructContainingStructWithUnusedParameterView;

namespace BiasedValue {}  // namespace BiasedValue

template <class Storage>
class GenericBiasedValueView;

namespace VirtualFirstFieldWithParam {}  // namespace VirtualFirstFieldWithParam

template <class Storage>
class GenericVirtualFirstFieldWithParamView;

namespace ConstVirtualFirstFieldWithParam {

}  // namespace ConstVirtualFirstFieldWithParam

template <class Storage>
class GenericConstVirtualFirstFieldWithParamView;

namespace SizedArrayOfBiasedValues {}  // namespace SizedArrayOfBiasedValues

template <class Storage>
class GenericSizedArrayOfBiasedValuesView;

enum class Product : ::std::uint64_t {
  VERSION_1 = static_cast</**/ ::std::int32_t>(0LL),
  VERSION_2 = static_cast</**/ ::std::int32_t>(10LL),
  VERSION_X = static_cast</**/ ::std::int32_t>(23LL),

};
template <class Enum>
class EnumTraits;

template <>
class EnumTraits<Product> final {
 public:
  static bool TryToGetEnumFromName(const char* emboss_reserved_local_name,
                                   Product* emboss_reserved_local_result) {
    if (emboss_reserved_local_name == nullptr) return false;
    if (!strcmp("VERSION_1", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = Product::VERSION_1;
      return true;
    }

    if (!strcmp("VERSION_2", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = Product::VERSION_2;
      return true;
    }

    if (!strcmp("VERSION_X", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = Product::VERSION_X;
      return true;
    }

    return false;
  }

  static const char* TryToGetNameFromEnum(Product emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case Product::VERSION_1:
        return "VERSION_1";

      case Product::VERSION_2:
        return "VERSION_2";

      case Product::VERSION_X:
        return "VERSION_X";

      default:
        return nullptr;
    }
  }

  static bool EnumIsKnown(Product emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case Product::VERSION_1:
        return true;

      case Product::VERSION_2:
        return true;

      case Product::VERSION_X:
        return true;

      default:
        return false;
    }
  }

  static ::std::ostream& SendToOstream(::std::ostream& emboss_reserved_local_os,
                                       Product 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<Product>::type>(
                 emboss_reserved_local_value);
    } else {
      emboss_reserved_local_os << emboss_reserved_local_name;
    }
    return emboss_reserved_local_os;
  }
};

static inline bool TryToGetEnumFromName(const char* emboss_reserved_local_name,
                                        Product* emboss_reserved_local_result) {
  return EnumTraits<Product>::TryToGetEnumFromName(
      emboss_reserved_local_name, emboss_reserved_local_result);
}

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

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

static inline ::std::ostream& operator<<(
    ::std::ostream& emboss_reserved_local_os,
    Product emboss_reserved_local_value) {
  return EnumTraits<Product>::SendToOstream(emboss_reserved_local_os,
                                            emboss_reserved_local_value);
}
enum class MessageId : ::std::uint64_t {
  AXIS = static_cast</**/ ::std::int32_t>(0LL),
  CONFIG = static_cast</**/ ::std::int32_t>(1LL),

};
template <class Enum>
class EnumTraits;

template <>
class EnumTraits<MessageId> final {
 public:
  static bool TryToGetEnumFromName(const char* emboss_reserved_local_name,
                                   MessageId* emboss_reserved_local_result) {
    if (emboss_reserved_local_name == nullptr) return false;
    if (!strcmp("AXIS", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = MessageId::AXIS;
      return true;
    }

    if (!strcmp("CONFIG", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = MessageId::CONFIG;
      return true;
    }

    return false;
  }

  static const char* TryToGetNameFromEnum(
      MessageId emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case MessageId::AXIS:
        return "AXIS";

      case MessageId::CONFIG:
        return "CONFIG";

      default:
        return nullptr;
    }
  }

  static bool EnumIsKnown(MessageId emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case MessageId::AXIS:
        return true;

      case MessageId::CONFIG:
        return true;

      default:
        return false;
    }
  }

  static ::std::ostream& SendToOstream(::std::ostream& emboss_reserved_local_os,
                                       MessageId 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<MessageId>::type>(
                 emboss_reserved_local_value);
    } else {
      emboss_reserved_local_os << emboss_reserved_local_name;
    }
    return emboss_reserved_local_os;
  }
};

static inline bool TryToGetEnumFromName(
    const char* emboss_reserved_local_name,
    MessageId* emboss_reserved_local_result) {
  return EnumTraits<MessageId>::TryToGetEnumFromName(
      emboss_reserved_local_name, emboss_reserved_local_result);
}

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

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

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

namespace MultiVersion {}  // namespace MultiVersion

template <class View>
struct EmbossReservedInternalIsGenericMultiVersionView;

template <class Storage>
class GenericMultiVersionView final {
 public:
  GenericMultiVersionView() : backing_() {}
  explicit GenericMultiVersionView(::emboss::test::Product product,
                                   Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes),
        product_(product),
        parameters_initialized_(true) {}

  template <typename OtherStorage>
  GenericMultiVersionView(
      const GenericMultiVersionView<OtherStorage>& emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()},
        product_(emboss_reserved_local_other.product_),
        parameters_initialized_(
            emboss_reserved_local_other.parameters_initialized_) {}

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericMultiVersionView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericMultiVersionView(::emboss::test::Product product,
                                   Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)),
        product_(product),
        parameters_initialized_(true) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericMultiVersionView(::emboss::test::Product product,
                                   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)...),
        product_(product),
        parameters_initialized_(true) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;
    if (!parameters_initialized_) return false;
    const auto emboss_reserved_local_ok_subexpr_1 = message_id();
    const auto emboss_reserved_local_ok_subexpr_2 =
        (emboss_reserved_local_ok_subexpr_1.Ok()
             ? ::emboss::support::Maybe</**/ ::emboss::test::MessageId>(
                   static_cast</**/ ::emboss::test::MessageId>(
                       emboss_reserved_local_ok_subexpr_1.UncheckedRead()))
             : ::emboss::support::Maybe</**/ ::emboss::test::MessageId>());

    if (!has_message_id().Known()) return false;
    if (has_message_id().ValueOrDefault() && !message_id().Ok()) return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    {
      const auto emboss_reserved_switch_discrim =
          emboss_reserved_local_ok_subexpr_2;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/ ::emboss::test::MessageId>(0):
          if (!axes().Ok()) return false;
          break;

        case static_cast</**/ ::emboss::test::MessageId>(1):
          if (!config().Ok()) return false;
          break;

        default:
          break;
      }
    }

    if (!has_config_vx().Known()) return false;
    if (has_config_vx().ValueOrDefault() && !config_vx().Ok()) return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(
      GenericMultiVersionView<OtherStorage> emboss_reserved_local_other) const {
    if (!has_product().Known()) return false;
    if (!emboss_reserved_local_other.has_product().Known()) return false;

    if (emboss_reserved_local_other.has_product().ValueOrDefault() &&
        !has_product().ValueOrDefault())
      return false;
    if (has_product().ValueOrDefault() &&
        !emboss_reserved_local_other.has_product().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_product().ValueOrDefault() &&
        has_product().ValueOrDefault() &&
        !product().Equals(emboss_reserved_local_other.product()))
      return false;

    if (!has_message_id().Known()) return false;
    if (!emboss_reserved_local_other.has_message_id().Known()) return false;

    if (emboss_reserved_local_other.has_message_id().ValueOrDefault() &&
        !has_message_id().ValueOrDefault())
      return false;
    if (has_message_id().ValueOrDefault() &&
        !emboss_reserved_local_other.has_message_id().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_message_id().ValueOrDefault() &&
        has_message_id().ValueOrDefault() &&
        !message_id().Equals(emboss_reserved_local_other.message_id()))
      return false;

    if (!has_axes().Known()) return false;
    if (!emboss_reserved_local_other.has_axes().Known()) return false;

    if (emboss_reserved_local_other.has_axes().ValueOrDefault() &&
        !has_axes().ValueOrDefault())
      return false;
    if (has_axes().ValueOrDefault() &&
        !emboss_reserved_local_other.has_axes().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_axes().ValueOrDefault() &&
        has_axes().ValueOrDefault() &&
        !axes().Equals(emboss_reserved_local_other.axes()))
      return false;

    if (!has_config().Known()) return false;
    if (!emboss_reserved_local_other.has_config().Known()) return false;

    if (emboss_reserved_local_other.has_config().ValueOrDefault() &&
        !has_config().ValueOrDefault())
      return false;
    if (has_config().ValueOrDefault() &&
        !emboss_reserved_local_other.has_config().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_config().ValueOrDefault() &&
        has_config().ValueOrDefault() &&
        !config().Equals(emboss_reserved_local_other.config()))
      return false;

    if (!has_config_vx().Known()) return false;
    if (!emboss_reserved_local_other.has_config_vx().Known()) return false;

    if (emboss_reserved_local_other.has_config_vx().ValueOrDefault() &&
        !has_config_vx().ValueOrDefault())
      return false;
    if (has_config_vx().ValueOrDefault() &&
        !emboss_reserved_local_other.has_config_vx().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_config_vx().ValueOrDefault() &&
        has_config_vx().ValueOrDefault() &&
        !config_vx().Equals(emboss_reserved_local_other.config_vx()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericMultiVersionView<OtherStorage> emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_product().ValueOr(false) &&
        !has_product().ValueOr(false))
      return false;
    if (has_product().ValueOr(false) &&
        !emboss_reserved_local_other.has_product().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_product().ValueOr(false) &&
        has_product().ValueOr(false) &&
        !product().UncheckedEquals(emboss_reserved_local_other.product()))
      return false;

    if (emboss_reserved_local_other.has_message_id().ValueOr(false) &&
        !has_message_id().ValueOr(false))
      return false;
    if (has_message_id().ValueOr(false) &&
        !emboss_reserved_local_other.has_message_id().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_message_id().ValueOr(false) &&
        has_message_id().ValueOr(false) &&
        !message_id().UncheckedEquals(emboss_reserved_local_other.message_id()))
      return false;

    if (emboss_reserved_local_other.has_axes().ValueOr(false) &&
        !has_axes().ValueOr(false))
      return false;
    if (has_axes().ValueOr(false) &&
        !emboss_reserved_local_other.has_axes().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_axes().ValueOr(false) &&
        has_axes().ValueOr(false) &&
        !axes().UncheckedEquals(emboss_reserved_local_other.axes()))
      return false;

    if (emboss_reserved_local_other.has_config().ValueOr(false) &&
        !has_config().ValueOr(false))
      return false;
    if (has_config().ValueOr(false) &&
        !emboss_reserved_local_other.has_config().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_config().ValueOr(false) &&
        has_config().ValueOr(false) &&
        !config().UncheckedEquals(emboss_reserved_local_other.config()))
      return false;

    if (emboss_reserved_local_other.has_config_vx().ValueOr(false) &&
        !has_config_vx().ValueOr(false))
      return false;
    if (has_config_vx().ValueOr(false) &&
        !emboss_reserved_local_other.has_config_vx().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_config_vx().ValueOr(false) &&
        has_config_vx().ValueOr(false) &&
        !config_vx().UncheckedEquals(emboss_reserved_local_other.config_vx()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericMultiVersionView<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericMultiVersionView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericMultiVersionView<OtherStorage> emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().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;
      if (emboss_reserved_local_name == "message_id") {
        if (!message_id().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "axes") {
        if (!axes().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "config") {
        if (!config().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "config_vx") {
        if (!config_vx().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_message_id().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          message_id().IsAggregate() || message_id().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("message_id: ");
        message_id().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() &&
                 !message_id().IsAggregate() && !message_id().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("# message_id: UNREADABLE\n");
      }
    }

    if (has_axes().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          axes().IsAggregate() || axes().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("axes: ");
        axes().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() &&
                 !axes().IsAggregate() && !axes().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("# axes: UNREADABLE\n");
      }
    }

    if (has_config().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          config().IsAggregate() || config().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("config: ");
        config().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() &&
                 !config().IsAggregate() && !config().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("# config: UNREADABLE\n");
      }
    }

    if (has_config_vx().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          config_vx().IsAggregate() || config_vx().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("config_vx: ");
        config_vx().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() &&
                 !config_vx().IsAggregate() && !config_vx().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("# config_vx: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 private:
  constexpr ::emboss::support::MaybeConstantView</**/ ::emboss::test::Product>
  product() const {
    return parameters_initialized_ ? ::emboss::support::MaybeConstantView<
                                         /**/ ::emboss::test::Product>(product_)
                                   : ::emboss::support::MaybeConstantView<
                                         /**/ ::emboss::test::Product>();
  }
  constexpr ::emboss::support::Maybe<bool> has_product() const {
    return ::emboss::support::Maybe<bool>(parameters_initialized_);
  }

 public:
  typename ::emboss::support::EnumView<
      /**/ ::emboss::test::MessageId,
      ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

  message_id() const;
  ::emboss::support::Maybe<bool> has_message_id() const;

 public:
  typename ::emboss::test::GenericAxesView<
      typename Storage::template OffsetStorageType</**/ 0, 1>>

  axes() const;
  ::emboss::support::Maybe<bool> has_axes() const;

 public:
  typename ::emboss::test::GenericConfigView<
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 1>>,
          32>>

  config() const;
  ::emboss::support::Maybe<bool> has_config() const;

 public:
  typename ::emboss::test::GenericConfigVXView<
      typename Storage::template OffsetStorageType</**/ 0, 1>>

  config_vx() const;
  ::emboss::support::Maybe<bool> has_config_vx() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        const GenericMultiVersionView& emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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();
    }
    ::std::int32_t UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }

   private:
    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.message_id();
      const auto emboss_reserved_local_subexpr_2 =
          (emboss_reserved_local_subexpr_1.Ok()
               ? ::emboss::support::Maybe</**/ ::emboss::test::MessageId>(
                     static_cast</**/ ::emboss::test::MessageId>(
                         emboss_reserved_local_subexpr_1.UncheckedRead()))
               : ::emboss::support::Maybe</**/ ::emboss::test::MessageId>());
      const auto emboss_reserved_local_subexpr_3 =
          ::emboss::support::Equal</**/ ::emboss::test::MessageId, bool,
                                   ::emboss::test::MessageId,
                                   ::emboss::test::MessageId>(
              emboss_reserved_local_subexpr_2,
              ::emboss::support::Maybe</**/ ::emboss::test::MessageId>(
                  static_cast</**/ ::emboss::test::MessageId>(0)));
      const auto emboss_reserved_local_subexpr_4 =
          ::emboss::support::Choice</**/ ::std::int32_t, ::std::int32_t, bool,
                                    ::std::int32_t, ::std::int32_t>(
              emboss_reserved_local_subexpr_3,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(13LL)),
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 =
          ::emboss::support::Equal</**/ ::emboss::test::MessageId, bool,
                                   ::emboss::test::MessageId,
                                   ::emboss::test::MessageId>(
              emboss_reserved_local_subexpr_2,
              ::emboss::support::Maybe</**/ ::emboss::test::MessageId>(
                  static_cast</**/ ::emboss::test::MessageId>(1)));
      const auto emboss_reserved_local_subexpr_6 =
          ::emboss::support::Choice</**/ ::std::int32_t, ::std::int32_t, bool,
                                    ::std::int32_t, ::std::int32_t>(
              emboss_reserved_local_subexpr_5,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(5LL)),
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_7 = view_.product();
      const auto emboss_reserved_local_subexpr_8 =
          (emboss_reserved_local_subexpr_7.Ok()
               ? ::emboss::support::Maybe</**/ ::emboss::test::Product>(
                     static_cast</**/ ::emboss::test::Product>(
                         emboss_reserved_local_subexpr_7.UncheckedRead()))
               : ::emboss::support::Maybe</**/ ::emboss::test::Product>());
      const auto emboss_reserved_local_subexpr_9 =
          ::emboss::support::Equal</**/ ::emboss::test::Product, bool,
                                   ::emboss::test::Product,
                                   ::emboss::test::Product>(
              emboss_reserved_local_subexpr_8,
              ::emboss::support::Maybe</**/ ::emboss::test::Product>(
                  static_cast</**/ ::emboss::test::Product>(23)));
      const auto emboss_reserved_local_subexpr_10 =
          ::emboss::support::And</**/ bool, bool, bool, bool>(
              emboss_reserved_local_subexpr_9, emboss_reserved_local_subexpr_5);
      const auto emboss_reserved_local_subexpr_11 =
          ::emboss::support::Choice</**/ ::std::int32_t, ::std::int32_t, bool,
                                    ::std::int32_t, ::std::int32_t>(
              emboss_reserved_local_subexpr_10,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(9LL)),
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_12 = ::emboss::support::Maximum<
          /**/ ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t,
          ::std::int32_t, ::std::int32_t, ::std::int32_t>(
          ::emboss::support::Maybe</**/ ::std::int32_t>(
              static_cast</**/ ::std::int32_t>(0LL)),
          ::emboss::support::Maybe</**/ ::std::int32_t>(
              static_cast</**/ ::std::int32_t>(1LL)),
          emboss_reserved_local_subexpr_4, emboss_reserved_local_subexpr_6,
          emboss_reserved_local_subexpr_11);

      return emboss_reserved_local_subexpr_12;
    }

    static constexpr bool ValueIsOk(
        ::std::int32_t emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Maybe<bool>(true).ValueOr(false);
    }

    const GenericMultiVersionView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes()
      const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;
  ::emboss::test::Product product_;
  bool parameters_initialized_ = false;

  template <class OtherStorage>
  friend class GenericMultiVersionView;
};
using MultiVersionView =
    GenericMultiVersionView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using MultiVersionWriter =
    GenericMultiVersionView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct EmbossReservedInternalIsGenericMultiVersionView<
    GenericMultiVersionView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericMultiVersionView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeMultiVersionView(::emboss::test::Product product,
                     T&& emboss_reserved_local_arg) {
  return GenericMultiVersionView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward</**/ ::emboss::test::Product>(product),
                 ::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericMultiVersionView<
    /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeMultiVersionView(::emboss::test::Product product,
                     T* emboss_reserved_local_data,
                     ::std::size_t emboss_reserved_local_size) {
  return GenericMultiVersionView<
      /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      ::std::forward</**/ ::emboss::test::Product>(product),
      emboss_reserved_local_data, emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericMultiVersionView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedMultiVersionView(::emboss::test::Product product,
                            T* emboss_reserved_local_data,
                            ::std::size_t emboss_reserved_local_size) {
  return GenericMultiVersionView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      ::std::forward</**/ ::emboss::test::Product>(product),
      emboss_reserved_local_data, emboss_reserved_local_size);
}

namespace Axes {}  // namespace Axes

template <class View>
struct EmbossReservedInternalIsGenericAxesView;

template <class Storage>
class GenericAxesView final {
 public:
  GenericAxesView() : backing_() {}
  explicit GenericAxesView(::std::int32_t axes,
                           Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes),
        axes_(axes),
        parameters_initialized_(true) {}

  template <typename OtherStorage>
  GenericAxesView(
      const GenericAxesView<OtherStorage>& emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()},
        axes_(emboss_reserved_local_other.axes_),
        parameters_initialized_(
            emboss_reserved_local_other.parameters_initialized_) {}

  template <
      typename Arg,
      typename = typename ::std::enable_if<
          !EmbossReservedInternalIsGenericAxesView<typename ::std::remove_cv<
              typename ::std::remove_reference<Arg>::type>::type>::value>::type>
  explicit GenericAxesView(::std::int32_t axes, Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)),
        axes_(axes),
        parameters_initialized_(true) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericAxesView(::std::int32_t axes,
                           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)...),
        axes_(axes),
        parameters_initialized_(true) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;
    if (!parameters_initialized_) return false;

    if (!has_values().Known()) return false;
    if (has_values().ValueOrDefault() && !values().Ok()) return false;

    if (!has_axis_count_plus_one().Known()) return false;
    if (has_axis_count_plus_one().ValueOrDefault() &&
        !axis_count_plus_one().Ok())
      return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    if (!has_x().Known()) return false;
    if (has_x().ValueOrDefault() && !x().Ok()) return false;

    if (!has_y().Known()) return false;
    if (has_y().ValueOrDefault() && !y().Ok()) return false;

    if (!has_z().Known()) return false;
    if (has_z().ValueOrDefault() && !z().Ok()) return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(GenericAxesView<OtherStorage> emboss_reserved_local_other) const {
    if (!has_axes().Known()) return false;
    if (!emboss_reserved_local_other.has_axes().Known()) return false;

    if (emboss_reserved_local_other.has_axes().ValueOrDefault() &&
        !has_axes().ValueOrDefault())
      return false;
    if (has_axes().ValueOrDefault() &&
        !emboss_reserved_local_other.has_axes().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_axes().ValueOrDefault() &&
        has_axes().ValueOrDefault() &&
        !axes().Equals(emboss_reserved_local_other.axes()))
      return false;

    if (!has_values().Known()) return false;
    if (!emboss_reserved_local_other.has_values().Known()) return false;

    if (emboss_reserved_local_other.has_values().ValueOrDefault() &&
        !has_values().ValueOrDefault())
      return false;
    if (has_values().ValueOrDefault() &&
        !emboss_reserved_local_other.has_values().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_values().ValueOrDefault() &&
        has_values().ValueOrDefault() &&
        !values().Equals(emboss_reserved_local_other.values()))
      return false;

    if (!has_x().Known()) return false;
    if (!emboss_reserved_local_other.has_x().Known()) return false;

    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
        !has_x().ValueOrDefault())
      return false;
    if (has_x().ValueOrDefault() &&
        !emboss_reserved_local_other.has_x().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
        has_x().ValueOrDefault() &&
        !x().Equals(emboss_reserved_local_other.x()))
      return false;

    if (!has_y().Known()) return false;
    if (!emboss_reserved_local_other.has_y().Known()) return false;

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        !has_y().ValueOrDefault())
      return false;
    if (has_y().ValueOrDefault() &&
        !emboss_reserved_local_other.has_y().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        has_y().ValueOrDefault() &&
        !y().Equals(emboss_reserved_local_other.y()))
      return false;

    if (!has_z().Known()) return false;
    if (!emboss_reserved_local_other.has_z().Known()) return false;

    if (emboss_reserved_local_other.has_z().ValueOrDefault() &&
        !has_z().ValueOrDefault())
      return false;
    if (has_z().ValueOrDefault() &&
        !emboss_reserved_local_other.has_z().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_z().ValueOrDefault() &&
        has_z().ValueOrDefault() &&
        !z().Equals(emboss_reserved_local_other.z()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericAxesView<OtherStorage> emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_axes().ValueOr(false) &&
        !has_axes().ValueOr(false))
      return false;
    if (has_axes().ValueOr(false) &&
        !emboss_reserved_local_other.has_axes().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_axes().ValueOr(false) &&
        has_axes().ValueOr(false) &&
        !axes().UncheckedEquals(emboss_reserved_local_other.axes()))
      return false;

    if (emboss_reserved_local_other.has_values().ValueOr(false) &&
        !has_values().ValueOr(false))
      return false;
    if (has_values().ValueOr(false) &&
        !emboss_reserved_local_other.has_values().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_values().ValueOr(false) &&
        has_values().ValueOr(false) &&
        !values().UncheckedEquals(emboss_reserved_local_other.values()))
      return false;

    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
        !has_x().ValueOr(false))
      return false;
    if (has_x().ValueOr(false) &&
        !emboss_reserved_local_other.has_x().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
        has_x().ValueOr(false) &&
        !x().UncheckedEquals(emboss_reserved_local_other.x()))
      return false;

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        !has_y().ValueOr(false))
      return false;
    if (has_y().ValueOr(false) &&
        !emboss_reserved_local_other.has_y().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        has_y().ValueOr(false) &&
        !y().UncheckedEquals(emboss_reserved_local_other.y()))
      return false;

    if (emboss_reserved_local_other.has_z().ValueOr(false) &&
        !has_z().ValueOr(false))
      return false;
    if (has_z().ValueOr(false) &&
        !emboss_reserved_local_other.has_z().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_z().ValueOr(false) &&
        has_z().ValueOr(false) &&
        !z().UncheckedEquals(emboss_reserved_local_other.z()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericAxesView<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericAxesView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericAxesView<OtherStorage> emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().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;
      if (emboss_reserved_local_name == "values") {
        if (!values().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "x") {
        if (!x().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "y") {
        if (!y().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "z") {
        if (!z().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_values().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          values().IsAggregate() || values().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("values: ");
        values().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() &&
                 !values().IsAggregate() && !values().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("# values: UNREADABLE\n");
      }
    }

    if (has_x().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          x().IsAggregate() || x().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("x: ");
        x().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() &&
                 !x().IsAggregate() && !x().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("# x: UNREADABLE\n");
      }
    }

    if (has_y().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          y().IsAggregate() || y().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("y: ");
        y().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() &&
                 !y().IsAggregate() && !y().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("# y: UNREADABLE\n");
      }
    }

    if (has_z().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          z().IsAggregate() || z().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("z: ");
        z().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() &&
                 !z().IsAggregate() && !z().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("# z: UNREADABLE\n");
      }
    }

    if (has_axis_count_plus_one().ValueOr(false) &&
        emboss_reserved_local_field_options.comments()) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          axis_count_plus_one().IsAggregate() || axis_count_plus_one().Ok()) {
        emboss_reserved_local_stream->Write(
            emboss_reserved_local_field_options.current_indent());
        emboss_reserved_local_stream->Write("# axis_count_plus_one: ");
        axis_count_plus_one().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(
            "# axis_count_plus_one: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 private:
  constexpr ::emboss::support::MaybeConstantView</**/ ::std::int32_t> axes()
      const {
    return parameters_initialized_
               ? ::emboss::support::MaybeConstantView</**/ ::std::int32_t>(
                     axes_)
               : ::emboss::support::MaybeConstantView</**/ ::std::int32_t>();
  }
  constexpr ::emboss::support::Maybe<bool> has_axes() const {
    return ::emboss::support::Maybe<bool>(parameters_initialized_);
  }

 public:
  typename ::emboss::support::GenericArrayView<
      typename ::emboss::test::GenericAxisView<
          typename Storage::template OffsetStorageType<
              /**/ 0, 0>::template OffsetStorageType</**/ 4, 0>>

      ,
      typename Storage::template OffsetStorageType</**/ 0, 0>, 4, 8,
      ::emboss::test::AxisType>

  values() const;
  ::emboss::support::Maybe<bool> has_values() const;

 public:
  typename ::emboss::test::GenericAxisView<
      typename Storage::template OffsetStorageType</**/ 0, 0>>

  x() const;
  ::emboss::support::Maybe<bool> has_x() const;

 public:
  typename ::emboss::test::GenericAxisView<
      typename Storage::template OffsetStorageType</**/ 0, 4>>

  y() const;
  ::emboss::support::Maybe<bool> has_y() const;

 public:
  typename ::emboss::test::GenericAxisView<
      typename Storage::template OffsetStorageType</**/ 0, 8>>

  z() const;
  ::emboss::support::Maybe<bool> has_z() const;

 public:
  class EmbossReservedVirtualAxisCountPlusOneView final {
   public:
    using ValueType = ::std::int32_t;

    explicit EmbossReservedVirtualAxisCountPlusOneView(
        const GenericAxesView& emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedVirtualAxisCountPlusOneView() = delete;
    EmbossReservedVirtualAxisCountPlusOneView(
        const EmbossReservedVirtualAxisCountPlusOneView&) = default;
    EmbossReservedVirtualAxisCountPlusOneView(
        EmbossReservedVirtualAxisCountPlusOneView&&) = default;
    EmbossReservedVirtualAxisCountPlusOneView& operator=(
        const EmbossReservedVirtualAxisCountPlusOneView&) = default;
    EmbossReservedVirtualAxisCountPlusOneView& operator=(
        EmbossReservedVirtualAxisCountPlusOneView&&) = default;
    ~EmbossReservedVirtualAxisCountPlusOneView() = default;

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_axis_count_plus_one().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();
    }
    ::std::int32_t UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }

   private:
    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.axes();
      const auto emboss_reserved_local_subexpr_2 =
          (emboss_reserved_local_subexpr_1.Ok()
               ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                     static_cast</**/ ::std::int32_t>(
                         emboss_reserved_local_subexpr_1.UncheckedRead()))
               : ::emboss::support::Maybe</**/ ::std::int32_t>());
      const auto emboss_reserved_local_subexpr_3 =
          ::emboss::support::Sum</**/ ::std::int32_t, ::std::int32_t,
                                 ::std::int32_t, ::std::int32_t>(
              emboss_reserved_local_subexpr_2,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(1LL)));

      return emboss_reserved_local_subexpr_3;
    }

    static constexpr bool ValueIsOk(
        ::std::int32_t emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Maybe<bool>(true).ValueOr(false);
    }

    const GenericAxesView view_;
  };
  EmbossReservedVirtualAxisCountPlusOneView axis_count_plus_one() const;
  ::emboss::support::Maybe<bool> has_axis_count_plus_one() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        const GenericAxesView& emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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();
    }
    ::std::int32_t UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }

   private:
    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.axes();
      const auto emboss_reserved_local_subexpr_2 =
          (emboss_reserved_local_subexpr_1.Ok()
               ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                     static_cast</**/ ::std::int32_t>(
                         emboss_reserved_local_subexpr_1.UncheckedRead()))
               : ::emboss::support::Maybe</**/ ::std::int32_t>());
      const auto emboss_reserved_local_subexpr_3 =
          ::emboss::support::Product</**/ ::std::int32_t, ::std::int32_t,
                                     ::std::int32_t, ::std::int32_t>(
              emboss_reserved_local_subexpr_2,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(4LL)));
      const auto emboss_reserved_local_subexpr_4 =
          ::emboss::support::Sum</**/ ::std::int32_t, ::std::int32_t,
                                 ::std::int32_t, ::std::int32_t>(
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(0LL)),
              emboss_reserved_local_subexpr_3);
      const auto emboss_reserved_local_subexpr_5 =
          ::emboss::support::Choice</**/ ::std::int32_t, ::std::int32_t, bool,
                                    ::std::int32_t, ::std::int32_t>(
              ::emboss::support::Maybe</**/ bool>(true),
              emboss_reserved_local_subexpr_4,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_6 =
          ::emboss::support::GreaterThan</**/ ::std::int32_t, bool,
                                         ::std::int32_t, ::std::int32_t>(
              emboss_reserved_local_subexpr_2,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_7 =
          ::emboss::support::Choice</**/ ::std::int32_t, ::std::int32_t, bool,
                                    ::std::int32_t, ::std::int32_t>(
              emboss_reserved_local_subexpr_6,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(4LL)),
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_8 =
          ::emboss::support::GreaterThan</**/ ::std::int32_t, bool,
                                         ::std::int32_t, ::std::int32_t>(
              emboss_reserved_local_subexpr_2,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(1LL)));
      const auto emboss_reserved_local_subexpr_9 =
          ::emboss::support::Choice</**/ ::std::int32_t, ::std::int32_t, bool,
                                    ::std::int32_t, ::std::int32_t>(
              emboss_reserved_local_subexpr_8,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(8LL)),
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_10 =
          ::emboss::support::GreaterThan</**/ ::std::int32_t, bool,
                                         ::std::int32_t, ::std::int32_t>(
              emboss_reserved_local_subexpr_2,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(2LL)));
      const auto emboss_reserved_local_subexpr_11 =
          ::emboss::support::Choice</**/ ::std::int32_t, ::std::int32_t, bool,
                                    ::std::int32_t, ::std::int32_t>(
              emboss_reserved_local_subexpr_10,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(12LL)),
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_12 = ::emboss::support::Maximum<
          /**/ ::std::int32_t, ::std::int32_t, ::std::int32_t, ::std::int32_t,
          ::std::int32_t, ::std::int32_t, ::std::int32_t>(
          ::emboss::support::Maybe</**/ ::std::int32_t>(
              static_cast</**/ ::std::int32_t>(0LL)),
          emboss_reserved_local_subexpr_5, emboss_reserved_local_subexpr_7,
          emboss_reserved_local_subexpr_9, emboss_reserved_local_subexpr_11);

      return emboss_reserved_local_subexpr_12;
    }

    static constexpr bool ValueIsOk(
        ::std::int32_t emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Maybe<bool>(true).ValueOr(false);
    }

    const GenericAxesView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes()
      const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;
  ::std::int32_t axes_;
  bool parameters_initialized_ = false;

  template <class OtherStorage>
  friend class GenericAxesView;
};
using AxesView =
    GenericAxesView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using AxesWriter =
    GenericAxesView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct EmbossReservedInternalIsGenericAxesView<GenericAxesView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericAxesView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeAxesView(::std::int32_t axes, T&& emboss_reserved_local_arg) {
  return GenericAxesView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward</**/ ::std::int32_t>(axes),
                 ::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericAxesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeAxesView(::std::int32_t axes, T* emboss_reserved_local_data,
             ::std::size_t emboss_reserved_local_size) {
  return GenericAxesView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      ::std::forward</**/ ::std::int32_t>(axes), emboss_reserved_local_data,
      emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericAxesView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedAxesView(::std::int32_t axes, T* emboss_reserved_local_data,
                    ::std::size_t emboss_reserved_local_size) {
  return GenericAxesView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      ::std::forward</**/ ::std::int32_t>(axes), emboss_reserved_local_data,
      emboss_reserved_local_size);
}

namespace AxisPair {}  // namespace AxisPair

template <class View>
struct EmbossReservedInternalIsGenericAxisPairView;

template <class Storage>
class GenericAxisPairView final {
 public:
  GenericAxisPairView() : backing_() {}
  explicit GenericAxisPairView(::emboss::test::AxisType axis_type_a_parameter,
                               ::emboss::test::AxisType axis_type_b_parameter,
                               Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes),
        axis_type_a_parameter_(axis_type_a_parameter),
        axis_type_b_parameter_(axis_type_b_parameter),
        parameters_initialized_(true) {}

  template <typename OtherStorage>
  GenericAxisPairView(
      const GenericAxisPairView<OtherStorage>& emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()},
        axis_type_a_parameter_(
            emboss_reserved_local_other.axis_type_a_parameter_),
        axis_type_b_parameter_(
            emboss_reserved_local_other.axis_type_b_parameter_),
        parameters_initialized_(
            emboss_reserved_local_other.parameters_initialized_) {}

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericAxisPairView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericAxisPairView(::emboss::test::AxisType axis_type_a_parameter,
                               ::emboss::test::AxisType axis_type_b_parameter,
                               Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)),
        axis_type_a_parameter_(axis_type_a_parameter),
        axis_type_b_parameter_(axis_type_b_parameter),
        parameters_initialized_(true) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericAxisPairView(::emboss::test::AxisType axis_type_a_parameter,
                               ::emboss::test::AxisType axis_type_b_parameter,
                               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)...),
        axis_type_a_parameter_(axis_type_a_parameter),
        axis_type_b_parameter_(axis_type_b_parameter),
        parameters_initialized_(true) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;
    if (!parameters_initialized_) return false;

    if (!has_axis_type_a().Known()) return false;
    if (has_axis_type_a().ValueOrDefault() && !axis_type_a().Ok()) return false;

    if (!has_axis_a().Known()) return false;
    if (has_axis_a().ValueOrDefault() && !axis_a().Ok()) return false;

    if (!has_axis_type_b().Known()) return false;
    if (has_axis_type_b().ValueOrDefault() && !axis_type_b().Ok()) return false;

    if (!has_axis_b().Known()) return false;
    if (has_axis_b().ValueOrDefault() && !axis_b().Ok()) return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  static constexpr ::std::size_t SizeInBytes() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  static constexpr bool SizeIsKnown() { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(
      GenericAxisPairView<OtherStorage> emboss_reserved_local_other) const {
    if (!has_axis_type_a_parameter().Known()) return false;
    if (!emboss_reserved_local_other.has_axis_type_a_parameter().Known())
      return false;

    if (emboss_reserved_local_other.has_axis_type_a_parameter()
            .ValueOrDefault() &&
        !has_axis_type_a_parameter().ValueOrDefault())
      return false;
    if (has_axis_type_a_parameter().ValueOrDefault() &&
        !emboss_reserved_local_other.has_axis_type_a_parameter()
             .ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_axis_type_a_parameter()
            .ValueOrDefault() &&
        has_axis_type_a_parameter().ValueOrDefault() &&
        !axis_type_a_parameter().Equals(
            emboss_reserved_local_other.axis_type_a_parameter()))
      return false;

    if (!has_axis_type_b_parameter().Known()) return false;
    if (!emboss_reserved_local_other.has_axis_type_b_parameter().Known())
      return false;

    if (emboss_reserved_local_other.has_axis_type_b_parameter()
            .ValueOrDefault() &&
        !has_axis_type_b_parameter().ValueOrDefault())
      return false;
    if (has_axis_type_b_parameter().ValueOrDefault() &&
        !emboss_reserved_local_other.has_axis_type_b_parameter()
             .ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_axis_type_b_parameter()
            .ValueOrDefault() &&
        has_axis_type_b_parameter().ValueOrDefault() &&
        !axis_type_b_parameter().Equals(
            emboss_reserved_local_other.axis_type_b_parameter()))
      return false;

    if (!has_axis_a().Known()) return false;
    if (!emboss_reserved_local_other.has_axis_a().Known()) return false;

    if (emboss_reserved_local_other.has_axis_a().ValueOrDefault() &&
        !has_axis_a().ValueOrDefault())
      return false;
    if (has_axis_a().ValueOrDefault() &&
        !emboss_reserved_local_other.has_axis_a().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_axis_a().ValueOrDefault() &&
        has_axis_a().ValueOrDefault() &&
        !axis_a().Equals(emboss_reserved_local_other.axis_a()))
      return false;

    if (!has_axis_b().Known()) return false;
    if (!emboss_reserved_local_other.has_axis_b().Known()) return false;

    if (emboss_reserved_local_other.has_axis_b().ValueOrDefault() &&
        !has_axis_b().ValueOrDefault())
      return false;
    if (has_axis_b().ValueOrDefault() &&
        !emboss_reserved_local_other.has_axis_b().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_axis_b().ValueOrDefault() &&
        has_axis_b().ValueOrDefault() &&
        !axis_b().Equals(emboss_reserved_local_other.axis_b()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericAxisPairView<OtherStorage> emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_axis_type_a_parameter().ValueOr(
            false) &&
        !has_axis_type_a_parameter().ValueOr(false))
      return false;
    if (has_axis_type_a_parameter().ValueOr(false) &&
        !emboss_reserved_local_other.has_axis_type_a_parameter().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_axis_type_a_parameter().ValueOr(
            false) &&
        has_axis_type_a_parameter().ValueOr(false) &&
        !axis_type_a_parameter().UncheckedEquals(
            emboss_reserved_local_other.axis_type_a_parameter()))
      return false;

    if (emboss_reserved_local_other.has_axis_type_b_parameter().ValueOr(
            false) &&
        !has_axis_type_b_parameter().ValueOr(false))
      return false;
    if (has_axis_type_b_parameter().ValueOr(false) &&
        !emboss_reserved_local_other.has_axis_type_b_parameter().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_axis_type_b_parameter().ValueOr(
            false) &&
        has_axis_type_b_parameter().ValueOr(false) &&
        !axis_type_b_parameter().UncheckedEquals(
            emboss_reserved_local_other.axis_type_b_parameter()))
      return false;

    if (emboss_reserved_local_other.has_axis_a().ValueOr(false) &&
        !has_axis_a().ValueOr(false))
      return false;
    if (has_axis_a().ValueOr(false) &&
        !emboss_reserved_local_other.has_axis_a().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_axis_a().ValueOr(false) &&
        has_axis_a().ValueOr(false) &&
        !axis_a().UncheckedEquals(emboss_reserved_local_other.axis_a()))
      return false;

    if (emboss_reserved_local_other.has_axis_b().ValueOr(false) &&
        !has_axis_b().ValueOr(false))
      return false;
    if (has_axis_b().ValueOr(false) &&
        !emboss_reserved_local_other.has_axis_b().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_axis_b().ValueOr(false) &&
        has_axis_b().ValueOr(false) &&
        !axis_b().UncheckedEquals(emboss_reserved_local_other.axis_b()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericAxisPairView<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericAxisPairView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericAxisPairView<OtherStorage> emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().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;
      if (emboss_reserved_local_name == "axis_a") {
        if (!axis_a().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "axis_b") {
        if (!axis_b().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_axis_type_a().ValueOr(false) &&
        emboss_reserved_local_field_options.comments()) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          axis_type_a().IsAggregate() || axis_type_a().Ok()) {
        emboss_reserved_local_stream->Write(
            emboss_reserved_local_field_options.current_indent());
        emboss_reserved_local_stream->Write("# axis_type_a: ");
        axis_type_a().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("# axis_type_a: UNREADABLE\n");
      }
    }

    if (has_axis_a().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          axis_a().IsAggregate() || axis_a().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("axis_a: ");
        axis_a().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() &&
                 !axis_a().IsAggregate() && !axis_a().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("# axis_a: UNREADABLE\n");
      }
    }

    if (has_axis_type_b().ValueOr(false) &&
        emboss_reserved_local_field_options.comments()) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          axis_type_b().IsAggregate() || axis_type_b().Ok()) {
        emboss_reserved_local_stream->Write(
            emboss_reserved_local_field_options.current_indent());
        emboss_reserved_local_stream->Write("# axis_type_b: ");
        axis_type_b().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("# axis_type_b: UNREADABLE\n");
      }
    }

    if (has_axis_b().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          axis_b().IsAggregate() || axis_b().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("axis_b: ");
        axis_b().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() &&
                 !axis_b().IsAggregate() && !axis_b().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("# axis_b: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 private:
  constexpr ::emboss::support::MaybeConstantView</**/ ::emboss::test::AxisType>
  axis_type_a_parameter() const {
    return parameters_initialized_
               ? ::emboss::support::MaybeConstantView<
                     /**/ ::emboss::test::AxisType>(axis_type_a_parameter_)
               : ::emboss::support::MaybeConstantView<
                     /**/ ::emboss::test::AxisType>();
  }
  constexpr ::emboss::support::Maybe<bool> has_axis_type_a_parameter() const {
    return ::emboss::support::Maybe<bool>(parameters_initialized_);
  }

 private:
  constexpr ::emboss::support::MaybeConstantView</**/ ::emboss::test::AxisType>
  axis_type_b_parameter() const {
    return parameters_initialized_
               ? ::emboss::support::MaybeConstantView<
                     /**/ ::emboss::test::AxisType>(axis_type_b_parameter_)
               : ::emboss::support::MaybeConstantView<
                     /**/ ::emboss::test::AxisType>();
  }
  constexpr ::emboss::support::Maybe<bool> has_axis_type_b_parameter() const {
    return ::emboss::support::Maybe<bool>(parameters_initialized_);
  }

 public:
  class EmbossReservedVirtualAxisTypeAView final {
   public:
    using ValueType = ::emboss::test::AxisType;

    explicit EmbossReservedVirtualAxisTypeAView(
        const GenericAxisPairView& emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedVirtualAxisTypeAView() = delete;
    EmbossReservedVirtualAxisTypeAView(
        const EmbossReservedVirtualAxisTypeAView&) = default;
    EmbossReservedVirtualAxisTypeAView(EmbossReservedVirtualAxisTypeAView&&) =
        default;
    EmbossReservedVirtualAxisTypeAView& operator=(
        const EmbossReservedVirtualAxisTypeAView&) = default;
    EmbossReservedVirtualAxisTypeAView& operator=(
        EmbossReservedVirtualAxisTypeAView&&) = default;
    ~EmbossReservedVirtualAxisTypeAView() = default;

    ::emboss::test::AxisType Read() const {
      EMBOSS_CHECK(view_.has_axis_type_a().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();
    }
    ::emboss::test::AxisType UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    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::WriteEnumViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }

   private:
    ::emboss::support::Maybe</**/ ::emboss::test::AxisType> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 =
          view_.axis_type_a_parameter();
      const auto emboss_reserved_local_subexpr_2 =
          (emboss_reserved_local_subexpr_1.Ok()
               ? ::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
                     static_cast</**/ ::emboss::test::AxisType>(
                         emboss_reserved_local_subexpr_1.UncheckedRead()))
               : ::emboss::support::Maybe</**/ ::emboss::test::AxisType>());

      return emboss_reserved_local_subexpr_2;
    }

    static constexpr bool ValueIsOk(
        ::emboss::test::AxisType emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Maybe<bool>(true).ValueOr(false);
    }

    const GenericAxisPairView view_;
  };
  EmbossReservedVirtualAxisTypeAView axis_type_a() const;
  ::emboss::support::Maybe<bool> has_axis_type_a() const;

 public:
  typename ::emboss::test::GenericAxisView<
      typename Storage::template OffsetStorageType</**/ 0, 0>>

  axis_a() const;
  ::emboss::support::Maybe<bool> has_axis_a() const;

 public:
  class EmbossReservedVirtualAxisTypeBView final {
   public:
    using ValueType = ::emboss::test::AxisType;

    explicit EmbossReservedVirtualAxisTypeBView(
        const GenericAxisPairView& emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedVirtualAxisTypeBView() = delete;
    EmbossReservedVirtualAxisTypeBView(
        const EmbossReservedVirtualAxisTypeBView&) = default;
    EmbossReservedVirtualAxisTypeBView(EmbossReservedVirtualAxisTypeBView&&) =
        default;
    EmbossReservedVirtualAxisTypeBView& operator=(
        const EmbossReservedVirtualAxisTypeBView&) = default;
    EmbossReservedVirtualAxisTypeBView& operator=(
        EmbossReservedVirtualAxisTypeBView&&) = default;
    ~EmbossReservedVirtualAxisTypeBView() = default;

    ::emboss::test::AxisType Read() const {
      EMBOSS_CHECK(view_.has_axis_type_b().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();
    }
    ::emboss::test::AxisType UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    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::WriteEnumViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }

   private:
    ::emboss::support::Maybe</**/ ::emboss::test::AxisType> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 =
          view_.axis_type_b_parameter();
      const auto emboss_reserved_local_subexpr_2 =
          (emboss_reserved_local_subexpr_1.Ok()
               ? ::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
                     static_cast</**/ ::emboss::test::AxisType>(
                         emboss_reserved_local_subexpr_1.UncheckedRead()))
               : ::emboss::support::Maybe</**/ ::emboss::test::AxisType>());

      return emboss_reserved_local_subexpr_2;
    }

    static constexpr bool ValueIsOk(
        ::emboss::test::AxisType emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Maybe<bool>(true).ValueOr(false);
    }

    const GenericAxisPairView view_;
  };
  EmbossReservedVirtualAxisTypeBView axis_type_b() const;
  ::emboss::support::Maybe<bool> has_axis_type_b() const;

 public:
  typename ::emboss::test::GenericAxisView<
      typename Storage::template OffsetStorageType</**/ 0, 4>>

  axis_b() const;
  ::emboss::support::Maybe<bool> has_axis_b() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView
  IntrinsicSizeInBytes() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;
  ::emboss::test::AxisType axis_type_a_parameter_;
  ::emboss::test::AxisType axis_type_b_parameter_;
  bool parameters_initialized_ = false;

  template <class OtherStorage>
  friend class GenericAxisPairView;
};
using AxisPairView =
    GenericAxisPairView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using AxisPairWriter =
    GenericAxisPairView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct EmbossReservedInternalIsGenericAxisPairView<
    GenericAxisPairView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericAxisPairView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeAxisPairView(::emboss::test::AxisType axis_type_a_parameter,
                 ::emboss::test::AxisType axis_type_b_parameter,
                 T&& emboss_reserved_local_arg) {
  return GenericAxisPairView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(
      ::std::forward</**/ ::emboss::test::AxisType>(axis_type_a_parameter),
      ::std::forward</**/ ::emboss::test::AxisType>(axis_type_b_parameter),
      ::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericAxisPairView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeAxisPairView(::emboss::test::AxisType axis_type_a_parameter,
                 ::emboss::test::AxisType axis_type_b_parameter,
                 T* emboss_reserved_local_data,
                 ::std::size_t emboss_reserved_local_size) {
  return GenericAxisPairView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      ::std::forward</**/ ::emboss::test::AxisType>(axis_type_a_parameter),
      ::std::forward</**/ ::emboss::test::AxisType>(axis_type_b_parameter),
      emboss_reserved_local_data, emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericAxisPairView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedAxisPairView(::emboss::test::AxisType axis_type_a_parameter,
                        ::emboss::test::AxisType axis_type_b_parameter,
                        T* emboss_reserved_local_data,
                        ::std::size_t emboss_reserved_local_size) {
  return GenericAxisPairView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      ::std::forward</**/ ::emboss::test::AxisType>(axis_type_a_parameter),
      ::std::forward</**/ ::emboss::test::AxisType>(axis_type_b_parameter),
      emboss_reserved_local_data, emboss_reserved_local_size);
}

namespace AxesEnvelope {}  // namespace AxesEnvelope

template <class View>
struct EmbossReservedInternalIsGenericAxesEnvelopeView;

template <class Storage>
class GenericAxesEnvelopeView final {
 public:
  GenericAxesEnvelopeView() : backing_() {}
  explicit GenericAxesEnvelopeView(Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes) {}

  template <typename OtherStorage>
  GenericAxesEnvelopeView(
      const GenericAxesEnvelopeView<OtherStorage>& emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()} {}

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericAxesEnvelopeView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericAxesEnvelopeView(Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericAxesEnvelopeView(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)...) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;

    if (!has_axis_count().Known()) return false;
    if (has_axis_count().ValueOrDefault() && !axis_count().Ok()) return false;

    if (!has_axes().Known()) return false;
    if (has_axes().ValueOrDefault() && !axes().Ok()) return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(
      GenericAxesEnvelopeView<OtherStorage> emboss_reserved_local_other) const {
    if (!has_axis_count().Known()) return false;
    if (!emboss_reserved_local_other.has_axis_count().Known()) return false;

    if (emboss_reserved_local_other.has_axis_count().ValueOrDefault() &&
        !has_axis_count().ValueOrDefault())
      return false;
    if (has_axis_count().ValueOrDefault() &&
        !emboss_reserved_local_other.has_axis_count().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_axis_count().ValueOrDefault() &&
        has_axis_count().ValueOrDefault() &&
        !axis_count().Equals(emboss_reserved_local_other.axis_count()))
      return false;

    if (!has_axes().Known()) return false;
    if (!emboss_reserved_local_other.has_axes().Known()) return false;

    if (emboss_reserved_local_other.has_axes().ValueOrDefault() &&
        !has_axes().ValueOrDefault())
      return false;
    if (has_axes().ValueOrDefault() &&
        !emboss_reserved_local_other.has_axes().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_axes().ValueOrDefault() &&
        has_axes().ValueOrDefault() &&
        !axes().Equals(emboss_reserved_local_other.axes()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericAxesEnvelopeView<OtherStorage> emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_axis_count().ValueOr(false) &&
        !has_axis_count().ValueOr(false))
      return false;
    if (has_axis_count().ValueOr(false) &&
        !emboss_reserved_local_other.has_axis_count().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_axis_count().ValueOr(false) &&
        has_axis_count().ValueOr(false) &&
        !axis_count().UncheckedEquals(emboss_reserved_local_other.axis_count()))
      return false;

    if (emboss_reserved_local_other.has_axes().ValueOr(false) &&
        !has_axes().ValueOr(false))
      return false;
    if (has_axes().ValueOr(false) &&
        !emboss_reserved_local_other.has_axes().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_axes().ValueOr(false) &&
        has_axes().ValueOr(false) &&
        !axes().UncheckedEquals(emboss_reserved_local_other.axes()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericAxesEnvelopeView<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericAxesEnvelopeView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericAxesEnvelopeView<OtherStorage> emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().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;
      if (emboss_reserved_local_name == "axis_count") {
        if (!axis_count().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "axes") {
        if (!axes().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_axis_count().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          axis_count().IsAggregate() || axis_count().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("axis_count: ");
        axis_count().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() &&
                 !axis_count().IsAggregate() && !axis_count().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("# axis_count: UNREADABLE\n");
      }
    }

    if (has_axes().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          axes().IsAggregate() || axes().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("axes: ");
        axes().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() &&
                 !axes().IsAggregate() && !axes().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("# axes: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

  axis_count() const;
  ::emboss::support::Maybe<bool> has_axis_count() const;

 public:
  typename ::emboss::test::GenericAxesView<
      typename Storage::template OffsetStorageType</**/ 0, 1>>

  axes() const;
  ::emboss::support::Maybe<bool> has_axes() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        const GenericAxesEnvelopeView& emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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();
    }
    ::std::int32_t UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }

   private:
    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.axis_count();
      const auto emboss_reserved_local_subexpr_2 =
          (emboss_reserved_local_subexpr_1.Ok()
               ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                     static_cast</**/ ::std::int32_t>(
                         emboss_reserved_local_subexpr_1.UncheckedRead()))
               : ::emboss::support::Maybe</**/ ::std::int32_t>());
      const auto emboss_reserved_local_subexpr_3 =
          ::emboss::support::Product</**/ ::std::int32_t, ::std::int32_t,
                                     ::std::int32_t, ::std::int32_t>(
              emboss_reserved_local_subexpr_2,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(4LL)));
      const auto emboss_reserved_local_subexpr_4 =
          ::emboss::support::Sum</**/ ::std::int32_t, ::std::int32_t,
                                 ::std::int32_t, ::std::int32_t>(
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(1LL)),
              emboss_reserved_local_subexpr_3);
      const auto emboss_reserved_local_subexpr_5 =
          ::emboss::support::Choice</**/ ::std::int32_t, ::std::int32_t, bool,
                                    ::std::int32_t, ::std::int32_t>(
              ::emboss::support::Maybe</**/ bool>(true),
              emboss_reserved_local_subexpr_4,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_6 =
          ::emboss::support::Maximum</**/ ::std::int32_t, ::std::int32_t,
                                     ::std::int32_t, ::std::int32_t,
                                     ::std::int32_t>(
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(0LL)),
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(1LL)),
              emboss_reserved_local_subexpr_5);

      return emboss_reserved_local_subexpr_6;
    }

    static constexpr bool ValueIsOk(
        ::std::int32_t emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Maybe<bool>(true).ValueOr(false);
    }

    const GenericAxesEnvelopeView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes()
      const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;

  template <class OtherStorage>
  friend class GenericAxesEnvelopeView;
};
using AxesEnvelopeView =
    GenericAxesEnvelopeView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using AxesEnvelopeWriter =
    GenericAxesEnvelopeView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct EmbossReservedInternalIsGenericAxesEnvelopeView<
    GenericAxesEnvelopeView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericAxesEnvelopeView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeAxesEnvelopeView(T&& emboss_reserved_local_arg) {
  return GenericAxesEnvelopeView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericAxesEnvelopeView<
    /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeAxesEnvelopeView(T* emboss_reserved_local_data,
                     ::std::size_t emboss_reserved_local_size) {
  return GenericAxesEnvelopeView<
      /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericAxesEnvelopeView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedAxesEnvelopeView(T* emboss_reserved_local_data,
                            ::std::size_t emboss_reserved_local_size) {
  return GenericAxesEnvelopeView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}
enum class AxisType : ::std::int64_t {
  GENERIC = static_cast</**/ ::std::int32_t>(-1LL),
  X_AXIS = static_cast</**/ ::std::int32_t>(1LL),
  Y_AXIS = static_cast</**/ ::std::int32_t>(2LL),
  Z_AXIS = static_cast</**/ ::std::int32_t>(3LL),

};
template <class Enum>
class EnumTraits;

template <>
class EnumTraits<AxisType> final {
 public:
  static bool TryToGetEnumFromName(const char* emboss_reserved_local_name,
                                   AxisType* emboss_reserved_local_result) {
    if (emboss_reserved_local_name == nullptr) return false;
    if (!strcmp("GENERIC", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = AxisType::GENERIC;
      return true;
    }

    if (!strcmp("X_AXIS", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = AxisType::X_AXIS;
      return true;
    }

    if (!strcmp("Y_AXIS", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = AxisType::Y_AXIS;
      return true;
    }

    if (!strcmp("Z_AXIS", emboss_reserved_local_name)) {
      *emboss_reserved_local_result = AxisType::Z_AXIS;
      return true;
    }

    return false;
  }

  static const char* TryToGetNameFromEnum(
      AxisType emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case AxisType::GENERIC:
        return "GENERIC";

      case AxisType::X_AXIS:
        return "X_AXIS";

      case AxisType::Y_AXIS:
        return "Y_AXIS";

      case AxisType::Z_AXIS:
        return "Z_AXIS";

      default:
        return nullptr;
    }
  }

  static bool EnumIsKnown(AxisType emboss_reserved_local_value) {
    switch (emboss_reserved_local_value) {
      case AxisType::GENERIC:
        return true;

      case AxisType::X_AXIS:
        return true;

      case AxisType::Y_AXIS:
        return true;

      case AxisType::Z_AXIS:
        return true;

      default:
        return false;
    }
  }

  static ::std::ostream& SendToOstream(::std::ostream& emboss_reserved_local_os,
                                       AxisType 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<AxisType>::type>(
                 emboss_reserved_local_value);
    } else {
      emboss_reserved_local_os << emboss_reserved_local_name;
    }
    return emboss_reserved_local_os;
  }
};

static inline bool TryToGetEnumFromName(
    const char* emboss_reserved_local_name,
    AxisType* emboss_reserved_local_result) {
  return EnumTraits<AxisType>::TryToGetEnumFromName(
      emboss_reserved_local_name, emboss_reserved_local_result);
}

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

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

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

namespace Axis {}  // namespace Axis

template <class View>
struct EmbossReservedInternalIsGenericAxisView;

template <class Storage>
class GenericAxisView final {
 public:
  GenericAxisView() : backing_() {}
  explicit GenericAxisView(::emboss::test::AxisType axis_type_parameter,
                           Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes),
        axis_type_parameter_(axis_type_parameter),
        parameters_initialized_(true) {}

  template <typename OtherStorage>
  GenericAxisView(
      const GenericAxisView<OtherStorage>& emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()},
        axis_type_parameter_(emboss_reserved_local_other.axis_type_parameter_),
        parameters_initialized_(
            emboss_reserved_local_other.parameters_initialized_) {}

  template <
      typename Arg,
      typename = typename ::std::enable_if<
          !EmbossReservedInternalIsGenericAxisView<typename ::std::remove_cv<
              typename ::std::remove_reference<Arg>::type>::type>::value>::type>
  explicit GenericAxisView(::emboss::test::AxisType axis_type_parameter,
                           Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)),
        axis_type_parameter_(axis_type_parameter),
        parameters_initialized_(true) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericAxisView(::emboss::test::AxisType axis_type_parameter,
                           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)...),
        axis_type_parameter_(axis_type_parameter),
        parameters_initialized_(true) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;
    if (!parameters_initialized_) return false;
    const auto emboss_reserved_local_ok_subexpr_1 = axis_type();
    const auto emboss_reserved_local_ok_subexpr_2 =
        (emboss_reserved_local_ok_subexpr_1.Ok()
             ? ::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
                   static_cast</**/ ::emboss::test::AxisType>(
                       emboss_reserved_local_ok_subexpr_1.UncheckedRead()))
             : ::emboss::support::Maybe</**/ ::emboss::test::AxisType>());

    if (!has_value().Known()) return false;
    if (has_value().ValueOrDefault() && !value().Ok()) return false;

    if (!has_axis_type().Known()) return false;
    if (has_axis_type().ValueOrDefault() && !axis_type().Ok()) return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    {
      const auto emboss_reserved_switch_discrim =
          emboss_reserved_local_ok_subexpr_2;
      if (!emboss_reserved_switch_discrim.Known()) return false;
      switch (emboss_reserved_switch_discrim.ValueOrDefault()) {
        case static_cast</**/ ::emboss::test::AxisType>(1):
          if (!x().Ok()) return false;
          break;

        case static_cast</**/ ::emboss::test::AxisType>(2):
          if (!y().Ok()) return false;
          break;

        case static_cast</**/ ::emboss::test::AxisType>(3):
          if (!z().Ok()) return false;
          break;

        default:
          break;
      }
    }

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  static constexpr ::std::size_t SizeInBytes() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  static constexpr bool SizeIsKnown() { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(GenericAxisView<OtherStorage> emboss_reserved_local_other) const {
    if (!has_axis_type_parameter().Known()) return false;
    if (!emboss_reserved_local_other.has_axis_type_parameter().Known())
      return false;

    if (emboss_reserved_local_other.has_axis_type_parameter()
            .ValueOrDefault() &&
        !has_axis_type_parameter().ValueOrDefault())
      return false;
    if (has_axis_type_parameter().ValueOrDefault() &&
        !emboss_reserved_local_other.has_axis_type_parameter().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_axis_type_parameter()
            .ValueOrDefault() &&
        has_axis_type_parameter().ValueOrDefault() &&
        !axis_type_parameter().Equals(
            emboss_reserved_local_other.axis_type_parameter()))
      return false;

    if (!has_value().Known()) return false;
    if (!emboss_reserved_local_other.has_value().Known()) return false;

    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
        !has_value().ValueOrDefault())
      return false;
    if (has_value().ValueOrDefault() &&
        !emboss_reserved_local_other.has_value().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_value().ValueOrDefault() &&
        has_value().ValueOrDefault() &&
        !value().Equals(emboss_reserved_local_other.value()))
      return false;

    if (!has_x().Known()) return false;
    if (!emboss_reserved_local_other.has_x().Known()) return false;

    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
        !has_x().ValueOrDefault())
      return false;
    if (has_x().ValueOrDefault() &&
        !emboss_reserved_local_other.has_x().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
        has_x().ValueOrDefault() &&
        !x().Equals(emboss_reserved_local_other.x()))
      return false;

    if (!has_y().Known()) return false;
    if (!emboss_reserved_local_other.has_y().Known()) return false;

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        !has_y().ValueOrDefault())
      return false;
    if (has_y().ValueOrDefault() &&
        !emboss_reserved_local_other.has_y().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        has_y().ValueOrDefault() &&
        !y().Equals(emboss_reserved_local_other.y()))
      return false;

    if (!has_z().Known()) return false;
    if (!emboss_reserved_local_other.has_z().Known()) return false;

    if (emboss_reserved_local_other.has_z().ValueOrDefault() &&
        !has_z().ValueOrDefault())
      return false;
    if (has_z().ValueOrDefault() &&
        !emboss_reserved_local_other.has_z().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_z().ValueOrDefault() &&
        has_z().ValueOrDefault() &&
        !z().Equals(emboss_reserved_local_other.z()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericAxisView<OtherStorage> emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_axis_type_parameter().ValueOr(false) &&
        !has_axis_type_parameter().ValueOr(false))
      return false;
    if (has_axis_type_parameter().ValueOr(false) &&
        !emboss_reserved_local_other.has_axis_type_parameter().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_axis_type_parameter().ValueOr(false) &&
        has_axis_type_parameter().ValueOr(false) &&
        !axis_type_parameter().UncheckedEquals(
            emboss_reserved_local_other.axis_type_parameter()))
      return false;

    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
        !has_value().ValueOr(false))
      return false;
    if (has_value().ValueOr(false) &&
        !emboss_reserved_local_other.has_value().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_value().ValueOr(false) &&
        has_value().ValueOr(false) &&
        !value().UncheckedEquals(emboss_reserved_local_other.value()))
      return false;

    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
        !has_x().ValueOr(false))
      return false;
    if (has_x().ValueOr(false) &&
        !emboss_reserved_local_other.has_x().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
        has_x().ValueOr(false) &&
        !x().UncheckedEquals(emboss_reserved_local_other.x()))
      return false;

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        !has_y().ValueOr(false))
      return false;
    if (has_y().ValueOr(false) &&
        !emboss_reserved_local_other.has_y().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        has_y().ValueOr(false) &&
        !y().UncheckedEquals(emboss_reserved_local_other.y()))
      return false;

    if (emboss_reserved_local_other.has_z().ValueOr(false) &&
        !has_z().ValueOr(false))
      return false;
    if (has_z().ValueOr(false) &&
        !emboss_reserved_local_other.has_z().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_z().ValueOr(false) &&
        has_z().ValueOr(false) &&
        !z().UncheckedEquals(emboss_reserved_local_other.z()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericAxisView<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericAxisView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericAxisView<OtherStorage> emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().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;
      if (emboss_reserved_local_name == "value") {
        if (!value().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "x") {
        if (!x().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "y") {
        if (!y().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "z") {
        if (!z().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_value().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          value().IsAggregate() || value().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("value: ");
        value().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() &&
                 !value().IsAggregate() && !value().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("# value: UNREADABLE\n");
      }
    }

    if (has_axis_type().ValueOr(false) &&
        emboss_reserved_local_field_options.comments()) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          axis_type().IsAggregate() || axis_type().Ok()) {
        emboss_reserved_local_stream->Write(
            emboss_reserved_local_field_options.current_indent());
        emboss_reserved_local_stream->Write("# axis_type: ");
        axis_type().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("# axis_type: UNREADABLE\n");
      }
    }

    if (has_x().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          x().IsAggregate() || x().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("x: ");
        x().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() &&
                 !x().IsAggregate() && !x().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("# x: UNREADABLE\n");
      }
    }

    if (has_y().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          y().IsAggregate() || y().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("y: ");
        y().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() &&
                 !y().IsAggregate() && !y().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("# y: UNREADABLE\n");
      }
    }

    if (has_z().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          z().IsAggregate() || z().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("z: ");
        z().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() &&
                 !z().IsAggregate() && !z().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("# z: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 private:
  constexpr ::emboss::support::MaybeConstantView</**/ ::emboss::test::AxisType>
  axis_type_parameter() const {
    return parameters_initialized_
               ? ::emboss::support::MaybeConstantView<
                     /**/ ::emboss::test::AxisType>(axis_type_parameter_)
               : ::emboss::support::MaybeConstantView<
                     /**/ ::emboss::test::AxisType>();
  }
  constexpr ::emboss::support::Maybe<bool> has_axis_type_parameter() const {
    return ::emboss::support::Maybe<bool>(parameters_initialized_);
  }

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          32, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          32>>

  value() const;
  ::emboss::support::Maybe<bool> has_value() const;

 public:
  class EmbossReservedVirtualAxisTypeView final {
   public:
    using ValueType = ::emboss::test::AxisType;

    explicit EmbossReservedVirtualAxisTypeView(
        const GenericAxisView& emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedVirtualAxisTypeView() = delete;
    EmbossReservedVirtualAxisTypeView(
        const EmbossReservedVirtualAxisTypeView&) = default;
    EmbossReservedVirtualAxisTypeView(EmbossReservedVirtualAxisTypeView&&) =
        default;
    EmbossReservedVirtualAxisTypeView& operator=(
        const EmbossReservedVirtualAxisTypeView&) = default;
    EmbossReservedVirtualAxisTypeView& operator=(
        EmbossReservedVirtualAxisTypeView&&) = default;
    ~EmbossReservedVirtualAxisTypeView() = default;

    ::emboss::test::AxisType Read() const {
      EMBOSS_CHECK(view_.has_axis_type().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();
    }
    ::emboss::test::AxisType UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    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::WriteEnumViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }

   private:
    ::emboss::support::Maybe</**/ ::emboss::test::AxisType> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.axis_type_parameter();
      const auto emboss_reserved_local_subexpr_2 =
          (emboss_reserved_local_subexpr_1.Ok()
               ? ::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
                     static_cast</**/ ::emboss::test::AxisType>(
                         emboss_reserved_local_subexpr_1.UncheckedRead()))
               : ::emboss::support::Maybe</**/ ::emboss::test::AxisType>());

      return emboss_reserved_local_subexpr_2;
    }

    static constexpr bool ValueIsOk(
        ::emboss::test::AxisType emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Maybe<bool>(true).ValueOr(false);
    }

    const GenericAxisView view_;
  };
  EmbossReservedVirtualAxisTypeView axis_type() const;
  ::emboss::support::Maybe<bool> has_axis_type() const;

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          32, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          32>>

  x() const;
  ::emboss::support::Maybe<bool> has_x() const;

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          32, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          32>>

  y() const;
  ::emboss::support::Maybe<bool> has_y() const;

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          32, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          32>>

  z() const;
  ::emboss::support::Maybe<bool> has_z() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView
  IntrinsicSizeInBytes() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;
  ::emboss::test::AxisType axis_type_parameter_;
  bool parameters_initialized_ = false;

  template <class OtherStorage>
  friend class GenericAxisView;
};
using AxisView =
    GenericAxisView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using AxisWriter =
    GenericAxisView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct EmbossReservedInternalIsGenericAxisView<GenericAxisView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericAxisView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeAxisView(::emboss::test::AxisType axis_type_parameter,
             T&& emboss_reserved_local_arg) {
  return GenericAxisView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(
      ::std::forward</**/ ::emboss::test::AxisType>(axis_type_parameter),
      ::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericAxisView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeAxisView(::emboss::test::AxisType axis_type_parameter,
             T* emboss_reserved_local_data,
             ::std::size_t emboss_reserved_local_size) {
  return GenericAxisView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      ::std::forward</**/ ::emboss::test::AxisType>(axis_type_parameter),
      emboss_reserved_local_data, emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericAxisView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedAxisView(::emboss::test::AxisType axis_type_parameter,
                    T* emboss_reserved_local_data,
                    ::std::size_t emboss_reserved_local_size) {
  return GenericAxisView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      ::std::forward</**/ ::emboss::test::AxisType>(axis_type_parameter),
      emboss_reserved_local_data, emboss_reserved_local_size);
}

namespace Config {}  // namespace Config

template <class View>
struct EmbossReservedInternalIsGenericConfigView;

template <class Storage>
class GenericConfigView final {
 public:
  GenericConfigView() : backing_() {}
  explicit GenericConfigView(Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes) {}

  template <typename OtherStorage>
  GenericConfigView(
      const GenericConfigView<OtherStorage>& emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()} {}

  template <
      typename Arg,
      typename = typename ::std::enable_if<
          !EmbossReservedInternalIsGenericConfigView<typename ::std::remove_cv<
              typename ::std::remove_reference<Arg>::type>::type>::value>::type>
  explicit GenericConfigView(Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericConfigView(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)...) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;

    if (!has_power().Known()) return false;
    if (has_power().ValueOrDefault() && !power().Ok()) return false;

    if (!has_IntrinsicSizeInBits().Known()) return false;
    if (has_IntrinsicSizeInBits().ValueOrDefault() &&
        !IntrinsicSizeInBits().Ok())
      return false;

    if (!has_MaxSizeInBits().Known()) return false;
    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok())
      return false;

    if (!has_MinSizeInBits().Known()) return false;
    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok())
      return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
           backing_.SizeInBits() >= static_cast</**/ ::std::size_t>(
                                        IntrinsicSizeInBits().UncheckedRead());
  }
  static constexpr ::std::size_t SizeInBits() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
  }
  static constexpr bool SizeIsKnown() { return IntrinsicSizeInBits().Ok(); }

  template <typename OtherStorage>
  bool Equals(
      GenericConfigView<OtherStorage> emboss_reserved_local_other) const {
    if (!has_power().Known()) return false;
    if (!emboss_reserved_local_other.has_power().Known()) return false;

    if (emboss_reserved_local_other.has_power().ValueOrDefault() &&
        !has_power().ValueOrDefault())
      return false;
    if (has_power().ValueOrDefault() &&
        !emboss_reserved_local_other.has_power().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_power().ValueOrDefault() &&
        has_power().ValueOrDefault() &&
        !power().Equals(emboss_reserved_local_other.power()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericConfigView<OtherStorage> emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_power().ValueOr(false) &&
        !has_power().ValueOr(false))
      return false;
    if (has_power().ValueOr(false) &&
        !emboss_reserved_local_other.has_power().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_power().ValueOr(false) &&
        has_power().ValueOr(false) &&
        !power().UncheckedEquals(emboss_reserved_local_other.power()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericConfigView<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericConfigView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(emboss_reserved_local_other.BackingStorage(),
                      emboss_reserved_local_other.IntrinsicSizeInBits().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericConfigView<OtherStorage> emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBits().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;
      if (emboss_reserved_local_name == "power") {
        if (!power().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_power().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          power().IsAggregate() || power().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("power: ");
        power().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() &&
                 !power().IsAggregate() && !power().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("# power: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 public:
  typename ::emboss::prelude::FlagView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          1, ::emboss::support::AllValuesAreOk>,
      typename Storage::template OffsetStorageType</**/ 0, 31>>

  power() const;
  ::emboss::support::Maybe<bool> has_power() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView
  IntrinsicSizeInBits() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView
  MaxSizeInBits() {
    return EmbossReservedDollarVirtualMaxSizeInBitsView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBitsView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView
  MinSizeInBits() {
    return EmbossReservedDollarVirtualMinSizeInBitsView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;

  template <class OtherStorage>
  friend class GenericConfigView;
};
using ConfigView =
    GenericConfigView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ConfigWriter =
    GenericConfigView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct EmbossReservedInternalIsGenericConfigView<GenericConfigView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericConfigView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeConfigView(T&& emboss_reserved_local_arg) {
  return GenericConfigView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericConfigView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeConfigView(T* emboss_reserved_local_data,
               ::std::size_t emboss_reserved_local_size) {
  return GenericConfigView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericConfigView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedConfigView(T* emboss_reserved_local_data,
                      ::std::size_t emboss_reserved_local_size) {
  return GenericConfigView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

namespace ConfigVX {

namespace EmbossReservedAnonymousField1 {

}  // namespace EmbossReservedAnonymousField1

template <class View>
struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View;

template <class Storage>
class GenericEmbossReservedAnonymousField1View final {
 public:
  GenericEmbossReservedAnonymousField1View() : backing_() {}
  explicit GenericEmbossReservedAnonymousField1View(
      Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes) {}

  template <typename OtherStorage>
  GenericEmbossReservedAnonymousField1View(
      const GenericEmbossReservedAnonymousField1View<OtherStorage>&
          emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()} {}

  template <
      typename Arg,
      typename = typename ::std::enable_if<
          !EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
              typename ::std::remove_cv<typename ::std::remove_reference<
                  Arg>::type>::type>::value>::type>
  explicit GenericEmbossReservedAnonymousField1View(
      Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericEmbossReservedAnonymousField1View(
      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)...) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;

    if (!has_power().Known()) return false;
    if (has_power().ValueOrDefault() && !power().Ok()) return false;

    if (!has_IntrinsicSizeInBits().Known()) return false;
    if (has_IntrinsicSizeInBits().ValueOrDefault() &&
        !IntrinsicSizeInBits().Ok())
      return false;

    if (!has_MaxSizeInBits().Known()) return false;
    if (has_MaxSizeInBits().ValueOrDefault() && !MaxSizeInBits().Ok())
      return false;

    if (!has_MinSizeInBits().Known()) return false;
    if (has_MinSizeInBits().ValueOrDefault() && !MinSizeInBits().Ok())
      return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBits().Ok() &&
           backing_.SizeInBits() >= static_cast</**/ ::std::size_t>(
                                        IntrinsicSizeInBits().UncheckedRead());
  }
  static constexpr ::std::size_t SizeInBits() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBits().Read());
  }
  static constexpr bool SizeIsKnown() { return IntrinsicSizeInBits().Ok(); }

  template <typename OtherStorage>
  bool Equals(GenericEmbossReservedAnonymousField1View<OtherStorage>
                  emboss_reserved_local_other) const {
    if (!has_power().Known()) return false;
    if (!emboss_reserved_local_other.has_power().Known()) return false;

    if (emboss_reserved_local_other.has_power().ValueOrDefault() &&
        !has_power().ValueOrDefault())
      return false;
    if (has_power().ValueOrDefault() &&
        !emboss_reserved_local_other.has_power().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_power().ValueOrDefault() &&
        has_power().ValueOrDefault() &&
        !power().Equals(emboss_reserved_local_other.power()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(GenericEmbossReservedAnonymousField1View<OtherStorage>
                           emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_power().ValueOr(false) &&
        !has_power().ValueOr(false))
      return false;
    if (has_power().ValueOr(false) &&
        !emboss_reserved_local_other.has_power().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_power().ValueOr(false) &&
        has_power().ValueOr(false) &&
        !power().UncheckedEquals(emboss_reserved_local_other.power()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(GenericEmbossReservedAnonymousField1View<OtherStorage>
                             emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBits().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(GenericEmbossReservedAnonymousField1View<OtherStorage>
                    emboss_reserved_local_other) const {
    backing_.CopyFrom(emboss_reserved_local_other.BackingStorage(),
                      emboss_reserved_local_other.IntrinsicSizeInBits().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(GenericEmbossReservedAnonymousField1View<OtherStorage>
                         emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBits().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;
      if (emboss_reserved_local_name == "power") {
        if (!power().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_power().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          power().IsAggregate() || power().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("power: ");
        power().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() &&
                 !power().IsAggregate() && !power().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("# power: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 public:
  typename ::emboss::prelude::FlagView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          1, ::emboss::support::AllValuesAreOk>,
      typename Storage::template OffsetStorageType</**/ 0, 31>>

  power() const;
  ::emboss::support::Maybe<bool> has_power() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBitsView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBitsView
  IntrinsicSizeInBits() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBitsView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBits() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMaxSizeInBitsView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBitsView
  MaxSizeInBits() {
    return EmbossReservedDollarVirtualMaxSizeInBitsView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBits() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBitsView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBitsView
  MinSizeInBits() {
    return EmbossReservedDollarVirtualMinSizeInBitsView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBits() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;

  template <class OtherStorage>
  friend class GenericEmbossReservedAnonymousField1View;
};
using EmbossReservedAnonymousField1View =
    GenericEmbossReservedAnonymousField1View<
        /**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using EmbossReservedAnonymousField1Writer =
    GenericEmbossReservedAnonymousField1View<
        /**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct EmbossReservedInternalIsGenericEmbossReservedAnonymousField1View<
    GenericEmbossReservedAnonymousField1View<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericEmbossReservedAnonymousField1View<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeEmbossReservedAnonymousField1View(T&& emboss_reserved_local_arg) {
  return GenericEmbossReservedAnonymousField1View<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericEmbossReservedAnonymousField1View<
    /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeEmbossReservedAnonymousField1View(
    T* emboss_reserved_local_data, ::std::size_t emboss_reserved_local_size) {
  return GenericEmbossReservedAnonymousField1View<
      /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericEmbossReservedAnonymousField1View<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedEmbossReservedAnonymousField1View(
    T* emboss_reserved_local_data, ::std::size_t emboss_reserved_local_size) {
  return GenericEmbossReservedAnonymousField1View<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

}  // namespace ConfigVX

template <class View>
struct EmbossReservedInternalIsGenericConfigVXView;

template <class Storage>
class GenericConfigVXView final {
 public:
  GenericConfigVXView() : backing_() {}
  explicit GenericConfigVXView(Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes) {}

  template <typename OtherStorage>
  GenericConfigVXView(
      const GenericConfigVXView<OtherStorage>& emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()} {}

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericConfigVXView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericConfigVXView(Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericConfigVXView(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)...) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;

    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
        !emboss_reserved_anonymous_field_1().Ok())
      return false;

    if (!has_gain().Known()) return false;
    if (has_gain().ValueOrDefault() && !gain().Ok()) return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    if (!has_power().Known()) return false;
    if (has_power().ValueOrDefault() && !power().Ok()) return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  static constexpr ::std::size_t SizeInBytes() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  static constexpr bool SizeIsKnown() { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(
      GenericConfigVXView<OtherStorage> emboss_reserved_local_other) const {
    if (!has_emboss_reserved_anonymous_field_1().Known()) return false;
    if (!emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1()
             .Known())
      return false;

    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1()
            .ValueOrDefault() &&
        !has_emboss_reserved_anonymous_field_1().ValueOrDefault())
      return false;
    if (has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1()
             .ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1()
            .ValueOrDefault() &&
        has_emboss_reserved_anonymous_field_1().ValueOrDefault() &&
        !emboss_reserved_anonymous_field_1().Equals(
            emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
      return false;

    if (!has_gain().Known()) return false;
    if (!emboss_reserved_local_other.has_gain().Known()) return false;

    if (emboss_reserved_local_other.has_gain().ValueOrDefault() &&
        !has_gain().ValueOrDefault())
      return false;
    if (has_gain().ValueOrDefault() &&
        !emboss_reserved_local_other.has_gain().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_gain().ValueOrDefault() &&
        has_gain().ValueOrDefault() &&
        !gain().Equals(emboss_reserved_local_other.gain()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericConfigVXView<OtherStorage> emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1()
            .ValueOr(false) &&
        !has_emboss_reserved_anonymous_field_1().ValueOr(false))
      return false;
    if (has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
        !emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1()
             .ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_emboss_reserved_anonymous_field_1()
            .ValueOr(false) &&
        has_emboss_reserved_anonymous_field_1().ValueOr(false) &&
        !emboss_reserved_anonymous_field_1().UncheckedEquals(
            emboss_reserved_local_other.emboss_reserved_anonymous_field_1()))
      return false;

    if (emboss_reserved_local_other.has_gain().ValueOr(false) &&
        !has_gain().ValueOr(false))
      return false;
    if (has_gain().ValueOr(false) &&
        !emboss_reserved_local_other.has_gain().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_gain().ValueOr(false) &&
        has_gain().ValueOr(false) &&
        !gain().UncheckedEquals(emboss_reserved_local_other.gain()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericConfigVXView<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericConfigVXView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericConfigVXView<OtherStorage> emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().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;
      if (emboss_reserved_local_name == "power") {
        if (!power().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "gain") {
        if (!gain().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_power().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          power().IsAggregate() || power().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("power: ");
        power().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() &&
                 !power().IsAggregate() && !power().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("# power: UNREADABLE\n");
      }
    }

    if (has_gain().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          gain().IsAggregate() || gain().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("gain: ");
        gain().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() &&
                 !gain().IsAggregate() && !gain().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("# gain: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 private:
  typename ::emboss::test::ConfigVX::GenericEmbossReservedAnonymousField1View<
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          32>>

  emboss_reserved_anonymous_field_1() const;
  ::emboss::support::Maybe<bool> has_emboss_reserved_anonymous_field_1() const;

 public:
  auto power() const
      -> decltype(this->emboss_reserved_anonymous_field_1().power()) {
    return has_power().ValueOrDefault()
               ? emboss_reserved_anonymous_field_1().power()
               : decltype(this->emboss_reserved_anonymous_field_1().power())();
  }
  ::emboss::support::Maybe<bool> has_power() const;

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          32, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 4>>,
          32>>

  gain() const;
  ::emboss::support::Maybe<bool> has_gain() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView
  IntrinsicSizeInBytes() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;

  template <class OtherStorage>
  friend class GenericConfigVXView;
};
using ConfigVXView =
    GenericConfigVXView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ConfigVXWriter =
    GenericConfigVXView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct EmbossReservedInternalIsGenericConfigVXView<
    GenericConfigVXView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericConfigVXView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeConfigVXView(T&& emboss_reserved_local_arg) {
  return GenericConfigVXView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericConfigVXView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeConfigVXView(T* emboss_reserved_local_data,
                 ::std::size_t emboss_reserved_local_size) {
  return GenericConfigVXView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericConfigVXView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedConfigVXView(T* emboss_reserved_local_data,
                        ::std::size_t emboss_reserved_local_size) {
  return GenericConfigVXView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

namespace StructWithUnusedParameter {}  // namespace StructWithUnusedParameter

template <class View>
struct EmbossReservedInternalIsGenericStructWithUnusedParameterView;

template <class Storage>
class GenericStructWithUnusedParameterView final {
 public:
  GenericStructWithUnusedParameterView() : backing_() {}
  explicit GenericStructWithUnusedParameterView(
      ::std::int32_t x, Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes),
        x_(x),
        parameters_initialized_(true) {}

  template <typename OtherStorage>
  GenericStructWithUnusedParameterView(
      const GenericStructWithUnusedParameterView<OtherStorage>&
          emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()},
        x_(emboss_reserved_local_other.x_),
        parameters_initialized_(
            emboss_reserved_local_other.parameters_initialized_) {}

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericStructWithUnusedParameterView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericStructWithUnusedParameterView(::std::int32_t x,
                                                Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)),
        x_(x),
        parameters_initialized_(true) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericStructWithUnusedParameterView(
      ::std::int32_t x, 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)...),
        x_(x),
        parameters_initialized_(true) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;
    if (!parameters_initialized_) return false;

    if (!has_y().Known()) return false;
    if (has_y().ValueOrDefault() && !y().Ok()) return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  static constexpr ::std::size_t SizeInBytes() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  static constexpr bool SizeIsKnown() { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(GenericStructWithUnusedParameterView<OtherStorage>
                  emboss_reserved_local_other) const {
    if (!has_x().Known()) return false;
    if (!emboss_reserved_local_other.has_x().Known()) return false;

    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
        !has_x().ValueOrDefault())
      return false;
    if (has_x().ValueOrDefault() &&
        !emboss_reserved_local_other.has_x().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
        has_x().ValueOrDefault() &&
        !x().Equals(emboss_reserved_local_other.x()))
      return false;

    if (!has_y().Known()) return false;
    if (!emboss_reserved_local_other.has_y().Known()) return false;

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        !has_y().ValueOrDefault())
      return false;
    if (has_y().ValueOrDefault() &&
        !emboss_reserved_local_other.has_y().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_y().ValueOrDefault() &&
        has_y().ValueOrDefault() &&
        !y().Equals(emboss_reserved_local_other.y()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(GenericStructWithUnusedParameterView<OtherStorage>
                           emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
        !has_x().ValueOr(false))
      return false;
    if (has_x().ValueOr(false) &&
        !emboss_reserved_local_other.has_x().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
        has_x().ValueOr(false) &&
        !x().UncheckedEquals(emboss_reserved_local_other.x()))
      return false;

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        !has_y().ValueOr(false))
      return false;
    if (has_y().ValueOr(false) &&
        !emboss_reserved_local_other.has_y().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_y().ValueOr(false) &&
        has_y().ValueOr(false) &&
        !y().UncheckedEquals(emboss_reserved_local_other.y()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(GenericStructWithUnusedParameterView<OtherStorage>
                             emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(GenericStructWithUnusedParameterView<OtherStorage>
                    emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(GenericStructWithUnusedParameterView<OtherStorage>
                         emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().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;
      if (emboss_reserved_local_name == "y") {
        if (!y().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_y().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          y().IsAggregate() || y().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("y: ");
        y().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() &&
                 !y().IsAggregate() && !y().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("# y: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 private:
  constexpr ::emboss::support::MaybeConstantView</**/ ::std::int32_t> x()
      const {
    return parameters_initialized_
               ? ::emboss::support::MaybeConstantView</**/ ::std::int32_t>(x_)
               : ::emboss::support::MaybeConstantView</**/ ::std::int32_t>();
  }
  constexpr ::emboss::support::Maybe<bool> has_x() const {
    return ::emboss::support::Maybe<bool>(parameters_initialized_);
  }

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

  y() const;
  ::emboss::support::Maybe<bool> has_y() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView
  IntrinsicSizeInBytes() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;
  ::std::int32_t x_;
  bool parameters_initialized_ = false;

  template <class OtherStorage>
  friend class GenericStructWithUnusedParameterView;
};
using StructWithUnusedParameterView = GenericStructWithUnusedParameterView<
    /**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using StructWithUnusedParameterWriter = GenericStructWithUnusedParameterView<
    /**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct EmbossReservedInternalIsGenericStructWithUnusedParameterView<
    GenericStructWithUnusedParameterView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericStructWithUnusedParameterView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeStructWithUnusedParameterView(::std::int32_t x,
                                  T&& emboss_reserved_local_arg) {
  return GenericStructWithUnusedParameterView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward</**/ ::std::int32_t>(x),
                 ::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericStructWithUnusedParameterView<
    /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeStructWithUnusedParameterView(::std::int32_t x,
                                  T* emboss_reserved_local_data,
                                  ::std::size_t emboss_reserved_local_size) {
  return GenericStructWithUnusedParameterView<
      /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      ::std::forward</**/ ::std::int32_t>(x), emboss_reserved_local_data,
      emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericStructWithUnusedParameterView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedStructWithUnusedParameterView(
    ::std::int32_t x, T* emboss_reserved_local_data,
    ::std::size_t emboss_reserved_local_size) {
  return GenericStructWithUnusedParameterView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      ::std::forward</**/ ::std::int32_t>(x), emboss_reserved_local_data,
      emboss_reserved_local_size);
}

namespace StructContainingStructWithUnusedParameter {

}  // namespace StructContainingStructWithUnusedParameter

template <class View>
struct
    EmbossReservedInternalIsGenericStructContainingStructWithUnusedParameterView;

template <class Storage>
class GenericStructContainingStructWithUnusedParameterView final {
 public:
  GenericStructContainingStructWithUnusedParameterView() : backing_() {}
  explicit GenericStructContainingStructWithUnusedParameterView(
      Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes) {}

  template <typename OtherStorage>
  GenericStructContainingStructWithUnusedParameterView(
      const GenericStructContainingStructWithUnusedParameterView<OtherStorage>&
          emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()} {}

  template <
      typename Arg,
      typename = typename ::std::enable_if<
          !EmbossReservedInternalIsGenericStructContainingStructWithUnusedParameterView<
              typename ::std::remove_cv<typename ::std::remove_reference<
                  Arg>::type>::type>::value>::type>
  explicit GenericStructContainingStructWithUnusedParameterView(
      Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericStructContainingStructWithUnusedParameterView(
      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)...) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;

    if (!has_x().Known()) return false;
    if (has_x().ValueOrDefault() && !x().Ok()) return false;

    if (!has_swup().Known()) return false;
    if (has_swup().ValueOrDefault() && !swup().Ok()) return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  static constexpr ::std::size_t SizeInBytes() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  static constexpr bool SizeIsKnown() { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(GenericStructContainingStructWithUnusedParameterView<OtherStorage>
                  emboss_reserved_local_other) const {
    if (!has_x().Known()) return false;
    if (!emboss_reserved_local_other.has_x().Known()) return false;

    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
        !has_x().ValueOrDefault())
      return false;
    if (has_x().ValueOrDefault() &&
        !emboss_reserved_local_other.has_x().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
        has_x().ValueOrDefault() &&
        !x().Equals(emboss_reserved_local_other.x()))
      return false;

    if (!has_swup().Known()) return false;
    if (!emboss_reserved_local_other.has_swup().Known()) return false;

    if (emboss_reserved_local_other.has_swup().ValueOrDefault() &&
        !has_swup().ValueOrDefault())
      return false;
    if (has_swup().ValueOrDefault() &&
        !emboss_reserved_local_other.has_swup().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_swup().ValueOrDefault() &&
        has_swup().ValueOrDefault() &&
        !swup().Equals(emboss_reserved_local_other.swup()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericStructContainingStructWithUnusedParameterView<OtherStorage>
          emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
        !has_x().ValueOr(false))
      return false;
    if (has_x().ValueOr(false) &&
        !emboss_reserved_local_other.has_x().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
        has_x().ValueOr(false) &&
        !x().UncheckedEquals(emboss_reserved_local_other.x()))
      return false;

    if (emboss_reserved_local_other.has_swup().ValueOr(false) &&
        !has_swup().ValueOr(false))
      return false;
    if (has_swup().ValueOr(false) &&
        !emboss_reserved_local_other.has_swup().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_swup().ValueOr(false) &&
        has_swup().ValueOr(false) &&
        !swup().UncheckedEquals(emboss_reserved_local_other.swup()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericStructContainingStructWithUnusedParameterView<OtherStorage>
          emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericStructContainingStructWithUnusedParameterView<OtherStorage>
          emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericStructContainingStructWithUnusedParameterView<OtherStorage>
          emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().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;
      if (emboss_reserved_local_name == "x") {
        if (!x().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "swup") {
        if (!swup().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_x().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          x().IsAggregate() || x().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("x: ");
        x().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() &&
                 !x().IsAggregate() && !x().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("# x: UNREADABLE\n");
      }
    }

    if (has_swup().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          swup().IsAggregate() || swup().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("swup: ");
        swup().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() &&
                 !swup().IsAggregate() && !swup().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("# swup: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 1>>,
          8>>

  x() const;
  ::emboss::support::Maybe<bool> has_x() const;

 public:
  typename ::emboss::test::GenericStructWithUnusedParameterView<
      typename Storage::template OffsetStorageType</**/ 0, 0>>

  swup() const;
  ::emboss::support::Maybe<bool> has_swup() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView
  IntrinsicSizeInBytes() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;

  template <class OtherStorage>
  friend class GenericStructContainingStructWithUnusedParameterView;
};
using StructContainingStructWithUnusedParameterView =
    GenericStructContainingStructWithUnusedParameterView<
        /**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using StructContainingStructWithUnusedParameterWriter =
    GenericStructContainingStructWithUnusedParameterView<
        /**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct
    EmbossReservedInternalIsGenericStructContainingStructWithUnusedParameterView<
        GenericStructContainingStructWithUnusedParameterView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericStructContainingStructWithUnusedParameterView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeStructContainingStructWithUnusedParameterView(
    T&& emboss_reserved_local_arg) {
  return GenericStructContainingStructWithUnusedParameterView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericStructContainingStructWithUnusedParameterView<
    /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeStructContainingStructWithUnusedParameterView(
    T* emboss_reserved_local_data, ::std::size_t emboss_reserved_local_size) {
  return GenericStructContainingStructWithUnusedParameterView<
      /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericStructContainingStructWithUnusedParameterView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedStructContainingStructWithUnusedParameterView(
    T* emboss_reserved_local_data, ::std::size_t emboss_reserved_local_size) {
  return GenericStructContainingStructWithUnusedParameterView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

namespace BiasedValue {}  // namespace BiasedValue

template <class View>
struct EmbossReservedInternalIsGenericBiasedValueView;

template <class Storage>
class GenericBiasedValueView final {
 public:
  GenericBiasedValueView() : backing_() {}
  explicit GenericBiasedValueView(::std::int32_t bias,
                                  Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes),
        bias_(bias),
        parameters_initialized_(true) {}

  template <typename OtherStorage>
  GenericBiasedValueView(
      const GenericBiasedValueView<OtherStorage>& emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()},
        bias_(emboss_reserved_local_other.bias_),
        parameters_initialized_(
            emboss_reserved_local_other.parameters_initialized_) {}

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericBiasedValueView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericBiasedValueView(::std::int32_t bias,
                                  Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)),
        bias_(bias),
        parameters_initialized_(true) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericBiasedValueView(::std::int32_t bias,
                                  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)...),
        bias_(bias),
        parameters_initialized_(true) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;
    if (!parameters_initialized_) return false;

    if (!has_raw_value().Known()) return false;
    if (has_raw_value().ValueOrDefault() && !raw_value().Ok()) return false;

    if (!has_value().Known()) return false;
    if (has_value().ValueOrDefault() && !value().Ok()) return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  static constexpr ::std::size_t SizeInBytes() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  static constexpr bool SizeIsKnown() { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(
      GenericBiasedValueView<OtherStorage> emboss_reserved_local_other) const {
    if (!has_bias().Known()) return false;
    if (!emboss_reserved_local_other.has_bias().Known()) return false;

    if (emboss_reserved_local_other.has_bias().ValueOrDefault() &&
        !has_bias().ValueOrDefault())
      return false;
    if (has_bias().ValueOrDefault() &&
        !emboss_reserved_local_other.has_bias().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_bias().ValueOrDefault() &&
        has_bias().ValueOrDefault() &&
        !bias().Equals(emboss_reserved_local_other.bias()))
      return false;

    if (!has_raw_value().Known()) return false;
    if (!emboss_reserved_local_other.has_raw_value().Known()) return false;

    if (emboss_reserved_local_other.has_raw_value().ValueOrDefault() &&
        !has_raw_value().ValueOrDefault())
      return false;
    if (has_raw_value().ValueOrDefault() &&
        !emboss_reserved_local_other.has_raw_value().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_raw_value().ValueOrDefault() &&
        has_raw_value().ValueOrDefault() &&
        !raw_value().Equals(emboss_reserved_local_other.raw_value()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(
      GenericBiasedValueView<OtherStorage> emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_bias().ValueOr(false) &&
        !has_bias().ValueOr(false))
      return false;
    if (has_bias().ValueOr(false) &&
        !emboss_reserved_local_other.has_bias().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_bias().ValueOr(false) &&
        has_bias().ValueOr(false) &&
        !bias().UncheckedEquals(emboss_reserved_local_other.bias()))
      return false;

    if (emboss_reserved_local_other.has_raw_value().ValueOr(false) &&
        !has_raw_value().ValueOr(false))
      return false;
    if (has_raw_value().ValueOr(false) &&
        !emboss_reserved_local_other.has_raw_value().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_raw_value().ValueOr(false) &&
        has_raw_value().ValueOr(false) &&
        !raw_value().UncheckedEquals(emboss_reserved_local_other.raw_value()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericBiasedValueView<OtherStorage> emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(
      GenericBiasedValueView<OtherStorage> emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(
      GenericBiasedValueView<OtherStorage> emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().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;
      if (emboss_reserved_local_name == "raw_value") {
        if (!raw_value().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_raw_value().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          raw_value().IsAggregate() || raw_value().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("raw_value: ");
        raw_value().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() &&
                 !raw_value().IsAggregate() && !raw_value().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("# raw_value: UNREADABLE\n");
      }
    }

    if (has_value().ValueOr(false) &&
        emboss_reserved_local_field_options.comments()) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          value().IsAggregate() || value().Ok()) {
        emboss_reserved_local_stream->Write(
            emboss_reserved_local_field_options.current_indent());
        emboss_reserved_local_stream->Write("# value: ");
        value().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("# value: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 private:
  constexpr ::emboss::support::MaybeConstantView</**/ ::std::int32_t> bias()
      const {
    return parameters_initialized_
               ? ::emboss::support::MaybeConstantView</**/ ::std::int32_t>(
                     bias_)
               : ::emboss::support::MaybeConstantView</**/ ::std::int32_t>();
  }
  constexpr ::emboss::support::Maybe<bool> has_bias() const {
    return ::emboss::support::Maybe<bool>(parameters_initialized_);
  }

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

  raw_value() const;
  ::emboss::support::Maybe<bool> has_raw_value() const;

 public:
  class EmbossReservedVirtualValueView final {
   public:
    using ValueType = ::std::int32_t;

    explicit EmbossReservedVirtualValueView(
        const GenericBiasedValueView& emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedVirtualValueView() = delete;
    EmbossReservedVirtualValueView(const EmbossReservedVirtualValueView&) =
        default;
    EmbossReservedVirtualValueView(EmbossReservedVirtualValueView&&) = default;
    EmbossReservedVirtualValueView& operator=(
        const EmbossReservedVirtualValueView&) = default;
    EmbossReservedVirtualValueView& operator=(
        EmbossReservedVirtualValueView&&) = default;
    ~EmbossReservedVirtualValueView() = default;

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_value().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();
    }
    ::std::int32_t UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }

   private:
    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.raw_value();
      const auto emboss_reserved_local_subexpr_2 =
          (emboss_reserved_local_subexpr_1.Ok()
               ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                     static_cast</**/ ::std::int32_t>(
                         emboss_reserved_local_subexpr_1.UncheckedRead()))
               : ::emboss::support::Maybe</**/ ::std::int32_t>());
      const auto emboss_reserved_local_subexpr_3 = view_.bias();
      const auto emboss_reserved_local_subexpr_4 =
          (emboss_reserved_local_subexpr_3.Ok()
               ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                     static_cast</**/ ::std::int32_t>(
                         emboss_reserved_local_subexpr_3.UncheckedRead()))
               : ::emboss::support::Maybe</**/ ::std::int32_t>());
      const auto emboss_reserved_local_subexpr_5 =
          ::emboss::support::Sum</**/ ::std::int32_t, ::std::int32_t,
                                 ::std::int32_t, ::std::int32_t>(
              emboss_reserved_local_subexpr_2, emboss_reserved_local_subexpr_4);

      return emboss_reserved_local_subexpr_5;
    }

    static constexpr bool ValueIsOk(
        ::std::int32_t emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Maybe<bool>(true).ValueOr(false);
    }

    const GenericBiasedValueView view_;
  };
  EmbossReservedVirtualValueView value() const;
  ::emboss::support::Maybe<bool> has_value() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView
  IntrinsicSizeInBytes() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;
  ::std::int32_t bias_;
  bool parameters_initialized_ = false;

  template <class OtherStorage>
  friend class GenericBiasedValueView;
};
using BiasedValueView =
    GenericBiasedValueView</**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using BiasedValueWriter =
    GenericBiasedValueView</**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct EmbossReservedInternalIsGenericBiasedValueView<
    GenericBiasedValueView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericBiasedValueView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeBiasedValueView(::std::int32_t bias, T&& emboss_reserved_local_arg) {
  return GenericBiasedValueView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward</**/ ::std::int32_t>(bias),
                 ::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericBiasedValueView</**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeBiasedValueView(::std::int32_t bias, T* emboss_reserved_local_data,
                    ::std::size_t emboss_reserved_local_size) {
  return GenericBiasedValueView<
      /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      ::std::forward</**/ ::std::int32_t>(bias), emboss_reserved_local_data,
      emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericBiasedValueView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedBiasedValueView(::std::int32_t bias, T* emboss_reserved_local_data,
                           ::std::size_t emboss_reserved_local_size) {
  return GenericBiasedValueView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      ::std::forward</**/ ::std::int32_t>(bias), emboss_reserved_local_data,
      emboss_reserved_local_size);
}

namespace VirtualFirstFieldWithParam {}  // namespace VirtualFirstFieldWithParam

template <class View>
struct EmbossReservedInternalIsGenericVirtualFirstFieldWithParamView;

template <class Storage>
class GenericVirtualFirstFieldWithParamView final {
 public:
  GenericVirtualFirstFieldWithParamView() : backing_() {}
  explicit GenericVirtualFirstFieldWithParamView(
      ::std::int32_t param, Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes),
        param_(param),
        parameters_initialized_(true) {}

  template <typename OtherStorage>
  GenericVirtualFirstFieldWithParamView(
      const GenericVirtualFirstFieldWithParamView<OtherStorage>&
          emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()},
        param_(emboss_reserved_local_other.param_),
        parameters_initialized_(
            emboss_reserved_local_other.parameters_initialized_) {}

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericVirtualFirstFieldWithParamView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericVirtualFirstFieldWithParamView(
      ::std::int32_t param, Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)),
        param_(param),
        parameters_initialized_(true) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericVirtualFirstFieldWithParamView(
      ::std::int32_t param, 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)...),
        param_(param),
        parameters_initialized_(true) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;
    if (!parameters_initialized_) return false;

    if (!has_x().Known()) return false;
    if (has_x().ValueOrDefault() && !x().Ok()) return false;

    if (!has_value().Known()) return false;
    if (has_value().ValueOrDefault() && !value().Ok()) return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  static constexpr ::std::size_t SizeInBytes() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  static constexpr bool SizeIsKnown() { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(GenericVirtualFirstFieldWithParamView<OtherStorage>
                  emboss_reserved_local_other) const {
    if (!has_param().Known()) return false;
    if (!emboss_reserved_local_other.has_param().Known()) return false;

    if (emboss_reserved_local_other.has_param().ValueOrDefault() &&
        !has_param().ValueOrDefault())
      return false;
    if (has_param().ValueOrDefault() &&
        !emboss_reserved_local_other.has_param().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_param().ValueOrDefault() &&
        has_param().ValueOrDefault() &&
        !param().Equals(emboss_reserved_local_other.param()))
      return false;

    if (!has_x().Known()) return false;
    if (!emboss_reserved_local_other.has_x().Known()) return false;

    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
        !has_x().ValueOrDefault())
      return false;
    if (has_x().ValueOrDefault() &&
        !emboss_reserved_local_other.has_x().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
        has_x().ValueOrDefault() &&
        !x().Equals(emboss_reserved_local_other.x()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(GenericVirtualFirstFieldWithParamView<OtherStorage>
                           emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_param().ValueOr(false) &&
        !has_param().ValueOr(false))
      return false;
    if (has_param().ValueOr(false) &&
        !emboss_reserved_local_other.has_param().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_param().ValueOr(false) &&
        has_param().ValueOr(false) &&
        !param().UncheckedEquals(emboss_reserved_local_other.param()))
      return false;

    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
        !has_x().ValueOr(false))
      return false;
    if (has_x().ValueOr(false) &&
        !emboss_reserved_local_other.has_x().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
        has_x().ValueOr(false) &&
        !x().UncheckedEquals(emboss_reserved_local_other.x()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(GenericVirtualFirstFieldWithParamView<OtherStorage>
                             emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(GenericVirtualFirstFieldWithParamView<OtherStorage>
                    emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(GenericVirtualFirstFieldWithParamView<OtherStorage>
                         emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().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;
      if (emboss_reserved_local_name == "x") {
        if (!x().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "value") {
        if (!value().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_x().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          x().IsAggregate() || x().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("x: ");
        x().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() &&
                 !x().IsAggregate() && !x().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("# x: UNREADABLE\n");
      }
    }

    if (has_value().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          value().IsAggregate() || value().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("value: ");
        value().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() &&
                 !value().IsAggregate() && !value().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("# value: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 private:
  constexpr ::emboss::support::MaybeConstantView</**/ ::std::int32_t> param()
      const {
    return parameters_initialized_
               ? ::emboss::support::MaybeConstantView</**/ ::std::int32_t>(
                     param_)
               : ::emboss::support::MaybeConstantView</**/ ::std::int32_t>();
  }
  constexpr ::emboss::support::Maybe<bool> has_param() const {
    return ::emboss::support::Maybe<bool>(parameters_initialized_);
  }

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

  x() const;
  ::emboss::support::Maybe<bool> has_x() const;

 public:
  auto value() const -> decltype(this->x()) {
    return has_value().ValueOrDefault() ? x() : decltype(this->x())();
  }
  ::emboss::support::Maybe<bool> has_value() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView
  IntrinsicSizeInBytes() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;
  ::std::int32_t param_;
  bool parameters_initialized_ = false;

  template <class OtherStorage>
  friend class GenericVirtualFirstFieldWithParamView;
};
using VirtualFirstFieldWithParamView = GenericVirtualFirstFieldWithParamView<
    /**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using VirtualFirstFieldWithParamWriter = GenericVirtualFirstFieldWithParamView<
    /**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct EmbossReservedInternalIsGenericVirtualFirstFieldWithParamView<
    GenericVirtualFirstFieldWithParamView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericVirtualFirstFieldWithParamView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeVirtualFirstFieldWithParamView(::std::int32_t param,
                                   T&& emboss_reserved_local_arg) {
  return GenericVirtualFirstFieldWithParamView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward</**/ ::std::int32_t>(param),
                 ::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericVirtualFirstFieldWithParamView<
    /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeVirtualFirstFieldWithParamView(::std::int32_t param,
                                   T* emboss_reserved_local_data,
                                   ::std::size_t emboss_reserved_local_size) {
  return GenericVirtualFirstFieldWithParamView<
      /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      ::std::forward</**/ ::std::int32_t>(param), emboss_reserved_local_data,
      emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericVirtualFirstFieldWithParamView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedVirtualFirstFieldWithParamView(
    ::std::int32_t param, T* emboss_reserved_local_data,
    ::std::size_t emboss_reserved_local_size) {
  return GenericVirtualFirstFieldWithParamView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      ::std::forward</**/ ::std::int32_t>(param), emboss_reserved_local_data,
      emboss_reserved_local_size);
}

namespace ConstVirtualFirstFieldWithParam {

}  // namespace ConstVirtualFirstFieldWithParam

template <class View>
struct EmbossReservedInternalIsGenericConstVirtualFirstFieldWithParamView;

template <class Storage>
class GenericConstVirtualFirstFieldWithParamView final {
 public:
  GenericConstVirtualFirstFieldWithParamView() : backing_() {}
  explicit GenericConstVirtualFirstFieldWithParamView(
      ::std::int32_t param, Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes),
        param_(param),
        parameters_initialized_(true) {}

  template <typename OtherStorage>
  GenericConstVirtualFirstFieldWithParamView(
      const GenericConstVirtualFirstFieldWithParamView<OtherStorage>&
          emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()},
        param_(emboss_reserved_local_other.param_),
        parameters_initialized_(
            emboss_reserved_local_other.parameters_initialized_) {}

  template <
      typename Arg,
      typename = typename ::std::enable_if<
          !EmbossReservedInternalIsGenericConstVirtualFirstFieldWithParamView<
              typename ::std::remove_cv<typename ::std::remove_reference<
                  Arg>::type>::type>::value>::type>
  explicit GenericConstVirtualFirstFieldWithParamView(
      ::std::int32_t param, Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)),
        param_(param),
        parameters_initialized_(true) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericConstVirtualFirstFieldWithParamView(
      ::std::int32_t param, 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)...),
        param_(param),
        parameters_initialized_(true) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;
    if (!parameters_initialized_) return false;

    if (!has_value().Known()) return false;
    if (has_value().ValueOrDefault() && !value().Ok()) return false;

    if (!has_x().Known()) return false;
    if (has_x().ValueOrDefault() && !x().Ok()) return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  static constexpr ::std::size_t SizeInBytes() {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  static constexpr bool SizeIsKnown() { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(GenericConstVirtualFirstFieldWithParamView<OtherStorage>
                  emboss_reserved_local_other) const {
    if (!has_param().Known()) return false;
    if (!emboss_reserved_local_other.has_param().Known()) return false;

    if (emboss_reserved_local_other.has_param().ValueOrDefault() &&
        !has_param().ValueOrDefault())
      return false;
    if (has_param().ValueOrDefault() &&
        !emboss_reserved_local_other.has_param().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_param().ValueOrDefault() &&
        has_param().ValueOrDefault() &&
        !param().Equals(emboss_reserved_local_other.param()))
      return false;

    if (!has_x().Known()) return false;
    if (!emboss_reserved_local_other.has_x().Known()) return false;

    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
        !has_x().ValueOrDefault())
      return false;
    if (has_x().ValueOrDefault() &&
        !emboss_reserved_local_other.has_x().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_x().ValueOrDefault() &&
        has_x().ValueOrDefault() &&
        !x().Equals(emboss_reserved_local_other.x()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(GenericConstVirtualFirstFieldWithParamView<OtherStorage>
                           emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_param().ValueOr(false) &&
        !has_param().ValueOr(false))
      return false;
    if (has_param().ValueOr(false) &&
        !emboss_reserved_local_other.has_param().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_param().ValueOr(false) &&
        has_param().ValueOr(false) &&
        !param().UncheckedEquals(emboss_reserved_local_other.param()))
      return false;

    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
        !has_x().ValueOr(false))
      return false;
    if (has_x().ValueOr(false) &&
        !emboss_reserved_local_other.has_x().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_x().ValueOr(false) &&
        has_x().ValueOr(false) &&
        !x().UncheckedEquals(emboss_reserved_local_other.x()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(
      GenericConstVirtualFirstFieldWithParamView<OtherStorage>
          emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(GenericConstVirtualFirstFieldWithParamView<OtherStorage>
                    emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(GenericConstVirtualFirstFieldWithParamView<OtherStorage>
                         emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().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;
      if (emboss_reserved_local_name == "x") {
        if (!x().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_value().ValueOr(false) &&
        emboss_reserved_local_field_options.comments()) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          value().IsAggregate() || value().Ok()) {
        emboss_reserved_local_stream->Write(
            emboss_reserved_local_field_options.current_indent());
        emboss_reserved_local_stream->Write("# value: ");
        value().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("# value: UNREADABLE\n");
      }
    }

    if (has_x().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          x().IsAggregate() || x().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("x: ");
        x().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() &&
                 !x().IsAggregate() && !x().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("# x: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 private:
  constexpr ::emboss::support::MaybeConstantView</**/ ::std::int32_t> param()
      const {
    return parameters_initialized_
               ? ::emboss::support::MaybeConstantView</**/ ::std::int32_t>(
                     param_)
               : ::emboss::support::MaybeConstantView</**/ ::std::int32_t>();
  }
  constexpr ::emboss::support::Maybe<bool> has_param() const {
    return ::emboss::support::Maybe<bool>(parameters_initialized_);
  }

 public:
  class EmbossReservedVirtualValueView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedVirtualValueView value() {
    return EmbossReservedVirtualValueView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_value() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

  x() const;
  ::emboss::support::Maybe<bool> has_x() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualIntrinsicSizeInBytesView
  IntrinsicSizeInBytes() {
    return EmbossReservedDollarVirtualIntrinsicSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;
  ::std::int32_t param_;
  bool parameters_initialized_ = false;

  template <class OtherStorage>
  friend class GenericConstVirtualFirstFieldWithParamView;
};
using ConstVirtualFirstFieldWithParamView =
    GenericConstVirtualFirstFieldWithParamView<
        /**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using ConstVirtualFirstFieldWithParamWriter =
    GenericConstVirtualFirstFieldWithParamView<
        /**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct EmbossReservedInternalIsGenericConstVirtualFirstFieldWithParamView<
    GenericConstVirtualFirstFieldWithParamView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericConstVirtualFirstFieldWithParamView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeConstVirtualFirstFieldWithParamView(::std::int32_t param,
                                        T&& emboss_reserved_local_arg) {
  return GenericConstVirtualFirstFieldWithParamView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward</**/ ::std::int32_t>(param),
                 ::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericConstVirtualFirstFieldWithParamView<
    /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeConstVirtualFirstFieldWithParamView(
    ::std::int32_t param, T* emboss_reserved_local_data,
    ::std::size_t emboss_reserved_local_size) {
  return GenericConstVirtualFirstFieldWithParamView<
      /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      ::std::forward</**/ ::std::int32_t>(param), emboss_reserved_local_data,
      emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericConstVirtualFirstFieldWithParamView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedConstVirtualFirstFieldWithParamView(
    ::std::int32_t param, T* emboss_reserved_local_data,
    ::std::size_t emboss_reserved_local_size) {
  return GenericConstVirtualFirstFieldWithParamView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      ::std::forward</**/ ::std::int32_t>(param), emboss_reserved_local_data,
      emboss_reserved_local_size);
}

namespace SizedArrayOfBiasedValues {}  // namespace SizedArrayOfBiasedValues

template <class View>
struct EmbossReservedInternalIsGenericSizedArrayOfBiasedValuesView;

template <class Storage>
class GenericSizedArrayOfBiasedValuesView final {
 public:
  GenericSizedArrayOfBiasedValuesView() : backing_() {}
  explicit GenericSizedArrayOfBiasedValuesView(
      Storage emboss_reserved_local_bytes)
      : backing_(emboss_reserved_local_bytes) {}

  template <typename OtherStorage>
  GenericSizedArrayOfBiasedValuesView(
      const GenericSizedArrayOfBiasedValuesView<OtherStorage>&
          emboss_reserved_local_other)
      : backing_{emboss_reserved_local_other.BackingStorage()} {}

  template <typename Arg,
            typename = typename ::std::enable_if<
                !EmbossReservedInternalIsGenericSizedArrayOfBiasedValuesView<
                    typename ::std::remove_cv<typename ::std::remove_reference<
                        Arg>::type>::type>::value>::type>
  explicit GenericSizedArrayOfBiasedValuesView(Arg&& emboss_reserved_local_arg)
      : backing_(::std::forward<Arg>(emboss_reserved_local_arg)) {}
  template <typename Arg0, typename Arg1, typename... Args>
  explicit GenericSizedArrayOfBiasedValuesView(
      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)...) {}

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

  bool Ok() const {
    if (!IsComplete()) return false;

    if (!has_element_count().Known()) return false;
    if (has_element_count().ValueOrDefault() && !element_count().Ok())
      return false;

    if (!has_bias().Known()) return false;
    if (has_bias().ValueOrDefault() && !bias().Ok()) return false;

    if (!has_values().Known()) return false;
    if (has_values().ValueOrDefault() && !values().Ok()) return false;

    if (!has_IntrinsicSizeInBytes().Known()) return false;
    if (has_IntrinsicSizeInBytes().ValueOrDefault() &&
        !IntrinsicSizeInBytes().Ok())
      return false;

    if (!has_MaxSizeInBytes().Known()) return false;
    if (has_MaxSizeInBytes().ValueOrDefault() && !MaxSizeInBytes().Ok())
      return false;

    if (!has_MinSizeInBytes().Known()) return false;
    if (has_MinSizeInBytes().ValueOrDefault() && !MinSizeInBytes().Ok())
      return false;

    return true;
  }
  Storage BackingStorage() const { return backing_; }
  bool IsComplete() const {
    return backing_.Ok() && IntrinsicSizeInBytes().Ok() &&
           backing_.SizeInBytes() >=
               static_cast</**/ ::std::size_t>(
                   IntrinsicSizeInBytes().UncheckedRead());
  }
  ::std::size_t SizeInBytes() const {
    return static_cast</**/ ::std::size_t>(IntrinsicSizeInBytes().Read());
  }
  bool SizeIsKnown() const { return IntrinsicSizeInBytes().Ok(); }

  template <typename OtherStorage>
  bool Equals(GenericSizedArrayOfBiasedValuesView<OtherStorage>
                  emboss_reserved_local_other) const {
    if (!has_element_count().Known()) return false;
    if (!emboss_reserved_local_other.has_element_count().Known()) return false;

    if (emboss_reserved_local_other.has_element_count().ValueOrDefault() &&
        !has_element_count().ValueOrDefault())
      return false;
    if (has_element_count().ValueOrDefault() &&
        !emboss_reserved_local_other.has_element_count().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_element_count().ValueOrDefault() &&
        has_element_count().ValueOrDefault() &&
        !element_count().Equals(emboss_reserved_local_other.element_count()))
      return false;

    if (!has_bias().Known()) return false;
    if (!emboss_reserved_local_other.has_bias().Known()) return false;

    if (emboss_reserved_local_other.has_bias().ValueOrDefault() &&
        !has_bias().ValueOrDefault())
      return false;
    if (has_bias().ValueOrDefault() &&
        !emboss_reserved_local_other.has_bias().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_bias().ValueOrDefault() &&
        has_bias().ValueOrDefault() &&
        !bias().Equals(emboss_reserved_local_other.bias()))
      return false;

    if (!has_values().Known()) return false;
    if (!emboss_reserved_local_other.has_values().Known()) return false;

    if (emboss_reserved_local_other.has_values().ValueOrDefault() &&
        !has_values().ValueOrDefault())
      return false;
    if (has_values().ValueOrDefault() &&
        !emboss_reserved_local_other.has_values().ValueOrDefault())
      return false;

    if (emboss_reserved_local_other.has_values().ValueOrDefault() &&
        has_values().ValueOrDefault() &&
        !values().Equals(emboss_reserved_local_other.values()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  bool UncheckedEquals(GenericSizedArrayOfBiasedValuesView<OtherStorage>
                           emboss_reserved_local_other) const {
    if (emboss_reserved_local_other.has_element_count().ValueOr(false) &&
        !has_element_count().ValueOr(false))
      return false;
    if (has_element_count().ValueOr(false) &&
        !emboss_reserved_local_other.has_element_count().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_element_count().ValueOr(false) &&
        has_element_count().ValueOr(false) &&
        !element_count().UncheckedEquals(
            emboss_reserved_local_other.element_count()))
      return false;

    if (emboss_reserved_local_other.has_bias().ValueOr(false) &&
        !has_bias().ValueOr(false))
      return false;
    if (has_bias().ValueOr(false) &&
        !emboss_reserved_local_other.has_bias().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_bias().ValueOr(false) &&
        has_bias().ValueOr(false) &&
        !bias().UncheckedEquals(emboss_reserved_local_other.bias()))
      return false;

    if (emboss_reserved_local_other.has_values().ValueOr(false) &&
        !has_values().ValueOr(false))
      return false;
    if (has_values().ValueOr(false) &&
        !emboss_reserved_local_other.has_values().ValueOr(false))
      return false;

    if (emboss_reserved_local_other.has_values().ValueOr(false) &&
        has_values().ValueOr(false) &&
        !values().UncheckedEquals(emboss_reserved_local_other.values()))
      return false;

    return true;
  }
  template <typename OtherStorage>
  void UncheckedCopyFrom(GenericSizedArrayOfBiasedValuesView<OtherStorage>
                             emboss_reserved_local_other) const {
    backing_.UncheckedCopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().UncheckedRead());
  }

  template <typename OtherStorage>
  void CopyFrom(GenericSizedArrayOfBiasedValuesView<OtherStorage>
                    emboss_reserved_local_other) const {
    backing_.CopyFrom(
        emboss_reserved_local_other.BackingStorage(),
        emboss_reserved_local_other.IntrinsicSizeInBytes().Read());
  }
  template <typename OtherStorage>
  bool TryToCopyFrom(GenericSizedArrayOfBiasedValuesView<OtherStorage>
                         emboss_reserved_local_other) const {
    return emboss_reserved_local_other.Ok() &&
           backing_.TryToCopyFrom(
               emboss_reserved_local_other.BackingStorage(),
               emboss_reserved_local_other.IntrinsicSizeInBytes().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;
      if (emboss_reserved_local_name == "element_count") {
        if (!element_count().UpdateFromTextStream(
                emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "bias") {
        if (!bias().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      if (emboss_reserved_local_name == "values") {
        if (!values().UpdateFromTextStream(emboss_reserved_local_stream)) {
          return false;
        }
        continue;
      }

      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;
    if (has_element_count().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          element_count().IsAggregate() || element_count().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("element_count: ");
        element_count().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() &&
                 !element_count().IsAggregate() && !element_count().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("# element_count: UNREADABLE\n");
      }
    }

    if (has_bias().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          bias().IsAggregate() || bias().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("bias: ");
        bias().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() &&
                 !bias().IsAggregate() && !bias().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("# bias: UNREADABLE\n");
      }
    }

    if (has_values().ValueOr(false)) {
      if (!emboss_reserved_local_field_options.allow_partial_output() ||
          values().IsAggregate() || values().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("values: ");
        values().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() &&
                 !values().IsAggregate() && !values().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("# values: UNREADABLE\n");
      }
    }

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

  static constexpr bool IsAggregate() { return true; }

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

  element_count() const;
  ::emboss::support::Maybe<bool> has_element_count() const;

 public:
  typename ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 1>>,
          8>>

  bias() const;
  ::emboss::support::Maybe<bool> has_bias() const;

 public:
  typename ::emboss::support::GenericArrayView<
      typename ::emboss::test::GenericBiasedValueView<
          typename Storage::template OffsetStorageType<
              /**/ 0, 2>::template OffsetStorageType</**/ 1, 0>>

      ,
      typename Storage::template OffsetStorageType</**/ 0, 2>, 1, 8,
      ::std::int32_t>

  values() const;
  ::emboss::support::Maybe<bool> has_values() const;

 public:
  class EmbossReservedDollarVirtualIntrinsicSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

    explicit EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        const GenericSizedArrayOfBiasedValuesView& emboss_reserved_local_view)
        : view_(emboss_reserved_local_view) {}
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = delete;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        const EmbossReservedDollarVirtualIntrinsicSizeInBytesView&) = default;
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView& operator=(
        EmbossReservedDollarVirtualIntrinsicSizeInBytesView&&) = default;
    ~EmbossReservedDollarVirtualIntrinsicSizeInBytesView() = default;

    ::std::int32_t Read() const {
      EMBOSS_CHECK(view_.has_IntrinsicSizeInBytes().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();
    }
    ::std::int32_t UncheckedRead() const {
      return MaybeRead().ValueOrDefault();
    }
    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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

    static constexpr bool IsAggregate() { return false; }

   private:
    ::emboss::support::Maybe</**/ ::std::int32_t> MaybeRead() const {
      const auto emboss_reserved_local_subexpr_1 = view_.element_count();
      const auto emboss_reserved_local_subexpr_2 =
          (emboss_reserved_local_subexpr_1.Ok()
               ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                     static_cast</**/ ::std::int32_t>(
                         emboss_reserved_local_subexpr_1.UncheckedRead()))
               : ::emboss::support::Maybe</**/ ::std::int32_t>());
      const auto emboss_reserved_local_subexpr_3 =
          ::emboss::support::Sum</**/ ::std::int32_t, ::std::int32_t,
                                 ::std::int32_t, ::std::int32_t>(
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(2LL)),
              emboss_reserved_local_subexpr_2);
      const auto emboss_reserved_local_subexpr_4 =
          ::emboss::support::Choice</**/ ::std::int32_t, ::std::int32_t, bool,
                                    ::std::int32_t, ::std::int32_t>(
              ::emboss::support::Maybe</**/ bool>(true),
              emboss_reserved_local_subexpr_3,
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(0LL)));
      const auto emboss_reserved_local_subexpr_5 =
          ::emboss::support::Maximum</**/ ::std::int32_t, ::std::int32_t,
                                     ::std::int32_t, ::std::int32_t,
                                     ::std::int32_t, ::std::int32_t>(
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(0LL)),
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(1LL)),
              ::emboss::support::Maybe</**/ ::std::int32_t>(
                  static_cast</**/ ::std::int32_t>(2LL)),
              emboss_reserved_local_subexpr_4);

      return emboss_reserved_local_subexpr_5;
    }

    static constexpr bool ValueIsOk(
        ::std::int32_t emboss_reserved_local_value) {
      return (void)emboss_reserved_local_value,  // Silence -Wunused-parameter
             ::emboss::support::Maybe<bool>(true).ValueOr(false);
    }

    const GenericSizedArrayOfBiasedValuesView view_;
  };
  EmbossReservedDollarVirtualIntrinsicSizeInBytesView IntrinsicSizeInBytes()
      const;
  ::emboss::support::Maybe<bool> has_IntrinsicSizeInBytes() const;

 public:
  class EmbossReservedDollarVirtualMaxSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMaxSizeInBytesView
  MaxSizeInBytes() {
    return EmbossReservedDollarVirtualMaxSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MaxSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 public:
  class EmbossReservedDollarVirtualMinSizeInBytesView final {
   public:
    using ValueType = ::std::int32_t;

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

    static constexpr ::std::int32_t Read();
    static constexpr ::std::int32_t 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::WriteIntegerViewToTextStream(
          this, emboss_reserved_local_stream, emboss_reserved_local_options);
    }

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

  static constexpr EmbossReservedDollarVirtualMinSizeInBytesView
  MinSizeInBytes() {
    return EmbossReservedDollarVirtualMinSizeInBytesView();
  }
  static constexpr ::emboss::support::Maybe<bool> has_MinSizeInBytes() {
    return ::emboss::support::Maybe<bool>(true);
  }

 private:
  Storage backing_;

  template <class OtherStorage>
  friend class GenericSizedArrayOfBiasedValuesView;
};
using SizedArrayOfBiasedValuesView = GenericSizedArrayOfBiasedValuesView<
    /**/ ::emboss::support::ReadOnlyContiguousBuffer>;
using SizedArrayOfBiasedValuesWriter = GenericSizedArrayOfBiasedValuesView<
    /**/ ::emboss::support::ReadWriteContiguousBuffer>;

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

template <class Storage>
struct EmbossReservedInternalIsGenericSizedArrayOfBiasedValuesView<
    GenericSizedArrayOfBiasedValuesView<Storage>> {
  static constexpr const bool value = true;
};

template <typename T>
inline GenericSizedArrayOfBiasedValuesView<
    /**/ ::emboss::support::ContiguousBuffer<
        typename ::std::remove_reference<
            decltype(*::std::declval<T>()->data())>::type,
        1, 0>>
MakeSizedArrayOfBiasedValuesView(T&& emboss_reserved_local_arg) {
  return GenericSizedArrayOfBiasedValuesView<
      /**/ ::emboss::support::ContiguousBuffer<
          typename ::std::remove_reference<
              decltype(*::std::declval<T>()->data())>::type,
          1, 0>>(::std::forward<T>(emboss_reserved_local_arg));
}

template <typename T>
inline GenericSizedArrayOfBiasedValuesView<
    /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>
MakeSizedArrayOfBiasedValuesView(T* emboss_reserved_local_data,
                                 ::std::size_t emboss_reserved_local_size) {
  return GenericSizedArrayOfBiasedValuesView<
      /**/ ::emboss::support::ContiguousBuffer<T, 1, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

template <typename T, ::std::size_t kAlignment>
inline GenericSizedArrayOfBiasedValuesView<
    /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>
MakeAlignedSizedArrayOfBiasedValuesView(
    T* emboss_reserved_local_data, ::std::size_t emboss_reserved_local_size) {
  return GenericSizedArrayOfBiasedValuesView<
      /**/ ::emboss::support::ContiguousBuffer<T, kAlignment, 0>>(
      emboss_reserved_local_data, emboss_reserved_local_size);
}

namespace MultiVersion {}  // namespace MultiVersion

template <class Storage>
inline typename ::emboss::support::EnumView<
    /**/ ::emboss::test::MessageId,
    ::emboss::support::FixedSizeViewParameters<
        8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 0>>,
        8>>

GenericMultiVersionView<Storage>::message_id() const {
  if (has_message_id().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::support::EnumView<
          /**/ ::emboss::test::MessageId,
          ::emboss::support::FixedSizeViewParameters<
              8, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 0>>,
              8>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::support::EnumView<
      /**/ ::emboss::test::MessageId,
      ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericMultiVersionView<Storage>::has_message_id() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::test::GenericAxesView<
    typename Storage::template OffsetStorageType</**/ 0, 1>>

GenericMultiVersionView<Storage>::axes() const {
  const auto emboss_reserved_local_subexpr_1 = product();
  const auto emboss_reserved_local_subexpr_2 =
      (emboss_reserved_local_subexpr_1.Ok()
           ? ::emboss::support::Maybe</**/ ::emboss::test::Product>(
                 static_cast</**/ ::emboss::test::Product>(
                     emboss_reserved_local_subexpr_1.UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::emboss::test::Product>());
  const auto emboss_reserved_local_subexpr_3 =
      ::emboss::support::Equal</**/ ::emboss::test::Product, bool,
                               ::emboss::test::Product,
                               ::emboss::test::Product>(
          emboss_reserved_local_subexpr_2,
          ::emboss::support::Maybe</**/ ::emboss::test::Product>(
              static_cast</**/ ::emboss::test::Product>(23)));
  const auto emboss_reserved_local_subexpr_4 =
      ::emboss::support::Choice</**/ ::std::int32_t, ::std::int32_t, bool,
                                ::std::int32_t, ::std::int32_t>(
          emboss_reserved_local_subexpr_3,
          ::emboss::support::Maybe</**/ ::std::int32_t>(
              static_cast</**/ ::std::int32_t>(3LL)),
          ::emboss::support::Maybe</**/ ::std::int32_t>(
              static_cast</**/ ::std::int32_t>(2LL)));

  if (emboss_reserved_local_subexpr_4.Known() && has_axes().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(12LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    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 ::emboss::test::GenericAxesView<
          typename Storage::template OffsetStorageType</**/ 0, 1>>

          (emboss_reserved_local_subexpr_4.ValueOrDefault(),
           backing_.template GetOffsetStorage<0, 1>(
               emboss_reserved_local_offset.ValueOrDefault(),
               emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericAxesView<
      typename Storage::template OffsetStorageType</**/ 0, 1>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericMultiVersionView<Storage>::has_axes() const {
  return ::emboss::support::Equal</**/ ::emboss::test::MessageId, bool,
                                  ::emboss::test::MessageId,
                                  ::emboss::test::MessageId>(
      (message_id().Ok()
           ? ::emboss::support::Maybe</**/ ::emboss::test::MessageId>(
                 static_cast</**/ ::emboss::test::MessageId>(
                     message_id().UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::emboss::test::MessageId>()),
      ::emboss::support::Maybe</**/ ::emboss::test::MessageId>(
          static_cast</**/ ::emboss::test::MessageId>(0)));
}

template <class Storage>
inline typename ::emboss::test::GenericConfigView<
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 1>>,
        32>>

GenericMultiVersionView<Storage>::config() const {
  if (has_config().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    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 ::emboss::test::GenericConfigView<
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 1>>,
              32>>

          (backing_.template GetOffsetStorage<0, 1>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericConfigView<typename ::emboss::support::BitBlock<
      /**/ ::emboss::support::LittleEndianByteOrderer<
          typename Storage::template OffsetStorageType</**/ 0, 1>>,
      32>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericMultiVersionView<Storage>::has_config() const {
  return ::emboss::support::Equal</**/ ::emboss::test::MessageId, bool,
                                  ::emboss::test::MessageId,
                                  ::emboss::test::MessageId>(
      (message_id().Ok()
           ? ::emboss::support::Maybe</**/ ::emboss::test::MessageId>(
                 static_cast</**/ ::emboss::test::MessageId>(
                     message_id().UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::emboss::test::MessageId>()),
      ::emboss::support::Maybe</**/ ::emboss::test::MessageId>(
          static_cast</**/ ::emboss::test::MessageId>(1)));
}

template <class Storage>
inline typename ::emboss::test::GenericConfigVXView<
    typename Storage::template OffsetStorageType</**/ 0, 1>>

GenericMultiVersionView<Storage>::config_vx() const {
  if (has_config_vx().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(8LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    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 ::emboss::test::GenericConfigVXView<
          typename Storage::template OffsetStorageType</**/ 0, 1>>

          (backing_.template GetOffsetStorage<0, 1>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericConfigVXView<
      typename Storage::template OffsetStorageType</**/ 0, 1>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericMultiVersionView<Storage>::has_config_vx() const {
  return ::emboss::support::And</**/ bool, bool, bool, bool>(
      ::emboss::support::Equal</**/ ::emboss::test::Product, bool,
                               ::emboss::test::Product,
                               ::emboss::test::Product>(
          (product().Ok()
               ? ::emboss::support::Maybe</**/ ::emboss::test::Product>(
                     static_cast</**/ ::emboss::test::Product>(
                         product().UncheckedRead()))
               : ::emboss::support::Maybe</**/ ::emboss::test::Product>()),
          ::emboss::support::Maybe</**/ ::emboss::test::Product>(
              static_cast</**/ ::emboss::test::Product>(23))),
      ::emboss::support::Equal</**/ ::emboss::test::MessageId, bool,
                               ::emboss::test::MessageId,
                               ::emboss::test::MessageId>(
          (message_id().Ok()
               ? ::emboss::support::Maybe</**/ ::emboss::test::MessageId>(
                     static_cast</**/ ::emboss::test::MessageId>(
                         message_id().UncheckedRead()))
               : ::emboss::support::Maybe</**/ ::emboss::test::MessageId>()),
          ::emboss::support::Maybe</**/ ::emboss::test::MessageId>(
              static_cast</**/ ::emboss::test::MessageId>(1))));
}

template <class Storage>
inline typename GenericMultiVersionView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericMultiVersionView<Storage>::IntrinsicSizeInBytes() const {
  return typename GenericMultiVersionView<
      Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(*this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericMultiVersionView<Storage>::has_IntrinsicSizeInBytes() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace MultiVersion {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(13LL))
      .ValueOrDefault();
}
}  // namespace MultiVersion

template <class Storage>
inline constexpr ::std::int32_t GenericMultiVersionView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return MultiVersion::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericMultiVersionView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return MultiVersion::MaxSizeInBytes();
}

namespace MultiVersion {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace MultiVersion

template <class Storage>
inline constexpr ::std::int32_t GenericMultiVersionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return MultiVersion::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericMultiVersionView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return MultiVersion::MinSizeInBytes();
}
namespace Axes {}  // namespace Axes

template <class Storage>
inline typename ::emboss::support::GenericArrayView<
    typename ::emboss::test::GenericAxisView<
        typename Storage::template OffsetStorageType<
            /**/ 0, 0>::template OffsetStorageType</**/ 4, 0>>

    ,
    typename Storage::template OffsetStorageType</**/ 0, 0>, 4, 8,
    ::emboss::test::AxisType>

GenericAxesView<Storage>::values() const {
  if (::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
          static_cast</**/ ::emboss::test::AxisType>(-1))
          .Known() &&
      has_values().ValueOr(false)) {
    const auto emboss_reserved_local_subexpr_1 = axes();
    const auto emboss_reserved_local_subexpr_2 =
        (emboss_reserved_local_subexpr_1.Ok()
             ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                   static_cast</**/ ::std::int32_t>(
                       emboss_reserved_local_subexpr_1.UncheckedRead()))
             : ::emboss::support::Maybe</**/ ::std::int32_t>());
    const auto emboss_reserved_local_subexpr_3 =
        ::emboss::support::Product</**/ ::std::int32_t, ::std::int32_t,
                                   ::std::int32_t, ::std::int32_t>(
            emboss_reserved_local_subexpr_2,
            ::emboss::support::Maybe</**/ ::std::int32_t>(
                static_cast</**/ ::std::int32_t>(4LL)));

    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_3;
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::support::GenericArrayView<
          typename ::emboss::test::GenericAxisView<
              typename Storage::template OffsetStorageType<
                  /**/ 0, 0>::template OffsetStorageType</**/ 4, 0>>

          ,
          typename Storage::template OffsetStorageType</**/ 0, 0>, 4, 8,
          ::emboss::test::AxisType>

          (::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
               static_cast</**/ ::emboss::test::AxisType>(-1))
               .ValueOrDefault(),
           backing_.template GetOffsetStorage<0, 0>(
               emboss_reserved_local_offset.ValueOrDefault(),
               emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::support::GenericArrayView<
      typename ::emboss::test::GenericAxisView<
          typename Storage::template OffsetStorageType<
              /**/ 0, 0>::template OffsetStorageType</**/ 4, 0>>

      ,
      typename Storage::template OffsetStorageType</**/ 0, 0>, 4, 8,
      ::emboss::test::AxisType>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericAxesView<Storage>::has_values()
    const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::test::GenericAxisView<
    typename Storage::template OffsetStorageType</**/ 0, 0>>

GenericAxesView<Storage>::x() const {
  if (::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
          static_cast</**/ ::emboss::test::AxisType>(1))
          .Known() &&
      has_x().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::test::GenericAxisView<
          typename Storage::template OffsetStorageType</**/ 0, 0>>

          (::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
               static_cast</**/ ::emboss::test::AxisType>(1))
               .ValueOrDefault(),
           backing_.template GetOffsetStorage<0, 0>(
               emboss_reserved_local_offset.ValueOrDefault(),
               emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericAxisView<
      typename Storage::template OffsetStorageType</**/ 0, 0>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericAxesView<Storage>::has_x() const {
  return ::emboss::support::GreaterThan</**/ ::std::int32_t, bool,
                                        ::std::int32_t, ::std::int32_t>(
      (axes().Ok()
           ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                 static_cast</**/ ::std::int32_t>(axes().UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::std::int32_t>()),
      ::emboss::support::Maybe</**/ ::std::int32_t>(
          static_cast</**/ ::std::int32_t>(0LL)));
}

template <class Storage>
inline typename ::emboss::test::GenericAxisView<
    typename Storage::template OffsetStorageType</**/ 0, 4>>

GenericAxesView<Storage>::y() const {
  if (::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
          static_cast</**/ ::emboss::test::AxisType>(2))
          .Known() &&
      has_y().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    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 ::emboss::test::GenericAxisView<
          typename Storage::template OffsetStorageType</**/ 0, 4>>

          (::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
               static_cast</**/ ::emboss::test::AxisType>(2))
               .ValueOrDefault(),
           backing_.template GetOffsetStorage<0, 4>(
               emboss_reserved_local_offset.ValueOrDefault(),
               emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericAxisView<
      typename Storage::template OffsetStorageType</**/ 0, 4>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericAxesView<Storage>::has_y() const {
  return ::emboss::support::GreaterThan</**/ ::std::int32_t, bool,
                                        ::std::int32_t, ::std::int32_t>(
      (axes().Ok()
           ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                 static_cast</**/ ::std::int32_t>(axes().UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::std::int32_t>()),
      ::emboss::support::Maybe</**/ ::std::int32_t>(
          static_cast</**/ ::std::int32_t>(1LL)));
}

template <class Storage>
inline typename ::emboss::test::GenericAxisView<
    typename Storage::template OffsetStorageType</**/ 0, 8>>

GenericAxesView<Storage>::z() const {
  if (::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
          static_cast</**/ ::emboss::test::AxisType>(3))
          .Known() &&
      has_z().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(8LL));
    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 ::emboss::test::GenericAxisView<
          typename Storage::template OffsetStorageType</**/ 0, 8>>

          (::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
               static_cast</**/ ::emboss::test::AxisType>(3))
               .ValueOrDefault(),
           backing_.template GetOffsetStorage<0, 8>(
               emboss_reserved_local_offset.ValueOrDefault(),
               emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericAxisView<
      typename Storage::template OffsetStorageType</**/ 0, 8>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericAxesView<Storage>::has_z() const {
  return ::emboss::support::GreaterThan</**/ ::std::int32_t, bool,
                                        ::std::int32_t, ::std::int32_t>(
      (axes().Ok()
           ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                 static_cast</**/ ::std::int32_t>(axes().UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::std::int32_t>()),
      ::emboss::support::Maybe</**/ ::std::int32_t>(
          static_cast</**/ ::std::int32_t>(2LL)));
}

template <class Storage>
inline
    typename GenericAxesView<Storage>::EmbossReservedVirtualAxisCountPlusOneView
    GenericAxesView<Storage>::axis_count_plus_one() const {
  return typename GenericAxesView<
      Storage>::EmbossReservedVirtualAxisCountPlusOneView(*this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAxesView<Storage>::has_axis_count_plus_one() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename GenericAxesView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericAxesView<Storage>::IntrinsicSizeInBytes() const {
  return typename GenericAxesView<
      Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(*this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAxesView<Storage>::has_IntrinsicSizeInBytes() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace Axes {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(60LL))
      .ValueOrDefault();
}
}  // namespace Axes

template <class Storage>
inline constexpr ::std::int32_t GenericAxesView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return Axes::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericAxesView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return Axes::MaxSizeInBytes();
}

namespace Axes {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(0LL))
      .ValueOrDefault();
}
}  // namespace Axes

template <class Storage>
inline constexpr ::std::int32_t GenericAxesView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return Axes::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericAxesView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return Axes::MinSizeInBytes();
}
namespace AxisPair {}  // namespace AxisPair

template <class Storage>
inline typename GenericAxisPairView<Storage>::EmbossReservedVirtualAxisTypeAView
GenericAxisPairView<Storage>::axis_type_a() const {
  return
      typename GenericAxisPairView<Storage>::EmbossReservedVirtualAxisTypeAView(
          *this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAxisPairView<Storage>::has_axis_type_a() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::test::GenericAxisView<
    typename Storage::template OffsetStorageType</**/ 0, 0>>

GenericAxisPairView<Storage>::axis_a() const {
  const auto emboss_reserved_local_subexpr_1 = axis_type_a();
  const auto emboss_reserved_local_subexpr_2 =
      (emboss_reserved_local_subexpr_1.Ok()
           ? ::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
                 static_cast</**/ ::emboss::test::AxisType>(
                     emboss_reserved_local_subexpr_1.UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::emboss::test::AxisType>());

  if (emboss_reserved_local_subexpr_2.Known() && has_axis_a().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::test::GenericAxisView<
          typename Storage::template OffsetStorageType</**/ 0, 0>>

          (emboss_reserved_local_subexpr_2.ValueOrDefault(),
           backing_.template GetOffsetStorage<0, 0>(
               emboss_reserved_local_offset.ValueOrDefault(),
               emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericAxisView<
      typename Storage::template OffsetStorageType</**/ 0, 0>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericAxisPairView<Storage>::has_axis_a()
    const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename GenericAxisPairView<Storage>::EmbossReservedVirtualAxisTypeBView
GenericAxisPairView<Storage>::axis_type_b() const {
  return
      typename GenericAxisPairView<Storage>::EmbossReservedVirtualAxisTypeBView(
          *this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAxisPairView<Storage>::has_axis_type_b() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::test::GenericAxisView<
    typename Storage::template OffsetStorageType</**/ 0, 4>>

GenericAxisPairView<Storage>::axis_b() const {
  const auto emboss_reserved_local_subexpr_1 = axis_type_b();
  const auto emboss_reserved_local_subexpr_2 =
      (emboss_reserved_local_subexpr_1.Ok()
           ? ::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
                 static_cast</**/ ::emboss::test::AxisType>(
                     emboss_reserved_local_subexpr_1.UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::emboss::test::AxisType>());

  if (emboss_reserved_local_subexpr_2.Known() && has_axis_b().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    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 ::emboss::test::GenericAxisView<
          typename Storage::template OffsetStorageType</**/ 0, 4>>

          (emboss_reserved_local_subexpr_2.ValueOrDefault(),
           backing_.template GetOffsetStorage<0, 4>(
               emboss_reserved_local_offset.ValueOrDefault(),
               emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericAxisView<
      typename Storage::template OffsetStorageType</**/ 0, 4>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericAxisPairView<Storage>::has_axis_b()
    const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace AxisPair {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(8LL))
      .ValueOrDefault();
}
}  // namespace AxisPair

template <class Storage>
inline constexpr ::std::int32_t GenericAxisPairView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return AxisPair::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericAxisPairView<Storage>::
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return AxisPair::IntrinsicSizeInBytes();
}

namespace AxisPair {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(8LL))
      .ValueOrDefault();
}
}  // namespace AxisPair

template <class Storage>
inline constexpr ::std::int32_t GenericAxisPairView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return AxisPair::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericAxisPairView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return AxisPair::MaxSizeInBytes();
}

namespace AxisPair {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(8LL))
      .ValueOrDefault();
}
}  // namespace AxisPair

template <class Storage>
inline constexpr ::std::int32_t GenericAxisPairView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return AxisPair::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericAxisPairView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return AxisPair::MinSizeInBytes();
}
namespace AxesEnvelope {}  // namespace AxesEnvelope

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 0>>,
        8>>

GenericAxesEnvelopeView<Storage>::axis_count() const {
  if (has_axis_count().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              8, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 0>>,
              8>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAxesEnvelopeView<Storage>::has_axis_count() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::test::GenericAxesView<
    typename Storage::template OffsetStorageType</**/ 0, 1>>

GenericAxesEnvelopeView<Storage>::axes() const {
  const auto emboss_reserved_local_subexpr_1 = axis_count();
  const auto emboss_reserved_local_subexpr_2 =
      (emboss_reserved_local_subexpr_1.Ok()
           ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                 static_cast</**/ ::std::int32_t>(
                     emboss_reserved_local_subexpr_1.UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::std::int32_t>());

  if (emboss_reserved_local_subexpr_2.Known() && has_axes().ValueOr(false)) {
    const auto emboss_reserved_local_subexpr_3 =
        ::emboss::support::Product</**/ ::std::int32_t, ::std::int32_t,
                                   ::std::int32_t, ::std::int32_t>(
            emboss_reserved_local_subexpr_2,
            ::emboss::support::Maybe</**/ ::std::int32_t>(
                static_cast</**/ ::std::int32_t>(4LL)));

    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_3;
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    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 ::emboss::test::GenericAxesView<
          typename Storage::template OffsetStorageType</**/ 0, 1>>

          (emboss_reserved_local_subexpr_2.ValueOrDefault(),
           backing_.template GetOffsetStorage<0, 1>(
               emboss_reserved_local_offset.ValueOrDefault(),
               emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericAxesView<
      typename Storage::template OffsetStorageType</**/ 0, 1>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAxesEnvelopeView<Storage>::has_axes() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename GenericAxesEnvelopeView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericAxesEnvelopeView<Storage>::IntrinsicSizeInBytes() const {
  return typename GenericAxesEnvelopeView<
      Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(*this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericAxesEnvelopeView<Storage>::has_IntrinsicSizeInBytes() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace AxesEnvelope {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1021LL))
      .ValueOrDefault();
}
}  // namespace AxesEnvelope

template <class Storage>
inline constexpr ::std::int32_t GenericAxesEnvelopeView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return AxesEnvelope::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericAxesEnvelopeView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return AxesEnvelope::MaxSizeInBytes();
}

namespace AxesEnvelope {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace AxesEnvelope

template <class Storage>
inline constexpr ::std::int32_t GenericAxesEnvelopeView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return AxesEnvelope::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericAxesEnvelopeView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return AxesEnvelope::MinSizeInBytes();
}
namespace Axis {}  // namespace Axis

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        32, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 0>>,
        32>>

GenericAxisView<Storage>::value() const {
  if (has_value().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              32, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 0>>,
              32>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          32, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          32>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericAxisView<Storage>::has_value()
    const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename GenericAxisView<Storage>::EmbossReservedVirtualAxisTypeView
GenericAxisView<Storage>::axis_type() const {
  return typename GenericAxisView<Storage>::EmbossReservedVirtualAxisTypeView(
      *this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericAxisView<Storage>::has_axis_type()
    const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        32, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 0>>,
        32>>

GenericAxisView<Storage>::x() const {
  if (has_x().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              32, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 0>>,
              32>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          32, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          32>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericAxisView<Storage>::has_x() const {
  return ::emboss::support::Equal</**/ ::emboss::test::AxisType, bool,
                                  ::emboss::test::AxisType,
                                  ::emboss::test::AxisType>(
      (axis_type().Ok()
           ? ::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
                 static_cast</**/ ::emboss::test::AxisType>(
                     axis_type().UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::emboss::test::AxisType>()),
      ::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
          static_cast</**/ ::emboss::test::AxisType>(1)));
}

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        32, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 0>>,
        32>>

GenericAxisView<Storage>::y() const {
  if (has_y().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              32, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 0>>,
              32>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          32, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          32>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericAxisView<Storage>::has_y() const {
  return ::emboss::support::Equal</**/ ::emboss::test::AxisType, bool,
                                  ::emboss::test::AxisType,
                                  ::emboss::test::AxisType>(
      (axis_type().Ok()
           ? ::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
                 static_cast</**/ ::emboss::test::AxisType>(
                     axis_type().UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::emboss::test::AxisType>()),
      ::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
          static_cast</**/ ::emboss::test::AxisType>(2)));
}

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        32, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 0>>,
        32>>

GenericAxisView<Storage>::z() const {
  if (has_z().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              32, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 0>>,
              32>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          32, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          32>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericAxisView<Storage>::has_z() const {
  return ::emboss::support::Equal</**/ ::emboss::test::AxisType, bool,
                                  ::emboss::test::AxisType,
                                  ::emboss::test::AxisType>(
      (axis_type().Ok()
           ? ::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
                 static_cast</**/ ::emboss::test::AxisType>(
                     axis_type().UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::emboss::test::AxisType>()),
      ::emboss::support::Maybe</**/ ::emboss::test::AxisType>(
          static_cast</**/ ::emboss::test::AxisType>(3)));
}

namespace Axis {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(4LL))
      .ValueOrDefault();
}
}  // namespace Axis

template <class Storage>
inline constexpr ::std::int32_t GenericAxisView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return Axis::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericAxisView<Storage>::
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return Axis::IntrinsicSizeInBytes();
}

namespace Axis {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(4LL))
      .ValueOrDefault();
}
}  // namespace Axis

template <class Storage>
inline constexpr ::std::int32_t GenericAxisView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return Axis::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericAxisView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return Axis::MaxSizeInBytes();
}

namespace Axis {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(4LL))
      .ValueOrDefault();
}
}  // namespace Axis

template <class Storage>
inline constexpr ::std::int32_t GenericAxisView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return Axis::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericAxisView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return Axis::MinSizeInBytes();
}
namespace Config {}  // namespace Config

template <class Storage>
inline typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/ 0, 31>>

GenericConfigView<Storage>::power() const {
  if (has_power().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(31LL));
    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 ::emboss::prelude::FlagView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              1, ::emboss::support::AllValuesAreOk>,
          typename Storage::template OffsetStorageType</**/ 0, 31>>

          (backing_.template GetOffsetStorage<0, 31>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::FlagView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          1, ::emboss::support::AllValuesAreOk>,
      typename Storage::template OffsetStorageType</**/ 0, 31>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericConfigView<Storage>::has_power()
    const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace Config {
inline constexpr ::std::int32_t IntrinsicSizeInBits() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(32LL))
      .ValueOrDefault();
}
}  // namespace Config

template <class Storage>
inline constexpr ::std::int32_t GenericConfigView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
  return Config::IntrinsicSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t GenericConfigView<Storage>::
    EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
  return Config::IntrinsicSizeInBits();
}

namespace Config {
inline constexpr ::std::int32_t MaxSizeInBits() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(32LL))
      .ValueOrDefault();
}
}  // namespace Config

template <class Storage>
inline constexpr ::std::int32_t GenericConfigView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
  return Config::MaxSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t GenericConfigView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
  return Config::MaxSizeInBits();
}

namespace Config {
inline constexpr ::std::int32_t MinSizeInBits() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(32LL))
      .ValueOrDefault();
}
}  // namespace Config

template <class Storage>
inline constexpr ::std::int32_t GenericConfigView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
  return Config::MinSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t GenericConfigView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
  return Config::MinSizeInBits();
}
namespace ConfigVX {
namespace EmbossReservedAnonymousField1 {

}  // namespace EmbossReservedAnonymousField1

template <class Storage>
inline typename ::emboss::prelude::FlagView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        1, ::emboss::support::AllValuesAreOk>,
    typename Storage::template OffsetStorageType</**/ 0, 31>>

GenericEmbossReservedAnonymousField1View<Storage>::power() const {
  if (has_power().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(31LL));
    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 ::emboss::prelude::FlagView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              1, ::emboss::support::AllValuesAreOk>,
          typename Storage::template OffsetStorageType</**/ 0, 31>>

          (backing_.template GetOffsetStorage<0, 31>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::FlagView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          1, ::emboss::support::AllValuesAreOk>,
      typename Storage::template OffsetStorageType</**/ 0, 31>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericEmbossReservedAnonymousField1View<Storage>::has_power() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace EmbossReservedAnonymousField1 {
inline constexpr ::std::int32_t IntrinsicSizeInBits() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(32LL))
      .ValueOrDefault();
}
}  // namespace EmbossReservedAnonymousField1

template <class Storage>
inline constexpr ::std::int32_t GenericEmbossReservedAnonymousField1View<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBitsView::Read() {
  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericEmbossReservedAnonymousField1View<Storage>::
    EmbossReservedDollarVirtualIntrinsicSizeInBitsView::UncheckedRead() {
  return EmbossReservedAnonymousField1::IntrinsicSizeInBits();
}

namespace EmbossReservedAnonymousField1 {
inline constexpr ::std::int32_t MaxSizeInBits() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(32LL))
      .ValueOrDefault();
}
}  // namespace EmbossReservedAnonymousField1

template <class Storage>
inline constexpr ::std::int32_t GenericEmbossReservedAnonymousField1View<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::Read() {
  return EmbossReservedAnonymousField1::MaxSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t GenericEmbossReservedAnonymousField1View<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBitsView::UncheckedRead() {
  return EmbossReservedAnonymousField1::MaxSizeInBits();
}

namespace EmbossReservedAnonymousField1 {
inline constexpr ::std::int32_t MinSizeInBits() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(32LL))
      .ValueOrDefault();
}
}  // namespace EmbossReservedAnonymousField1

template <class Storage>
inline constexpr ::std::int32_t GenericEmbossReservedAnonymousField1View<
    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::Read() {
  return EmbossReservedAnonymousField1::MinSizeInBits();
}

template <class Storage>
inline constexpr ::std::int32_t GenericEmbossReservedAnonymousField1View<
    Storage>::EmbossReservedDollarVirtualMinSizeInBitsView::UncheckedRead() {
  return EmbossReservedAnonymousField1::MinSizeInBits();
}

}  // namespace ConfigVX

template <class Storage>
inline
    typename ::emboss::test::ConfigVX::GenericEmbossReservedAnonymousField1View<
        typename ::emboss::support::BitBlock<
            /**/ ::emboss::support::LittleEndianByteOrderer<
                typename Storage::template OffsetStorageType</**/ 0, 0>>,
            32>>

    GenericConfigVXView<Storage>::emboss_reserved_anonymous_field_1() const {
  if (has_emboss_reserved_anonymous_field_1().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::test::ConfigVX::GenericEmbossReservedAnonymousField1View<
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 0>>,
              32>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::ConfigVX::GenericEmbossReservedAnonymousField1View<
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          32>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConfigVXView<Storage>::has_emboss_reserved_anonymous_field_1() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericConfigVXView<Storage>::has_power()
    const {
  return ::emboss::support::And</**/ bool, bool, bool, bool>(
      ::emboss::support::Maybe</**/ bool>(true),
      ::emboss::support::Maybe</**/ bool>(true));
}

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        32, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 4>>,
        32>>

GenericConfigVXView<Storage>::gain() const {
  if (has_gain().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(4LL));
    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 ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              32, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 4>>,
              32>>

          (backing_.template GetOffsetStorage<0, 4>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          32, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 4>>,
          32>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool> GenericConfigVXView<Storage>::has_gain()
    const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace ConfigVX {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(8LL))
      .ValueOrDefault();
}
}  // namespace ConfigVX

template <class Storage>
inline constexpr ::std::int32_t GenericConfigVXView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return ConfigVX::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericConfigVXView<Storage>::
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return ConfigVX::IntrinsicSizeInBytes();
}

namespace ConfigVX {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(8LL))
      .ValueOrDefault();
}
}  // namespace ConfigVX

template <class Storage>
inline constexpr ::std::int32_t GenericConfigVXView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return ConfigVX::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericConfigVXView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return ConfigVX::MaxSizeInBytes();
}

namespace ConfigVX {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(8LL))
      .ValueOrDefault();
}
}  // namespace ConfigVX

template <class Storage>
inline constexpr ::std::int32_t GenericConfigVXView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return ConfigVX::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericConfigVXView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ConfigVX::MinSizeInBytes();
}
namespace StructWithUnusedParameter {}  // namespace StructWithUnusedParameter

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 0>>,
        8>>

GenericStructWithUnusedParameterView<Storage>::y() const {
  if (has_y().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              8, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 0>>,
              8>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericStructWithUnusedParameterView<Storage>::has_y() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace StructWithUnusedParameter {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace StructWithUnusedParameter

template <class Storage>
inline constexpr ::std::int32_t GenericStructWithUnusedParameterView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return StructWithUnusedParameter::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericStructWithUnusedParameterView<Storage>::
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return StructWithUnusedParameter::IntrinsicSizeInBytes();
}

namespace StructWithUnusedParameter {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace StructWithUnusedParameter

template <class Storage>
inline constexpr ::std::int32_t GenericStructWithUnusedParameterView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return StructWithUnusedParameter::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericStructWithUnusedParameterView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return StructWithUnusedParameter::MaxSizeInBytes();
}

namespace StructWithUnusedParameter {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace StructWithUnusedParameter

template <class Storage>
inline constexpr ::std::int32_t GenericStructWithUnusedParameterView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return StructWithUnusedParameter::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericStructWithUnusedParameterView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return StructWithUnusedParameter::MinSizeInBytes();
}
namespace StructContainingStructWithUnusedParameter {

}  // namespace StructContainingStructWithUnusedParameter

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 1>>,
        8>>

GenericStructContainingStructWithUnusedParameterView<Storage>::x() const {
  if (has_x().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    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 ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              8, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 1>>,
              8>>

          (backing_.template GetOffsetStorage<0, 1>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 1>>,
          8>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericStructContainingStructWithUnusedParameterView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::test::GenericStructWithUnusedParameterView<
    typename Storage::template OffsetStorageType</**/ 0, 0>>

GenericStructContainingStructWithUnusedParameterView<Storage>::swup() const {
  const auto emboss_reserved_local_subexpr_1 = x();
  const auto emboss_reserved_local_subexpr_2 =
      (emboss_reserved_local_subexpr_1.Ok()
           ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                 static_cast</**/ ::std::int32_t>(
                     emboss_reserved_local_subexpr_1.UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::std::int32_t>());

  if (emboss_reserved_local_subexpr_2.Known() && has_swup().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::test::GenericStructWithUnusedParameterView<
          typename Storage::template OffsetStorageType</**/ 0, 0>>

          (emboss_reserved_local_subexpr_2.ValueOrDefault(),
           backing_.template GetOffsetStorage<0, 0>(
               emboss_reserved_local_offset.ValueOrDefault(),
               emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::test::GenericStructWithUnusedParameterView<
      typename Storage::template OffsetStorageType</**/ 0, 0>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericStructContainingStructWithUnusedParameterView<Storage>::has_swup()
    const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace StructContainingStructWithUnusedParameter {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(2LL))
      .ValueOrDefault();
}
}  // namespace StructContainingStructWithUnusedParameter

template <class Storage>
inline constexpr ::std::int32_t
GenericStructContainingStructWithUnusedParameterView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return StructContainingStructWithUnusedParameter::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericStructContainingStructWithUnusedParameterView<Storage>::
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return StructContainingStructWithUnusedParameter::IntrinsicSizeInBytes();
}

namespace StructContainingStructWithUnusedParameter {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(2LL))
      .ValueOrDefault();
}
}  // namespace StructContainingStructWithUnusedParameter

template <class Storage>
inline constexpr ::std::int32_t
GenericStructContainingStructWithUnusedParameterView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return StructContainingStructWithUnusedParameter::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericStructContainingStructWithUnusedParameterView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return StructContainingStructWithUnusedParameter::MaxSizeInBytes();
}

namespace StructContainingStructWithUnusedParameter {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(2LL))
      .ValueOrDefault();
}
}  // namespace StructContainingStructWithUnusedParameter

template <class Storage>
inline constexpr ::std::int32_t
GenericStructContainingStructWithUnusedParameterView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return StructContainingStructWithUnusedParameter::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericStructContainingStructWithUnusedParameterView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return StructContainingStructWithUnusedParameter::MinSizeInBytes();
}
namespace BiasedValue {}  // namespace BiasedValue

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 0>>,
        8>>

GenericBiasedValueView<Storage>::raw_value() const {
  if (has_raw_value().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              8, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 0>>,
              8>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericBiasedValueView<Storage>::has_raw_value() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename GenericBiasedValueView<Storage>::EmbossReservedVirtualValueView
GenericBiasedValueView<Storage>::value() const {
  return
      typename GenericBiasedValueView<Storage>::EmbossReservedVirtualValueView(
          *this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericBiasedValueView<Storage>::has_value() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace BiasedValue {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace BiasedValue

template <class Storage>
inline constexpr ::std::int32_t GenericBiasedValueView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return BiasedValue::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericBiasedValueView<Storage>::
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return BiasedValue::IntrinsicSizeInBytes();
}

namespace BiasedValue {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace BiasedValue

template <class Storage>
inline constexpr ::std::int32_t GenericBiasedValueView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return BiasedValue::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericBiasedValueView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return BiasedValue::MaxSizeInBytes();
}

namespace BiasedValue {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace BiasedValue

template <class Storage>
inline constexpr ::std::int32_t GenericBiasedValueView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return BiasedValue::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericBiasedValueView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return BiasedValue::MinSizeInBytes();
}
namespace VirtualFirstFieldWithParam {}  // namespace VirtualFirstFieldWithParam

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 0>>,
        8>>

GenericVirtualFirstFieldWithParamView<Storage>::x() const {
  if (has_x().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              8, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 0>>,
              8>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericVirtualFirstFieldWithParamView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericVirtualFirstFieldWithParamView<Storage>::has_value() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace VirtualFirstFieldWithParam {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace VirtualFirstFieldWithParam

template <class Storage>
inline constexpr ::std::int32_t GenericVirtualFirstFieldWithParamView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return VirtualFirstFieldWithParam::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericVirtualFirstFieldWithParamView<Storage>::
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return VirtualFirstFieldWithParam::IntrinsicSizeInBytes();
}

namespace VirtualFirstFieldWithParam {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace VirtualFirstFieldWithParam

template <class Storage>
inline constexpr ::std::int32_t GenericVirtualFirstFieldWithParamView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return VirtualFirstFieldWithParam::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericVirtualFirstFieldWithParamView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return VirtualFirstFieldWithParam::MaxSizeInBytes();
}

namespace VirtualFirstFieldWithParam {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace VirtualFirstFieldWithParam

template <class Storage>
inline constexpr ::std::int32_t GenericVirtualFirstFieldWithParamView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return VirtualFirstFieldWithParam::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericVirtualFirstFieldWithParamView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return VirtualFirstFieldWithParam::MinSizeInBytes();
}
namespace ConstVirtualFirstFieldWithParam {

}  // namespace ConstVirtualFirstFieldWithParam

namespace ConstVirtualFirstFieldWithParam {
inline constexpr ::std::int32_t value() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(10LL))
      .ValueOrDefault();
}
}  // namespace ConstVirtualFirstFieldWithParam

template <class Storage>
inline constexpr ::std::int32_t GenericConstVirtualFirstFieldWithParamView<
    Storage>::EmbossReservedVirtualValueView::Read() {
  return ConstVirtualFirstFieldWithParam::value();
}

template <class Storage>
inline constexpr ::std::int32_t GenericConstVirtualFirstFieldWithParamView<
    Storage>::EmbossReservedVirtualValueView::UncheckedRead() {
  return ConstVirtualFirstFieldWithParam::value();
}

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 0>>,
        8>>

GenericConstVirtualFirstFieldWithParamView<Storage>::x() const {
  if (has_x().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              8, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 0>>,
              8>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericConstVirtualFirstFieldWithParamView<Storage>::has_x() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace ConstVirtualFirstFieldWithParam {
inline constexpr ::std::int32_t IntrinsicSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace ConstVirtualFirstFieldWithParam

template <class Storage>
inline constexpr ::std::int32_t GenericConstVirtualFirstFieldWithParamView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView::Read() {
  return ConstVirtualFirstFieldWithParam::IntrinsicSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t
GenericConstVirtualFirstFieldWithParamView<Storage>::
    EmbossReservedDollarVirtualIntrinsicSizeInBytesView::UncheckedRead() {
  return ConstVirtualFirstFieldWithParam::IntrinsicSizeInBytes();
}

namespace ConstVirtualFirstFieldWithParam {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace ConstVirtualFirstFieldWithParam

template <class Storage>
inline constexpr ::std::int32_t GenericConstVirtualFirstFieldWithParamView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return ConstVirtualFirstFieldWithParam::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericConstVirtualFirstFieldWithParamView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return ConstVirtualFirstFieldWithParam::MaxSizeInBytes();
}

namespace ConstVirtualFirstFieldWithParam {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(1LL))
      .ValueOrDefault();
}
}  // namespace ConstVirtualFirstFieldWithParam

template <class Storage>
inline constexpr ::std::int32_t GenericConstVirtualFirstFieldWithParamView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return ConstVirtualFirstFieldWithParam::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericConstVirtualFirstFieldWithParamView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return ConstVirtualFirstFieldWithParam::MinSizeInBytes();
}
namespace SizedArrayOfBiasedValues {}  // namespace SizedArrayOfBiasedValues

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 0>>,
        8>>

GenericSizedArrayOfBiasedValuesView<Storage>::element_count() const {
  if (has_element_count().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(0LL));
    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 ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              8, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 0>>,
              8>>

          (backing_.template GetOffsetStorage<0, 0>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 0>>,
          8>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericSizedArrayOfBiasedValuesView<Storage>::has_element_count() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::prelude::UIntView<
    /**/ ::emboss::support::FixedSizeViewParameters<
        8, ::emboss::support::AllValuesAreOk>,
    typename ::emboss::support::BitBlock<
        /**/ ::emboss::support::LittleEndianByteOrderer<
            typename Storage::template OffsetStorageType</**/ 0, 1>>,
        8>>

GenericSizedArrayOfBiasedValuesView<Storage>::bias() const {
  if (has_bias().ValueOr(false)) {
    auto emboss_reserved_local_size =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(1LL));
    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 ::emboss::prelude::UIntView<
          /**/ ::emboss::support::FixedSizeViewParameters<
              8, ::emboss::support::AllValuesAreOk>,
          typename ::emboss::support::BitBlock<
              /**/ ::emboss::support::LittleEndianByteOrderer<
                  typename Storage::template OffsetStorageType</**/ 0, 1>>,
              8>>

          (backing_.template GetOffsetStorage<0, 1>(
              emboss_reserved_local_offset.ValueOrDefault(),
              emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::prelude::UIntView<
      /**/ ::emboss::support::FixedSizeViewParameters<
          8, ::emboss::support::AllValuesAreOk>,
      typename ::emboss::support::BitBlock<
          /**/ ::emboss::support::LittleEndianByteOrderer<
              typename Storage::template OffsetStorageType</**/ 0, 1>>,
          8>>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericSizedArrayOfBiasedValuesView<Storage>::has_bias() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename ::emboss::support::GenericArrayView<
    typename ::emboss::test::GenericBiasedValueView<
        typename Storage::template OffsetStorageType<
            /**/ 0, 2>::template OffsetStorageType</**/ 1, 0>>

    ,
    typename Storage::template OffsetStorageType</**/ 0, 2>, 1, 8,
    ::std::int32_t>

GenericSizedArrayOfBiasedValuesView<Storage>::values() const {
  const auto emboss_reserved_local_subexpr_1 = bias();
  const auto emboss_reserved_local_subexpr_2 =
      (emboss_reserved_local_subexpr_1.Ok()
           ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                 static_cast</**/ ::std::int32_t>(
                     emboss_reserved_local_subexpr_1.UncheckedRead()))
           : ::emboss::support::Maybe</**/ ::std::int32_t>());

  if (emboss_reserved_local_subexpr_2.Known() && has_values().ValueOr(false)) {
    const auto emboss_reserved_local_subexpr_3 = element_count();
    const auto emboss_reserved_local_subexpr_4 =
        (emboss_reserved_local_subexpr_3.Ok()
             ? ::emboss::support::Maybe</**/ ::std::int32_t>(
                   static_cast</**/ ::std::int32_t>(
                       emboss_reserved_local_subexpr_3.UncheckedRead()))
             : ::emboss::support::Maybe</**/ ::std::int32_t>());

    auto emboss_reserved_local_size = emboss_reserved_local_subexpr_4;
    auto emboss_reserved_local_offset =
        ::emboss::support::Maybe</**/ ::std::int32_t>(
            static_cast</**/ ::std::int32_t>(2LL));
    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 ::emboss::support::GenericArrayView<
          typename ::emboss::test::GenericBiasedValueView<
              typename Storage::template OffsetStorageType<
                  /**/ 0, 2>::template OffsetStorageType</**/ 1, 0>>

          ,
          typename Storage::template OffsetStorageType</**/ 0, 2>, 1, 8,
          ::std::int32_t>

          (emboss_reserved_local_subexpr_2.ValueOrDefault(),
           backing_.template GetOffsetStorage<0, 2>(
               emboss_reserved_local_offset.ValueOrDefault(),
               emboss_reserved_local_size.ValueOrDefault()));
    }
  }
  return ::emboss::support::GenericArrayView<
      typename ::emboss::test::GenericBiasedValueView<
          typename Storage::template OffsetStorageType<
              /**/ 0, 2>::template OffsetStorageType</**/ 1, 0>>

      ,
      typename Storage::template OffsetStorageType</**/ 0, 2>, 1, 8,
      ::std::int32_t>

      ();
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericSizedArrayOfBiasedValuesView<Storage>::has_values() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

template <class Storage>
inline typename GenericSizedArrayOfBiasedValuesView<
    Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView
GenericSizedArrayOfBiasedValuesView<Storage>::IntrinsicSizeInBytes() const {
  return typename GenericSizedArrayOfBiasedValuesView<
      Storage>::EmbossReservedDollarVirtualIntrinsicSizeInBytesView(*this);
}

template <class Storage>
inline ::emboss::support::Maybe<bool>
GenericSizedArrayOfBiasedValuesView<Storage>::has_IntrinsicSizeInBytes() const {
  return ::emboss::support::Maybe</**/ bool>(true);
}

namespace SizedArrayOfBiasedValues {
inline constexpr ::std::int32_t MaxSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(257LL))
      .ValueOrDefault();
}
}  // namespace SizedArrayOfBiasedValues

template <class Storage>
inline constexpr ::std::int32_t GenericSizedArrayOfBiasedValuesView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::Read() {
  return SizedArrayOfBiasedValues::MaxSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericSizedArrayOfBiasedValuesView<
    Storage>::EmbossReservedDollarVirtualMaxSizeInBytesView::UncheckedRead() {
  return SizedArrayOfBiasedValues::MaxSizeInBytes();
}

namespace SizedArrayOfBiasedValues {
inline constexpr ::std::int32_t MinSizeInBytes() {
  return ::emboss::support::Maybe</**/ ::std::int32_t>(
             static_cast</**/ ::std::int32_t>(2LL))
      .ValueOrDefault();
}
}  // namespace SizedArrayOfBiasedValues

template <class Storage>
inline constexpr ::std::int32_t GenericSizedArrayOfBiasedValuesView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::Read() {
  return SizedArrayOfBiasedValues::MinSizeInBytes();
}

template <class Storage>
inline constexpr ::std::int32_t GenericSizedArrayOfBiasedValuesView<
    Storage>::EmbossReservedDollarVirtualMinSizeInBytesView::UncheckedRead() {
  return SizedArrayOfBiasedValues::MinSizeInBytes();
}

}  // namespace test

}  // namespace emboss

/* NOLINTEND */

#endif  // TESTDATA_PARAMETERS_EMB_H_
