//===- DXContainerYAML.cpp - DXContainer YAMLIO implementation ------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines classes for handling the YAML representation of
// DXContainerYAML.
//
//===----------------------------------------------------------------------===//

#include "llvm/ObjectYAML/DXContainerYAML.h"
#include "llvm/ADT/STLForwardCompat.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/BinaryFormat/DXContainer.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ScopedPrinter.h"
#include <cstdint>
#include <system_error>

namespace llvm {

// This assert is duplicated here to leave a breadcrumb of the places that need
// to be updated if flags grow past 64-bits.
static_assert((uint64_t)dxbc::FeatureFlags::NextUnusedBit <= 1ull << 63,
              "Shader flag bits exceed enum size.");

DXContainerYAML::ShaderFeatureFlags::ShaderFeatureFlags(uint64_t FlagData) {
#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str)                      \
  Val = (FlagData & (uint64_t)dxbc::FeatureFlags::Val) > 0;
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

template <typename T>
static llvm::Error
readDescriptorRanges(DXContainerYAML::RootParameterHeaderYaml &Header,
                     DXContainerYAML::RootSignatureYamlDesc &RootSigDesc,
                     object::DirectX::DescriptorTableView *DTV) {

  llvm::Expected<object::DirectX::DescriptorTable<T>> TableOrErr =
      DTV->read<T>();
  if (Error E = TableOrErr.takeError())
    return E;
  auto Table = *TableOrErr;

  DXContainerYAML::RootParameterLocationYaml Location(Header);
  DXContainerYAML::DescriptorTableYaml &TableYaml =
      RootSigDesc.Parameters.getOrInsertTable(Location);
  RootSigDesc.Parameters.insertLocation(Location);

  TableYaml.NumRanges = Table.NumRanges;
  TableYaml.RangesOffset = Table.RangesOffset;

  for (const auto &R : Table.Ranges) {
    DXContainerYAML::DescriptorRangeYaml NewR;
    NewR.OffsetInDescriptorsFromTableStart =
        R.OffsetInDescriptorsFromTableStart;
    NewR.NumDescriptors = R.NumDescriptors;
    NewR.BaseShaderRegister = R.BaseShaderRegister;
    NewR.RegisterSpace = R.RegisterSpace;
    if (!dxbc::isValidRangeType(R.RangeType))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for descriptor range type");
    NewR.RangeType = dxil::ResourceClass(R.RangeType);
    if constexpr (std::is_same_v<T, dxbc::RTS0::v2::DescriptorRange>) {
      // Set all flag fields for v2
#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag)                                 \
  NewR.Enum =                                                                  \
      (R.Flags & llvm::to_underlying(dxbc::DescriptorRangeFlags::Enum)) != 0;
#include "llvm/BinaryFormat/DXContainerConstants.def"
    }
    TableYaml.Ranges.push_back(NewR);
  }

  return Error::success();
}

llvm::Expected<DXContainerYAML::RootSignatureYamlDesc>
DXContainerYAML::RootSignatureYamlDesc::create(
    const object::DirectX::RootSignature &Data) {

  RootSignatureYamlDesc RootSigDesc;
  uint32_t Version = Data.getVersion();

  RootSigDesc.Version = Version;
  RootSigDesc.NumStaticSamplers = Data.getNumStaticSamplers();
  RootSigDesc.StaticSamplersOffset = Data.getStaticSamplersOffset();
  RootSigDesc.NumRootParameters = Data.getNumRootParameters();
  RootSigDesc.RootParametersOffset = Data.getRootParametersOffset();

  uint32_t Flags = Data.getFlags();
  for (const dxbc::RTS0::v1::RootParameterHeader &PH : Data.param_headers()) {

    if (!dxbc::isValidParameterType(PH.ParameterType))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for parameter type");

    RootParameterHeaderYaml Header(dxbc::RootParameterType(PH.ParameterType));
    Header.Offset = PH.ParameterOffset;

    if (!dxbc::isValidShaderVisibility(PH.ShaderVisibility))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for shader visibility");

    Header.Visibility = dxbc::ShaderVisibility(PH.ShaderVisibility);

    llvm::Expected<object::DirectX::RootParameterView> ParamViewOrErr =
        Data.getParameter(PH);
    if (Error E = ParamViewOrErr.takeError())
      return std::move(E);
    object::DirectX::RootParameterView ParamView = ParamViewOrErr.get();

    if (auto *RCV = dyn_cast<object::DirectX::RootConstantView>(&ParamView)) {
      llvm::Expected<dxbc::RTS0::v1::RootConstants> ConstantsOrErr =
          RCV->read();
      if (Error E = ConstantsOrErr.takeError())
        return std::move(E);

      auto Constants = *ConstantsOrErr;
      RootParameterLocationYaml Location(Header);
      RootConstantsYaml &ConstantYaml =
          RootSigDesc.Parameters.getOrInsertConstants(Location);
      RootSigDesc.Parameters.insertLocation(Location);
      ConstantYaml.Num32BitValues = Constants.Num32BitValues;
      ConstantYaml.ShaderRegister = Constants.ShaderRegister;
      ConstantYaml.RegisterSpace = Constants.RegisterSpace;

    } else if (auto *RDV =
                   dyn_cast<object::DirectX::RootDescriptorView>(&ParamView)) {
      llvm::Expected<dxbc::RTS0::v2::RootDescriptor> DescriptorOrErr =
          RDV->read(Version);
      if (Error E = DescriptorOrErr.takeError())
        return std::move(E);
      auto Descriptor = *DescriptorOrErr;
      RootParameterLocationYaml Location(Header);
      RootDescriptorYaml &YamlDescriptor =
          RootSigDesc.Parameters.getOrInsertDescriptor(Location);
      RootSigDesc.Parameters.insertLocation(Location);

      YamlDescriptor.ShaderRegister = Descriptor.ShaderRegister;
      YamlDescriptor.RegisterSpace = Descriptor.RegisterSpace;
      if (Version > 1) {
#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag)                                  \
  YamlDescriptor.Enum =                                                        \
      (Descriptor.Flags &                                                      \
       llvm::to_underlying(dxbc::RootDescriptorFlags::Enum)) > 0;
#include "llvm/BinaryFormat/DXContainerConstants.def"
      }
    } else if (auto *DTV =
                   dyn_cast<object::DirectX::DescriptorTableView>(&ParamView)) {
      if (Version == 1) {
        if (Error E = readDescriptorRanges<dxbc::RTS0::v1::DescriptorRange>(
                Header, RootSigDesc, DTV))
          return std::move(E);
      } else if (Version == 2 || Version == 3) {
        if (Error E = readDescriptorRanges<dxbc::RTS0::v2::DescriptorRange>(
                Header, RootSigDesc, DTV))
          return std::move(E);
      } else
        llvm_unreachable("Unknown version for DescriptorRanges");
    }
  }

  for (const auto &S : Data.samplers()) {
    if (!dxbc::isValidSamplerFilter(S.Filter))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for static sampler filter");

    if (!dxbc::isValidAddress(S.AddressU))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for static sampler AddressU");

    if (!dxbc::isValidAddress(S.AddressV))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for static sampler AddressV");

    if (!dxbc::isValidAddress(S.AddressW))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for static sampler AddressW");

    if (!dxbc::isValidComparisonFunc(S.ComparisonFunc))
      return createStringError(
          std::errc::invalid_argument,
          "Invalid value for static sampler ComparisonFunc");

    if (!dxbc::isValidBorderColor(S.BorderColor))
      return createStringError(std::errc::invalid_argument,
                               "Invalid value for static sampler BorderColor");

    if (!dxbc::isValidShaderVisibility(S.ShaderVisibility))
      return createStringError(
          std::errc::invalid_argument,
          "Invalid value for static sampler ShaderVisibility");

    StaticSamplerYamlDesc NewS;
    NewS.Filter = dxbc::SamplerFilter(S.Filter);
    NewS.AddressU = dxbc::TextureAddressMode(S.AddressU);
    NewS.AddressV = dxbc::TextureAddressMode(S.AddressV);
    NewS.AddressW = dxbc::TextureAddressMode(S.AddressW);
    NewS.MipLODBias = S.MipLODBias;
    NewS.MaxAnisotropy = S.MaxAnisotropy;
    NewS.ComparisonFunc = dxbc::ComparisonFunc(S.ComparisonFunc);
    NewS.BorderColor = dxbc::StaticBorderColor(S.BorderColor);
    NewS.MinLOD = S.MinLOD;
    NewS.MaxLOD = S.MaxLOD;
    NewS.ShaderRegister = S.ShaderRegister;
    NewS.RegisterSpace = S.RegisterSpace;
    NewS.ShaderVisibility = dxbc::ShaderVisibility(S.ShaderVisibility);

    if (Version > 2) {
#define STATIC_SAMPLER_FLAG(Num, Enum, Flag)                                   \
  NewS.Enum = (S.Flags & llvm::to_underlying(dxbc::StaticSamplerFlags::Enum));
#include "llvm/BinaryFormat/DXContainerConstants.def"
    }
    RootSigDesc.StaticSamplers.push_back(NewS);
  }

#define ROOT_SIGNATURE_FLAG(Num, Val)                                          \
  RootSigDesc.Val = (Flags & llvm::to_underlying(dxbc::RootFlags::Val)) > 0;
#include "llvm/BinaryFormat/DXContainerConstants.def"
  return RootSigDesc;
}

uint32_t DXContainerYAML::RootDescriptorYaml::getEncodedFlags() const {
  uint64_t Flags = 0;
#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag)                                  \
  if (Enum)                                                                    \
    Flags |= (uint32_t)dxbc::RootDescriptorFlags::Enum;
#include "llvm/BinaryFormat/DXContainerConstants.def"
  return Flags;
}

uint32_t DXContainerYAML::RootSignatureYamlDesc::getEncodedFlags() {
  uint64_t Flag = 0;
#define ROOT_SIGNATURE_FLAG(Num, Val)                                          \
  if (Val)                                                                     \
    Flag |= (uint32_t)dxbc::RootFlags::Val;
#include "llvm/BinaryFormat/DXContainerConstants.def"
  return Flag;
}

uint32_t DXContainerYAML::DescriptorRangeYaml::getEncodedFlags() const {
  uint64_t Flags = 0;
#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag)                                 \
  if (Enum)                                                                    \
    Flags |= (uint32_t)dxbc::DescriptorRangeFlags::Enum;
#include "llvm/BinaryFormat/DXContainerConstants.def"
  return Flags;
}

uint32_t DXContainerYAML::StaticSamplerYamlDesc::getEncodedFlags() const {
  uint64_t Flags = 0;
#define STATIC_SAMPLER_FLAG(Num, Enum, Flag)                                   \
  if (Enum)                                                                    \
    Flags |= (uint32_t)dxbc::StaticSamplerFlags::Enum;
#include "llvm/BinaryFormat/DXContainerConstants.def"
  return Flags;
}

uint64_t DXContainerYAML::ShaderFeatureFlags::getEncodedFlags() {
  uint64_t Flag = 0;
#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str)                      \
  if (Val)                                                                     \
    Flag |= (uint64_t)dxbc::FeatureFlags::Val;
#include "llvm/BinaryFormat/DXContainerConstants.def"
  return Flag;
}

DXContainerYAML::ShaderHash::ShaderHash(const dxbc::ShaderHash &Data)
    : IncludesSource((Data.Flags & static_cast<uint32_t>(
                                       dxbc::HashFlags::IncludesSource)) != 0),
      Digest(16, 0) {
  memcpy(Digest.data(), &Data.Digest[0], 16);
}

DXContainerYAML::PSVInfo::PSVInfo() : Version(0) {
  memset(&Info, 0, sizeof(Info));
}

DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v0::RuntimeInfo *P,
                                  uint16_t Stage)
    : Version(0) {
  memset(&Info, 0, sizeof(Info));
  memcpy(&Info, P, sizeof(dxbc::PSV::v0::RuntimeInfo));

  assert(Stage < std::numeric_limits<uint8_t>::max() &&
         "Stage should be a very small number");
  // We need to bring the stage in separately since it isn't part of the v1 data
  // structure.
  Info.ShaderStage = static_cast<uint8_t>(Stage);
}

DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v1::RuntimeInfo *P)
    : Version(1) {
  memset(&Info, 0, sizeof(Info));
  memcpy(&Info, P, sizeof(dxbc::PSV::v1::RuntimeInfo));
}

DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v2::RuntimeInfo *P)
    : Version(2) {
  memset(&Info, 0, sizeof(Info));
  memcpy(&Info, P, sizeof(dxbc::PSV::v2::RuntimeInfo));
}

DXContainerYAML::PSVInfo::PSVInfo(const dxbc::PSV::v3::RuntimeInfo *P,
                                  StringRef StringTable)
    : Version(3),
      EntryName(StringTable.substr(P->EntryNameOffset,
                                   StringTable.find('\0', P->EntryNameOffset) -
                                       P->EntryNameOffset)) {
  memset(&Info, 0, sizeof(Info));
  memcpy(&Info, P, sizeof(dxbc::PSV::v3::RuntimeInfo));
}

namespace yaml {

void MappingTraits<DXContainerYAML::VersionTuple>::mapping(
    IO &IO, DXContainerYAML::VersionTuple &Version) {
  IO.mapRequired("Major", Version.Major);
  IO.mapRequired("Minor", Version.Minor);
}

void MappingTraits<DXContainerYAML::FileHeader>::mapping(
    IO &IO, DXContainerYAML::FileHeader &Header) {
  IO.mapRequired("Hash", Header.Hash);
  IO.mapRequired("Version", Header.Version);
  IO.mapOptional("FileSize", Header.FileSize);
  IO.mapRequired("PartCount", Header.PartCount);
  IO.mapOptional("PartOffsets", Header.PartOffsets);
}

void MappingTraits<DXContainerYAML::DXILProgram>::mapping(
    IO &IO, DXContainerYAML::DXILProgram &Program) {
  IO.mapRequired("MajorVersion", Program.MajorVersion);
  IO.mapRequired("MinorVersion", Program.MinorVersion);
  IO.mapRequired("ShaderKind", Program.ShaderKind);
  IO.mapOptional("Size", Program.Size);
  IO.mapRequired("DXILMajorVersion", Program.DXILMajorVersion);
  IO.mapRequired("DXILMinorVersion", Program.DXILMinorVersion);
  IO.mapOptional("DXILSize", Program.DXILSize);
  IO.mapOptional("DXIL", Program.DXIL);
}

void MappingTraits<DXContainerYAML::ShaderFeatureFlags>::mapping(
    IO &IO, DXContainerYAML::ShaderFeatureFlags &Flags) {
#define SHADER_FEATURE_FLAG(Num, DxilModuleNum, Val, Str)                      \
  IO.mapRequired(#Val, Flags.Val);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

void MappingTraits<DXContainerYAML::ShaderHash>::mapping(
    IO &IO, DXContainerYAML::ShaderHash &Hash) {
  IO.mapRequired("IncludesSource", Hash.IncludesSource);
  IO.mapRequired("Digest", Hash.Digest);
}

void MappingTraits<DXContainerYAML::PSVInfo>::mapping(
    IO &IO, DXContainerYAML::PSVInfo &PSV) {
  IO.mapRequired("Version", PSV.Version);

  // Store the PSV version in the YAML context.
  void *OldContext = IO.getContext();
  uint32_t Version = PSV.Version;
  IO.setContext(&Version);

  // Restore the YAML context on function exit.
  llvm::scope_exit RestoreContext([&]() { IO.setContext(OldContext); });

  // Shader stage is only included in binaries for v1 and later, but we always
  // include it since it simplifies parsing and file construction.
  IO.mapRequired("ShaderStage", PSV.Info.ShaderStage);
  PSV.mapInfoForVersion(IO);

  IO.mapRequired("ResourceStride", PSV.ResourceStride);
  if (PSV.Version > 0) {
    IO.mapOptional("RuntimeInfoSize", PSV.RuntimeInfoSize);
    IO.mapOptional("StringTable", PSV.StringTable);
  }
  IO.mapRequired("Resources", PSV.Resources);
  if (PSV.Version == 0)
    return;
  IO.mapRequired("SigInputElements", PSV.SigInputElements);
  IO.mapRequired("SigOutputElements", PSV.SigOutputElements);
  IO.mapRequired("SigPatchOrPrimElements", PSV.SigPatchOrPrimElements);

  Triple::EnvironmentType Stage = dxbc::getShaderStage(PSV.Info.ShaderStage);
  if (PSV.Info.UsesViewID) {
    MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableOutMasks(
        PSV.OutputVectorMasks);
    IO.mapRequired("OutputVectorMasks", MutableOutMasks);
    if (Stage == Triple::EnvironmentType::Hull)
      IO.mapRequired("PatchOrPrimMasks", PSV.PatchOrPrimMasks);
  }
  MutableArrayRef<SmallVector<llvm::yaml::Hex32>> MutableIOMap(
      PSV.InputOutputMap);
  IO.mapRequired("InputOutputMap", MutableIOMap);

  if (Stage == Triple::EnvironmentType::Hull)
    IO.mapRequired("InputPatchMap", PSV.InputPatchMap);

  if (Stage == Triple::EnvironmentType::Domain)
    IO.mapRequired("PatchOutputMap", PSV.PatchOutputMap);
}

void MappingTraits<DXContainerYAML::SignatureParameter>::mapping(
    IO &IO, DXContainerYAML::SignatureParameter &S) {
  IO.mapRequired("Stream", S.Stream);
  IO.mapRequired("Name", S.Name);
  IO.mapRequired("Index", S.Index);
  IO.mapRequired("SystemValue", S.SystemValue);
  IO.mapRequired("CompType", S.CompType);
  IO.mapRequired("Register", S.Register);
  IO.mapRequired("Mask", S.Mask);
  IO.mapRequired("ExclusiveMask", S.ExclusiveMask);
  IO.mapRequired("MinPrecision", S.MinPrecision);
}

void MappingTraits<DXContainerYAML::Signature>::mapping(
    IO &IO, DXContainerYAML::Signature &S) {
  IO.mapRequired("Parameters", S.Parameters);
}

void MappingTraits<DXContainerYAML::RootSignatureYamlDesc>::mapping(
    IO &IO, DXContainerYAML::RootSignatureYamlDesc &S) {
  IO.mapRequired("Version", S.Version);
  IO.mapRequired("NumRootParameters", S.NumRootParameters);
  IO.mapOptional("RootParametersOffset", S.RootParametersOffset, std::nullopt);
  IO.mapRequired("NumStaticSamplers", S.NumStaticSamplers);
  IO.mapOptional("StaticSamplersOffset", S.StaticSamplersOffset, std::nullopt);
  IO.mapRequired("Parameters", S.Parameters.Locations, S);
  IO.mapOptional("Samplers", S.StaticSamplers);
#define ROOT_SIGNATURE_FLAG(Num, Val) IO.mapOptional(#Val, S.Val, false);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

void MappingTraits<llvm::DXContainerYAML::DescriptorRangeYaml>::mapping(
    IO &IO, llvm::DXContainerYAML::DescriptorRangeYaml &R) {
  IO.mapRequired("RangeType", R.RangeType);
  // handling the edge case where NumDescriptors might be -1
  if (IO.outputting()) {
    if (R.NumDescriptors == UINT_MAX) {
      int32_t NegOne = -1;
      IO.mapRequired("NumDescriptors", NegOne);
    } else
      IO.mapRequired("NumDescriptors", R.NumDescriptors);
  } else {
    int32_t TmpNumDesc = 0;
    IO.mapRequired("NumDescriptors", TmpNumDesc);
    R.NumDescriptors = static_cast<uint32_t>(TmpNumDesc);
  }

  IO.mapRequired("BaseShaderRegister", R.BaseShaderRegister);
  IO.mapRequired("RegisterSpace", R.RegisterSpace);
  IO.mapRequired("OffsetInDescriptorsFromTableStart",
                 R.OffsetInDescriptorsFromTableStart);
#define DESCRIPTOR_RANGE_FLAG(Num, Enum, Flag)                                 \
  IO.mapOptional(#Flag, R.Enum, false);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

void MappingTraits<llvm::DXContainerYAML::DescriptorTableYaml>::mapping(
    IO &IO, llvm::DXContainerYAML::DescriptorTableYaml &T) {
  IO.mapRequired("NumRanges", T.NumRanges);
  IO.mapOptional("RangesOffset", T.RangesOffset);
  IO.mapRequired("Ranges", T.Ranges);
}

void MappingContextTraits<DXContainerYAML::RootParameterLocationYaml,
                          DXContainerYAML::RootSignatureYamlDesc>::
    mapping(IO &IO, DXContainerYAML::RootParameterLocationYaml &L,
            DXContainerYAML::RootSignatureYamlDesc &S) {
  IO.mapRequired("ParameterType", L.Header.Type);
  IO.mapRequired("ShaderVisibility", L.Header.Visibility);

  switch (L.Header.Type) {
  case dxbc::RootParameterType::Constants32Bit: {
    DXContainerYAML::RootConstantsYaml &Constants =
        S.Parameters.getOrInsertConstants(L);
    IO.mapRequired("Constants", Constants);
    break;
  }
  case dxbc::RootParameterType::CBV:
  case dxbc::RootParameterType::SRV:
  case dxbc::RootParameterType::UAV: {
    DXContainerYAML::RootDescriptorYaml &Descriptor =
        S.Parameters.getOrInsertDescriptor(L);
    IO.mapRequired("Descriptor", Descriptor);
    break;
  }
  case dxbc::RootParameterType::DescriptorTable: {
    DXContainerYAML::DescriptorTableYaml &Table =
        S.Parameters.getOrInsertTable(L);
    IO.mapRequired("Table", Table);
    break;
  }
  }
}

void MappingTraits<llvm::DXContainerYAML::RootConstantsYaml>::mapping(
    IO &IO, llvm::DXContainerYAML::RootConstantsYaml &C) {
  IO.mapRequired("Num32BitValues", C.Num32BitValues);
  IO.mapRequired("RegisterSpace", C.RegisterSpace);
  IO.mapRequired("ShaderRegister", C.ShaderRegister);
}

void MappingTraits<llvm::DXContainerYAML::RootDescriptorYaml>::mapping(
    IO &IO, llvm::DXContainerYAML::RootDescriptorYaml &D) {
  IO.mapRequired("RegisterSpace", D.RegisterSpace);
  IO.mapRequired("ShaderRegister", D.ShaderRegister);
#define ROOT_DESCRIPTOR_FLAG(Num, Enum, Flag)                                  \
  IO.mapOptional(#Flag, D.Enum, false);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

void MappingTraits<llvm::DXContainerYAML::StaticSamplerYamlDesc>::mapping(
    IO &IO, llvm::DXContainerYAML::StaticSamplerYamlDesc &S) {

  IO.mapOptional("Filter", S.Filter);
  IO.mapOptional("AddressU", S.AddressU);
  IO.mapOptional("AddressV", S.AddressV);
  IO.mapOptional("AddressW", S.AddressW);
  IO.mapOptional("MipLODBias", S.MipLODBias);
  IO.mapOptional("MaxAnisotropy", S.MaxAnisotropy);
  IO.mapOptional("ComparisonFunc", S.ComparisonFunc);
  IO.mapOptional("BorderColor", S.BorderColor);
  IO.mapOptional("MinLOD", S.MinLOD);
  IO.mapOptional("MaxLOD", S.MaxLOD);
  IO.mapRequired("ShaderRegister", S.ShaderRegister);
  IO.mapRequired("RegisterSpace", S.RegisterSpace);
  IO.mapRequired("ShaderVisibility", S.ShaderVisibility);
#define STATIC_SAMPLER_FLAG(Num, Enum, Flag)                                   \
  IO.mapOptional(#Flag, S.Enum, false);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

void MappingTraits<DXContainerYAML::DebugName>::mapping(
    IO &IO, DXContainerYAML::DebugName &DebugName) {
  IO.mapOptional("Flags", DebugName.Flags);
  IO.mapOptional("NameLength", DebugName.NameLength);
  IO.mapRequired("DebugName", DebugName.Filename);
}

void MappingTraits<DXContainerYAML::CompilerVersion>::mapping(
    IO &IO, DXContainerYAML::CompilerVersion &CompilerVersion) {
  IO.mapOptional("Major", CompilerVersion.Major);
  IO.mapOptional("Minor", CompilerVersion.Minor);
  IO.mapOptional("IsDebugBuild", CompilerVersion.IsDebugBuild);
  IO.mapOptional("IsValidated", CompilerVersion.IsValidated);
  IO.mapOptional("CommitCount", CompilerVersion.CommitCount);
  IO.mapOptional("ContentSizeInBytes", CompilerVersion.ContentSizeInBytes);
  IO.mapOptional("CommitSha", CompilerVersion.CommitSha);
  IO.mapOptional("CustomVersionString", CompilerVersion.CustomVersionString);
}

void MappingTraits<DXContainerYAML::Part>::mapping(IO &IO,
                                                   DXContainerYAML::Part &P) {
  IO.mapRequired("Name", P.Name);
  IO.mapRequired("Size", P.Size);
  IO.mapOptional("Program", P.Program);
  IO.mapOptional("Flags", P.Flags);
  IO.mapOptional("Hash", P.Hash);
  IO.mapOptional("PSVInfo", P.Info);
  IO.mapOptional("Signature", P.Signature);
  IO.mapOptional("RootSignature", P.RootSignature);
  IO.mapOptional("DebugName", P.DebugName);
  IO.mapOptional("CompilerVersion", P.CompilerVersion);
  IO.mapOptional("SourceInfo", P.SourceInfo);
  IO.mapOptional("PrivateData", P.PrivateData);
}

void MappingTraits<DXContainerYAML::Object>::mapping(
    IO &IO, DXContainerYAML::Object &Obj) {
  IO.mapTag("!dxcontainer", true);
  IO.mapRequired("Header", Obj.Header);
  IO.mapRequired("Parts", Obj.Parts);
}

void MappingTraits<DXContainerYAML::ResourceFlags>::mapping(
    IO &IO, DXContainerYAML::ResourceFlags &Flags) {
#define RESOURCE_FLAG(FlagIndex, Enum) IO.mapRequired(#Enum, Flags.Bits.Enum);
#include "llvm/BinaryFormat/DXContainerConstants.def"
}

void MappingTraits<DXContainerYAML::ResourceBindInfo>::mapping(
    IO &IO, DXContainerYAML::ResourceBindInfo &Res) {
  IO.mapRequired("Type", Res.Type);
  IO.mapRequired("Space", Res.Space);
  IO.mapRequired("LowerBound", Res.LowerBound);
  IO.mapRequired("UpperBound", Res.UpperBound);

  const uint32_t *PSVVersion = static_cast<uint32_t *>(IO.getContext());
  if (*PSVVersion < 2)
    return;

  IO.mapRequired("Kind", Res.Kind);
  IO.mapRequired("Flags", Res.Flags);
}

void MappingTraits<DXContainerYAML::SignatureElement>::mapping(
    IO &IO, DXContainerYAML::SignatureElement &El) {
  IO.mapRequired("Name", El.Name);
  IO.mapRequired("Indices", El.Indices);
  IO.mapRequired("StartRow", El.StartRow);
  IO.mapRequired("Cols", El.Cols);
  IO.mapRequired("StartCol", El.StartCol);
  IO.mapRequired("Allocated", El.Allocated);
  IO.mapRequired("Kind", El.Kind);
  IO.mapRequired("ComponentType", El.Type);
  IO.mapRequired("Interpolation", El.Mode);
  IO.mapRequired("DynamicMask", El.DynamicMask);
  IO.mapRequired("Stream", El.Stream);
}

void MappingTraits<DXContainerYAML::StringTableEntry>::mapping(
    IO &IO, DXContainerYAML::StringTableEntry &E) {
  IO.mapRequired("String", E.String);
  IO.mapRequired("Offset", E.Offset);
}

void ScalarEnumerationTraits<dxbc::PSV::SemanticKind>::enumeration(
    IO &IO, dxbc::PSV::SemanticKind &Value) {
  for (const auto &E : dxbc::PSV::getSemanticKinds())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxbc::PSV::ComponentType>::enumeration(
    IO &IO, dxbc::PSV::ComponentType &Value) {
  for (const auto &E : dxbc::PSV::getComponentTypes())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxbc::PSV::InterpolationMode>::enumeration(
    IO &IO, dxbc::PSV::InterpolationMode &Value) {
  for (const auto &E : dxbc::PSV::getInterpolationModes())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxbc::PSV::ResourceType>::enumeration(
    IO &IO, dxbc::PSV::ResourceType &Value) {
  for (const auto &E : dxbc::PSV::getResourceTypes())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxbc::PSV::ResourceKind>::enumeration(
    IO &IO, dxbc::PSV::ResourceKind &Value) {
  for (const auto &E : dxbc::PSV::getResourceKinds())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxbc::D3DSystemValue>::enumeration(
    IO &IO, dxbc::D3DSystemValue &Value) {
  for (const auto &E : dxbc::getD3DSystemValues())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxbc::SigMinPrecision>::enumeration(
    IO &IO, dxbc::SigMinPrecision &Value) {
  for (const auto &E : dxbc::getSigMinPrecisions())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxbc::SigComponentType>::enumeration(
    IO &IO, dxbc::SigComponentType &Value) {
  for (const auto &E : dxbc::getSigComponentTypes())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxbc::RootParameterType>::enumeration(
    IO &IO, dxbc::RootParameterType &Value) {
  for (const auto &E : dxbc::getRootParameterTypes())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxil::ResourceClass>::enumeration(
    IO &IO, dxil::ResourceClass &Value) {
  constexpr EnumStringDef<dxil::ResourceClass> ResourceClassDefs[] = {
      {{"CBuffer"}, dxil::ResourceClass::CBuffer},
      {{"SRV"}, dxil::ResourceClass::SRV},
      {{"UAV"}, dxil::ResourceClass::UAV},
      {{"Sampler"}, dxil::ResourceClass::Sampler},
  };
  static constexpr auto ResourceClasses = BUILD_ENUM_STRINGS(ResourceClassDefs);

  for (const auto &E : EnumStrings(ResourceClasses))
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxbc::SamplerFilter>::enumeration(
    IO &IO, dxbc::SamplerFilter &Value) {
  for (const auto &E : dxbc::getSamplerFilters())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxbc::StaticBorderColor>::enumeration(
    IO &IO, dxbc::StaticBorderColor &Value) {
  for (const auto &E : dxbc::getStaticBorderColors())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxbc::TextureAddressMode>::enumeration(
    IO &IO, dxbc::TextureAddressMode &Value) {
  for (const auto &E : dxbc::getTextureAddressModes())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxbc::ShaderVisibility>::enumeration(
    IO &IO, dxbc::ShaderVisibility &Value) {
  for (const auto &E : dxbc::getShaderVisibility())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<dxbc::ComparisonFunc>::enumeration(
    IO &IO, dxbc::ComparisonFunc &Value) {
  for (const auto &E : dxbc::getComparisonFuncs())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<llvm::dxbc::SourceInfo::SectionType>::enumeration(
    IO &IO, llvm::dxbc::SourceInfo::SectionType &Value) {
  for (const auto &E : dxbc::SourceInfo::getSectionTypes())
    IO.enumCase(Value, E.name(), E.value());
}

void ScalarEnumerationTraits<
    llvm::dxbc::SourceInfo::Contents::CompressionType>::
    enumeration(IO &IO,
                llvm::dxbc::SourceInfo::Contents::CompressionType &Value) {
  for (const auto &E : dxbc::SourceInfo::Contents::getCompressionTypes())
    IO.enumCase(Value, E.name(), E.value());
}

void MappingTraits<llvm::DXContainerYAML::SourceInfo::Header>::mapping(
    IO &IO, llvm::DXContainerYAML::SourceInfo::Header &H) {
  IO.mapOptional("AlignedSizeInBytes", H.AlignedSizeInBytes);
  IO.mapOptional("Flags", H.Flags);
  IO.mapOptional("SectionCount", H.SectionCount);
}

void MappingTraits<llvm::DXContainerYAML::SourceInfo::SectionHeader>::mapping(
    IO &IO, llvm::DXContainerYAML::SourceInfo::SectionHeader &H) {
  IO.mapOptional("AlignedSizeInBytes", H.AlignedSizeInBytes);
  IO.mapOptional("Flags", H.Flags);
  IO.mapOptional("Type", H.Type);
}

void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceNames::Header>::
    mapping(IO &IO, llvm::DXContainerYAML::SourceInfo::SourceNames::Header &H) {
  IO.mapOptional("Flags", H.Flags);
  IO.mapOptional("Count", H.Count);
  IO.mapOptional("EntriesSizeInBytes", H.EntriesSizeInBytes);
}

void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceNames::Entry>::
    mapping(IO &IO, llvm::DXContainerYAML::SourceInfo::SourceNames::Entry &E) {
  IO.mapOptional("AlignedSizeInBytes", E.AlignedSizeInBytes);
  IO.mapOptional("Flags", E.Flags);
  IO.mapOptional("NameSizeInBytes", E.NameSizeInBytes);
  IO.mapOptional("ContentSizeInBytes", E.ContentSizeInBytes);
  IO.mapRequired("FileName", E.FileName);
}

void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceNames>::mapping(
    IO &IO, llvm::DXContainerYAML::SourceInfo::SourceNames &S) {
  IO.mapRequired("SectionHeader", S.GenericHeader);
  IO.mapRequired("Header", S.Parameters);
  IO.mapRequired("Entries", S.Entries);
}

void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceContents::Header>::
    mapping(IO &IO,
            llvm::DXContainerYAML::SourceInfo::SourceContents::Header &H) {
  IO.mapOptional("AlignedSizeInBytes", H.AlignedSizeInBytes);
  IO.mapOptional("Flags", H.Flags);
  IO.mapRequired("Type", H.Type);
  IO.mapOptional("EntriesSizeInBytes", H.EntriesSizeInBytes);
  IO.mapOptional("UncompressedEntriesSizeInBytes",
                 H.UncompressedEntriesSizeInBytes);
  IO.mapOptional("Count", H.Count);
}

void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceContents::Entry>::
    mapping(IO &IO,
            llvm::DXContainerYAML::SourceInfo::SourceContents::Entry &E) {
  IO.mapOptional("AlignedSizeInBytes", E.AlignedSizeInBytes);
  IO.mapOptional("Flags", E.Flags);
  IO.mapOptional("ContentSizeInBytes", E.ContentSizeInBytes);
  IO.mapRequired("FileContent", E.FileContent);
}

void MappingTraits<llvm::DXContainerYAML::SourceInfo::SourceContents>::mapping(
    IO &IO, llvm::DXContainerYAML::SourceInfo::SourceContents &S) {
  IO.mapRequired("SectionHeader", S.GenericHeader);
  IO.mapRequired("Header", S.Parameters);
  IO.mapRequired("Entries", S.Entries);
}

void MappingTraits<llvm::DXContainerYAML::SourceInfo::ProgramArgs::Header>::
    mapping(IO &IO, llvm::DXContainerYAML::SourceInfo::ProgramArgs::Header &H) {
  IO.mapOptional("Flags", H.Flags);
  IO.mapOptional("SizeInBytes", H.SizeInBytes);
  IO.mapOptional("Count", H.Count);
}

void MappingTraits<mcdxbc::SourceInfo::ProgramArgs::Entry>::mapping(
    IO &IO, mcdxbc::SourceInfo::ProgramArgs::Entry &E) {
  IO.mapRequired("Arg", E.first);
  IO.mapRequired("Value", E.second);
}

void MappingTraits<llvm::DXContainerYAML::SourceInfo::ProgramArgs>::mapping(
    IO &IO, llvm::DXContainerYAML::SourceInfo::ProgramArgs &S) {
  IO.mapRequired("SectionHeader", S.GenericHeader);
  IO.mapRequired("Header", S.Parameters);
  IO.mapRequired("Args", S.Args);
}

void MappingTraits<llvm::DXContainerYAML::SourceInfo>::mapping(
    IO &IO, llvm::DXContainerYAML::SourceInfo &S) {
  IO.mapRequired("Header", S.Parameters);
  IO.mapRequired("Names", S.Names);
  IO.mapRequired("Contents", S.Contents);
  IO.mapRequired("Args", S.Args);
}

} // namespace yaml

void DXContainerYAML::PSVInfo::mapInfoForVersion(yaml::IO &IO) {
  dxbc::PipelinePSVInfo &StageInfo = Info.StageInfo;
  Triple::EnvironmentType Stage = dxbc::getShaderStage(Info.ShaderStage);

  switch (Stage) {
  case Triple::EnvironmentType::Pixel:
    IO.mapRequired("DepthOutput", StageInfo.PS.DepthOutput);
    IO.mapRequired("SampleFrequency", StageInfo.PS.SampleFrequency);
    break;
  case Triple::EnvironmentType::Vertex:
    IO.mapRequired("OutputPositionPresent", StageInfo.VS.OutputPositionPresent);
    break;
  case Triple::EnvironmentType::Geometry:
    IO.mapRequired("InputPrimitive", StageInfo.GS.InputPrimitive);
    IO.mapRequired("OutputTopology", StageInfo.GS.OutputTopology);
    IO.mapRequired("OutputStreamMask", StageInfo.GS.OutputStreamMask);
    IO.mapRequired("OutputPositionPresent", StageInfo.GS.OutputPositionPresent);
    break;
  case Triple::EnvironmentType::Hull:
    IO.mapRequired("InputControlPointCount",
                   StageInfo.HS.InputControlPointCount);
    IO.mapRequired("OutputControlPointCount",
                   StageInfo.HS.OutputControlPointCount);
    IO.mapRequired("TessellatorDomain", StageInfo.HS.TessellatorDomain);
    IO.mapRequired("TessellatorOutputPrimitive",
                   StageInfo.HS.TessellatorOutputPrimitive);
    break;
  case Triple::EnvironmentType::Domain:
    IO.mapRequired("InputControlPointCount",
                   StageInfo.DS.InputControlPointCount);
    IO.mapRequired("OutputPositionPresent", StageInfo.DS.OutputPositionPresent);
    IO.mapRequired("TessellatorDomain", StageInfo.DS.TessellatorDomain);
    break;
  case Triple::EnvironmentType::Mesh:
    IO.mapRequired("GroupSharedBytesUsed", StageInfo.MS.GroupSharedBytesUsed);
    IO.mapRequired("GroupSharedBytesDependentOnViewID",
                   StageInfo.MS.GroupSharedBytesDependentOnViewID);
    IO.mapRequired("PayloadSizeInBytes", StageInfo.MS.PayloadSizeInBytes);
    IO.mapRequired("MaxOutputVertices", StageInfo.MS.MaxOutputVertices);
    IO.mapRequired("MaxOutputPrimitives", StageInfo.MS.MaxOutputPrimitives);
    break;
  case Triple::EnvironmentType::Amplification:
    IO.mapRequired("PayloadSizeInBytes", StageInfo.AS.PayloadSizeInBytes);
    break;
  default:
    break;
  }

  IO.mapRequired("MinimumWaveLaneCount", Info.MinimumWaveLaneCount);
  IO.mapRequired("MaximumWaveLaneCount", Info.MaximumWaveLaneCount);

  if (Version == 0)
    return;

  IO.mapRequired("UsesViewID", Info.UsesViewID);

  switch (Stage) {
  case Triple::EnvironmentType::Geometry:
    IO.mapRequired("MaxVertexCount", Info.GeomData.MaxVertexCount);
    break;
  case Triple::EnvironmentType::Hull:
  case Triple::EnvironmentType::Domain:
    IO.mapRequired("SigPatchConstOrPrimVectors",
                   Info.GeomData.SigPatchConstOrPrimVectors);
    break;
  case Triple::EnvironmentType::Mesh:
    IO.mapRequired("SigPrimVectors", Info.GeomData.MeshInfo.SigPrimVectors);
    IO.mapRequired("MeshOutputTopology",
                   Info.GeomData.MeshInfo.MeshOutputTopology);
    break;
  default:
    break;
  }

  IO.mapRequired("SigInputVectors", Info.SigInputVectors);
  MutableArrayRef<uint8_t> Vec(Info.SigOutputVectors);
  IO.mapRequired("SigOutputVectors", Vec);

  if (Version == 1)
    return;

  IO.mapRequired("NumThreadsX", Info.NumThreadsX);
  IO.mapRequired("NumThreadsY", Info.NumThreadsY);
  IO.mapRequired("NumThreadsZ", Info.NumThreadsZ);

  if (Version == 2)
    return;

  IO.mapRequired("EntryName", EntryName);
}

static DXContainerYAML::Signature
dumpSignature(const object::DirectX::Signature &Sig) {
  DXContainerYAML::Signature YAML;
  for (auto Param : Sig)
    YAML.Parameters.push_back(DXContainerYAML::SignatureParameter{
        Param.Stream, Sig.getName(Param.NameOffset).str(), Param.Index,
        Param.SystemValue, Param.CompType, Param.Register, Param.Mask,
        Param.ExclusiveMask, Param.MinPrecision});
  return YAML;
}

static void assign(DXContainerYAML::SourceInfo::SectionHeader &Dst,
                   const dxbc::SourceInfo::SectionHeader &Src) {
  Dst.AlignedSizeInBytes = Src.AlignedSizeInBytes;
  Dst.Flags = Src.Flags;
  Dst.Type = Src.Type;
}

Expected<std::unique_ptr<DXContainerYAML::Object>>
DXContainerYAML::fromDXContainer(object::DXContainer &Container) {
  std::unique_ptr<DXContainerYAML::Object> Obj =
      std::make_unique<DXContainerYAML::Object>();

  for (uint8_t Byte : Container.getHeader().FileHash.Digest)
    Obj->Header.Hash.push_back(Byte);
  Obj->Header.Version.Major = Container.getHeader().Version.Major;
  Obj->Header.Version.Minor = Container.getHeader().Version.Minor;
  Obj->Header.FileSize = Container.getHeader().FileSize;
  Obj->Header.PartCount = Container.getHeader().PartCount;

  Obj->Header.PartOffsets = std::vector<uint32_t>();
  for (const auto P : Container) {
    Obj->Header.PartOffsets->push_back(P.Offset);
    Obj->Parts.push_back(
        DXContainerYAML::Part(P.Part.getName().str(), P.Part.Size));
    DXContainerYAML::Part &NewPart = Obj->Parts.back();
    dxbc::PartType PT = dxbc::parsePartType(P.Part.getName());
    switch (PT) {
    case dxbc::PartType::DXIL:
    case dxbc::PartType::ILDB: {
      std::optional<object::DXContainer::DXILData> DXIL =
          Container.getDXIL(dxbc::isDebugProgramPart(PT));
      assert(DXIL && "Since we are iterating and found a DXIL/ILDB part, "
                     "this should never not have a value");
      NewPart.Program = DXContainerYAML::DXILProgram{
          DXIL->first.getMajorVersion(),
          DXIL->first.getMinorVersion(),
          DXIL->first.ShaderKind,
          DXIL->first.Size,
          DXIL->first.Bitcode.MajorVersion,
          DXIL->first.Bitcode.MinorVersion,
          DXIL->first.Bitcode.Offset,
          DXIL->first.Bitcode.Size,
          std::vector<llvm::yaml::Hex8>(
              DXIL->second, DXIL->second + DXIL->first.Bitcode.Size)};
      break;
    }
    case dxbc::PartType::ILDN: {
      std::optional<mcdxbc::DebugName> DebugName = Container.getDebugName();
      assert(DebugName && "Since we are iterating and found a ILDN part, this "
                          "should never not have a value");
      NewPart.DebugName = DXContainerYAML::DebugName{
          DebugName->Parameters.Flags, DebugName->Parameters.NameLength,
          DebugName->Filename.str()};
      break;
    }
    case dxbc::PartType::PRIV: {
      std::optional<StringRef> PrivateData = Container.getPrivateData();
      assert(PrivateData && "Since we are iterating and found a PRIV part, "
                            "this should never not have a value");
      NewPart.PrivateData.emplace(PrivateData->data(),
                                  PrivateData->data() + PrivateData->size());
      break;
    }
    case dxbc::PartType::SFI0: {
      std::optional<uint64_t> Flags = Container.getShaderFeatureFlags();
      // Omit the flags in the YAML if they are missing or zero.
      if (Flags && *Flags > 0)
        NewPart.Flags = DXContainerYAML::ShaderFeatureFlags(*Flags);
      break;
    }
    case dxbc::PartType::HASH: {
      std::optional<dxbc::ShaderHash> Hash = Container.getShaderHash();
      if (Hash && Hash->isPopulated())
        NewPart.Hash = DXContainerYAML::ShaderHash(*Hash);
      break;
    }
    case dxbc::PartType::PSV0: {
      const auto &PSVInfo = Container.getPSVInfo();
      if (!PSVInfo)
        break;
      if (const auto *P =
              std::get_if<dxbc::PSV::v0::RuntimeInfo>(&PSVInfo->getInfo())) {
        std::optional<uint16_t> ShaderKind = Container.getShaderKind();
        if (!ShaderKind)
          break;
        NewPart.Info = DXContainerYAML::PSVInfo(P, *ShaderKind);
      } else if (const auto *P = std::get_if<dxbc::PSV::v1::RuntimeInfo>(
                     &PSVInfo->getInfo()))
        NewPart.Info = DXContainerYAML::PSVInfo(P);
      else if (const auto *P =
                   std::get_if<dxbc::PSV::v2::RuntimeInfo>(&PSVInfo->getInfo()))
        NewPart.Info = DXContainerYAML::PSVInfo(P);
      else if (const auto *P =
                   std::get_if<dxbc::PSV::v3::RuntimeInfo>(&PSVInfo->getInfo()))
        NewPart.Info = DXContainerYAML::PSVInfo(P, PSVInfo->getStringTable());
      NewPart.Info->ResourceStride = PSVInfo->getResourceStride();
      NewPart.Info->RuntimeInfoSize = PSVInfo->getSize();
      if (PSVInfo->getVersion() > 0) {
        StringRef ST = PSVInfo->getStringTable();
        size_t Pos = 0;
        while (Pos < ST.size()) {
          size_t End = ST.find('\0', Pos);
          if (End == StringRef::npos)
            End = ST.size();
          if (End > Pos)
            NewPart.Info->StringTable.push_back(
                {ST.slice(Pos, End), static_cast<uint32_t>(Pos)});
          Pos = End + 1;
        }
      }
      for (auto Res : PSVInfo->getResources())
        NewPart.Info->Resources.push_back(Res);

      for (auto El : PSVInfo->getSigInputElements())
        NewPart.Info->SigInputElements.push_back(
            DXContainerYAML::SignatureElement(
                El, PSVInfo->getStringTable(),
                PSVInfo->getSemanticIndexTable()));
      for (auto El : PSVInfo->getSigOutputElements())
        NewPart.Info->SigOutputElements.push_back(
            DXContainerYAML::SignatureElement(
                El, PSVInfo->getStringTable(),
                PSVInfo->getSemanticIndexTable()));
      for (auto El : PSVInfo->getSigPatchOrPrimElements())
        NewPart.Info->SigPatchOrPrimElements.push_back(
            DXContainerYAML::SignatureElement(
                El, PSVInfo->getStringTable(),
                PSVInfo->getSemanticIndexTable()));

      if (PSVInfo->usesViewID()) {
        for (int I = 0; I < 4; ++I)
          for (auto Mask : PSVInfo->getOutputVectorMasks(I))
            NewPart.Info->OutputVectorMasks[I].push_back(Mask);
        for (auto Mask : PSVInfo->getPatchOrPrimMasks())
          NewPart.Info->PatchOrPrimMasks.push_back(Mask);
      }

      for (int I = 0; I < 4; ++I)
        for (auto Mask : PSVInfo->getInputOutputMap(I))
          NewPart.Info->InputOutputMap[I].push_back(Mask);

      for (auto Mask : PSVInfo->getInputPatchMap())
        NewPart.Info->InputPatchMap.push_back(Mask);

      for (auto Mask : PSVInfo->getPatchOutputMap())
        NewPart.Info->PatchOutputMap.push_back(Mask);

      break;
    }
    case dxbc::PartType::ISG1:
      NewPart.Signature = dumpSignature(Container.getInputSignature());
      break;
    case dxbc::PartType::OSG1:
      NewPart.Signature = dumpSignature(Container.getOutputSignature());
      break;
    case dxbc::PartType::PSG1:
      NewPart.Signature = dumpSignature(Container.getPatchConstantSignature());
      break;
    case dxbc::PartType::Unknown:
      break;
    case dxbc::PartType::RTS0: {
      std::optional<object::DirectX::RootSignature> RS =
          Container.getRootSignature();
      if (RS.has_value()) {
        auto RootSigDescOrErr =
            DXContainerYAML::RootSignatureYamlDesc::create(*RS);
        if (Error E = RootSigDescOrErr.takeError())
          return std::move(E);
        NewPart.RootSignature = RootSigDescOrErr.get();
      }
      break;
    }
    case dxbc::PartType::SRCI: {
      std::optional<mcdxbc::SourceInfo> SourceInfo = Container.getSourceInfo();
      assert(SourceInfo && "Since we are iterating and found a SRCI part, this "
                           "should never not have a value");
      auto &SourceInfoYAML = NewPart.SourceInfo.emplace();
      SourceInfoYAML.Parameters.AlignedSizeInBytes =
          SourceInfo->Parameters.AlignedSizeInBytes;
      SourceInfoYAML.Parameters.Flags = SourceInfo->Parameters.Flags;
      SourceInfoYAML.Parameters.SectionCount =
          SourceInfo->Parameters.SectionCount;

      auto &NamesYAML = SourceInfoYAML.Names;
      auto &Names = SourceInfo->Names;
      assign(NamesYAML.GenericHeader, SourceInfo->Names.GenericHeader);
      NamesYAML.Parameters.Flags = Names.Parameters.Flags;
      NamesYAML.Parameters.Count = Names.Parameters.Count;
      NamesYAML.Parameters.EntriesSizeInBytes =
          Names.Parameters.EntriesSizeInBytes;
      NamesYAML.Entries.reserve(Names.Entries.size());
      for (const auto &NameEntry : Names.Entries) {
        DXContainerYAML::SourceInfo::SourceNames::Entry NameEntryYAML;
        NameEntryYAML.AlignedSizeInBytes =
            NameEntry.Parameters.AlignedSizeInBytes;
        NameEntryYAML.Flags = NameEntry.Parameters.Flags;
        NameEntryYAML.NameSizeInBytes = NameEntry.Parameters.NameSizeInBytes;
        NameEntryYAML.ContentSizeInBytes =
            NameEntry.Parameters.ContentSizeInBytes;
        NameEntryYAML.FileName = NameEntry.FileName;
        NamesYAML.Entries.emplace_back(NameEntryYAML);
      }

      auto &ContentsYAML = SourceInfoYAML.Contents;
      auto &Contents = SourceInfo->Contents;
      assign(ContentsYAML.GenericHeader, Contents.GenericHeader);
      ContentsYAML.Parameters.AlignedSizeInBytes =
          Contents.Parameters.AlignedSizeInBytes;
      ContentsYAML.Parameters.Flags = Contents.Parameters.Flags;
      ContentsYAML.Parameters.Type = Contents.Parameters.Type;
      ContentsYAML.Parameters.EntriesSizeInBytes =
          Contents.Parameters.EntriesSizeInBytes;
      ContentsYAML.Parameters.UncompressedEntriesSizeInBytes =
          Contents.Parameters.UncompressedEntriesSizeInBytes;
      ContentsYAML.Parameters.Count = Contents.Parameters.Count;
      ContentsYAML.Entries.reserve(Contents.Entries.size());
      for (const auto &ContentEntry : Contents.Entries) {
        DXContainerYAML::SourceInfo::SourceContents::Entry ContentEntryYAML;
        ContentEntryYAML.AlignedSizeInBytes =
            ContentEntry.Parameters.AlignedSizeInBytes;
        ContentEntryYAML.Flags = ContentEntry.Parameters.Flags;
        ContentEntryYAML.ContentSizeInBytes =
            ContentEntry.Parameters.ContentSizeInBytes;
        ContentEntryYAML.FileContent = ContentEntry.FileContent;
        ContentsYAML.Entries.emplace_back(ContentEntryYAML);
      }

      auto &ArgsYAML = SourceInfoYAML.Args;
      auto &Args = SourceInfo->Args;
      assign(ArgsYAML.GenericHeader, Args.GenericHeader);
      ArgsYAML.Parameters.Flags = Args.Parameters.Flags;
      ArgsYAML.Parameters.SizeInBytes = Args.Parameters.SizeInBytes;
      ArgsYAML.Parameters.Count = Args.Parameters.Count;
      ArgsYAML.Args = Args.Args;
      break;
    }
    case dxbc::PartType::VERS: {
      std::optional<mcdxbc::CompilerVersion> Version =
          Container.getCompilerVersionInfo();
      assert(Version && "Since we are iterating and found a VERS part, this "
                        "should never not have a value");
      NewPart.CompilerVersion.emplace(DXContainerYAML::CompilerVersion{
          Version->Parameters.Major, Version->Parameters.Minor,
          !!(Version->Parameters.Flags & dxbc::CompilerVersionFlags::Debug),
          !!(Version->Parameters.Flags & dxbc::CompilerVersionFlags::Internal),
          Version->Parameters.CommitCount,
          Version->Parameters.ContentSizeInBytes, Version->CommitSha.str(),
          Version->CustomVersionString.str()});
      break;
    }
    }
  }
  return std::move(Obj);
}

} // namespace llvm
