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

#pragma once

#include <lib/fidl/llcpp/array.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/message.h>
#include <lib/fidl/llcpp/message_storage.h>
#include <lib/fidl/llcpp/object_view.h>
#include <lib/fidl/llcpp/string_view.h>
#include <lib/fidl/llcpp/traits.h>
#include <lib/fidl/llcpp/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>

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

using SomeProtocolSomeMethodError =
    ::test_anonymous::SomeProtocolSomeMethodError;
using Op = ::test_anonymous::Op;

struct TableData;

struct SomeProtocolSomeMethodRequest;

struct OverrideTest;

struct SomeProtocolSomeMethodResponse;

struct SomeProtocolSomeMethodTopResponse;

class TableMember;

class FunctionApplication;

class UnionMember;

class Expression;

class SomeProtocolSomeMethodResult;

extern "C" const fidl_type_t test_anonymous_TableDataTable;

struct TableData {
  uint8_t data = {};
};

extern "C" const fidl_type_t
    test_anonymous_SomeProtocol_SomeMethod_ResponseTable;

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::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;
  [[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 {
extern "C" const fidl_type_t test_anonymous_TableMemberTable;

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);

  const ::fidl::VectorView<::test_anonymous::wire::TableData>& table_data()
      const {
    ZX_ASSERT(has_table_data());
    return frame_ptr_->table_data_.get_data();
  }
  ::fidl::VectorView<::test_anonymous::wire::TableData>& table_data() {
    ZX_ASSERT(has_table_data());
    return frame_ptr_->table_data_.get_data();
  }
  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();
    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> {
 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;
  }

  BuilderImpl& table_data(
      ::fidl::ObjectView<::fidl::VectorView<::test_anonymous::wire::TableData>>
          elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->table_data_.set_data(elem);
    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... Args>
  ::fidl::WireTableBuilder<::test_anonymous::wire::TableMember>& table_data(
      Args&&... args_) {
    table_data(::fidl::ObjectView<
               ::fidl::VectorView<::test_anonymous::wire::TableData>>(
        arena_.get(), std::forward<Args>(args_)...));
    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));
}

}  // 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;
  ::fidl::Envelope<::fidl::StringView> func_;
  [[maybe_unused]] ::fidl::UntypedEnvelope reserved_1_;
  ::fidl::Envelope<::fidl::VectorView<::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 {
extern "C" const fidl_type_t test_anonymous_FunctionApplicationTable;

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);

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

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

  const ::test_anonymous::wire::Flags& flags() const {
    ZX_ASSERT(has_flags());
    return frame_ptr_->flags_.get_data();
  }
  ::test_anonymous::wire::Flags& flags() {
    ZX_ASSERT(has_flags());
    return frame_ptr_->flags_.get_data();
  }
  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();
    return *this;
  }
  FunctionApplication& set_args(
      ::fidl::ObjectView<::fidl::VectorView<::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<::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();
    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();
    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> {
 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;
  }

  BuilderImpl& func(::fidl::ObjectView<::fidl::StringView> elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->func_.set_data(elem);
    table_.max_ordinal_ =
        std::max(table_.max_ordinal_, static_cast<uint64_t>(1));
    return *static_cast<BuilderImpl*>(this);
  }

  BuilderImpl& args(
      ::fidl::ObjectView<::fidl::VectorView<::test_anonymous::wire::Expression>>
          elem) {
    ZX_DEBUG_ASSERT(table_.frame_ptr_ != nullptr);
    table_.frame_ptr_->args_.set_data(elem);
    table_.max_ordinal_ =
        std::max(table_.max_ordinal_, static_cast<uint64_t>(3));
    return *static_cast<BuilderImpl*>(this);
  }

  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... Args>
  ::fidl::WireTableBuilder<::test_anonymous::wire::FunctionApplication>& func(
      Args&&... args_) {
    func(::fidl::ObjectView<::fidl::StringView>(arena_.get(),
                                                std::forward<Args>(args_)...));
    return *this;
  }
  using Base::args;

  template <typename... Args>
  ::fidl::WireTableBuilder<::test_anonymous::wire::FunctionApplication>& args(
      Args&&... args_) {
    args(::fidl::ObjectView<
         ::fidl::VectorView<::test_anonymous::wire::Expression>>(
        arena_.get(), std::forward<Args>(args_)...));
    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));
}

extern "C" const fidl_type_t test_anonymous_UnionMemberTable;

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
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  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_;
};

extern "C" const fidl_type_t test_anonymous_ExpressionTable;

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
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  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_;
};

extern "C" const fidl_type_t test_anonymous_SomeProtocol_SomeMethod_ResultTable;

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_;
};

extern "C" const fidl_type_t test_anonymous_SomeProtocolSomeMethodRequestTable;

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 = {};
};

extern "C" const fidl_type_t test_anonymous_OverrideTestTable;

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

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

  ::test_anonymous::wire::Expression left = {};

  ::test_anonymous::wire::Expression right = {};
};

extern "C" const fidl_type_t
    test_anonymous_SomeProtocolSomeMethodTopResponseTable;

struct SomeProtocolSomeMethodTopResponse {
  using Result = test_anonymous::wire::SomeProtocolSomeMethodResult;

  ::test_anonymous::wire::SomeProtocolSomeMethodResult result = {};
};

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

template <>
struct TypeTraits<::test_anonymous::wire::TableData> {
  static constexpr const fidl_type_t* kType =
      &::test_anonymous::wire::test_anonymous_TableDataTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 1;
  static constexpr uint32_t kPrimarySizeV1 = 1;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsFidlType<::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 <>
struct TypeTraits<::test_anonymous::wire::SomeProtocolSomeMethodRequest> {
  static constexpr const fidl_type_t* kType =
      &::test_anonymous::wire::
          test_anonymous_SomeProtocolSomeMethodRequestTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 32;
  static constexpr uint32_t kPrimarySizeV1 = 40;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 48;
  static constexpr uint32_t kMaxOutOfLineV1 = 72;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::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 <>
struct TypeTraits<::test_anonymous::wire::OverrideTest> {
  static constexpr const fidl_type_t* kType =
      &::test_anonymous::wire::test_anonymous_OverrideTestTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 40;
  static constexpr uint32_t kPrimarySizeV1 = 56;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::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 <>
struct TypeTraits<::test_anonymous::wire::SomeProtocolSomeMethodResponse> {
  static constexpr const fidl_type_t* kType =
      &::test_anonymous::wire::
          test_anonymous_SomeProtocol_SomeMethod_ResponseTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 4;
  static constexpr uint32_t kPrimarySizeV1 = 4;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 0;
  static constexpr bool kHasPointer = false;
};

template <>
struct IsFidlType<::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 <>
struct TypeTraits<::test_anonymous::wire::SomeProtocolSomeMethodTopResponse> {
  static constexpr const fidl_type_t* kType =
      &::test_anonymous::wire::
          test_anonymous_SomeProtocolSomeMethodTopResponseTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

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

template <>
struct TypeTraits<::test_anonymous::wire::TableMember> {
  static constexpr const fidl_type_t* kType =
      &::test_anonymous::wire::test_anonymous_TableMemberTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 16;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 48;
  static constexpr uint32_t kMaxOutOfLineV1 = 64;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::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 <>
struct TypeTraits<::test_anonymous::wire::FunctionApplication> {
  static constexpr const fidl_type_t* kType =
      &::test_anonymous::wire::test_anonymous_FunctionApplicationTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 16;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::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 <>
struct TypeTraits<::test_anonymous::wire::UnionMember> {
  static constexpr const fidl_type_t* kType =
      &::test_anonymous::wire::test_anonymous_UnionMemberTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::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 <>
struct TypeTraits<::test_anonymous::wire::Expression> {
  static constexpr const fidl_type_t* kType =
      &::test_anonymous::wire::test_anonymous_ExpressionTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 4294967295;
  static constexpr uint32_t kMaxOutOfLineV1 = 4294967295;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::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 <>
struct TypeTraits<::test_anonymous::wire::SomeProtocolSomeMethodResult> {
  static constexpr const fidl_type_t* kType =
      &::test_anonymous::wire::
          test_anonymous_SomeProtocol_SomeMethod_ResultTable;
  static constexpr uint32_t kMaxNumHandles = 0;
  static constexpr uint32_t kPrimarySize = 16;
  static constexpr uint32_t kPrimarySizeV1 = 24;
  [[maybe_unused]] static constexpr uint32_t kMaxOutOfLine = 0;
  static constexpr uint32_t kMaxOutOfLineV1 = 8;
  static constexpr bool kHasPointer = true;
};

template <>
struct IsFidlType<::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>);

}  // namespace fidl
