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

// fidl_experiment = output_index_json

#pragma once

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

#include <cinttypes>
#ifdef __Fuchsia__

#endif  // __Fuchsia__

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

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

namespace test_consts {

namespace wire {
using BitsType = ::test_consts::BitsType;

using EnumType = ::test_consts::EnumType;

constexpr bool kEnabledFlag = true;

constexpr int8_t kOffset = -33;

constexpr uint16_t kAnswer = 42u;

constexpr uint8_t kAnswerNarrowed = ::test_consts::wire::kAnswer;

constexpr uint16_t kAnswerInBinary = 42u;

constexpr uint32_t kPopulationUsa2018 = 330000000u;

constexpr uint64_t kDiamond = 1746410393481133080u;

constexpr uint64_t kFuchsia = 4054509061583223046u;

extern const char* kUsername;

constexpr float kMinTemp = -273.15f;

constexpr double kConversionFactor = 1.41421;

constexpr zx_obj_type_t kZxObjVal = ZX_OBJ_TYPE_CHANNEL;

constexpr zx_rights_t kZxRightsVal = ZX_RIGHT_READ;

constexpr uint64_t kZxConst = ZX_CHANNEL_MAX_MSG_BYTES;

constexpr ::test_consts::wire::EnumType kEnumVal = ::test_consts::wire::EnumType::kValue;

constexpr int32_t kEnumPrimitiveVal = ::test_consts::wire::EnumType::kValue;

constexpr int8_t kEnumPrimitiveValNarrowed = ::test_consts::wire::EnumType::kValue;

constexpr ::test_consts::wire::EnumType kEnumTrue = ::test_consts::wire::EnumType::kTrue;

constexpr int32_t kEnumPrimitiveTrue = ::test_consts::wire::EnumType::kTrue;

constexpr ::test_consts::wire::BitsType kBitsVal = ::test_consts::wire::BitsType::kValue;

constexpr uint32_t kBitsPrimitiveVal = ::test_consts::wire::BitsType::kValue;

constexpr uint8_t kBitsPrimitiveValNarrowed = ::test_consts::wire::BitsType::kValue;

constexpr ::test_consts::wire::BitsType kBitsTrue = ::test_consts::wire::BitsType::kTrue;

constexpr uint32_t kBitsPrimitiveTrue = ::test_consts::wire::BitsType::kTrue;

}  // namespace wire
}  // namespace test_consts
namespace fidl {

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

  static void Encode(internal::WireEncoder* encoder, ::test_consts::wire::BitsType* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    if (unlikely(static_cast<uint32_t>(*value) & ~3ull)) {
      encoder->SetError(::fidl::internal::kCodingErrorUnknownBitSetInBitsValue);
    }
    *position.As<::test_consts::wire::BitsType>() = *value;
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    ::test_consts::wire::BitsType value = *position.As<::test_consts::wire::BitsType>();
    if (unlikely(static_cast<uint32_t>(value) & ~3ull)) {
      decoder->SetError(::fidl::internal::kCodingErrorUnknownBitSetInBitsValue);
    }
  }
};

template <bool IsRecursive>
struct internal::WireCodingTraits<::test_consts::wire::EnumType, ::fidl::internal::WireCodingConstraintEmpty, IsRecursive> {
  static constexpr size_t kInlineSize = sizeof(int32_t);
  static constexpr bool kIsMemcpyCompatible = false;

  static void Encode(internal::WireEncoder* encoder, ::test_consts::wire::EnumType* value, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    switch (*value) {
      case ::test_consts::wire::EnumType::kValue:
      case ::test_consts::wire::EnumType::kTrue:
        break;
      default:
        encoder->SetError(::fidl::internal::kCodingErrorUnknownEnumValue);
        return;
    }
    *position.As<::test_consts::wire::EnumType>() = *value;
  }
  static void Decode(internal::WireDecoder* decoder, ::fidl::internal::WirePosition position, RecursionDepth<IsRecursive> recursion_depth) {
    [[maybe_unused]] ::test_consts::wire::EnumType value = *position.As<::test_consts::wire::EnumType>();
    switch (value) {
      case ::test_consts::wire::EnumType::kValue:
      case ::test_consts::wire::EnumType::kTrue:
        break;
      default:
        decoder->SetError(::fidl::internal::kCodingErrorUnknownEnumValue);
        return;
    }
  }
};

#pragma clang diagnostic pop

}  // namespace fidl
