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

// fidl_experiment = output_index_json

#include <fidl/test.protocollayoutssamelibrary/cpp/wire_types.h>

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

void ::test_protocollayoutssamelibrary::wire::UnionPayload::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(UnionPayload) == sizeof(fidl_union_t));
  static_assert(offsetof(UnionPayload, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof(UnionPayload, envelope_) == offsetof(fidl_union_t, envelope));
}

void ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedRequest::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(ComposedProtocolTwoWayAnonComposedRequest) == sizeof(fidl_union_t));
  static_assert(offsetof(ComposedProtocolTwoWayAnonComposedRequest, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof(ComposedProtocolTwoWayAnonComposedRequest, envelope_) == offsetof(fidl_union_t, envelope));
}

void ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResponse::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(ComposedProtocolTwoWayAnonComposedWithErrorResponse) == sizeof(fidl_union_t));
  static_assert(offsetof(ComposedProtocolTwoWayAnonComposedWithErrorResponse, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof(ComposedProtocolTwoWayAnonComposedWithErrorResponse, envelope_) == offsetof(fidl_union_t, envelope));
}

void ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorResult::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(ComposedProtocolTwoWayAnonComposedWithErrorResult) == sizeof(fidl_union_t));
  static_assert(offsetof(ComposedProtocolTwoWayAnonComposedWithErrorResult, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof(ComposedProtocolTwoWayAnonComposedWithErrorResult, envelope_) == offsetof(fidl_union_t, envelope));
}

void ::test_protocollayoutssamelibrary::wire::ComposedProtocolOnAnonComposedRequest::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(ComposedProtocolOnAnonComposedRequest) == sizeof(fidl_union_t));
  static_assert(offsetof(ComposedProtocolOnAnonComposedRequest, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof(ComposedProtocolOnAnonComposedRequest, envelope_) == offsetof(fidl_union_t, envelope));
}

void ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayNamedComposedWithErrorResult::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(ComposedProtocolTwoWayNamedComposedWithErrorResult) == sizeof(fidl_union_t));
  static_assert(offsetof(ComposedProtocolTwoWayNamedComposedWithErrorResult, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof(ComposedProtocolTwoWayNamedComposedWithErrorResult, envelope_) == offsetof(fidl_union_t, envelope));
}

void ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayLocalWithErrorResult::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(MainProtocolTwoWayLocalWithErrorResult) == sizeof(fidl_union_t));
  static_assert(offsetof(MainProtocolTwoWayLocalWithErrorResult, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof(MainProtocolTwoWayLocalWithErrorResult, envelope_) == offsetof(fidl_union_t, envelope));
}

auto ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest::Which() const -> ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest::Ordinal::kB:
      return static_cast<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest::Tag>(ordinal_);
    default:
      return ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest::Tag::_do_not_handle_this__write_a_default_case_instead;
  }
}

void ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonRequest::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(MainProtocolTwoWayAnonRequest) == sizeof(fidl_union_t));
  static_assert(offsetof(MainProtocolTwoWayAnonRequest, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof(MainProtocolTwoWayAnonRequest, envelope_) == offsetof(fidl_union_t, envelope));
}

auto ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse::Which() const -> ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse::Ordinal::kB:
      return static_cast<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse::Tag>(ordinal_);
    default:
      return ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse::Tag::_do_not_handle_this__write_a_default_case_instead;
  }
}

void ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResponse::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(MainProtocolTwoWayAnonWithErrorResponse) == sizeof(fidl_union_t));
  static_assert(offsetof(MainProtocolTwoWayAnonWithErrorResponse, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof(MainProtocolTwoWayAnonWithErrorResponse, envelope_) == offsetof(fidl_union_t, envelope));
}

void ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorResult::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(MainProtocolTwoWayAnonWithErrorResult) == sizeof(fidl_union_t));
  static_assert(offsetof(MainProtocolTwoWayAnonWithErrorResult, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof(MainProtocolTwoWayAnonWithErrorResult, envelope_) == offsetof(fidl_union_t, envelope));
}

auto ::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest::Which() const -> ::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest::Tag {
  ZX_ASSERT(!has_invalid_tag());
  switch (ordinal_) {
    case ::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest::Ordinal::kB:
      return static_cast<::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest::Tag>(ordinal_);
    default:
      return ::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest::Tag::_do_not_handle_this__write_a_default_case_instead;
  }
}

void ::test_protocollayoutssamelibrary::wire::MainProtocolOnAnonRequest::SizeAndOffsetAssertionHelper() {
  static_assert(sizeof(MainProtocolOnAnonRequest) == sizeof(fidl_union_t));
  static_assert(offsetof(MainProtocolOnAnonRequest, ordinal_) == offsetof(fidl_union_t, tag));
  static_assert(offsetof(MainProtocolOnAnonRequest, envelope_) == offsetof(fidl_union_t, envelope));
}

bool ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::TablePayload>::HasUnknownData() const {
  return false;
}

uint64_t fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::TablePayload>::ComputeMaxOrdinal() const {
  uint64_t max_ordinal = 0;
  if (!a_.has_data()) {
    max_ordinal = 1;
  }
  return max_ordinal;
}

bool ::test_protocollayoutssamelibrary::wire::TablePayload::HasUnknownData() const {
  if (max_ordinal_ > 1) {
    return true;
  }
  if (frame_ptr_ == nullptr) {
    return false;
  }
  return frame_ptr_->HasUnknownData();
}

bool ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>::HasUnknownData() const {
  return false;
}

uint64_t fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest>::ComputeMaxOrdinal() const {
  uint64_t max_ordinal = 0;
  if (!a_.has_data()) {
    max_ordinal = 1;
  }
  return max_ordinal;
}

bool ::test_protocollayoutssamelibrary::wire::ComposedProtocolOneWayAnonComposedRequest::HasUnknownData() const {
  if (max_ordinal_ > 1) {
    return true;
  }
  if (frame_ptr_ == nullptr) {
    return false;
  }
  return frame_ptr_->HasUnknownData();
}

bool ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>::HasUnknownData() const {
  return false;
}

uint64_t fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse>::ComputeMaxOrdinal() const {
  uint64_t max_ordinal = 0;
  if (!a_.has_data()) {
    max_ordinal = 1;
  }
  return max_ordinal;
}

bool ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedResponse::HasUnknownData() const {
  if (max_ordinal_ > 1) {
    return true;
  }
  if (frame_ptr_ == nullptr) {
    return false;
  }
  return frame_ptr_->HasUnknownData();
}

bool ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>::HasUnknownData() const {
  return false;
}

uint64_t fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest>::ComputeMaxOrdinal() const {
  uint64_t max_ordinal = 0;
  if (!a_.has_data()) {
    max_ordinal = 1;
  }
  return max_ordinal;
}

bool ::test_protocollayoutssamelibrary::wire::ComposedProtocolTwoWayAnonComposedWithErrorRequest::HasUnknownData() const {
  if (max_ordinal_ > 1) {
    return true;
  }
  if (frame_ptr_ == nullptr) {
    return false;
  }
  return frame_ptr_->HasUnknownData();
}

bool ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest>::HasUnknownData() const {
  return false;
}

uint64_t fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest>::ComputeMaxOrdinal() const {
  uint64_t max_ordinal = 0;
  if (!a_.has_data()) {
    max_ordinal = 1;
  }
  return max_ordinal;
}

bool ::test_protocollayoutssamelibrary::wire::MainProtocolOneWayAnonRequest::HasUnknownData() const {
  if (max_ordinal_ > 1) {
    return true;
  }
  if (frame_ptr_ == nullptr) {
    return false;
  }
  return frame_ptr_->HasUnknownData();
}

bool ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse>::HasUnknownData() const {
  return false;
}

uint64_t fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse>::ComputeMaxOrdinal() const {
  uint64_t max_ordinal = 0;
  if (!a_.has_data()) {
    max_ordinal = 1;
  }
  return max_ordinal;
}

bool ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonResponse::HasUnknownData() const {
  if (max_ordinal_ > 1) {
    return true;
  }
  if (frame_ptr_ == nullptr) {
    return false;
  }
  return frame_ptr_->HasUnknownData();
}

bool ::fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest>::HasUnknownData() const {
  return false;
}

uint64_t fidl::WireTableFrame<::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest>::ComputeMaxOrdinal() const {
  uint64_t max_ordinal = 0;
  if (!a_.has_data()) {
    max_ordinal = 1;
  }
  return max_ordinal;
}

bool ::test_protocollayoutssamelibrary::wire::MainProtocolTwoWayAnonWithErrorRequest::HasUnknownData() const {
  if (max_ordinal_ > 1) {
    return true;
  }
  if (frame_ptr_ == nullptr) {
    return false;
  }
  return frame_ptr_->HasUnknownData();
}

#pragma clang diagnostic pop
