// WARNING: This file is machine generated by fidlgen.

// fidl_experiment = output_index_json

#pragma once

#include <lib/fidl/cpp/wire/array.h>
#include <lib/fidl/cpp/wire/envelope.h>
#include <lib/fidl/cpp/wire/internal/framework_err.h>
#include <lib/fidl/cpp/wire/message.h>
#include <lib/fidl/cpp/wire/message_storage.h>
#include <lib/fidl/cpp/wire/object_view.h>
#include <lib/fidl/cpp/wire/string_view.h>
#include <lib/fidl/cpp/wire/traits.h>
#include <lib/fidl/cpp/wire/wire_types.h>
#include <lib/stdcompat/optional.h>

#include <cinttypes>
#ifdef __Fuchsia__
#include <lib/zx/channel.h>

#endif  // __Fuchsia__

#include <fidl/test.anonymous/cpp/common_types.h>
#include <fidl/test.anonymous/cpp/markers.h>

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"

namespace test_anonymous {

namespace wire {
using Flags = ::test_anonymous::Flags;

using BitsMember = ::test_anonymous::BitsMember;

using Op = ::test_anonymous::Op;

using SomeProtocolSomeMethodError = ::test_anonymous::SomeProtocolSomeMethodError;

struct OverrideTest;

struct TableData;

struct SomeProtocolSomeMethodRequest;

struct SomeProtocolSomeMethodResponse;

class FunctionApplication;

class TableMember;

class Expression;

class UnionMember;

class SomeProtocolSomeMethodResult;

struct TableData {
  uint8_t data = {};
};

struct SomeProtocolSomeMethodResponse {
  using BitsMember = test_anonymous::wire::BitsMember;

  ::test_anonymous::wire::BitsMember bits_member = {};
};

}  // namespace wire
}  // namespace test_anonymous

template <>
class ::fidl::WireTableBuilder<::test_anonymous::wire::FunctionApplication>;
template <>
class ::fidl::WireTableExternalBuilder<::test_anonymous::wire::FunctionApplication>;

template <>
struct ::fidl::WireTableFrame<::test_anonymous::wire::FunctionApplication> final {
 public:
  WireTableFrame() = default;
  // In its intended usage, WireTableFrame will be referenced by an ObjectView.
  // If the ObjectView is assigned before a move or copy, then it will reference
  // the old invalid object. Because this is unsafe, copies are disallowed and
  // moves are only allowed by friend classes that operate safely.
  WireTableFrame(const WireTableFrame&) = delete;
  WireTableFrame& operator=(const WireTableFrame&) = delete;

 private:
  WireTableFrame(WireTableFrame&&) noexcept = default;
  WireTableFrame& operator=(WireTableFrame&&) noexcept = default;

  bool HasUnknownData() const;
  uint64_t ComputeMaxOrdinal() const;
  ::fidl::Envelope<::fidl::StringView> func_;
  [[maybe_unused]] ::fidl::UntypedEnvelope reserved_1_;
  ::fidl::Envelope<::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>> args_;
  ::fidl::Envelope<::test_anonymous::wire::Flags> flags_;

  friend class ::test_anonymous::wire::FunctionApplication;
  friend ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::FunctionApplication, ::fidl::WireTableBuilder<::test_anonymous::wire::FunctionApplication>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::FunctionApplication, ::fidl::WireTableExternalBuilder<::test_anonymous::wire::FunctionApplication>>;
};

namespace test_anonymous {
namespace wire {

class FunctionApplication {
 public:
  using Flags = test_anonymous::wire::Flags;
  FunctionApplication() = default;
  FunctionApplication(const FunctionApplication& other) noexcept = default;
  FunctionApplication& operator=(const FunctionApplication& other) noexcept = default;
  FunctionApplication(FunctionApplication&& other) noexcept = default;
  FunctionApplication& operator=(FunctionApplication&& other) noexcept = default;

  ~FunctionApplication() = default;

  // Returns whether no field is set.
  bool IsEmpty() const { return max_ordinal_ == 0; }

  // Returns whether the table references unknown fields.
  bool HasUnknownData() const;

  // Return a builder that by defaults allocates of an arena.
  static ::fidl::WireTableBuilder<::test_anonymous::wire::FunctionApplication> Builder(::fidl::AnyArena& arena);

  // Return a builder that relies on explicitly allocating |fidl::ObjectView|s.
  static ::fidl::WireTableExternalBuilder<::test_anonymous::wire::FunctionApplication> ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::FunctionApplication>> frame);

  [[nodiscard]] ::fidl::StringView& func() const {
    ZX_ASSERT(has_func());
    return frame_ptr_->func_.get_data();
  }
  [[nodiscard]] bool has_func() const {
    return max_ordinal_ >= 1 && frame_ptr_->func_.has_data();
  }

  [[nodiscard]] ::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>& args() const {
    ZX_ASSERT(has_args());
    return frame_ptr_->args_.get_data();
  }
  [[nodiscard]] bool has_args() const {
    return max_ordinal_ >= 3 && frame_ptr_->args_.has_data();
  }

  [[nodiscard]] ::test_anonymous::wire::Flags& flags() const {
    ZX_ASSERT(has_flags());
    return frame_ptr_->flags_.get_data();
  }
  [[nodiscard]] bool has_flags() const {
    return max_ordinal_ >= 4 && frame_ptr_->flags_.has_data();
  }
#if defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES) || false
 public:
#else   // !defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES)
 private:
#endif  // FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES

  FunctionApplication& set_func(::fidl::ObjectView<::fidl::StringView> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->func_.set_data(elem);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }
  FunctionApplication& set_func(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->func_.set_data(nullptr);
    return *this;
  }
  template <typename... Args>
  FunctionApplication& set_func(::fidl::AnyArena& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->func_.set_data(
        ::fidl::ObjectView<::fidl::StringView>(allocator, std::forward<Args>(args)...));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  FunctionApplication& clear_func() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->func_.clear_data();
    max_ordinal_ = frame_ptr_->ComputeMaxOrdinal();
    return *this;
  }
  FunctionApplication& set_args(::fidl::ObjectView<::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->args_.set_data(elem);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(3));
    return *this;
  }
  FunctionApplication& set_args(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->args_.set_data(nullptr);
    return *this;
  }
  template <typename... Args>
  FunctionApplication& set_args(::fidl::AnyArena& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->args_.set_data(
        ::fidl::ObjectView<::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>>(allocator, std::forward<Args>(args)...));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(3));
    return *this;
  }

  FunctionApplication& clear_args() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->args_.clear_data();
    max_ordinal_ = frame_ptr_->ComputeMaxOrdinal();
    return *this;
  }
  FunctionApplication& set_flags(::test_anonymous::wire::Flags elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->flags_.set_data(std::move(elem));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(4));
    return *this;
  }

  FunctionApplication& clear_flags() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->flags_.clear_data();
    max_ordinal_ = frame_ptr_->ComputeMaxOrdinal();
    return *this;
  }

  explicit FunctionApplication(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::FunctionApplication>>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a Arena).
  // It should only be used when performance is key.
  // As soon as the frame is given to the table, it must not be used directly or for another table.
  explicit FunctionApplication(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::FunctionApplication>>&& frame)
      : frame_ptr_(std::move(frame)) {}

  void Allocate(::fidl::AnyArena& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::FunctionApplication>>(allocator);
  }
  void Init(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::FunctionApplication>>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

 private:
  friend ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::FunctionApplication, ::fidl::WireTableBuilder<::test_anonymous::wire::FunctionApplication>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::FunctionApplication, ::fidl::WireTableExternalBuilder<::test_anonymous::wire::FunctionApplication>>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::FunctionApplication>> frame_ptr_;
};
}  // namespace wire
}  // namespace test_anonymous

template <typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::FunctionApplication, BuilderImpl> {
 protected:
  // |Wrapper_Ignore_Me_| wraps a |fidl::ObjectView<T>| and reduces its
  // priority in overload resolution. When the user writes `{}` as the
  // setter argument, that would default construct the field instead of
  // constructing a NULL object view.
  template <typename U>
  struct Wrapper_Ignore_Me_ {
    Wrapper_Ignore_Me_(U v) : value(v) {}
    U value;
  };

 public:
  // Build and return the table. The builder should not be used after this.
  ::test_anonymous::wire::FunctionApplication Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_anonymous::wire::FunctionApplication t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }
  [[nodiscard]] bool has_func() const {
    return table_.has_func();
  }

  // Clears the func field.
  //
  // This method should be used sparingly, such as only during tests, as it has
  // O(number_of_fields) complexity.
  void clear_func() {
    table_.clear_func();
  }

  // Getter for func.
  //

  [[nodiscard]] ::fidl::StringView& func() const {
    return table_.func();
  }

  // Setter for func.
  //

  BuilderImpl& func(Wrapper_Ignore_Me_<::fidl::ObjectView<::fidl::StringView>> elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ZX_DEBUG_ASSERT(elem.value.get() != nullptr);
    table_.frame_ptr_->func_.set_data(elem.value);
    table_.max_ordinal_ = std::max(table_.max_ordinal_, static_cast<uint64_t>(1));
    return *static_cast<BuilderImpl*>(this);
  }
  [[nodiscard]] bool has_args() const {
    return table_.has_args();
  }

  // Clears the args field.
  //
  // This method should be used sparingly, such as only during tests, as it has
  // O(number_of_fields) complexity.
  void clear_args() {
    table_.clear_args();
  }

  // Getter for args.
  //

  [[nodiscard]] ::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>& args() const {
    return table_.args();
  }

  // Setter for args.
  //

  BuilderImpl& args(Wrapper_Ignore_Me_<::fidl::ObjectView<::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>>> elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ZX_DEBUG_ASSERT(elem.value.get() != nullptr);
    table_.frame_ptr_->args_.set_data(elem.value);
    table_.max_ordinal_ = std::max(table_.max_ordinal_, static_cast<uint64_t>(3));
    return *static_cast<BuilderImpl*>(this);
  }
  [[nodiscard]] bool has_flags() const {
    return table_.has_flags();
  }

  // Clears the flags field.
  //
  // This method should be used sparingly, such as only during tests, as it has
  // O(number_of_fields) complexity.
  void clear_flags() {
    table_.clear_flags();
  }

  // Getter for flags.
  //

  [[nodiscard]] ::test_anonymous::wire::Flags& flags() const {
    return table_.flags();
  }

  // Setter for flags.
  //

  BuilderImpl& flags(::test_anonymous::wire::Flags elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->flags_.set_data(std::move(elem));
    table_.max_ordinal_ = std::max(table_.max_ordinal_, static_cast<uint64_t>(4));
    return *static_cast<BuilderImpl*>(this);
  }

 protected:
  WireTableBaseBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::FunctionApplication>>&& frame)
      : table_(std::move(frame)) {}

 private:
  ::test_anonymous::wire::FunctionApplication table_;
};

template <>
class ::fidl::WireTableBuilder<::test_anonymous::wire::FunctionApplication> final : public ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::FunctionApplication, ::fidl::WireTableBuilder<::test_anonymous::wire::FunctionApplication>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::FunctionApplication, ::fidl::WireTableBuilder<::test_anonymous::wire::FunctionApplication>>;

 public:
  using Base::func;

  template <
      typename First = ::fidl::StringView,
      typename... Args,
      std::enable_if_t<!std::is_same_v<cpp20::remove_cvref_t<First>, fidl::ObjectView<::fidl::StringView>>, int> = 0>
  ::fidl::WireTableBuilder<::test_anonymous::wire::FunctionApplication>& func(First&& first, Args&&... args_) {
    fidl::ObjectView<::fidl::StringView> view_(arena_.get(), std::forward<First>(first), std::forward<Args>(args_)...);
    func(Base::Wrapper_Ignore_Me_<fidl::ObjectView<::fidl::StringView>>(view_));
    return *this;
  }
  using Base::args;

  template <
      typename First = ::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>,
      typename... Args,
      std::enable_if_t<!std::is_same_v<cpp20::remove_cvref_t<First>, fidl::ObjectView<::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>>>, int> = 0>
  ::fidl::WireTableBuilder<::test_anonymous::wire::FunctionApplication>& args(First&& first, Args&&... args_) {
    fidl::ObjectView<::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>> view_(arena_.get(), std::forward<First>(first), std::forward<Args>(args_)...);
    args(Base::Wrapper_Ignore_Me_<fidl::ObjectView<::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>>>(view_));
    return *this;
  }

 private:
  friend class ::test_anonymous::wire::FunctionApplication;
  WireTableBuilder(::fidl::AnyArena& arena)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::FunctionApplication>>(arena)),
        arena_(arena) {}

  [[maybe_unused]] std::reference_wrapper<::fidl::AnyArena> arena_;
};

template <>
class ::fidl::WireTableExternalBuilder<::test_anonymous::wire::FunctionApplication> final : public ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::FunctionApplication, ::fidl::WireTableExternalBuilder<::test_anonymous::wire::FunctionApplication>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::FunctionApplication, ::fidl::WireTableExternalBuilder<::test_anonymous::wire::FunctionApplication>>;

 private:
  friend class ::test_anonymous::wire::FunctionApplication;
  using Base::Base;
  WireTableExternalBuilder(::fidl::WireTableFrame<::test_anonymous::wire::FunctionApplication>* frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::FunctionApplication>>::FromExternal(frame)) {}
};
namespace test_anonymous {
namespace wire {

inline ::fidl::WireTableBuilder<::test_anonymous::wire::FunctionApplication> FunctionApplication::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<::test_anonymous::wire::FunctionApplication>(arena);
}
inline ::fidl::WireTableExternalBuilder<::test_anonymous::wire::FunctionApplication> FunctionApplication::ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::FunctionApplication>> frame) {
  return ::fidl::WireTableExternalBuilder<::test_anonymous::wire::FunctionApplication>(std::move(frame));
}

}  // namespace wire
}  // namespace test_anonymous

template <>
class ::fidl::WireTableBuilder<::test_anonymous::wire::TableMember>;
template <>
class ::fidl::WireTableExternalBuilder<::test_anonymous::wire::TableMember>;

template <>
struct ::fidl::WireTableFrame<::test_anonymous::wire::TableMember> final {
 public:
  WireTableFrame() = default;
  // In its intended usage, WireTableFrame will be referenced by an ObjectView.
  // If the ObjectView is assigned before a move or copy, then it will reference
  // the old invalid object. Because this is unsafe, copies are disallowed and
  // moves are only allowed by friend classes that operate safely.
  WireTableFrame(const WireTableFrame&) = delete;
  WireTableFrame& operator=(const WireTableFrame&) = delete;

 private:
  WireTableFrame(WireTableFrame&&) noexcept = default;
  WireTableFrame& operator=(WireTableFrame&&) noexcept = default;

  bool HasUnknownData() const;
  uint64_t ComputeMaxOrdinal() const;
  [[maybe_unused]] ::fidl::UntypedEnvelope reserved_0_;
  ::fidl::Envelope<::fidl::VectorView<::test_anonymous::wire::TableData>> table_data_;

  friend class ::test_anonymous::wire::TableMember;
  friend ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::TableMember, ::fidl::WireTableBuilder<::test_anonymous::wire::TableMember>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::TableMember, ::fidl::WireTableExternalBuilder<::test_anonymous::wire::TableMember>>;
};

namespace test_anonymous {
namespace wire {

class TableMember {
 public:
  using TableData = test_anonymous::wire::TableData;
  TableMember() = default;
  TableMember(const TableMember& other) noexcept = default;
  TableMember& operator=(const TableMember& other) noexcept = default;
  TableMember(TableMember&& other) noexcept = default;
  TableMember& operator=(TableMember&& other) noexcept = default;

  ~TableMember() = default;

  // Returns whether no field is set.
  bool IsEmpty() const { return max_ordinal_ == 0; }

  // Returns whether the table references unknown fields.
  bool HasUnknownData() const;

  // Return a builder that by defaults allocates of an arena.
  static ::fidl::WireTableBuilder<::test_anonymous::wire::TableMember> Builder(::fidl::AnyArena& arena);

  // Return a builder that relies on explicitly allocating |fidl::ObjectView|s.
  static ::fidl::WireTableExternalBuilder<::test_anonymous::wire::TableMember> ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::TableMember>> frame);

  [[nodiscard]] ::fidl::VectorView<::test_anonymous::wire::TableData>& table_data() const {
    ZX_ASSERT(has_table_data());
    return frame_ptr_->table_data_.get_data();
  }
  [[nodiscard]] bool has_table_data() const {
    return max_ordinal_ >= 2 && frame_ptr_->table_data_.has_data();
  }
#if defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES) || false
 public:
#else   // !defined(FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES)
 private:
#endif  // FIDL_WIRE_ALLOW_DEPRECATED_MUTABLE_TABLES

  TableMember& set_table_data(::fidl::ObjectView<::fidl::VectorView<::test_anonymous::wire::TableData>> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->table_data_.set_data(elem);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(2));
    return *this;
  }
  TableMember& set_table_data(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->table_data_.set_data(nullptr);
    return *this;
  }
  template <typename... Args>
  TableMember& set_table_data(::fidl::AnyArena& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->table_data_.set_data(
        ::fidl::ObjectView<::fidl::VectorView<::test_anonymous::wire::TableData>>(allocator, std::forward<Args>(args)...));
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(2));
    return *this;
  }

  TableMember& clear_table_data() {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->table_data_.clear_data();
    max_ordinal_ = frame_ptr_->ComputeMaxOrdinal();
    return *this;
  }

  explicit TableMember(::fidl::AnyArena& allocator)
      : frame_ptr_(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::TableMember>>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a Arena).
  // It should only be used when performance is key.
  // As soon as the frame is given to the table, it must not be used directly or for another table.
  explicit TableMember(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::TableMember>>&& frame)
      : frame_ptr_(std::move(frame)) {}

  void Allocate(::fidl::AnyArena& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::TableMember>>(allocator);
  }
  void Init(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::TableMember>>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

 private:
  friend ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::TableMember, ::fidl::WireTableBuilder<::test_anonymous::wire::TableMember>>;
  friend ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::TableMember, ::fidl::WireTableExternalBuilder<::test_anonymous::wire::TableMember>>;

  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::TableMember>> frame_ptr_;
};
}  // namespace wire
}  // namespace test_anonymous

template <typename BuilderImpl>
class ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::TableMember, BuilderImpl> {
 protected:
  // |Wrapper_Ignore_Me_| wraps a |fidl::ObjectView<T>| and reduces its
  // priority in overload resolution. When the user writes `{}` as the
  // setter argument, that would default construct the field instead of
  // constructing a NULL object view.
  template <typename U>
  struct Wrapper_Ignore_Me_ {
    Wrapper_Ignore_Me_(U v) : value(v) {}
    U value;
  };

 public:
  // Build and return the table. The builder should not be used after this.
  ::test_anonymous::wire::TableMember Build() {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ::test_anonymous::wire::TableMember t = std::move(table_);
    // Poison this builder to prevent accidental reuse.
    table_.frame_ptr_ = nullptr;
    return t;
  }
  [[nodiscard]] bool has_table_data() const {
    return table_.has_table_data();
  }

  // Clears the table_data field.
  //
  // This method should be used sparingly, such as only during tests, as it has
  // O(number_of_fields) complexity.
  void clear_table_data() {
    table_.clear_table_data();
  }

  // Getter for table_data.
  //

  [[nodiscard]] ::fidl::VectorView<::test_anonymous::wire::TableData>& table_data() const {
    return table_.table_data();
  }

  // Setter for table_data.
  //

  BuilderImpl& table_data(Wrapper_Ignore_Me_<::fidl::ObjectView<::fidl::VectorView<::test_anonymous::wire::TableData>>> elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    ZX_DEBUG_ASSERT(elem.value.get() != nullptr);
    table_.frame_ptr_->table_data_.set_data(elem.value);
    table_.max_ordinal_ = std::max(table_.max_ordinal_, static_cast<uint64_t>(2));
    return *static_cast<BuilderImpl*>(this);
  }

 protected:
  WireTableBaseBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::TableMember>>&& frame)
      : table_(std::move(frame)) {}

 private:
  ::test_anonymous::wire::TableMember table_;
};

template <>
class ::fidl::WireTableBuilder<::test_anonymous::wire::TableMember> final : public ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::TableMember, ::fidl::WireTableBuilder<::test_anonymous::wire::TableMember>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::TableMember, ::fidl::WireTableBuilder<::test_anonymous::wire::TableMember>>;

 public:
  using Base::table_data;

  template <
      typename First = ::fidl::VectorView<::test_anonymous::wire::TableData>,
      typename... Args,
      std::enable_if_t<!std::is_same_v<cpp20::remove_cvref_t<First>, fidl::ObjectView<::fidl::VectorView<::test_anonymous::wire::TableData>>>, int> = 0>
  ::fidl::WireTableBuilder<::test_anonymous::wire::TableMember>& table_data(First&& first, Args&&... args_) {
    fidl::ObjectView<::fidl::VectorView<::test_anonymous::wire::TableData>> view_(arena_.get(), std::forward<First>(first), std::forward<Args>(args_)...);
    table_data(Base::Wrapper_Ignore_Me_<fidl::ObjectView<::fidl::VectorView<::test_anonymous::wire::TableData>>>(view_));
    return *this;
  }

 private:
  friend class ::test_anonymous::wire::TableMember;
  WireTableBuilder(::fidl::AnyArena& arena)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::TableMember>>(arena)),
        arena_(arena) {}

  [[maybe_unused]] std::reference_wrapper<::fidl::AnyArena> arena_;
};

template <>
class ::fidl::WireTableExternalBuilder<::test_anonymous::wire::TableMember> final : public ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::TableMember, ::fidl::WireTableExternalBuilder<::test_anonymous::wire::TableMember>> {
  using Base = ::fidl::internal::WireTableBaseBuilder<::test_anonymous::wire::TableMember, ::fidl::WireTableExternalBuilder<::test_anonymous::wire::TableMember>>;

 private:
  friend class ::test_anonymous::wire::TableMember;
  using Base::Base;
  WireTableExternalBuilder(::fidl::WireTableFrame<::test_anonymous::wire::TableMember>* frame)
      : Base(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::TableMember>>::FromExternal(frame)) {}
};
namespace test_anonymous {
namespace wire {

inline ::fidl::WireTableBuilder<::test_anonymous::wire::TableMember> TableMember::Builder(::fidl::AnyArena& arena) {
  return ::fidl::WireTableBuilder<::test_anonymous::wire::TableMember>(arena);
}
inline ::fidl::WireTableExternalBuilder<::test_anonymous::wire::TableMember> TableMember::ExternalBuilder(::fidl::ObjectView<::fidl::WireTableFrame<::test_anonymous::wire::TableMember>> frame) {
  return ::fidl::WireTableExternalBuilder<::test_anonymous::wire::TableMember>(std::move(frame));
}

class Expression {
 public:
  using FunctionApplication = test_anonymous::wire::FunctionApplication;
  using BinOp = test_anonymous::wire::OverrideTest;

  Expression() : ordinal_(::test_anonymous::wire::Expression::Ordinal::Invalid), envelope_{} {}

  Expression(const Expression&) = default;
  Expression& operator=(const Expression&) = default;
  Expression(Expression&&) = default;
  Expression& operator=(Expression&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kValue = 1,                // 0x1
    kBinOp = 2,                // 0x2
    kFunctionApplication = 3,  // 0x3
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_anonymous::wire::Expression::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  bool has_invalid_tag() const { return ordinal_ == ::test_anonymous::wire::Expression::Ordinal::Invalid; }

  bool is_value() const { return ordinal_ == ::test_anonymous::wire::Expression::Ordinal::kValue; }

  static Expression WithValue(::fidl::ObjectView<uint64_t> val) {
    Expression result;
    result.ordinal_ = ::test_anonymous::wire::Expression::Ordinal::kValue;
    result.envelope_.As<uint64_t>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static Expression WithValue(::fidl::AnyArena& allocator, Args&&... args) {
    return WithValue(::fidl::ObjectView<uint64_t>(allocator,
                                                  std::forward<Args>(args)...));
  }

  uint64_t& value() {
    ZX_ASSERT(ordinal_ == ::test_anonymous::wire::Expression::Ordinal::kValue);
    return envelope_.As<uint64_t>().get_data();
  }
  const uint64_t& value() const {
    ZX_ASSERT(ordinal_ == ::test_anonymous::wire::Expression::Ordinal::kValue);
    return envelope_.As<uint64_t>().get_data();
  }

  bool is_bin_op() const { return ordinal_ == ::test_anonymous::wire::Expression::Ordinal::kBinOp; }

  static Expression WithBinOp(::fidl::ObjectView<::test_anonymous::wire::OverrideTest> val) {
    Expression result;
    result.ordinal_ = ::test_anonymous::wire::Expression::Ordinal::kBinOp;
    result.envelope_.As<::test_anonymous::wire::OverrideTest>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static Expression WithBinOp(::fidl::AnyArena& allocator, Args&&... args) {
    return WithBinOp(::fidl::ObjectView<::test_anonymous::wire::OverrideTest>(allocator,
                                                                              std::forward<Args>(args)...));
  }

  ::test_anonymous::wire::OverrideTest& bin_op() {
    ZX_ASSERT(ordinal_ == ::test_anonymous::wire::Expression::Ordinal::kBinOp);
    return envelope_.As<::test_anonymous::wire::OverrideTest>().get_data();
  }
  const ::test_anonymous::wire::OverrideTest& bin_op() const {
    ZX_ASSERT(ordinal_ == ::test_anonymous::wire::Expression::Ordinal::kBinOp);
    return envelope_.As<::test_anonymous::wire::OverrideTest>().get_data();
  }

  bool is_function_application() const { return ordinal_ == ::test_anonymous::wire::Expression::Ordinal::kFunctionApplication; }

  static Expression WithFunctionApplication(::fidl::ObjectView<::test_anonymous::wire::FunctionApplication> val) {
    Expression result;
    result.ordinal_ = ::test_anonymous::wire::Expression::Ordinal::kFunctionApplication;
    result.envelope_.As<::test_anonymous::wire::FunctionApplication>().set_data(std::move(val));
    return result;
  }

  template <typename... Args>
  static Expression WithFunctionApplication(::fidl::AnyArena& allocator, Args&&... args) {
    return WithFunctionApplication(::fidl::ObjectView<::test_anonymous::wire::FunctionApplication>(allocator,
                                                                                                   std::forward<Args>(args)...));
  }

  ::test_anonymous::wire::FunctionApplication& function_application() {
    ZX_ASSERT(ordinal_ == ::test_anonymous::wire::Expression::Ordinal::kFunctionApplication);
    return envelope_.As<::test_anonymous::wire::FunctionApplication>().get_data();
  }
  const ::test_anonymous::wire::FunctionApplication& function_application() const {
    ZX_ASSERT(ordinal_ == ::test_anonymous::wire::Expression::Ordinal::kFunctionApplication);
    return envelope_.As<::test_anonymous::wire::FunctionApplication>().get_data();
  }
  ::test_anonymous::wire::Expression::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kValue = 1,                // 0x1
    kBinOp = 2,                // 0x2
    kFunctionApplication = 3,  // 0x3
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_anonymous::wire::Expression::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

class UnionMember {
 public:
  UnionMember() : ordinal_(::test_anonymous::wire::UnionMember::Ordinal::Invalid), envelope_{} {}

  UnionMember(const UnionMember&) = default;
  UnionMember& operator=(const UnionMember&) = default;
  UnionMember(UnionMember&&) = default;
  UnionMember& operator=(UnionMember&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kUnionData = 2,  // 0x2
    _do_not_handle_this__write_a_default_case_instead = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };
  constexpr bool IsUnknown() const {
    return Which() == ::test_anonymous::wire::UnionMember::Tag::_do_not_handle_this__write_a_default_case_instead;
  }

  bool has_invalid_tag() const { return ordinal_ == ::test_anonymous::wire::UnionMember::Ordinal::Invalid; }

  bool is_union_data() const { return ordinal_ == ::test_anonymous::wire::UnionMember::Ordinal::kUnionData; }

  static UnionMember WithUnionData(uint8_t val) {
    UnionMember result;
    result.ordinal_ = ::test_anonymous::wire::UnionMember::Ordinal::kUnionData;
    result.envelope_.As<uint8_t>().set_data(std::move(val));
    return result;
  }

  uint8_t& union_data() {
    ZX_ASSERT(ordinal_ == ::test_anonymous::wire::UnionMember::Ordinal::kUnionData);
    return envelope_.As<uint8_t>().get_data();
  }
  const uint8_t& union_data() const {
    ZX_ASSERT(ordinal_ == ::test_anonymous::wire::UnionMember::Ordinal::kUnionData);
    return envelope_.As<uint8_t>().get_data();
  }
  ::test_anonymous::wire::UnionMember::Tag Which() const;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kUnionData = 2,  // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_anonymous::wire::UnionMember::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

class SomeProtocolSomeMethodResult {
 public:
  using Err = test_anonymous::wire::SomeProtocolSomeMethodError;
  using Response = test_anonymous::wire::SomeProtocolSomeMethodResponse;

  SomeProtocolSomeMethodResult() : ordinal_(::test_anonymous::wire::SomeProtocolSomeMethodResult::Ordinal::Invalid), envelope_{} {}

  SomeProtocolSomeMethodResult(const SomeProtocolSomeMethodResult&) = default;
  SomeProtocolSomeMethodResult& operator=(const SomeProtocolSomeMethodResult&) = default;
  SomeProtocolSomeMethodResult(SomeProtocolSomeMethodResult&&) = default;
  SomeProtocolSomeMethodResult& operator=(SomeProtocolSomeMethodResult&&) = default;

  enum class Tag : fidl_xunion_tag_t {
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  bool has_invalid_tag() const { return ordinal_ == ::test_anonymous::wire::SomeProtocolSomeMethodResult::Ordinal::Invalid; }

  bool is_response() const { return ordinal_ == ::test_anonymous::wire::SomeProtocolSomeMethodResult::Ordinal::kResponse; }

  static SomeProtocolSomeMethodResult WithResponse(::test_anonymous::wire::SomeProtocolSomeMethodResponse val) {
    SomeProtocolSomeMethodResult result;
    result.ordinal_ = ::test_anonymous::wire::SomeProtocolSomeMethodResult::Ordinal::kResponse;
    result.envelope_.As<::test_anonymous::wire::SomeProtocolSomeMethodResponse>().set_data(std::move(val));
    return result;
  }

  ::test_anonymous::wire::SomeProtocolSomeMethodResponse& response() {
    ZX_ASSERT(ordinal_ == ::test_anonymous::wire::SomeProtocolSomeMethodResult::Ordinal::kResponse);
    return envelope_.As<::test_anonymous::wire::SomeProtocolSomeMethodResponse>().get_data();
  }
  const ::test_anonymous::wire::SomeProtocolSomeMethodResponse& response() const {
    ZX_ASSERT(ordinal_ == ::test_anonymous::wire::SomeProtocolSomeMethodResult::Ordinal::kResponse);
    return envelope_.As<::test_anonymous::wire::SomeProtocolSomeMethodResponse>().get_data();
  }

  bool is_err() const { return ordinal_ == ::test_anonymous::wire::SomeProtocolSomeMethodResult::Ordinal::kErr; }

  static SomeProtocolSomeMethodResult WithErr(::test_anonymous::wire::SomeProtocolSomeMethodError val) {
    SomeProtocolSomeMethodResult result;
    result.ordinal_ = ::test_anonymous::wire::SomeProtocolSomeMethodResult::Ordinal::kErr;
    result.envelope_.As<::test_anonymous::wire::SomeProtocolSomeMethodError>().set_data(std::move(val));
    return result;
  }

  ::test_anonymous::wire::SomeProtocolSomeMethodError& err() {
    ZX_ASSERT(ordinal_ == ::test_anonymous::wire::SomeProtocolSomeMethodResult::Ordinal::kErr);
    return envelope_.As<::test_anonymous::wire::SomeProtocolSomeMethodError>().get_data();
  }
  const ::test_anonymous::wire::SomeProtocolSomeMethodError& err() const {
    ZX_ASSERT(ordinal_ == ::test_anonymous::wire::SomeProtocolSomeMethodResult::Ordinal::kErr);
    return envelope_.As<::test_anonymous::wire::SomeProtocolSomeMethodError>().get_data();
  }
  ::test_anonymous::wire::SomeProtocolSomeMethodResult::Tag Which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::test_anonymous::wire::SomeProtocolSomeMethodResult::Tag>(ordinal_);
  }

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kResponse = 1,  // 0x1
    kErr = 2,       // 0x2
  };

  static void SizeAndOffsetAssertionHelper();
  ::test_anonymous::wire::SomeProtocolSomeMethodResult::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::UntypedEnvelope envelope_;
};

struct OverrideTest {
  using Op = test_anonymous::wire::Op;

  ::test_anonymous::wire::Op op = {};

  ::fidl::WireOptional<::test_anonymous::wire::Expression> left = {};

  ::fidl::WireOptional<::test_anonymous::wire::Expression> right = {};
};

struct SomeProtocolSomeMethodRequest {
  using UnionMember = test_anonymous::wire::UnionMember;
  using TableMember = test_anonymous::wire::TableMember;

  ::test_anonymous::wire::UnionMember union_member = {};

  ::test_anonymous::wire::TableMember table_member = {};
};

}  // namespace wire
}  // namespace test_anonymous
namespace fidl {

template <bool IsRecursive>
struct internal::WireCodingTraits<::test_anonymous::wire::Flags, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = sizeof(uint16_t);
  static constexpr bool kIsMemcpyCompatible = true;

  static void Encode(internal::WireEncoder* encoder, ::test_anonymous::wire::Flags* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    *position.As<::test_anonymous::wire::Flags>() = *value;
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
  }
};

template <bool IsRecursive>
struct internal::WireCodingTraits<::test_anonymous::wire::BitsMember, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = sizeof(uint32_t);
  static constexpr bool kIsMemcpyCompatible = true;

  static void Encode(internal::WireEncoder* encoder, ::test_anonymous::wire::BitsMember* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    *position.As<::test_anonymous::wire::BitsMember>() = *value;
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
  }
};

template <bool IsRecursive>
struct internal::WireCodingTraits<::test_anonymous::wire::Op, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = sizeof(uint32_t);
  static constexpr bool kIsMemcpyCompatible = true;

  static void Encode(internal::WireEncoder* encoder, ::test_anonymous::wire::Op* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    *position.As<::test_anonymous::wire::Op>() = *value;
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
  }
};

template <bool IsRecursive>
struct internal::WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodError, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = sizeof(uint32_t);
  static constexpr bool kIsMemcpyCompatible = true;

  static void Encode(internal::WireEncoder* encoder, ::test_anonymous::wire::SomeProtocolSomeMethodError* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    *position.As<::test_anonymous::wire::SomeProtocolSomeMethodError>() = *value;
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
  }
};

template <>
struct TypeTraits<::test_anonymous::wire::OverrideTest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 4294967295;
  static constexpr uint32_t kPrimarySize = 40;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_anonymous::wire::OverrideTest> : public std::true_type {};
template <>
struct IsWire<::test_anonymous::wire::OverrideTest> : public std::true_type {};
template <>
struct IsStruct<::test_anonymous::wire::OverrideTest> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_anonymous::wire::OverrideTest>);
static_assert(offsetof(::test_anonymous::wire::OverrideTest, op) == 0);
static_assert(offsetof(::test_anonymous::wire::OverrideTest, left) == 8);
static_assert(offsetof(::test_anonymous::wire::OverrideTest, right) == 24);
static_assert(sizeof(::test_anonymous::wire::OverrideTest) == TypeTraits<::test_anonymous::wire::OverrideTest>::kPrimarySize);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_anonymous::wire::OverrideTest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 40;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::test_anonymous::wire::Op, fidl::internal::WireCodingConstraintEmpty, IsRecursive>(), ::fidl::internal::WireStructMemberCodingInfo<::fidl::WireOptional<::test_anonymous::wire::Expression>, fidl::internal::WireCodingConstraintUnion<true>, IsRecursive>(), ::fidl::internal::WireStructMemberCodingInfo<::fidl::WireOptional<::test_anonymous::wire::Expression>, fidl::internal::WireCodingConstraintUnion<true>, IsRecursive>());
  static constexpr bool kHasPadding = true;
  using Base = WireStructCodingTraitsBase<::test_anonymous::wire::OverrideTest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_anonymous::wire::OverrideTest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_anonymous::wire::OverrideTest));
    } else {
      internal::WireZeroPadding<uint64_t>(encoder, position + 0);
      internal::WireCodingTraits<::test_anonymous::wire::Op, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->op, position + 0, recursion_depth);
      internal::WireCodingTraits<::fidl::WireOptional<::test_anonymous::wire::Expression>, fidl::internal::WireCodingConstraintUnion<true>, IsRecursive>::Encode(encoder, &value->left, position + 8, recursion_depth);
      internal::WireCodingTraits<::fidl::WireOptional<::test_anonymous::wire::Expression>, fidl::internal::WireCodingConstraintUnion<true>, IsRecursive>::Encode(encoder, &value->right, position + 24, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::test_anonymous::wire::Op, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
      internal::WireCodingTraits<::fidl::WireOptional<::test_anonymous::wire::Expression>, fidl::internal::WireCodingConstraintUnion<true>, IsRecursive>::Decode(
          decoder, position + 8, recursion_depth);
      internal::WireCodingTraits<::fidl::WireOptional<::test_anonymous::wire::Expression>, fidl::internal::WireCodingConstraintUnion<true>, IsRecursive>::Decode(
          decoder, position + 24, recursion_depth);
    }
    internal::WireCheckPadding<uint64_t>(decoder, position + 0, 0xffffffff00000000);
  }
};

template <>
struct TypeTraits<::test_anonymous::wire::TableData> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 1;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsFidlType<::test_anonymous::wire::TableData> : public std::true_type {};
template <>
struct IsWire<::test_anonymous::wire::TableData> : public std::true_type {};
template <>
struct IsStruct<::test_anonymous::wire::TableData> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_anonymous::wire::TableData>);
static_assert(offsetof(::test_anonymous::wire::TableData, data) == 0);
static_assert(sizeof(::test_anonymous::wire::TableData) == TypeTraits<::test_anonymous::wire::TableData>::kPrimarySize);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_anonymous::wire::TableData, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 1;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<uint8_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_anonymous::wire::TableData, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_anonymous::wire::TableData* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_anonymous::wire::TableData));
    } else {
      internal::WireCodingTraits<uint8_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->data, position + 0, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<uint8_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
  }
};

template <>
struct TypeTraits<::test_anonymous::wire::SomeProtocolSomeMethodRequest> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = 32;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 48;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_anonymous::wire::SomeProtocolSomeMethodRequest> : public std::true_type {};
template <>
struct IsWire<::test_anonymous::wire::SomeProtocolSomeMethodRequest> : public std::true_type {};
template <>
struct IsStruct<::test_anonymous::wire::SomeProtocolSomeMethodRequest> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_anonymous::wire::SomeProtocolSomeMethodRequest>);
static_assert(offsetof(::test_anonymous::wire::SomeProtocolSomeMethodRequest, union_member) == 0);
static_assert(offsetof(::test_anonymous::wire::SomeProtocolSomeMethodRequest, table_member) == 16);
static_assert(sizeof(::test_anonymous::wire::SomeProtocolSomeMethodRequest) == TypeTraits<::test_anonymous::wire::SomeProtocolSomeMethodRequest>::kPrimarySize);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 32;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::test_anonymous::wire::UnionMember, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>(), ::fidl::internal::WireStructMemberCodingInfo<::test_anonymous::wire::TableMember, fidl::internal::WireCodingConstraintEmpty, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_anonymous::wire::SomeProtocolSomeMethodRequest, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_anonymous::wire::SomeProtocolSomeMethodRequest* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_anonymous::wire::SomeProtocolSomeMethodRequest));
    } else {
      internal::WireCodingTraits<::test_anonymous::wire::UnionMember, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::Encode(encoder, &value->union_member, position + 0, recursion_depth);
      internal::WireCodingTraits<::test_anonymous::wire::TableMember, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->table_member, position + 16, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::test_anonymous::wire::UnionMember, fidl::internal::WireCodingConstraintUnion<false>, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
      internal::WireCodingTraits<::test_anonymous::wire::TableMember, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
          decoder, position + 16, recursion_depth);
    }
  }
};

template <>
struct TypeTraits<::test_anonymous::wire::SomeProtocolSomeMethodResponse> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 0;
  static constexpr uint32_t kPrimarySize = 4;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsFidlType<::test_anonymous::wire::SomeProtocolSomeMethodResponse> : public std::true_type {};
template <>
struct IsWire<::test_anonymous::wire::SomeProtocolSomeMethodResponse> : public std::true_type {};
template <>
struct IsStruct<::test_anonymous::wire::SomeProtocolSomeMethodResponse> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_anonymous::wire::SomeProtocolSomeMethodResponse>);
static_assert(offsetof(::test_anonymous::wire::SomeProtocolSomeMethodResponse, bits_member) == 0);
static_assert(sizeof(::test_anonymous::wire::SomeProtocolSomeMethodResponse) == TypeTraits<::test_anonymous::wire::SomeProtocolSomeMethodResponse>::kPrimarySize);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodResponse, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = 4;
  static constexpr auto kMembers = std::make_tuple(::fidl::internal::WireStructMemberCodingInfo<::test_anonymous::wire::BitsMember, fidl::internal::WireCodingConstraintEmpty, IsRecursive>());
  static constexpr bool kHasPadding = false;
  using Base = WireStructCodingTraitsBase<::test_anonymous::wire::SomeProtocolSomeMethodResponse, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>;
  static constexpr bool kIsMemcpyCompatible = Base::kIsMemcpyCompatible;

  static void Encode(
      internal::WireEncoder* encoder, ::test_anonymous::wire::SomeProtocolSomeMethodResponse* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (kIsMemcpyCompatible) {
      memcpy(position.As<void>(), value, sizeof(::test_anonymous::wire::SomeProtocolSomeMethodResponse));
    } else {
      internal::WireCodingTraits<::test_anonymous::wire::BitsMember, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Encode(encoder, &value->bits_member, position + 0, recursion_depth);
    }
  }
  static void Decode(
      internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if constexpr (!Base::are_members_memcpy_compatible) {
      internal::WireCodingTraits<::test_anonymous::wire::BitsMember, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::Decode(
          decoder, position + 0, recursion_depth);
    }
  }
};

template <>
struct TypeTraits<::test_anonymous::wire::FunctionApplication> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 4294967295;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_anonymous::wire::FunctionApplication> : public std::true_type {};
template <>
struct IsWire<::test_anonymous::wire::FunctionApplication> : public std::true_type {};
template <>
struct IsTable<::test_anonymous::wire::FunctionApplication> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_anonymous::wire::FunctionApplication>);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_anonymous::wire::FunctionApplication, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : ::fidl::internal::WireTableCodingTraitsBase<IsRecursive> {
  using Base = ::fidl::internal::WireTableCodingTraitsBase<IsRecursive>;
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_anonymous::wire::FunctionApplication* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit ==
        Base::PrepareForBodyEncode(encoder, value, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = reinterpret_cast<fidl_vector_t*>(value);
    fidl_envelope_t* envelopes = static_cast<fidl_envelope_t*>(vec->data);
    for (size_t i = 0; i < vec->count; i++) {
      size_t encode_inline_size = 0;
      switch (i) {
        case 0:
          encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false, 100>, IsRecursive>::kInlineSize;
          break;
        case 2:
          encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintUnion<true>, false, 5>, IsRecursive>::kInlineSize;
          break;
        case 3:
          encode_inline_size = ::fidl::internal::WireCodingTraits<::test_anonymous::wire::Flags, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      ::fidl::internal::EncodeFn<IsRecursive> encode_fn = nullptr;
      switch (i) {
        case 0:
          encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false, 100>, IsRecursive>();
          break;
        case 2:
          encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintUnion<true>, false, 5>, IsRecursive>();
          break;
        case 3:
          encode_fn = ::fidl::internal::MakeEncodeFn<::test_anonymous::wire::Flags, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      WirePosition envelope_position = vector_position + i * sizeof(fidl_envelope_t);
      WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &envelopes[i], envelope_position, inner_depth);
    }
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit == Base::DecodePrework(decoder, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = position.As<fidl_vector_t>();
    for (size_t i = 0; i < vec->count; i++) {
      size_t decode_inline_size = 0;
      switch (i) {
        case 0:
          decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::StringView, fidl::internal::WireCodingConstraintString<false, 100>, IsRecursive>::kInlineSize;
          break;
        case 2:
          decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintUnion<true>, false, 5>, IsRecursive>::kInlineSize;
          break;
        case 3:
          decode_inline_size = ::fidl::internal::WireCodingTraits<::test_anonymous::wire::Flags, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
          break;
      }
      DecodeFn<IsRecursive> decode_fn = nullptr;
      switch (i) {
        case 0:
          decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::StringView, fidl::internal::WireCodingConstraintString<false, 100>, IsRecursive>();
          break;
        case 2:
          decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::VectorView<::fidl::WireOptional<::test_anonymous::wire::Expression>>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintUnion<true>, false, 5>, IsRecursive>();
          break;
        case 3:
          decode_fn = ::fidl::internal::MakeDecodeFn<::test_anonymous::wire::Flags, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
          break;
      }
      ::fidl::internal::WireDecodeOptionalEnvelope(decode_inline_size, decode_fn, decoder, vector_position + i * sizeof(fidl_envelope_t), inner_depth);
    }
  }
};

template <>
struct TypeTraits<::test_anonymous::wire::TableMember> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 3;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 48;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_anonymous::wire::TableMember> : public std::true_type {};
template <>
struct IsWire<::test_anonymous::wire::TableMember> : public std::true_type {};
template <>
struct IsTable<::test_anonymous::wire::TableMember> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_anonymous::wire::TableMember>);

template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_anonymous::wire::TableMember, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : ::fidl::internal::WireTableCodingTraitsBase<IsRecursive> {
  using Base = ::fidl::internal::WireTableCodingTraitsBase<IsRecursive>;
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_anonymous::wire::TableMember* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit ==
        Base::PrepareForBodyEncode(encoder, value, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = reinterpret_cast<fidl_vector_t*>(value);
    fidl_envelope_t* envelopes = static_cast<fidl_envelope_t*>(vec->data);
    for (size_t i = 0; i < vec->count; i++) {
      size_t encode_inline_size = 0;
      switch (i) {
        case 1:
          encode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<::test_anonymous::wire::TableData>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintEmpty, false, 10>, IsRecursive>::kInlineSize;
          break;
      }
      ::fidl::internal::EncodeFn<IsRecursive> encode_fn = nullptr;
      switch (i) {
        case 1:
          encode_fn = ::fidl::internal::MakeEncodeFn<::fidl::VectorView<::test_anonymous::wire::TableData>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintEmpty, false, 10>, IsRecursive>();
          break;
      }
      WirePosition envelope_position = vector_position + i * sizeof(fidl_envelope_t);
      WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &envelopes[i], envelope_position, inner_depth);
    }
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 2);
    if (!inner_depth.IsValid()) {
      return;
    }

    ::fidl::internal::WirePosition vector_position;
    if (Base::PreworkResult::kEarlyExit == Base::DecodePrework(decoder, position, &vector_position)) {
      return;
    }

    fidl_vector_t* vec = position.As<fidl_vector_t>();
    for (size_t i = 0; i < vec->count; i++) {
      size_t decode_inline_size = 0;
      switch (i) {
        case 1:
          decode_inline_size = ::fidl::internal::WireCodingTraits<::fidl::VectorView<::test_anonymous::wire::TableData>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintEmpty, false, 10>, IsRecursive>::kInlineSize;
          break;
      }
      DecodeFn<IsRecursive> decode_fn = nullptr;
      switch (i) {
        case 1:
          decode_fn = ::fidl::internal::MakeDecodeFn<::fidl::VectorView<::test_anonymous::wire::TableData>, fidl::internal::WireCodingConstraintVector<fidl::internal::WireCodingConstraintEmpty, false, 10>, IsRecursive>();
          break;
      }
      ::fidl::internal::WireDecodeOptionalEnvelope(decode_inline_size, decode_fn, decoder, vector_position + i * sizeof(fidl_envelope_t), inner_depth);
    }
  }
};

template <>
struct TypeTraits<::test_anonymous::wire::Expression> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 4294967295;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_anonymous::wire::Expression> : public std::true_type {};
template <>
struct IsWire<::test_anonymous::wire::Expression> : public std::true_type {};
template <>
struct IsUnion<::test_anonymous::wire::Expression> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_anonymous::wire::Expression>);

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_anonymous::wire::Expression, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_anonymous::wire::Expression* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    size_t encode_inline_size;
    switch (u->tag) {
      case 1:  // ::test_anonymous::wire::Expression::Tag::kValue
        encode_inline_size = ::fidl::internal::WireCodingTraits<uint64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 2:  // ::test_anonymous::wire::Expression::Tag::kBinOp
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_anonymous::wire::OverrideTest, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 3:  // ::test_anonymous::wire::Expression::Tag::kFunctionApplication
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_anonymous::wire::FunctionApplication, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1:  // ::test_anonymous::wire::Expression::Tag::kValue
        encode_fn = ::fidl::internal::MakeEncodeFn<uint64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 2:  // ::test_anonymous::wire::Expression::Tag::kBinOp
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_anonymous::wire::OverrideTest, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 3:  // ::test_anonymous::wire::Expression::Tag::kFunctionApplication
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_anonymous::wire::FunctionApplication, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_anonymous::wire::Expression::Tag tag = *position.As<::test_anonymous::wire::Expression::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    size_t decode_inline_size;
    switch (tag) {
      case ::test_anonymous::wire::Expression::Tag::kValue:
        decode_inline_size = ::fidl::internal::WireCodingTraits<uint64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_anonymous::wire::Expression::Tag::kBinOp:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_anonymous::wire::OverrideTest, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_anonymous::wire::Expression::Tag::kFunctionApplication:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_anonymous::wire::FunctionApplication, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch (tag) {
      case ::test_anonymous::wire::Expression::Tag::kValue:
        decode_fn = ::fidl::internal::MakeDecodeFn<uint64_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_anonymous::wire::Expression::Tag::kBinOp:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_anonymous::wire::OverrideTest, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_anonymous::wire::Expression::Tag::kFunctionApplication:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_anonymous::wire::FunctionApplication, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_anonymous::wire::Expression, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : public ::fidl::internal::WireCodingTraits<::test_anonymous::wire::Expression, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};

template <>
struct TypeTraits<::test_anonymous::wire::UnionMember> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = true;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_anonymous::wire::UnionMember> : public std::true_type {};
template <>
struct IsWire<::test_anonymous::wire::UnionMember> : public std::true_type {};
template <>
struct IsUnion<::test_anonymous::wire::UnionMember> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_anonymous::wire::UnionMember>);

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_anonymous::wire::UnionMember, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_anonymous::wire::UnionMember* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    size_t encode_inline_size;
    switch (u->tag) {
      case 2:  // ::test_anonymous::wire::UnionMember::Tag::kUnionData
        encode_inline_size = ::fidl::internal::WireCodingTraits<uint8_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 2:  // ::test_anonymous::wire::UnionMember::Tag::kUnionData
        encode_fn = ::fidl::internal::MakeEncodeFn<uint8_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_anonymous::wire::UnionMember::Tag tag = *position.As<::test_anonymous::wire::UnionMember::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    size_t decode_inline_size;
    switch (tag) {
      case ::test_anonymous::wire::UnionMember::Tag::kUnionData:
        decode_inline_size = ::fidl::internal::WireCodingTraits<uint8_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch (tag) {
      case ::test_anonymous::wire::UnionMember::Tag::kUnionData:
        decode_fn = ::fidl::internal::MakeDecodeFn<uint8_t, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeFlexibleEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_anonymous::wire::UnionMember, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : public ::fidl::internal::WireCodingTraits<::test_anonymous::wire::UnionMember, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};

template <>
struct TypeTraits<::test_anonymous::wire::SomeProtocolSomeMethodResult> {
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kMaxDepth = 1;
  static constexpr uint32_t kPrimarySize = 16;
  [[maybe_unused]]
  static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr bool kHasFlexibleEnvelope = false;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::test_anonymous::wire::SomeProtocolSomeMethodResult> : public std::true_type {};
template <>
struct IsWire<::test_anonymous::wire::SomeProtocolSomeMethodResult> : public std::true_type {};
template <>
struct IsUnion<::test_anonymous::wire::SomeProtocolSomeMethodResult> : public std::true_type {};
static_assert(std::is_standard_layout_v<::test_anonymous::wire::SomeProtocolSomeMethodResult>);

template <typename Constraint, bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodResult, Constraint, IsRecursive> {
  static constexpr size_t kInlineSize = 16;
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_anonymous::wire::SomeProtocolSomeMethodResult* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    fidl_union_t* u = reinterpret_cast<fidl_union_t*>(value);

    if (unlikely(u->tag == 0)) {
      if constexpr (Constraint::is_optional) {
        *position.As<fidl_union_t>() = {};
        return;
      }
      encoder->SetError(kCodingErrorInvalidUnionTag);
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(encoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    *position.As<fidl_xunion_tag_t>() = u->tag;

    size_t encode_inline_size;
    switch (u->tag) {
      case 1:  // ::test_anonymous::wire::SomeProtocolSomeMethodResult::Tag::kResponse
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodResponse, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case 2:  // ::test_anonymous::wire::SomeProtocolSomeMethodResult::Tag::kErr
        encode_inline_size = ::fidl::internal::WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodError, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        encode_inline_size = 0;
        break;
    }
    ::fidl::internal::EncodeFn<IsRecursive> encode_fn;
    switch (u->tag) {
      case 1:  // ::test_anonymous::wire::SomeProtocolSomeMethodResult::Tag::kResponse
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_anonymous::wire::SomeProtocolSomeMethodResponse, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case 2:  // ::test_anonymous::wire::SomeProtocolSomeMethodResult::Tag::kErr
        encode_fn = ::fidl::internal::MakeEncodeFn<::test_anonymous::wire::SomeProtocolSomeMethodError, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        encode_fn = nullptr;
        break;
    }
    WireEncodeEnvelope(encode_inline_size, encode_fn, encoder, &u->envelope, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }

  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_anonymous::wire::SomeProtocolSomeMethodResult::Tag tag = *position.As<::test_anonymous::wire::SomeProtocolSomeMethodResult::Tag>();
    if (unlikely(static_cast<uint64_t>(tag) == 0)) {
      if constexpr (!Constraint::is_optional) {
        decoder->SetError(kCodingErrorInvalidUnionTag);
        return;
      }
      static_assert(sizeof(fidl_envelope_t) == sizeof(uint64_t));
      if (*(position + sizeof(fidl_xunion_tag_t)).As<uint64_t>() != 0) {
        decoder->SetError(kCodingErrorZeroTagButNonZeroEnvelope);
      }
      return;
    }

    RecursionDepth<IsRecursive> inner_depth = recursion_depth.Add(decoder, 1);
    if (!inner_depth.IsValid()) {
      return;
    }

    size_t decode_inline_size;
    switch (tag) {
      case ::test_anonymous::wire::SomeProtocolSomeMethodResult::Tag::kResponse:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodResponse, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      case ::test_anonymous::wire::SomeProtocolSomeMethodResult::Tag::kErr:
        decode_inline_size = ::fidl::internal::WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodError, fidl::internal::WireCodingConstraintEmpty, IsRecursive>::kInlineSize;
        break;
      default:
        decode_inline_size = 0;
        break;
    }
    DecodeFn<IsRecursive> decode_fn;
    switch (tag) {
      case ::test_anonymous::wire::SomeProtocolSomeMethodResult::Tag::kResponse:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_anonymous::wire::SomeProtocolSomeMethodResponse, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      case ::test_anonymous::wire::SomeProtocolSomeMethodResult::Tag::kErr:
        decode_fn = ::fidl::internal::MakeDecodeFn<::test_anonymous::wire::SomeProtocolSomeMethodError, fidl::internal::WireCodingConstraintEmpty, IsRecursive>();
        break;
      default:
        decode_fn = nullptr;
        break;
    }
    ::fidl::internal::WireDecodeStrictEnvelope(decode_inline_size, decode_fn, decoder, position + sizeof(fidl_xunion_tag_t), inner_depth);
  }
};

// Top-level union.
template <bool IsRecursive>
struct ::fidl::internal::WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodResult, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive>
    : public ::fidl::internal::WireCodingTraits<::test_anonymous::wire::SomeProtocolSomeMethodResult, ::fidl::internal::WireCodingConstraintUnion<false>, IsRecursive> {};

#pragma clang diagnostic pop

}  // namespace fidl
