//===- unittests/Serialization/SourceLocationEncodingTests.cpp ------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "clang/Serialization/SourceLocationEncoding.h"

#include "gtest/gtest.h"
#include <climits>
#include <optional>

using namespace llvm;
using namespace clang;

namespace {
using LocSeq = SourceLocationSequence;

// Convert a single source location into encoded form and back.
// If ExpectedEncoded is provided, verify the encoded value too.
// Loc is the raw (in-memory) form of SourceLocation.
void roundTrip(SourceLocation::UIntTy Loc,
               std::optional<uint64_t> ExpectedEncoded = std::nullopt) {
  uint64_t ActualEncoded =
      SourceLocationEncoding::encode(SourceLocation::getFromRawEncoding(Loc));
  if (ExpectedEncoded)
    ASSERT_EQ(ActualEncoded, *ExpectedEncoded) << "Encoding " << Loc;
  SourceLocation::UIntTy DecodedEncoded =
      SourceLocationEncoding::decode(ActualEncoded).getRawEncoding();
  ASSERT_EQ(DecodedEncoded, Loc) << "Decoding " << ActualEncoded;
}

// As above, but use sequence encoding for a series of locations.
void roundTrip(std::vector<SourceLocation::UIntTy> Locs,
               std::vector<uint64_t> ExpectedEncoded = {}) {
  std::vector<uint64_t> ActualEncoded;
  {
    LocSeq::State Seq;
    for (auto L : Locs)
      ActualEncoded.push_back(SourceLocationEncoding::encode(
          SourceLocation::getFromRawEncoding(L), Seq));
    if (!ExpectedEncoded.empty())
      ASSERT_EQ(ActualEncoded, ExpectedEncoded)
          << "Encoding " << testing::PrintToString(Locs);
  }
  std::vector<SourceLocation::UIntTy> DecodedEncoded;
  {
    LocSeq::State Seq;
    for (auto L : ActualEncoded) {
      SourceLocation Loc = SourceLocationEncoding::decode(L, Seq);
      DecodedEncoded.push_back(Loc.getRawEncoding());
    }
    ASSERT_EQ(DecodedEncoded, Locs)
        << "Decoding " << testing::PrintToString(ActualEncoded);
  }
}

constexpr SourceLocation::UIntTy MacroBit =
    1 << (sizeof(SourceLocation::UIntTy) * CHAR_BIT - 1);
constexpr SourceLocation::UIntTy Big = MacroBit >> 1;
constexpr SourceLocation::UIntTy Biggest = -1;

TEST(SourceLocationEncoding, Individual) {
  roundTrip(1, 2);
  roundTrip(100, 200);
  roundTrip(MacroBit, 1);
  roundTrip(MacroBit | 5, 11);
  roundTrip(Big);
  roundTrip(Big + 1);
  roundTrip(MacroBit | Big);
  roundTrip(MacroBit | Big + 1);
}

TEST(SourceLocationEncoding, Sequence) {
  roundTrip({1, 2, 3, 3, 2, 1},
            {2, // 1
             5, // +2 (+1 of non-raw)
             5, // +2
             1, // +0
             4, // -2
             4} // -2
  );
  roundTrip({100, 0, 100},
            {200, // 100
             0,   // 0
             1}   // +0
  );

  roundTrip({1, Big}, {2, ((Big - 1) << 2) + 1});
  roundTrip({2, MacroBit | Big}, {4, ((Big - 1) << 2) - 1});

  roundTrip({3, MacroBit | 5, MacroBit | 4, 3},
            {6,  // 3
             11, // +5 (+2 of non-raw + set macro bit)
             4,  // -2
             6}  // -3 (-2 of non-raw, clear macro bit)
  );

  roundTrip(
      {123 | MacroBit, 1, 9, Biggest, Big, Big + 1, 0, MacroBit | Big, 0});
}

} // namespace
