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

#pragma once

#include <lib/fidl/internal.h>
#include <lib/fidl/llcpp/array.h>
#include <lib/fidl/llcpp/coding.h>
#include <lib/fidl/llcpp/envelope.h>
#include <lib/fidl/llcpp/errors.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/vector_view.h>
#include <lib/fit/function.h>
#include <lib/stdcompat/optional.h>

#include <algorithm>
#include <cstddef>
#include <variant>
#ifdef __Fuchsia__
#include <lib/fidl/llcpp/client.h>
#include <lib/fidl/llcpp/client_end.h>
#include <lib/fidl/llcpp/connect_service.h>
#include <lib/fidl/llcpp/result.h>
#include <lib/fidl/llcpp/server.h>
#include <lib/fidl/llcpp/server_end.h>
#include <lib/fidl/llcpp/service_handler_interface.h>
#include <lib/fidl/llcpp/sync_call.h>
#include <lib/fidl/llcpp/transaction.h>
#include <lib/fidl/llcpp/wire_messaging.h>
#include <lib/fidl/txn_header.h>
#include <lib/zx/channel.h>

#endif  // __Fuchsia__
#include <zircon/fidl.h>

namespace fidl_test_doccomments {
namespace wire {
class Table;

struct Struct;

class StrictUnion;
}  // namespace wire
class Interface;

class Service;
namespace wire {

/// strict enum comment #1.
///
/// strict enum comment #2.
enum class MyStrictEnum : uint32_t {

  /// FOO member comment #1
  ///
  /// FOO member comment #3
  FOO = 1u,

  /// BAR member comment #1
  ///
  /// BAR member comment #3
  BAR = 2u,
};

/// strict bits comment #1
///
/// strict bits comment #2
// |MyStrictBits| is strict, hence is guaranteed to only contain
// members defined in the FIDL schema when receiving it in a message.
// Sending unknown members will fail at runtime.
class MyStrictBits final {
 public:
  constexpr MyStrictBits() = default;
  constexpr MyStrictBits(const MyStrictBits& other) = default;

  // Constructs an instance of |MyStrictBits| from an underlying primitive
  // value, preserving any bit member not defined in the FIDL schema.
  explicit constexpr MyStrictBits(uint32_t value) : value_(value) {}
  const static MyStrictBits MY_FIRST_BIT;
  const static MyStrictBits MY_OTHER_BIT;
  const static MyStrictBits 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 MyStrictBits& other) const {
    return value_ == other.value_;
  }
  constexpr inline bool operator!=(const MyStrictBits& other) const {
    return value_ != other.value_;
  }
  constexpr inline MyStrictBits operator~() const;
  constexpr inline MyStrictBits operator|(const MyStrictBits& other) const;
  constexpr inline MyStrictBits operator&(const MyStrictBits& other) const;
  constexpr inline MyStrictBits operator^(const MyStrictBits& other) const;
  constexpr inline void operator|=(const MyStrictBits& other);
  constexpr inline void operator&=(const MyStrictBits& other);
  constexpr inline void operator^=(const MyStrictBits& other);

  // Constructs an instance of |MyStrictBits| 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<MyStrictBits> TryFrom(
      uint32_t value) {
    if (value & ~kMask.value_) {
      return cpp17::nullopt;
    }
    return MyStrictBits(value & MyStrictBits::kMask.value_);
  }

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

 private:
  uint32_t value_ = 0;
};
constexpr const ::fidl_test_doccomments::wire::MyStrictBits
    MyStrictBits::MY_FIRST_BIT =
        ::fidl_test_doccomments::wire::MyStrictBits(1u);
constexpr const ::fidl_test_doccomments::wire::MyStrictBits
    MyStrictBits::MY_OTHER_BIT =
        ::fidl_test_doccomments::wire::MyStrictBits(2u);
constexpr const ::fidl_test_doccomments::wire::MyStrictBits
    MyStrictBits::kMask = ::fidl_test_doccomments::wire::MyStrictBits(3u);

constexpr inline ::fidl_test_doccomments::wire::MyStrictBits
MyStrictBits::operator~() const {
  return ::fidl_test_doccomments::wire::MyStrictBits(
      static_cast<uint32_t>(~this->value_ & kMask.value_));
}

constexpr inline ::fidl_test_doccomments::wire::MyStrictBits
MyStrictBits::operator|(
    const ::fidl_test_doccomments::wire::MyStrictBits& other) const {
  return ::fidl_test_doccomments::wire::MyStrictBits(
      static_cast<uint32_t>(this->value_ | other.value_));
}

constexpr inline ::fidl_test_doccomments::wire::MyStrictBits
MyStrictBits::operator&(
    const ::fidl_test_doccomments::wire::MyStrictBits& other) const {
  return ::fidl_test_doccomments::wire::MyStrictBits(
      static_cast<uint32_t>(this->value_ & other.value_));
}

constexpr inline ::fidl_test_doccomments::wire::MyStrictBits
MyStrictBits::operator^(
    const ::fidl_test_doccomments::wire::MyStrictBits& other) const {
  return ::fidl_test_doccomments::wire::MyStrictBits(
      static_cast<uint32_t>(this->value_ ^ other.value_));
}

constexpr inline void MyStrictBits::operator|=(
    const ::fidl_test_doccomments::wire::MyStrictBits& other) {
  this->value_ |= other.value_;
}

constexpr inline void MyStrictBits::operator&=(
    const ::fidl_test_doccomments::wire::MyStrictBits& other) {
  this->value_ &= other.value_;
}

constexpr inline void MyStrictBits::operator^=(
    const ::fidl_test_doccomments::wire::MyStrictBits& other) {
  this->value_ ^= other.value_;
}

/// flexible enum comment #1.
///
/// flexible enum comment #2.
class MyFlexibleEnum final {
 public:
  constexpr MyFlexibleEnum() : value_(0) {}
  constexpr explicit MyFlexibleEnum(uint32_t value) : value_(value) {}
  constexpr MyFlexibleEnum(const MyFlexibleEnum& other) = default;
  constexpr operator uint32_t() const { return value_; }

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

      case 2u:

        return false;
      default:
        return true;
    }
  }

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

  /// FOO member comment #1
  ///
  /// FOO member comment #3
  static const MyFlexibleEnum FOO;

  /// BAR member comment #1
  ///
  /// BAR member comment #3
  static const MyFlexibleEnum BAR;

 private:
  uint32_t value_;
};
constexpr const ::fidl_test_doccomments::wire::MyFlexibleEnum
    MyFlexibleEnum::FOO = ::fidl_test_doccomments::wire::MyFlexibleEnum(1u);
constexpr const ::fidl_test_doccomments::wire::MyFlexibleEnum
    MyFlexibleEnum::BAR = ::fidl_test_doccomments::wire::MyFlexibleEnum(2u);

/// flexible bits comment #1
///
/// flexible bits comment #2
// |MyFlexibleBits| is flexible, hence may contain unknown members not
// defined in the FIDL schema.
class MyFlexibleBits final {
 public:
  constexpr MyFlexibleBits() = default;
  constexpr MyFlexibleBits(const MyFlexibleBits& other) = default;

  // Constructs an instance of |MyFlexibleBits| from an underlying primitive
  // value, preserving any bit member not defined in the FIDL schema.
  explicit constexpr MyFlexibleBits(uint32_t value) : value_(value) {}
  const static MyFlexibleBits MY_FIRST_BIT;
  const static MyFlexibleBits MY_OTHER_BIT;
  const static MyFlexibleBits 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 MyFlexibleBits& other) const {
    return value_ == other.value_;
  }
  constexpr inline bool operator!=(const MyFlexibleBits& other) const {
    return value_ != other.value_;
  }
  constexpr inline MyFlexibleBits operator~() const;
  constexpr inline MyFlexibleBits operator|(const MyFlexibleBits& other) const;
  constexpr inline MyFlexibleBits operator&(const MyFlexibleBits& other) const;
  constexpr inline MyFlexibleBits operator^(const MyFlexibleBits& other) const;
  constexpr inline void operator|=(const MyFlexibleBits& other);
  constexpr inline void operator&=(const MyFlexibleBits& other);
  constexpr inline void operator^=(const MyFlexibleBits& other);

  // Constructs an instance of |MyFlexibleBits| 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<MyFlexibleBits> TryFrom(
      uint32_t value) {
    if (value & ~kMask.value_) {
      return cpp17::nullopt;
    }
    return MyFlexibleBits(value & MyFlexibleBits::kMask.value_);
  }

  // Constructs an instance of |MyFlexibleBits| from an underlying primitive
  // value, clearing any bit member not defined in the FIDL schema.
  constexpr inline static MyFlexibleBits TruncatingUnknown(uint32_t value) {
    return MyFlexibleBits(value & MyFlexibleBits::kMask.value_);
  }
  constexpr inline MyFlexibleBits unknown_bits() const {
    return *this & MyFlexibleBits(~kMask.value_);
  }
  constexpr inline bool has_unknown_bits() const {
    return static_cast<bool>(unknown_bits());
  }

 private:
  uint32_t value_ = 0;
};
constexpr const ::fidl_test_doccomments::wire::MyFlexibleBits
    MyFlexibleBits::MY_FIRST_BIT =
        ::fidl_test_doccomments::wire::MyFlexibleBits(1u);
constexpr const ::fidl_test_doccomments::wire::MyFlexibleBits
    MyFlexibleBits::MY_OTHER_BIT =
        ::fidl_test_doccomments::wire::MyFlexibleBits(2u);
constexpr const ::fidl_test_doccomments::wire::MyFlexibleBits
    MyFlexibleBits::kMask = ::fidl_test_doccomments::wire::MyFlexibleBits(3u);

constexpr inline ::fidl_test_doccomments::wire::MyFlexibleBits
MyFlexibleBits::operator~() const {
  return ::fidl_test_doccomments::wire::MyFlexibleBits(
      static_cast<uint32_t>(~this->value_ & kMask.value_));
}

constexpr inline ::fidl_test_doccomments::wire::MyFlexibleBits
MyFlexibleBits::operator|(
    const ::fidl_test_doccomments::wire::MyFlexibleBits& other) const {
  return ::fidl_test_doccomments::wire::MyFlexibleBits(
      static_cast<uint32_t>(this->value_ | other.value_));
}

constexpr inline ::fidl_test_doccomments::wire::MyFlexibleBits
MyFlexibleBits::operator&(
    const ::fidl_test_doccomments::wire::MyFlexibleBits& other) const {
  return ::fidl_test_doccomments::wire::MyFlexibleBits(
      static_cast<uint32_t>(this->value_ & other.value_));
}

constexpr inline ::fidl_test_doccomments::wire::MyFlexibleBits
MyFlexibleBits::operator^(
    const ::fidl_test_doccomments::wire::MyFlexibleBits& other) const {
  return ::fidl_test_doccomments::wire::MyFlexibleBits(
      static_cast<uint32_t>(this->value_ ^ other.value_));
}

constexpr inline void MyFlexibleBits::operator|=(
    const ::fidl_test_doccomments::wire::MyFlexibleBits& other) {
  this->value_ |= other.value_;
}

constexpr inline void MyFlexibleBits::operator&=(
    const ::fidl_test_doccomments::wire::MyFlexibleBits& other) {
  this->value_ &= other.value_;
}

constexpr inline void MyFlexibleBits::operator^=(
    const ::fidl_test_doccomments::wire::MyFlexibleBits& other) {
  this->value_ ^= other.value_;
}

class FlexibleUnion;

extern "C" const fidl_type_t fidl_test_doccomments_TableTable;

/// table comment #1
///
/// table comment #3
class Table final {
 public:
  // Returns whether no field is set.
  bool IsEmpty() const { return max_ordinal_ == 0; }

  class Frame;

  /// table field comment #1
  ///
  /// table field comment #3
  const int32_t& Field() const {
    ZX_ASSERT(has_Field());
    return *frame_ptr_->Field_.data;
  }
  int32_t& Field() {
    ZX_ASSERT(has_Field());
    return *frame_ptr_->Field_.data;
  }
  bool has_Field() const {
    return max_ordinal_ >= 1 && frame_ptr_->Field_.data != nullptr;
  }
  Table& set_Field(::fidl::ObjectView<int32_t> elem) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->Field_.data = elem;
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }
  Table& set_Field(std::nullptr_t) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->Field_.data = nullptr;
    return *this;
  }
  template <typename... Args>
  Table& set_Field(::fidl::AnyAllocator& allocator, Args&&... args) {
    ZX_DEBUG_ASSERT(frame_ptr_ != nullptr);
    frame_ptr_->Field_.data =
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...);
    max_ordinal_ = std::max(max_ordinal_, static_cast<uint64_t>(1));
    return *this;
  }

  Table() = default;
  explicit Table(::fidl::AnyAllocator& allocator)
      : frame_ptr_(::fidl::ObjectView<Frame>(allocator)) {}
  // This constructor allows a user controlled allocation (not using a
  // FidlAllocator). 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 Table(::fidl::ObjectView<Frame>&& frame)
      : frame_ptr_(std::move(frame)) {}
  ~Table() = default;
  Table(const Table& other) noexcept = default;
  Table& operator=(const Table& other) noexcept = default;
  Table(Table&& other) noexcept = default;
  Table& operator=(Table&& other) noexcept = default;

  static constexpr const fidl_type_t* Type = &fidl_test_doccomments_TableTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 24;
  static constexpr bool HasPointer = true;

  void Allocate(::fidl::AnyAllocator& allocator) {
    max_ordinal_ = 0;
    frame_ptr_ = ::fidl::ObjectView<Frame>(allocator);
  }
  void Init(::fidl::ObjectView<Frame>&& frame_ptr) {
    max_ordinal_ = 0;
    frame_ptr_ = std::move(frame_ptr);
  }

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size, Table* value)
        : message_(bytes, byte_size, sizeof(Table), nullptr, 0, 0) {
      message_.Encode<Table>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(Table* value)
        : message_(bytes_.data(), bytes_.size(), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    ::fidl::internal::InlineMessageBuffer<40> bytes_;
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<Table>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<Table>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    Table* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<Table*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };

  // Frames are managed automatically by the FidlAllocator class.
  // The only direct usage is when performance is key and a frame needs to be
  // allocated outside a FidlAllocator. Once created, a frame can only be used
  // for one single table.
  class Frame final {
   public:
    Frame() = default;
    // In its intended usage, Frame 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.
    Frame(const Frame&) = delete;
    Frame& operator=(const Frame&) = delete;

   private:
    Frame(Frame&&) noexcept = default;
    Frame& operator=(Frame&&) noexcept = default;
    ::fidl::Envelope<int32_t> Field_;

    friend class Table;
  };

 private:
  uint64_t max_ordinal_ = 0;
  ::fidl::ObjectView<Frame> frame_ptr_;
};

extern "C" const fidl_type_t fidl_test_doccomments_StrictUnionTable;

/// strict union comment #1
///
/// strict union comment #3
class StrictUnion {
 public:
  StrictUnion()
      : ordinal_(::fidl_test_doccomments::wire::StrictUnion::Ordinal::Invalid),
        envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kField = 1,  // 0x1
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::fidl_test_doccomments::wire::StrictUnion::Ordinal::Invalid;
  }

  bool is_Field() const {
    return ordinal_ ==
           ::fidl_test_doccomments::wire::StrictUnion::Ordinal::kField;
  }

  static StrictUnion WithField(::fidl::ObjectView<int32_t> val) {
    StrictUnion result;
    result.set_Field(val);
    return result;
  }

  template <typename... Args>
  static StrictUnion WithField(::fidl::AnyAllocator& allocator,
                               Args&&... args) {
    StrictUnion result;
    result.set_Field(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  /// union member comment #1
  ///
  /// union member comment #3
  void set_Field(::fidl::ObjectView<int32_t> elem) {
    ordinal_ = ::fidl_test_doccomments::wire::StrictUnion::Ordinal::kField;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_Field(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_doccomments::wire::StrictUnion::Ordinal::kField;
    set_Field(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
  }

  /// union member comment #1
  ///
  /// union member comment #3
  int32_t& mutable_Field() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_doccomments::wire::StrictUnion::Ordinal::kField);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  const int32_t& Field() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_doccomments::wire::StrictUnion::Ordinal::kField);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  ::fidl_test_doccomments::wire::StrictUnion::Tag which() const {
    ZX_ASSERT(!has_invalid_tag());
    return static_cast<::fidl_test_doccomments::wire::StrictUnion::Tag>(
        ordinal_);
  }

  static constexpr const fidl_type_t* Type =
      &fidl_test_doccomments_StrictUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kField = 1,  // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_doccomments::wire::StrictUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_doccomments_FlexibleUnionTable;

/// flexible union comment #1
///
/// flexible union comment #3
class FlexibleUnion {
 public:
  FlexibleUnion()
      : ordinal_(
            ::fidl_test_doccomments::wire::FlexibleUnion::Ordinal::Invalid),
        envelope_{} {}

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

  enum class Tag : fidl_xunion_tag_t {
    kField = 1,  // 0x1
    kUnknown = ::std::numeric_limits<::fidl_union_tag_t>::max(),
  };

  bool has_invalid_tag() const {
    return ordinal_ ==
           ::fidl_test_doccomments::wire::FlexibleUnion::Ordinal::Invalid;
  }

  bool is_Field() const {
    return ordinal_ ==
           ::fidl_test_doccomments::wire::FlexibleUnion::Ordinal::kField;
  }

  static FlexibleUnion WithField(::fidl::ObjectView<int32_t> val) {
    FlexibleUnion result;
    result.set_Field(val);
    return result;
  }

  template <typename... Args>
  static FlexibleUnion WithField(::fidl::AnyAllocator& allocator,
                                 Args&&... args) {
    FlexibleUnion result;
    result.set_Field(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
    return result;
  }

  /// union member comment #1
  ///
  /// union member comment #3
  void set_Field(::fidl::ObjectView<int32_t> elem) {
    ordinal_ = ::fidl_test_doccomments::wire::FlexibleUnion::Ordinal::kField;
    envelope_.data =
        ::fidl::ObjectView<void>::FromExternal(static_cast<void*>(elem.get()));
  }

  template <typename... Args>
  void set_Field(::fidl::AnyAllocator& allocator, Args&&... args) {
    ordinal_ = ::fidl_test_doccomments::wire::FlexibleUnion::Ordinal::kField;
    set_Field(
        ::fidl::ObjectView<int32_t>(allocator, std::forward<Args>(args)...));
  }

  /// union member comment #1
  ///
  /// union member comment #3
  int32_t& mutable_Field() {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_doccomments::wire::FlexibleUnion::Ordinal::kField);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  const int32_t& Field() const {
    ZX_ASSERT(ordinal_ ==
              ::fidl_test_doccomments::wire::FlexibleUnion::Ordinal::kField);
    return *static_cast<int32_t*>(envelope_.data.get());
  }
  ::fidl_test_doccomments::wire::FlexibleUnion::Tag which() const;

  static constexpr const fidl_type_t* Type =
      &fidl_test_doccomments_FlexibleUnionTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 24;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 8;
  static constexpr bool HasPointer = true;

 private:
  enum class Ordinal : fidl_xunion_tag_t {
    Invalid = 0,
    kField = 1,  // 0x1
  };

  static void SizeAndOffsetAssertionHelper();
  ::fidl_test_doccomments::wire::FlexibleUnion::Ordinal ordinal_;
  FIDL_ALIGNDECL
  ::fidl::Envelope<void> envelope_;
};

extern "C" const fidl_type_t fidl_test_doccomments_StructTable;

/// struct comment #1
///
/// struct comment #3
struct Struct {
  static constexpr const fidl_type_t* Type = &fidl_test_doccomments_StructTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 4;
  [[maybe_unused]] static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasPointer = false;

  /// struct member comment #1
  ///
  /// struct member comment #3
  int32_t Field = {};

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size, Struct* value)
        : message_(bytes, byte_size, sizeof(Struct), nullptr, 0, 0) {
      message_.Encode<Struct>(value);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }

   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(Struct* value)
        : message_(bytes_.data(), bytes_.size(), value) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }

   private:
    ::fidl::internal::InlineMessageBuffer<8> bytes_;
    UnownedEncodedMessage message_;
  };

  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<struct Struct>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<struct Struct>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    struct Struct* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<struct Struct*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };
};

}  // namespace wire
extern "C" const fidl_type_t fidl_test_doccomments_InterfaceMethodRequestTable;

extern "C" const fidl_type_t fidl_test_doccomments_InterfaceMethodResponseTable;

extern "C" const fidl_type_t fidl_test_doccomments_InterfaceOnEventRequestTable;

extern "C" const fidl_type_t fidl_test_doccomments_InterfaceOnEventEventTable;

/// interface comment #1
///
/// interface comment #3
class Interface final {
  Interface() = delete;

 public:
  /// method comment #1
  ///
  /// method comment #3
  class Method final {
    Method() = delete;
  };
  /// event comment #1
  ///
  /// event comment #3
  class OnEvent final {
    OnEvent() = delete;
  };
};
}  // namespace fidl_test_doccomments
#ifdef __Fuchsia__

template <>
struct ::fidl::internal::ProtocolDetails<::fidl_test_doccomments::Interface> {};
#endif  // __Fuchsia__

#ifdef __Fuchsia__

template <>
struct ::fidl::internal::WireDispatcher<::fidl_test_doccomments::Interface>
    final {
  WireDispatcher() = delete;
  static ::fidl::DispatchResult TryDispatch(
      ::fidl::WireInterface<::fidl_test_doccomments::Interface>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
  static ::fidl::DispatchResult Dispatch(
      ::fidl::WireInterface<::fidl_test_doccomments::Interface>* impl,
      fidl_incoming_msg_t* msg, ::fidl::Transaction* txn);
};
#endif  // __Fuchsia__

template <>
struct ::fidl::WireRequest<::fidl_test_doccomments::Interface::Method> final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  explicit WireRequest(zx_txid_t _txid) { _InitHeader(_txid); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr uint32_t AltPrimarySize = 16;
  static constexpr uint32_t AltMaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kRequest;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size, zx_txid_t _txid)
        : message_(_bytes, _byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireRequest _request(_txid);
      message_.Encode<WireRequest>(&_request);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireRequest* request)
        : message_(bytes, byte_size, sizeof(WireRequest), nullptr, 0, 0) {
      message_.Encode<WireRequest>(request);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage(zx_txid_t _txid)
        : message_(bytes_.data(), bytes_.size(), _txid) {}
    explicit OwnedEncodedMessage(WireRequest* request)
        : message_(bytes_.data(), bytes_.size(), request) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<WireRequest>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<WireRequest>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireRequest* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<WireRequest*>(bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };

 private:
  void _InitHeader(zx_txid_t _txid);
};
template <>
struct ::fidl::WireResponse<::fidl_test_doccomments::Interface::OnEvent> final {
  FIDL_ALIGNDECL
  fidl_message_header_t _hdr;
  WireResponse() { _InitHeader(); }

  static constexpr const fidl_type_t* Type =
      &::fidl::_llcpp_coding_AnyZeroArgMessageTable;
  static constexpr uint32_t MaxNumHandles = 0;
  static constexpr uint32_t PrimarySize = 16;
  static constexpr uint32_t MaxOutOfLine = 0;
  static constexpr bool HasFlexibleEnvelope = false;
  static constexpr bool HasPointer = false;
  static constexpr ::fidl::internal::TransactionalMessageKind MessageKind =
      ::fidl::internal::TransactionalMessageKind::kResponse;

  class UnownedEncodedMessage final {
   public:
    UnownedEncodedMessage(uint8_t* _bytes, uint32_t _byte_size)
        : message_(_bytes, _byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      FIDL_ALIGNDECL WireResponse _response{};
      message_.Encode<
          ::fidl::WireResponse<::fidl_test_doccomments::Interface::OnEvent>>(
          &_response);
    }
    UnownedEncodedMessage(uint8_t* bytes, uint32_t byte_size,
                          WireResponse* response)
        : message_(bytes, byte_size, sizeof(WireResponse), nullptr, 0, 0) {
      message_.Encode<
          ::fidl::WireResponse<::fidl_test_doccomments::Interface::OnEvent>>(
          response);
    }
    UnownedEncodedMessage(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage(UnownedEncodedMessage&&) = delete;
    UnownedEncodedMessage* operator=(const UnownedEncodedMessage&) = delete;
    UnownedEncodedMessage* operator=(UnownedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.status() == ZX_OK; }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() { return message_; }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::OutgoingMessage message_;
  };

  class OwnedEncodedMessage final {
   public:
    explicit OwnedEncodedMessage() : message_(bytes_.data(), bytes_.size()) {}
    explicit OwnedEncodedMessage(
        ::fidl::WireResponse<::fidl_test_doccomments::Interface::OnEvent>*
            response)
        : message_(bytes_.data(), bytes_.size(), response) {}
    OwnedEncodedMessage(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage(OwnedEncodedMessage&&) = delete;
    OwnedEncodedMessage* operator=(const OwnedEncodedMessage&) = delete;
    OwnedEncodedMessage* operator=(OwnedEncodedMessage&&) = delete;

    zx_status_t status() const { return message_.status(); }
#ifdef __Fuchsia__
    const char* status_string() const { return message_.status_string(); }
#endif  // __Fuchsia__
    bool ok() const { return message_.ok(); }
    const char* error() const { return message_.error(); }

    ::fidl::OutgoingMessage& GetOutgoingMessage() {
      return message_.GetOutgoingMessage();
    }
#ifdef __Fuchsia__
    template <typename ChannelLike>
    void Write(ChannelLike&& client) {
      message_.Write(std::forward<ChannelLike>(client));
    }
#endif  // __Fuchsia__
   private:
    ::fidl::internal::InlineMessageBuffer<16> bytes_;
    UnownedEncodedMessage message_;
  };

 public:
  class DecodedMessage final : public ::fidl::internal::IncomingMessage {
   public:
    DecodedMessage(uint8_t* bytes, uint32_t byte_actual,
                   zx_handle_info_t* handles = nullptr,
                   uint32_t handle_actual = 0)
        : ::fidl::internal::IncomingMessage(bytes, byte_actual, handles,
                                            handle_actual) {
      Decode<
          ::fidl::WireResponse<::fidl_test_doccomments::Interface::OnEvent>>();
    }
    DecodedMessage(fidl_incoming_msg_t* msg)
        : ::fidl::internal::IncomingMessage(msg) {
      Decode<
          ::fidl::WireResponse<::fidl_test_doccomments::Interface::OnEvent>>();
    }
    DecodedMessage(const DecodedMessage&) = delete;
    DecodedMessage(DecodedMessage&&) = delete;
    DecodedMessage* operator=(const DecodedMessage&) = delete;
    DecodedMessage* operator=(DecodedMessage&&) = delete;

    WireResponse* PrimaryObject() {
      ZX_DEBUG_ASSERT(ok());
      return reinterpret_cast<
          ::fidl::WireResponse<::fidl_test_doccomments::Interface::OnEvent>*>(
          bytes());
    }

    // Release the ownership of the decoded message. That means that the handles
    // won't be closed When the object is destroyed. After calling this method,
    // the DecodedMessage object should not be used anymore.
    void ReleasePrimaryObject() { ResetBytes(); }
  };

 private:
  void _InitHeader();
};
template <>
class ::fidl::WireResult<::fidl_test_doccomments::Interface::Method> final
    : public ::fidl::Result {
 public:
  explicit WireResult(
      ::fidl::UnownedClientEnd<::fidl_test_doccomments::Interface> _client);
  explicit WireResult(const ::fidl::Result& result) : ::fidl::Result(result) {}
  WireResult(WireResult&&) = delete;
  WireResult(const WireResult&) = delete;
  WireResult* operator=(WireResult&&) = delete;
  WireResult* operator=(const WireResult&) = delete;
  ~WireResult() = default;

 private:
};
template <>
class ::fidl::WireUnownedResult<::fidl_test_doccomments::Interface::Method>
    final : public ::fidl::Result {
 public:
  explicit WireUnownedResult(
      ::fidl::UnownedClientEnd<::fidl_test_doccomments::Interface> _client);
  explicit WireUnownedResult(const ::fidl::Result& result)
      : ::fidl::Result(result) {}
  WireUnownedResult(WireUnownedResult&&) = delete;
  WireUnownedResult(const WireUnownedResult&) = delete;
  WireUnownedResult* operator=(WireUnownedResult&&) = delete;
  WireUnownedResult* operator=(const WireUnownedResult&) = delete;
  ~WireUnownedResult() = default;
};

// Methods to make a sync FIDL call directly on an unowned channel or a
// const reference to a |fidl::ClientEnd<::fidl_test_doccomments::Interface>|,
// avoiding setting up a client.
template <>
class ::fidl::internal::WireCaller<::fidl_test_doccomments::Interface> final {
 public:
  explicit WireCaller(
      ::fidl::UnownedClientEnd<::fidl_test_doccomments::Interface> client_end)
      : client_end_(client_end) {}

  /// method comment #1
  ///
  /// method comment #3
  // Allocates 16 bytes of message buffer on the stack. No heap allocation
  // necessary.
  static ::fidl::WireResult<::fidl_test_doccomments::Interface::Method> Method(
      ::fidl::UnownedClientEnd<::fidl_test_doccomments::Interface>
          _client_end) {
    return ::fidl::WireResult<::fidl_test_doccomments::Interface::Method>(
        _client_end);
  }
  /// method comment #1
  ///
  /// method comment #3
  // Allocates 16 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_doccomments::Interface::Method> Method() && {
    return ::fidl::WireResult<::fidl_test_doccomments::Interface::Method>(
        client_end_);
  }

 private:
  ::fidl::UnownedClientEnd<::fidl_test_doccomments::Interface> client_end_;
};
#ifdef __Fuchsia__

template <>
class ::fidl::internal::WireEventHandlerInterface<
    ::fidl_test_doccomments::Interface> {
 public:
  WireEventHandlerInterface() = default;
  virtual ~WireEventHandlerInterface() = default;
  /// event comment #1
  ///
  /// event comment #3
  virtual void OnEvent(
      ::fidl::WireResponse<::fidl_test_doccomments::Interface::OnEvent>*
          event) {}
};

template <>
class ::fidl::WireAsyncEventHandler<::fidl_test_doccomments::Interface>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::fidl_test_doccomments::Interface> {
 public:
  WireAsyncEventHandler() = default;

  virtual void Unbound(::fidl::UnbindInfo info) {}
};

template <>
class ::fidl::WireSyncEventHandler<::fidl_test_doccomments::Interface>
    : public ::fidl::internal::WireEventHandlerInterface<
          ::fidl_test_doccomments::Interface> {
 public:
  WireSyncEventHandler() = default;

  // Method called when an unknown event is found. This methods gives the status
  // which, in this case, is returned by HandleOneEvent.
  virtual zx_status_t Unknown() = 0;

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the
  // corresponding virtual method.
  ::fidl::Result HandleOneEvent(
      ::fidl::UnownedClientEnd<::fidl_test_doccomments::Interface> client_end);
};
#endif  // __Fuchsia__

template <>
class ::fidl::WireSyncClient<::fidl_test_doccomments::Interface> final {
 public:
  WireSyncClient() = default;

  explicit WireSyncClient(
      ::fidl::ClientEnd<::fidl_test_doccomments::Interface> client_end)
      : client_end_(std::move(client_end)) {}

  ~WireSyncClient() = default;
  WireSyncClient(WireSyncClient&&) = default;
  WireSyncClient& operator=(WireSyncClient&&) = default;

  const ::fidl::ClientEnd<::fidl_test_doccomments::Interface>& client_end()
      const {
    return client_end_;
  }
  ::fidl::ClientEnd<::fidl_test_doccomments::Interface>& client_end() {
    return client_end_;
  }

  const ::zx::channel& channel() const { return client_end_.channel(); }
  ::zx::channel* mutable_channel() { return &client_end_.channel(); }

  /// method comment #1
  ///
  /// method comment #3
  // Allocates 16 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::WireResult<::fidl_test_doccomments::Interface::Method> Method() {
    return ::fidl::WireResult<::fidl_test_doccomments::Interface::Method>(
        this->client_end());
  }

  // Handle all possible events defined in this protocol.
  // Blocks to consume exactly one message from the channel, then call the
  // corresponding virtual method defined in |SyncEventHandler|. The return
  // status of the handler function is folded with any transport-level errors
  // and returned.
  ::fidl::Result HandleOneEvent(
      ::fidl::WireSyncEventHandler<::fidl_test_doccomments::Interface>&
          event_handler) {
    return event_handler.HandleOneEvent(client_end_);
  }

 private:
  ::fidl::ClientEnd<::fidl_test_doccomments::Interface> client_end_;
};

// Pure-virtual interface to be implemented by a server.
// This interface uses typed channels (i.e. |fidl::ClientEnd<SomeProtocol>|
// and |fidl::ServerEnd<SomeProtocol>|).
template <>
class ::fidl::WireInterface<::fidl_test_doccomments::Interface>
    : public ::fidl::internal::IncomingMessageDispatcher {
 public:
  WireInterface() = default;
  virtual ~WireInterface() = default;

  // The marker protocol type within which this |WireInterface| class is
  // defined.
  using _EnclosingProtocol = ::fidl_test_doccomments::Interface;

  using MethodCompleter = ::fidl::Completer<>;

  /// method comment #1
  ///
  /// method comment #3
  virtual void Method(MethodCompleter::Sync& _completer) = 0;

 private:
  ::fidl::DispatchResult dispatch_message(fidl_incoming_msg_t* msg,
                                          ::fidl::Transaction* txn) final;
};

namespace fidl_test_doccomments {

/// service comment #1
///
/// service comment #3
class Service final {
  Service() = default;

 public:
  static constexpr char Name[] = "fidl.test.doccomments.Service";

  // Client protocol for connecting to member protocols of a service instance.
  class ServiceClient final {
    ServiceClient() = delete;

   public:
    ServiceClient(::zx::channel dir,
                  ::fidl::internal::ConnectMemberFunc connect_func)
        : dir_(std::move(dir)), connect_func_(connect_func) {}

    // Connects to the member protocol "interface".
    // Returns a |fidl::ClientEnd<::fidl_test_doccomments::Interface>| on
    // success, which can be used with |fidl::BindSyncClient| to create a
    // synchronous client, or |fidl::Client| to create a client that supports
    // both asynchronous and synchronous operations.
    //
    // # Errors
    //
    // On failure, returns a |zx::error| with status != ZX_OK.
    // Failures can occur if channel creation failed, or if there was an issue
    // making a |fuchsia.io.Directory/Open| call.
    //
    // Since the call to |Open| is asynchronous, an error sent by the remote end
    // will not result in a failure of this method. Any errors sent by the
    // remote will appear on the |ClientEnd| returned from this method.
    ::zx::status<::fidl::ClientEnd<::fidl_test_doccomments::Interface>>
    connect_interface() {
      auto endpoints =
          ::fidl::CreateEndpoints<::fidl_test_doccomments::Interface>();
      if (endpoints.is_error()) {
        return endpoints.take_error();
      }
      auto connection = connect_func_(::zx::unowned_channel(dir_),
                                      ::fidl::StringView("interface"),
                                      endpoints->server.TakeChannel());
      if (connection.is_error()) {
        return connection.take_error();
      }
      return ::zx::ok(std::move(endpoints->client));
    }

   private:
    ::zx::channel dir_;
    ::fidl::internal::ConnectMemberFunc connect_func_;
  };

  // Facilitates member protocol registration for servers.
  class Handler final {
   public:
    // Constructs a FIDL Service-typed handler. Does not take ownership of
    // |service_handler|.
    explicit Handler(::fidl::ServiceHandlerInterface* service_handler)
        : service_handler_(service_handler) {}

    // Adds member "interface" to the service instance. |handler| will be
    // invoked on connection attempts.
    //
    // # Errors
    //
    // Returns ZX_ERR_ALREADY_EXISTS if the member was already added.
    ::zx::status<> add_interface(::fidl::ServiceHandlerInterface::MemberHandler<
                                 ::fidl_test_doccomments::Interface>
                                     handler) {
      return service_handler_->AddMember("interface", std::move(handler));
    }

   private:
    ::fidl::ServiceHandlerInterface* service_handler_;  // Not owned.
  };
};
namespace wire {

/// const comment #1
///
/// const comment #3
constexpr int32_t C = 4u;

}  // namespace wire
}  // namespace fidl_test_doccomments
namespace fidl {

template <>
struct IsFidlType<::fidl_test_doccomments::wire::Table>
    : public std::true_type {};
template <>
struct IsTable<::fidl_test_doccomments::wire::Table> : public std::true_type {};
static_assert(std::is_standard_layout_v<::fidl_test_doccomments::wire::Table>);

template <>
struct IsFidlType<::fidl_test_doccomments::wire::Struct>
    : public std::true_type {};
template <>
struct IsStruct<::fidl_test_doccomments::wire::Struct> : public std::true_type {
};
static_assert(std::is_standard_layout_v<::fidl_test_doccomments::wire::Struct>);
static_assert(offsetof(::fidl_test_doccomments::wire::Struct, Field) == 0);
static_assert(sizeof(::fidl_test_doccomments::wire::Struct) ==
              ::fidl_test_doccomments::wire::Struct::PrimarySize);

template <>
struct IsFidlType<::fidl_test_doccomments::wire::StrictUnion>
    : public std::true_type {};
template <>
struct IsUnion<::fidl_test_doccomments::wire::StrictUnion>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::fidl_test_doccomments::wire::StrictUnion>);

template <>
struct IsFidlType<
    ::fidl::WireRequest<::fidl_test_doccomments::Interface::Method>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireRequest<::fidl_test_doccomments::Interface::Method>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireRequest<::fidl_test_doccomments::Interface::Method>) ==
    ::fidl::WireRequest<
        ::fidl_test_doccomments::Interface::Method>::PrimarySize);

template <>
struct IsFidlType<
    ::fidl::WireResponse<::fidl_test_doccomments::Interface::OnEvent>>
    : public std::true_type {};
template <>
struct IsFidlMessage<
    ::fidl::WireResponse<::fidl_test_doccomments::Interface::OnEvent>>
    : public std::true_type {};
static_assert(
    sizeof(::fidl::WireResponse<::fidl_test_doccomments::Interface::OnEvent>) ==
    ::fidl::WireResponse<
        ::fidl_test_doccomments::Interface::OnEvent>::PrimarySize);

template <>
struct IsFidlType<::fidl_test_doccomments::wire::MyStrictEnum>
    : public std::true_type {};

template <>
struct IsFidlType<::fidl_test_doccomments::wire::MyStrictBits>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::fidl_test_doccomments::wire::MyStrictBits>);
static_assert(sizeof(::fidl_test_doccomments::wire::MyStrictBits) ==
              sizeof(uint32_t));

template <>
struct IsFidlType<::fidl_test_doccomments::wire::MyFlexibleEnum>
    : public std::true_type {};

template <>
struct IsFidlType<::fidl_test_doccomments::wire::MyFlexibleBits>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::fidl_test_doccomments::wire::MyFlexibleBits>);
static_assert(sizeof(::fidl_test_doccomments::wire::MyFlexibleBits) ==
              sizeof(uint32_t));

template <>
struct IsFidlType<::fidl_test_doccomments::wire::FlexibleUnion>
    : public std::true_type {};
template <>
struct IsUnion<::fidl_test_doccomments::wire::FlexibleUnion>
    : public std::true_type {};
static_assert(
    std::is_standard_layout_v<::fidl_test_doccomments::wire::FlexibleUnion>);

#ifdef __Fuchsia__
}  // namespace fidl
template <>
class ::fidl::internal::WireClientImpl<::fidl_test_doccomments::Interface> final
    : private ::fidl::internal::ClientBase {
 public:
  /// method comment #1
  ///
  /// method comment #3
  //
  // Allocates 16 bytes of message buffer on the stack. No heap allocation
  // necessary.
  ::fidl::Result Method();

  ::fidl::WireAsyncEventHandler<::fidl_test_doccomments::Interface>*
  event_handler() const {
    return event_handler_.get();
  }

 private:
  friend class ::fidl::Client<::fidl_test_doccomments::Interface>;
  friend class ::fidl::internal::ControlBlock<
      ::fidl_test_doccomments::Interface>;

  explicit WireClientImpl(
      std::shared_ptr<
          ::fidl::WireAsyncEventHandler<::fidl_test_doccomments::Interface>>
          event_handler)
      : event_handler_(std::move(event_handler)) {}

  std::optional<::fidl::UnbindInfo> DispatchEvent(
      fidl_incoming_msg_t* msg) override;

  std::shared_ptr<
      ::fidl::WireAsyncEventHandler<::fidl_test_doccomments::Interface>>
      event_handler_;
};
namespace fidl {
#endif  // __Fuchsia__

}  // namespace fidl
#ifdef __Fuchsia__
// |EventSender| owns a server endpoint of a channel speaking
// the Interface protocol, and can send events in that protocol.
template <>
class ::fidl::WireEventSender<::fidl_test_doccomments::Interface> {
 public:
  // Constructs an event sender with an invalid channel.
  WireEventSender() = default;

  explicit WireEventSender(
      ::fidl::ServerEnd<::fidl_test_doccomments::Interface> server_end)
      : server_end_(std::move(server_end)) {}

  // The underlying server channel endpoint, which may be replaced at run-time.
  const ::fidl::ServerEnd<::fidl_test_doccomments::Interface>& server_end()
      const {
    return server_end_;
  }
  ::fidl::ServerEnd<::fidl_test_doccomments::Interface>& server_end() {
    return server_end_;
  }

  const ::zx::channel& channel() const { return server_end_.channel(); }
  ::zx::channel& channel() { return server_end_.channel(); }

  // Whether the underlying channel is valid.
  bool is_valid() const { return server_end_.is_valid(); }

  /// event comment #1
  ///
  /// event comment #3
  zx_status_t OnEvent() const;

 private:
  ::fidl::ServerEnd<::fidl_test_doccomments::Interface> server_end_;
};

template <>
class ::fidl::internal::WireWeakEventSender<
    ::fidl_test_doccomments::Interface> {
 public:
  /// event comment #1
  ///
  /// event comment #3
  zx_status_t OnEvent() const {
    if (auto _binding = binding_.lock()) {
      return _binding->event_sender().OnEvent();
    }
    return ZX_ERR_CANCELED;
  }

 private:
  friend class ::fidl::ServerBindingRef<::fidl_test_doccomments::Interface>;

  explicit WireWeakEventSender(
      std::weak_ptr<::fidl::internal::AsyncServerBinding<
          ::fidl_test_doccomments::Interface>>
          binding)
      : binding_(std::move(binding)) {}

  std::weak_ptr<
      ::fidl::internal::AsyncServerBinding<::fidl_test_doccomments::Interface>>
      binding_;
};
#endif  // __Fuchsia__
