//===- CoverageExporterJson.cpp - Code coverage export --------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements export of code coverage data to JSON.
//
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
//
// The json code coverage export follows the following format
// Root: dict => Root Element containing metadata
// -- Data: array => Homogeneous array of one or more export objects
// ---- Export: dict => Json representation of one CoverageMapping
// ------ Files: array => List of objects describing coverage for files
// -------- File: dict => Coverage for a single file
// ---------- Segments: array => List of Segments contained in the file
// ------------ Segment: dict => Describes a segment of the file with a counter
// ---------- Expansions: array => List of expansion records
// ------------ Expansion: dict => Object that descibes a single expansion
// -------------- CountedRegion: dict => The region to be expanded
// -------------- TargetRegions: array => List of Regions in the expansion
// ---------------- CountedRegion: dict => Single Region in the expansion
// ---------- Summary: dict => Object summarizing the coverage for this file
// ------------ LineCoverage: dict => Object summarizing line coverage
// ------------ FunctionCoverage: dict => Object summarizing function coverage
// ------------ RegionCoverage: dict => Object summarizing region coverage
// ------ Functions: array => List of objects describing coverage for functions
// -------- Function: dict => Coverage info for a single function
// ---------- Filenames: array => List of filenames that the function relates to
// ---- Summary: dict => Object summarizing the coverage for the entire binary
// ------ LineCoverage: dict => Object summarizing line coverage
// ------ FunctionCoverage: dict => Object summarizing function coverage
// ------ InstantiationCoverage: dict => Object summarizing inst. coverage
// ------ RegionCoverage: dict => Object summarizing region coverage
//
//===----------------------------------------------------------------------===//

#include "CoverageReport.h"
#include "CoverageSummaryInfo.h"
#include "CoverageViewOptions.h"
#include "llvm/ProfileData/Coverage/CoverageMapping.h"
#include <stack>

/// \brief The semantic version combined as a string.
#define LLVM_COVERAGE_EXPORT_JSON_STR "2.0.0"

/// \brief Unique type identifier for JSON coverage export.
#define LLVM_COVERAGE_EXPORT_JSON_TYPE_STR "llvm.coverage.json.export"

using namespace llvm;
using namespace coverage;

class CoverageExporterJson {
  const CoverageViewOptions &Options;

  /// \brief Output stream to print JSON to.
  raw_ostream &OS;

  /// \brief The full CoverageMapping object to export.
  const CoverageMapping &Coverage;

  /// \brief States that the JSON rendering machine can be in.
  enum JsonState { None, NonEmptyElement, EmptyElement };

  /// \brief Tracks state of the JSON output.
  std::stack<JsonState> State;

  /// \brief Emit a serialized scalar.
  void emitSerialized(const int64_t Value) { OS << Value; }

  /// \brief Emit a serialized string.
  void emitSerialized(const std::string &Value) {
    OS << "\"";
    for (char C : Value) {
      if (C != '\\')
        OS << C;
      else
        OS << "\\\\";
    }
    OS << "\"";
  }

  /// \brief Emit a comma if there is a previous element to delimit.
  void emitComma() {
    if (State.top() == JsonState::NonEmptyElement) {
      OS << ",";
    } else if (State.top() == JsonState::EmptyElement) {
      State.pop();
      assert((State.size() >= 1) && "Closed too many JSON elements");
      State.push(JsonState::NonEmptyElement);
    }
  }

  /// \brief Emit a starting dictionary/object character.
  void emitDictStart() {
    emitComma();
    State.push(JsonState::EmptyElement);
    OS << "{";
  }

  /// \brief Emit a dictionary/object key but no value.
  void emitDictKey(const std::string &Key) {
    emitComma();
    emitSerialized(Key);
    OS << ":";
    State.pop();
    assert((State.size() >= 1) && "Closed too many JSON elements");

    // We do not want to emit a comma after this key.
    State.push(JsonState::EmptyElement);
  }

  /// \brief Emit a dictionary/object key/value pair.
  template <typename V>
  void emitDictElement(const std::string &Key, const V &Value) {
    emitComma();
    emitSerialized(Key);
    OS << ":";
    emitSerialized(Value);
  }

  /// \brief Emit a closing dictionary/object character.
  void emitDictEnd() {
    State.pop();
    assert((State.size() >= 1) && "Closed too many JSON elements");
    OS << "}";
  }

  /// \brief Emit a starting array character.
  void emitArrayStart() {
    emitComma();
    State.push(JsonState::EmptyElement);
    OS << "[";
  }

  /// \brief Emit an array element.
  template <typename V> void emitArrayElement(const V &Value) {
    emitComma();
    emitSerialized(Value);
  }

  /// \brief emit a closing array character.
  void emitArrayEnd() {
    State.pop();
    assert((State.size() >= 1) && "Closed too many JSON elements");
    OS << "]";
  }

  /// \brief Render the CoverageMapping object.
  void renderRoot() {
    // Start Root of JSON object.
    emitDictStart();

    emitDictElement("version", LLVM_COVERAGE_EXPORT_JSON_STR);
    emitDictElement("type", LLVM_COVERAGE_EXPORT_JSON_TYPE_STR);
    emitDictKey("data");

    // Start List of Exports.
    emitArrayStart();

    // Start Export.
    emitDictStart();

    emitDictKey("files");

    FileCoverageSummary Totals = FileCoverageSummary("Totals");
    std::vector<std::string> SourceFiles;
    for (StringRef SF : Coverage.getUniqueSourceFiles())
      SourceFiles.emplace_back(SF);
    auto FileReports = CoverageReport::prepareFileReports(Coverage, Totals,
                                                          SourceFiles, Options);
    renderFiles(SourceFiles, FileReports);

    emitDictKey("functions");
    renderFunctions(Coverage.getCoveredFunctions());

    emitDictKey("totals");
    renderSummary(Totals);

    // End Export.
    emitDictEnd();

    // End List of Exports.
    emitArrayEnd();

    // End Root of JSON Object.
    emitDictEnd();

    assert((State.top() == JsonState::None) &&
           "All Elements In JSON were Closed");
  }

  /// \brief Render an array of all the given functions.
  void
  renderFunctions(const iterator_range<FunctionRecordIterator> &Functions) {
    // Start List of Functions.
    emitArrayStart();

    for (const auto &Function : Functions) {
      // Start Function.
      emitDictStart();

      emitDictElement("name", Function.Name);
      emitDictElement("count", Function.ExecutionCount);
      emitDictKey("regions");

      renderRegions(Function.CountedRegions);

      emitDictKey("filenames");

      // Start Filenames for Function.
      emitArrayStart();

      for (const auto &FileName : Function.Filenames)
        emitArrayElement(FileName);

      // End Filenames for Function.
      emitArrayEnd();

      // End Function.
      emitDictEnd();
    }

    // End List of Functions.
    emitArrayEnd();
  }

  /// \brief Render an array of all the source files, also pass back a Summary.
  void renderFiles(ArrayRef<std::string> SourceFiles,
                   ArrayRef<FileCoverageSummary> FileReports) {
    // Start List of Files.
    emitArrayStart();

    for (unsigned I = 0, E = SourceFiles.size(); I < E; ++I) {
      // Render the file.
      auto FileCoverage = Coverage.getCoverageForFile(SourceFiles[I]);
      renderFile(FileCoverage, FileReports[I]);
    }

    // End List of Files.
    emitArrayEnd();
  }

  /// \brief Render a single file.
  void renderFile(const CoverageData &FileCoverage,
                  const FileCoverageSummary &FileReport) {
    // Start File.
    emitDictStart();

    emitDictElement("filename", FileCoverage.getFilename());
    emitDictKey("segments");

    // Start List of Segments.
    emitArrayStart();

    for (const auto &Segment : FileCoverage)
      renderSegment(Segment);

    // End List of Segments.
    emitArrayEnd();

    emitDictKey("expansions");

    // Start List of Expansions.
    emitArrayStart();

    for (const auto &Expansion : FileCoverage.getExpansions())
      renderExpansion(Expansion);

    // End List of Expansions.
    emitArrayEnd();

    emitDictKey("summary");
    renderSummary(FileReport);

    // End File.
    emitDictEnd();
  }

  /// \brief Render a CoverageSegment.
  void renderSegment(const CoverageSegment &Segment) {
    // Start Segment.
    emitArrayStart();

    emitArrayElement(Segment.Line);
    emitArrayElement(Segment.Col);
    emitArrayElement(Segment.Count);
    emitArrayElement(Segment.HasCount);
    emitArrayElement(Segment.IsRegionEntry);

    // End Segment.
    emitArrayEnd();
  }

  /// \brief Render an ExpansionRecord.
  void renderExpansion(const ExpansionRecord &Expansion) {
    // Start Expansion.
    emitDictStart();

    // Mark the beginning and end of this expansion in the source file.
    emitDictKey("source_region");
    renderRegion(Expansion.Region);

    // Enumerate the coverage information for the expansion.
    emitDictKey("target_regions");
    renderRegions(Expansion.Function.CountedRegions);

    emitDictKey("filenames");
    // Start List of Filenames to map the fileIDs.
    emitArrayStart();
    for (const auto &Filename : Expansion.Function.Filenames)
      emitArrayElement(Filename);
    // End List of Filenames.
    emitArrayEnd();

    // End Expansion.
    emitDictEnd();
  }

  /// \brief Render a list of CountedRegions.
  void renderRegions(ArrayRef<CountedRegion> Regions) {
    // Start List of Regions.
    emitArrayStart();

    for (const auto &Region : Regions)
      renderRegion(Region);

    // End List of Regions.
    emitArrayEnd();
  }

  /// \brief Render a single CountedRegion.
  void renderRegion(const CountedRegion &Region) {
    // Start CountedRegion.
    emitArrayStart();

    emitArrayElement(Region.LineStart);
    emitArrayElement(Region.ColumnStart);
    emitArrayElement(Region.LineEnd);
    emitArrayElement(Region.ColumnEnd);
    emitArrayElement(Region.ExecutionCount);
    emitArrayElement(Region.FileID);
    emitArrayElement(Region.ExpandedFileID);
    emitArrayElement(Region.Kind);

    // End CountedRegion.
    emitArrayEnd();
  }

  /// \brief Render a FileCoverageSummary.
  void renderSummary(const FileCoverageSummary &Summary) {
    // Start Summary for the file.
    emitDictStart();

    emitDictKey("lines");

    // Start Line Coverage Summary.
    emitDictStart();
    emitDictElement("count", Summary.LineCoverage.getNumLines());
    emitDictElement("covered", Summary.LineCoverage.getCovered());
    emitDictElement("percent", Summary.LineCoverage.getPercentCovered());
    // End Line Coverage Summary.
    emitDictEnd();

    emitDictKey("functions");

    // Start Function Coverage Summary.
    emitDictStart();
    emitDictElement("count", Summary.FunctionCoverage.getNumFunctions());
    emitDictElement("covered", Summary.FunctionCoverage.getExecuted());
    emitDictElement("percent", Summary.FunctionCoverage.getPercentCovered());
    // End Function Coverage Summary.
    emitDictEnd();

    emitDictKey("instantiations");

    // Start Instantiation Coverage Summary.
    emitDictStart();
    emitDictElement("count", Summary.InstantiationCoverage.getNumFunctions());
    emitDictElement("covered", Summary.InstantiationCoverage.getExecuted());
    emitDictElement("percent",
                    Summary.InstantiationCoverage.getPercentCovered());
    // End Function Coverage Summary.
    emitDictEnd();

    emitDictKey("regions");

    // Start Region Coverage Summary.
    emitDictStart();
    emitDictElement("count", Summary.RegionCoverage.getNumRegions());
    emitDictElement("covered", Summary.RegionCoverage.getCovered());
    emitDictElement("notcovered",
                    Summary.RegionCoverage.getNumRegions() -
                        Summary.RegionCoverage.getCovered());
    emitDictElement("percent", Summary.RegionCoverage.getPercentCovered());
    // End Region Coverage Summary.
    emitDictEnd();

    // End Summary for the file.
    emitDictEnd();
  }

public:
  CoverageExporterJson(const CoverageMapping &CoverageMapping,
                       const CoverageViewOptions &Options, raw_ostream &OS)
      : Options(Options), OS(OS), Coverage(CoverageMapping) {
    State.push(JsonState::None);
  }

  /// \brief Print the CoverageMapping.
  void print() { renderRoot(); }
};

/// \brief Export the given CoverageMapping to a JSON Format.
void exportCoverageDataToJson(const CoverageMapping &CoverageMapping,
                              const CoverageViewOptions &Options,
                              raw_ostream &OS) {
  auto Exporter = CoverageExporterJson(CoverageMapping, Options, OS);

  Exporter.print();
}
