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

#pragma once

#include "lib/fidl/cpp/internal/header.h"

namespace test {
namespace versions {

//
// Domain objects declarations
//

class Union;

class Table;

class Struct;

#ifdef __Fuchsia__
class Service;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class OtherProtocol;
using OtherProtocolHandle = ::fidl::InterfaceHandle<OtherProtocol>;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class Protocol;
using ProtocolHandle = ::fidl::InterfaceHandle<Protocol>;
#endif  // __Fuchsia__

class Enum final {
 public:
  constexpr Enum() : value_(0) {}
  constexpr explicit Enum(uint32_t value) : value_(value) {}
  constexpr operator uint32_t() const { return value_; }

  constexpr bool IsUnknown() const {
    switch (value_) {
      case 1u:

        return false;
    }
    return true;
  }

  constexpr static Enum Unknown() {
    return Enum(0xffffffff);
  }

  static const Enum A;

 private:
  uint32_t value_;
};

#if !(__cplusplus < 201703)
constexpr const ::test::versions::Enum Enum::A = ::test::versions::Enum(1u);
#endif  // !(__cplusplus < 201703)

inline zx_status_t Clone(::test::versions::Enum value,
                         ::test::versions::Enum* result) {
  *result = value;
  return ZX_OK;
}

// |Bits| is flexible, hence may contain unknown members not
// defined in the FIDL schema.
class Bits final {
 public:
  constexpr Bits() = default;

  // Constructs an instance of |Bits| from an underlying primitive value
  // if the primitive does not contain any unknown members not defined in the
  // FIDL schema. Otherwise, returns |cpp17::nullopt|.
  constexpr inline static cpp17::optional<Bits> TryFrom(uint32_t value) {
    if (value & ~kMask.value_) {
      return cpp17::nullopt;
    }
    return Bits(value & Bits::kMask.value_);
  }

  // Constructs an instance of |Bits| from an underlying primitive value,
  // clearing any bit member not defined in the FIDL schema.
  constexpr inline static Bits TruncatingUnknown(uint32_t value) {
    return Bits(value & Bits::kMask.value_);
  }

  // Constructs an instance of |Bits| from an underlying primitive value,
  // preserving any bit member not defined in the FIDL schema.
  constexpr explicit Bits(uint32_t value) : value_(value) {}
  const static Bits A;
  const static Bits kMask;

  explicit constexpr inline operator uint32_t() const { return value_; }
  explicit constexpr inline operator bool() const { return static_cast<bool>(value_); }
  constexpr inline bool operator==(const Bits& other) const { return value_ == other.value_; }
  constexpr inline bool operator!=(const Bits& other) const { return value_ != other.value_; }
  constexpr inline Bits operator~() const;
  constexpr inline Bits operator|(const Bits& other) const;
  constexpr inline Bits operator&(const Bits& other) const;
  constexpr inline Bits operator^(const Bits& other) const;
  constexpr inline void operator|=(const Bits& other);
  constexpr inline void operator&=(const Bits& other);
  constexpr inline void operator^=(const Bits& other);
  constexpr inline Bits unknown_bits() const {
    return *this & Bits(~kMask.value_);
  }
  constexpr inline bool has_unknown_bits() const { return static_cast<bool>(unknown_bits()); }

 private:
  uint32_t value_ = 0;
};

#if !(__cplusplus < 201703)
constexpr const ::test::versions::Bits Bits::A = ::test::versions::Bits(1u);
constexpr const ::test::versions::Bits Bits::kMask = ::test::versions::Bits(1u);

#endif  // !(__cplusplus < 201703)

constexpr inline ::test::versions::Bits Bits::operator~() const {
  return ::test::versions::Bits(static_cast<uint32_t>(~this->value_ & kMask.value_));
}

constexpr inline ::test::versions::Bits Bits::operator|(
    const ::test::versions::Bits& other) const {
  return ::test::versions::Bits(static_cast<uint32_t>(this->value_ | other.value_));
}

constexpr inline ::test::versions::Bits Bits::operator&(
    const ::test::versions::Bits& other) const {
  return ::test::versions::Bits(static_cast<uint32_t>(this->value_ & other.value_));
}

constexpr inline ::test::versions::Bits Bits::operator^(
    const ::test::versions::Bits& other) const {
  return ::test::versions::Bits(static_cast<uint32_t>(this->value_ ^ other.value_));
}

constexpr inline void Bits::operator|=(
    const ::test::versions::Bits& other) {
  this->value_ |= other.value_;
}

constexpr inline void Bits::operator&=(
    const ::test::versions::Bits& other) {
  this->value_ &= other.value_;
}

constexpr inline void Bits::operator^=(
    const ::test::versions::Bits& other) {
  this->value_ ^= other.value_;
}

inline zx_status_t Clone(::test::versions::Bits value,
                         ::test::versions::Bits* result) {
  *result = value;
  return ZX_OK;
}

class Union final {
 public:
  static const fidl_type_t* FidlType;

  Union();
  ~Union();

  Union(Union&&);
  Union& operator=(Union&&);

  static Union WithX(uint32_t&&);

  enum __attribute__((enum_extensibility(closed))) Tag : fidl_xunion_tag_t {
    kUnknown = 0,

    kX = 1,  // 0x1
    Invalid = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  static inline ::std::unique_ptr<Union> New() { return ::std::make_unique<Union>(); }

  void Encode(::fidl::Encoder* encoder, size_t offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, Union* value, size_t offset);
  zx_status_t Clone(Union* result) const;

  bool has_invalid_tag() const {
    return tag_ == Invalid;
  }

  bool is_x() const { return tag_ == ::test::versions::Union::Tag::kX; }

  uint32_t& x() {
    EnsureStorageInitialized(::test::versions::Union::Tag::kX);
    return x_;
  }

  const uint32_t& x() const {
    ZX_ASSERT(is_x());
    return x_;
  }
  Union& set_x(uint32_t value);
  Union& SetUnknownData(fidl_xunion_tag_t ordinal, std::vector<uint8_t> bytes);

  ::test::versions::Union::Tag Which() const {
    switch (tag_) {
      case ::test::versions::Union::Tag::Invalid:
      case ::test::versions::Union::Tag::kX:
        return ::test::versions::Union::Tag(tag_);
      default:
        return ::test::versions::Union::Tag::kUnknown;
    }
  }

  // You probably want to use Which() method instead of Ordinal(). Use Ordinal() only when you need
  // access to the raw integral ordinal value.
  fidl_xunion_tag_t Ordinal() const {
    return tag_;
  }
  const std::vector<uint8_t>* UnknownBytes() const {
    if (Which() != ::test::versions::Union::Tag::kUnknown) {
      return nullptr;
    }
    return &unknown_data_;
  }

  friend ::fidl::Equality<::test::versions::Union>;

 private:
  void Destroy();
  void EnsureStorageInitialized(::fidl_xunion_tag_t tag);

  ::fidl_xunion_tag_t tag_ = static_cast<fidl_xunion_tag_t>(::test::versions::Union::Tag::Invalid);
  union {
    uint32_t x_;
    std::vector<uint8_t> unknown_data_;
  };
};

inline zx_status_t Clone(const ::test::versions::Union& value,
                         ::test::versions::Union* result) {
  return value.Clone(result);
}

using UnionPtr = ::std::unique_ptr<Union>;

class Table final {
 public:
  static const fidl_type_t* FidlType;
  /// Returns whether no field is set.
  bool IsEmpty() const;

  const uint32_t& x() const {
    ZX_ASSERT(field_presence_.IsSet<0>());
    return x_value_.value;
  }
  bool has_x() const {
    return field_presence_.IsSet<0>();
  }

  uint32_t* mutable_x() {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&x_value_.value);
    }
    return &x_value_.value;
  }
  Table& set_x(uint32_t _value) {
    if (!field_presence_.IsSet<0>()) {
      field_presence_.Set<0>();
      Construct(&x_value_.value, std::move(_value));
    } else {
      x_value_.value = std::move(_value);
    }
    return *this;
  }
  void clear_x() {
    if (!field_presence_.IsSet<0>()) {
      return;
    }
    field_presence_.Clear<0>();
    Destruct(&x_value_.value);
  }

  Table();
  Table(Table&& other);
  ~Table();
  Table& operator=(Table&& other);

  static inline ::std::unique_ptr<Table> New() { return ::std::make_unique<Table>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, Table* _value, size_t _offset);
  zx_status_t Clone(Table* _result) const;

 private:
  template <class T, class... Args>
  void Construct(T* p, Args&&... args) {
    new (p) T(std::forward<Args>(args)...);
  }

  template <class T>
  void Destruct(T* p) {
    p->~T();
  }

  size_t MaxOrdinal() const {
    return static_cast<size_t>(field_presence_.MaxSetIndex()) + std::size_t{1};
  }

  static bool IsOrdinalKnown(uint64_t ordinal) {
    switch (ordinal) {
      case 1:
        return true;
      default:
        return false;
    }
  }

  ::fidl::internal::BitSet<1> field_presence_;
  union ValueUnion_x {
    ValueUnion_x() {}
    ~ValueUnion_x() {}

    uint32_t value;
  };
  ValueUnion_x x_value_;
};

using TablePtr = ::std::unique_ptr<Table>;

class Struct final {
 public:
  static const fidl_type_t* FidlType;

  uint32_t x{};

  static inline ::std::unique_ptr<Struct> New() { return ::std::make_unique<Struct>(); }

  void Encode(::fidl::Encoder* _encoder, size_t _offset,
              cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt);
  static void Decode(::fidl::Decoder* _decoder, Struct* value, size_t _offset);
  zx_status_t Clone(Struct* result) const;
};

inline zx_status_t Clone(const ::test::versions::Struct& _value,
                         ::test::versions::Struct* _result) {
  return _value.Clone(_result);
}

using StructPtr = ::std::unique_ptr<Struct>;

#ifdef __Fuchsia__

class OtherProtocol_RequestEncoder {
 public:
};

class OtherProtocol_ResponseEncoder {
 public:
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class Protocol_RequestEncoder {
 public:
  static ::fidl::HLCPPOutgoingMessage Foo(::fidl::MessageEncoder* _encoder) {
    return _encoder->GetMessage();
  }
};

class Protocol_ResponseEncoder {
 public:
};
#endif  // __Fuchsia__

constexpr uint32_t Const = 0u;

constexpr bool ADDED_AT_HEAD = true;

}  // namespace versions
}  // namespace test
namespace fidl {
template <>
struct IsFidlXUnion<::test::versions::Union> : public std::true_type {};

template <>
struct CodingTraits<::test::versions::Union>
    : public EncodableCodingTraits<::test::versions::Union, 16> {};

template <>
struct CodingTraits<std::unique_ptr<::test::versions::Union>> {
  static constexpr size_t inline_size_v2 = 16;

  static void Encode(Encoder* encoder, std::unique_ptr<::test::versions::Union>* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info = cpp17::nullopt) {
    auto&& p_xunion = *value;
    if (p_xunion) {
      p_xunion->Encode(encoder, offset);
    }
  }

  static void Decode(Decoder* _decoder, std::unique_ptr<::test::versions::Union>* value, size_t offset) {
    fidl_xunion_t* encoded = _decoder->GetPtr<fidl_xunion_t>(offset);
    if (encoded->tag == 0) {
      value->reset(nullptr);
      return;
    }

    value->reset(new ::test::versions::Union);

    ::test::versions::Union::Decode(_decoder, value->get(), offset);
  }
};

inline zx_status_t Clone(const ::test::versions::Union& value,
                         ::test::versions::Union* result) {
  return ::test::versions::Clone(value, result);
}

template <>
struct Equality<::test::versions::Union> {
  bool operator()(const ::test::versions::Union& _lhs, const ::test::versions::Union& _rhs) const {
    if (_lhs.Ordinal() != _rhs.Ordinal()) {
      return false;
    }

    switch (_lhs.Ordinal()) {
      case static_cast<fidl_xunion_tag_t>(::test::versions::Union::Tag::Invalid):
        return true;
      case ::test::versions::Union::Tag::kX:
        return ::fidl::Equals(_lhs.x_, _rhs.x_);
      default:
        return ::fidl::Equals(_lhs.unknown_data_, _rhs.unknown_data_);
    }
  }
};
template <>
struct CodingTraits<::test::versions::Table>
    : public EncodableCodingTraits<::test::versions::Table, 16> {};

inline zx_status_t Clone(const ::test::versions::Table& _value,
                         ::test::versions::Table* result) {
  return _value.Clone(result);
}
template <>
struct Equality<::test::versions::Table> {
  bool operator()(const ::test::versions::Table& _lhs, const ::test::versions::Table& _rhs) const {
    if (_lhs.has_x()) {
      if (!_rhs.has_x()) {
        return false;
      }
      if (!::fidl::Equals(_lhs.x(), _rhs.x())) {
        return false;
      }
    } else if (_rhs.has_x()) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::versions::Struct>
    : public EncodableCodingTraits<::test::versions::Struct, 4> {};

template <>
struct IsMemcpyCompatible<::test::versions::Struct> : public internal::BoolConstant<
                                                          !HasPadding<::test::versions::Struct>::value && IsMemcpyCompatible<uint32_t>::value> {};

inline zx_status_t Clone(const ::test::versions::Struct& value,
                         ::test::versions::Struct* result) {
  return ::test::versions::Clone(value, result);
}

template <>
struct Equality<::test::versions::Struct> {
  bool operator()(const ::test::versions::Struct& _lhs, const ::test::versions::Struct& _rhs) const {
    if (!::fidl::Equals(_lhs.x, _rhs.x)) {
      return false;
    }
    return true;
  }
};
template <>
struct CodingTraits<::test::versions::Enum> {
  static constexpr size_t inline_size_v2 = sizeof(::test::versions::Enum);
  static void Encode(Encoder* encoder, ::test::versions::Enum* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder, ::test::versions::Enum* value, size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::test::versions::Enum>(underlying);
  }
};

inline zx_status_t Clone(::test::versions::Enum value,
                         ::test::versions::Enum* result) {
  return ::test::versions::Clone(value, result);
}
template <>
struct Equality<::test::versions::Enum> {
  bool operator()(const ::test::versions::Enum& _lhs, const ::test::versions::Enum& _rhs) const {
    return _lhs == _rhs;
  }
};

template <>
struct CodingTraits<::test::versions::Bits> {
  static constexpr size_t inline_size_v2 = sizeof(::test::versions::Bits);
  static void Encode(Encoder* encoder, ::test::versions::Bits* value, size_t offset,
                     cpp17::optional<::fidl::HandleInformation> maybe_handle_info) {
    ZX_DEBUG_ASSERT(!maybe_handle_info);
    uint32_t underlying = static_cast<uint32_t>(*value);
    ::fidl::Encode(encoder, &underlying, offset);
  }
  static void Decode(Decoder* decoder, ::test::versions::Bits* value, size_t offset) {
    uint32_t underlying = {};
    ::fidl::Decode(decoder, &underlying, offset);
    *value = static_cast<::test::versions::Bits>(underlying);
  }
};

inline zx_status_t Clone(::test::versions::Bits value,
                         ::test::versions::Bits* result) {
  return ::test::versions::Clone(value, result);
}

template <>
struct Equality<::test::versions::Bits> {
  bool operator()(const ::test::versions::Bits& _lhs, const ::test::versions::Bits& _rhs) const {
    uint32_t _lhs_underlying = static_cast<uint32_t>(_lhs);
    uint32_t _rhs_underlying = static_cast<uint32_t>(_rhs);
    return ::fidl::Equals(_lhs_underlying, _rhs_underlying);
  }
};

//
// Proxies and stubs declarations
//
}  // namespace fidl
namespace test {
namespace versions {
#ifdef __Fuchsia__
class Service;
#endif  // __Fuchsia__

#ifdef __Fuchsia__

using OtherProtocolPtr = ::fidl::InterfacePtr<OtherProtocol>;
class OtherProtocol_Proxy;
class OtherProtocol_Stub;
class OtherProtocol_EventSender;
class OtherProtocol_Sync;
using OtherProtocolSyncPtr = ::fidl::SynchronousInterfacePtr<OtherProtocol>;
class OtherProtocol_SyncProxy;

#endif  // __Fuchsia__

#ifdef __Fuchsia__

using ProtocolPtr = ::fidl::InterfacePtr<Protocol>;
class Protocol_Proxy;
class Protocol_Stub;
class Protocol_EventSender;
class Protocol_Sync;
using ProtocolSyncPtr = ::fidl::SynchronousInterfacePtr<Protocol>;
class Protocol_SyncProxy;

namespace internal {
constexpr uint64_t kProtocol_Foo_Ordinal = 0x567a8096af6e6139lu;
constexpr ::fidl::MessageDynamicFlags kProtocol_Foo_DynamicFlags = ::fidl::MessageDynamicFlags::kStrictMethod;
}  // namespace internal
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class Service final {
 public:
  class Handler;

  static constexpr char Name[] = "test.versions.Service";

  explicit Service(std::unique_ptr<::fidl::ServiceConnector> service)
      : service_(std::move(service)) {}

  explicit operator bool() const { return !!service_; }
  /// Returns a |fidl::MemberConnector| which can be used to connect to the member protocol "p".
  ::fidl::MemberConnector<::test::versions::Protocol> p() const {
    return ::fidl::MemberConnector<::test::versions::Protocol>(service_.get(), "p");
  }

 private:
  std::unique_ptr<::fidl::ServiceConnector> service_;
};

/// Facilitates member protocol registration for servers.
class Service::Handler final {
 public:
  /// Constructs a new |Handler|. Does not take ownership of |service|.
  explicit Handler(::fidl::ServiceHandlerBase* service)
      : service_(service) {}
  /// Adds member "p" to the service instance. |handler| is invoked when a connection
  /// is made to the member protocol.
  ///
  /// # Errors
  ///
  /// Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
  zx_status_t add_p(::fidl::InterfaceRequestHandler<::test::versions::Protocol> handler) {
    return service_->AddMember("p", std::move(handler));
  }

 private:
  ::fidl::ServiceHandlerBase* const service_;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class OtherProtocol {
 public:
  using Proxy_ = ::test::versions::OtherProtocol_Proxy;
  using Stub_ = ::test::versions::OtherProtocol_Stub;
  using EventSender_ = ::test::versions::OtherProtocol_EventSender;
  using Sync_ = ::test::versions::OtherProtocol_Sync;
  virtual ~OtherProtocol();
};

class OtherProtocol_RequestDecoder {
 public:
  OtherProtocol_RequestDecoder() = default;
  virtual ~OtherProtocol_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
};

class OtherProtocol_ResponseDecoder {
 public:
  OtherProtocol_ResponseDecoder() = default;
  virtual ~OtherProtocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
};

class OtherProtocol_EventSender {
 public:
  virtual ~OtherProtocol_EventSender();
};

class OtherProtocol_Sync {
 public:
  using Proxy_ = ::test::versions::OtherProtocol_SyncProxy;
  virtual ~OtherProtocol_Sync();
};

class OtherProtocol_Proxy final : public ::fidl::internal::Proxy, public OtherProtocol {
 public:
  explicit OtherProtocol_Proxy(::fidl::internal::ProxyController* controller);
  ~OtherProtocol_Proxy() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;

 private:
  OtherProtocol_Proxy(const ::test::versions::OtherProtocol_Proxy&) = delete;
  OtherProtocol_Proxy& operator=(const ::test::versions::OtherProtocol_Proxy&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class OtherProtocol_Stub final : public ::fidl::internal::Stub, public ::test::versions::OtherProtocol_EventSender {
 public:
  typedef class ::test::versions::OtherProtocol OtherProtocol_clazz;
  explicit OtherProtocol_Stub(::test::versions::OtherProtocol_Stub::OtherProtocol_clazz* impl);
  ~OtherProtocol_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;

 private:
  ::test::versions::OtherProtocol_Stub::OtherProtocol_clazz* impl_;
};

class OtherProtocol_SyncProxy : public ::test::versions::OtherProtocol_Sync {
 public:
  explicit OtherProtocol_SyncProxy(::zx::channel channel);
  ~OtherProtocol_SyncProxy() override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<OtherProtocol>;
};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

class Protocol {
 public:
  using Proxy_ = ::test::versions::Protocol_Proxy;
  using Stub_ = ::test::versions::Protocol_Stub;
  using EventSender_ = ::test::versions::Protocol_EventSender;
  using Sync_ = ::test::versions::Protocol_Sync;
  virtual ~Protocol();

  virtual void Foo() = 0;
};

class Protocol_RequestDecoder {
 public:
  Protocol_RequestDecoder() = default;
  virtual ~Protocol_RequestDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal, bool* out_needs_response);
  virtual void Foo() = 0;
};

class Protocol_ResponseDecoder {
 public:
  Protocol_ResponseDecoder() = default;
  virtual ~Protocol_ResponseDecoder() = default;
  static const fidl_type_t* GetType(uint64_t ordinal);
};

class Protocol_EventSender {
 public:
  virtual ~Protocol_EventSender();
};

class Protocol_Sync {
 public:
  using Proxy_ = ::test::versions::Protocol_SyncProxy;
  virtual ~Protocol_Sync();
  virtual zx_status_t Foo() = 0;
};

class Protocol_Proxy final : public ::fidl::internal::Proxy, public Protocol {
 public:
  explicit Protocol_Proxy(::fidl::internal::ProxyController* controller);
  ~Protocol_Proxy() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message) override;
  // cts-coverage-fidl-name:test.versions/Protocol.Foo
  void Foo() override;

 private:
  Protocol_Proxy(const ::test::versions::Protocol_Proxy&) = delete;
  Protocol_Proxy& operator=(const ::test::versions::Protocol_Proxy&) = delete;

  ::fidl::internal::ProxyController* controller_;
};

class Protocol_Stub final : public ::fidl::internal::Stub, public ::test::versions::Protocol_EventSender {
 public:
  typedef class ::test::versions::Protocol Protocol_clazz;
  explicit Protocol_Stub(::test::versions::Protocol_Stub::Protocol_clazz* impl);
  ~Protocol_Stub() override;

  zx_status_t Dispatch_(::fidl::HLCPPIncomingMessage message,
                        ::fidl::internal::PendingResponse response) override;

 private:
  ::test::versions::Protocol_Stub::Protocol_clazz* impl_;
};

class Protocol_SyncProxy : public ::test::versions::Protocol_Sync {
 public:
  explicit Protocol_SyncProxy(::zx::channel channel);
  ~Protocol_SyncProxy() override;
  // cts-coverage-fidl-name:test.versions/Protocol.Foo
  zx_status_t Foo() override;

 private:
  ::fidl::internal::SynchronousProxy proxy_;
  friend class ::fidl::SynchronousInterfacePtr<Protocol>;
};
#endif  // __Fuchsia__

}  // namespace versions
}  // namespace test
