/* SARIF output for diagnostics
   Copyright (C) 2018-2022 Free Software Foundation, Inc.
   Contributed by David Malcolm <dmalcolm@redhat.com>.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */


#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "diagnostic.h"
#include "diagnostic-metadata.h"
#include "diagnostic-path.h"
#include "json.h"
#include "cpplib.h"
#include "logical-location.h"
#include "diagnostic-client-data-hooks.h"

class sarif_builder;

/* Subclass of json::object for SARIF result objects
   (SARIF v2.1.0 section 3.27.  */

class sarif_result : public json::object
{
public:
  sarif_result () : m_related_locations_arr (NULL) {}

  void
  on_nested_diagnostic (diagnostic_context *context,
			diagnostic_info *diagnostic,
			diagnostic_t orig_diag_kind,
			sarif_builder *builder);

private:
  json::array *m_related_locations_arr;
};

/* A class for managing SARIF output (for -fdiagnostics-format=sarif-stderr
   and -fdiagnostics-format=sarif-file).

   As diagnostics occur, we build "result" JSON objects, and
   accumulate state:
   - which source files are referenced
   - which warnings are emitted
   - which CWEs are used

   At the end of the compile, we use the above to build the full SARIF
   object tree, adding the result objects to the correct place, and
   creating objects for the various source files, warnings and CWEs
   referenced.

   Implemented:
   - fix-it hints
   - CWE metadata
   - diagnostic groups (see limitations below)
   - logical locations (e.g. cfun)

   Known limitations:
   - GCC supports one-deep nesting of diagnostics (via auto_diagnostic_group),
     but we only capture location and message information from such nested
     diagnostics (e.g. we ignore fix-it hints on them)
   - doesn't yet capture command-line arguments: would be run.invocations
     property (SARIF v2.1.0 section 3.14.11), as invocation objects
     (SARIF v2.1.0 section 3.20), but we'd want to capture the arguments to
     toplev::main, and the response files.
   - doesn't capture escape_on_output_p
   - doesn't capture secondary locations within a rich_location
     (perhaps we should use the "relatedLocations" property: SARIF v2.1.0
     section 3.27.22)
   - doesn't capture "artifact.encoding" property
     (SARIF v2.1.0 section 3.24.9).
   - doesn't capture hashes of the source files
     ("artifact.hashes" property (SARIF v2.1.0 section 3.24.11).
   - doesn't capture the "analysisTarget" property
     (SARIF v2.1.0 section 3.27.13).
   - doesn't capture labelled ranges
   - doesn't capture -Werror cleanly
   - doesn't capture inlining information (can SARIF handle this?)
   - doesn't capture macro expansion information (can SARIF handle this?).  */

class sarif_builder
{
public:
  sarif_builder (diagnostic_context *context);

  void end_diagnostic (diagnostic_context *context, diagnostic_info *diagnostic,
		       diagnostic_t orig_diag_kind);

  void end_group ();

  void flush_to_file (FILE *outf);

  json::object *make_location_object (const rich_location &rich_loc,
				      const logical_location *logical_loc);
  json::object *make_message_object (const char *msg) const;

private:
  sarif_result *make_result_object (diagnostic_context *context,
				    diagnostic_info *diagnostic,
				    diagnostic_t orig_diag_kind);
  void set_any_logical_locs_arr (json::object *location_obj,
				 const logical_location *logical_loc);
  json::object *make_location_object (const diagnostic_event &event);
  json::object *
  make_logical_location_object (const logical_location &logical_loc) const;
  json::object *make_code_flow_object (const diagnostic_path &path);
  json::object *make_thread_flow_object (const diagnostic_path &path);
  json::object *
  make_thread_flow_location_object (const diagnostic_event &event);
  json::array *maybe_make_kinds_array (diagnostic_event::meaning m) const;
  json::object *maybe_make_physical_location_object (location_t loc);
  json::object *make_artifact_location_object (location_t loc);
  json::object *make_artifact_location_object (const char *filename);
  json::object *make_artifact_location_object_for_pwd () const;
  json::object *maybe_make_region_object (location_t loc) const;
  json::object *maybe_make_region_object_for_context (location_t loc) const;
  json::object *make_region_object_for_hint (const fixit_hint &hint) const;
  json::object *make_multiformat_message_string (const char *msg) const;
  json::object *make_top_level_object (json::array *results);
  json::object *make_run_object (json::array *results);
  json::object *make_tool_object () const;
  json::object *make_driver_tool_component_object () const;
  json::array *maybe_make_taxonomies_array () const;
  json::object *maybe_make_cwe_taxonomy_object () const;
  json::object *make_tool_component_reference_object_for_cwe () const;
  json::object *
  make_reporting_descriptor_object_for_warning (diagnostic_context *context,
						diagnostic_info *diagnostic,
						diagnostic_t orig_diag_kind,
						const char *option_text);
  json::object *make_reporting_descriptor_object_for_cwe_id (int cwe_id) const;
  json::object *
  make_reporting_descriptor_reference_object_for_cwe_id (int cwe_id);
  json::object *make_artifact_object (const char *filename);
  json::object *maybe_make_artifact_content_object (const char *filename) const;
  json::object *maybe_make_artifact_content_object (const char *filename,
						    int start_line,
						    int end_line) const;
  json::object *make_fix_object (const rich_location &rich_loc);
  json::object *make_artifact_change_object (const rich_location &richloc);
  json::object *make_replacement_object (const fixit_hint &hint) const;
  json::object *make_artifact_content_object (const char *text) const;
  int get_sarif_column (expanded_location exploc) const;

  diagnostic_context *m_context;

  /* The JSON array of pending diagnostics.  */
  json::array *m_results_array;

  /* The JSON object for the result object (if any) in the current
     diagnostic group.  */
  sarif_result *m_cur_group_result;

  hash_set <const char *> m_filenames;
  bool m_seen_any_relative_paths;
  hash_set <free_string_hash> m_rule_id_set;
  json::array *m_rules_arr;

  /* The set of all CWE IDs we've seen, if any.  */
  hash_set <int_hash <int, 0, 1> > m_cwe_id_set;

  int m_tabstop;
};

static sarif_builder *the_builder;

/* class sarif_result : public json::object.  */

/* Handle secondary diagnostics that occur within a diagnostic group.
   The closest SARIF seems to have to nested diagnostics is the
   "relatedLocations" property of result objects (SARIF v2.1.0 section 3.27.22),
   so we lazily set this property and populate the array if and when
   secondary diagnostics occur (such as notes to a warning).  */

void
sarif_result::on_nested_diagnostic (diagnostic_context *context,
				    diagnostic_info *diagnostic,
				    diagnostic_t /*orig_diag_kind*/,
				    sarif_builder *builder)
{
  if (!m_related_locations_arr)
    {
      m_related_locations_arr = new json::array ();
      set ("relatedLocations", m_related_locations_arr);
    }

  /* We don't yet generate meaningful logical locations for notes;
     sometimes these will related to current_function_decl, but
     often they won't.  */
  json::object *location_obj
    = builder->make_location_object (*diagnostic->richloc, NULL);
  json::object *message_obj
    = builder->make_message_object (pp_formatted_text (context->printer));
  pp_clear_output_area (context->printer);
  location_obj->set ("message", message_obj);

  m_related_locations_arr->append (location_obj);
}

/* class sarif_builder.  */

/* sarif_builder's ctor.  */

sarif_builder::sarif_builder (diagnostic_context *context)
: m_context (context),
  m_results_array (new json::array ()),
  m_cur_group_result (NULL),
  m_seen_any_relative_paths (false),
  m_rule_id_set (),
  m_rules_arr (new json::array ()),
  m_tabstop (context->tabstop)
{
}

/* Implementation of "end_diagnostic" for SARIF output.  */

void
sarif_builder::end_diagnostic (diagnostic_context *context,
			       diagnostic_info *diagnostic,
			       diagnostic_t orig_diag_kind)
{

  if (m_cur_group_result)
    /* Nested diagnostic.  */
    m_cur_group_result->on_nested_diagnostic (context,
					      diagnostic,
					      orig_diag_kind,
					      this);
  else
    {
      /* Top-level diagnostic.  */
      sarif_result *result_obj
	= make_result_object (context, diagnostic, orig_diag_kind);
      m_results_array->append (result_obj);
      m_cur_group_result = result_obj;
    }
}

/* Implementation of "end_group_cb" for SARIF output.  */

void
sarif_builder::end_group ()
{
  m_cur_group_result = NULL;
}

/* Create a top-level object, and add it to all the results
   (and other entities) we've seen so far.

   Flush it all to OUTF.  */

void
sarif_builder::flush_to_file (FILE *outf)
{
  json::object *top = make_top_level_object (m_results_array);
  top->dump (outf);
  m_results_array = NULL;
  fprintf (outf, "\n");
  delete top;
}

/* Attempt to convert DIAG_KIND to a suitable value for the "level"
   property (SARIF v2.1.0 section 3.27.10).

   Return NULL if there isn't one.  */

static const char *
maybe_get_sarif_level (diagnostic_t diag_kind)
{
  switch (diag_kind)
    {
    case DK_WARNING:
      return "warning";
    case DK_ERROR:
      return "error";
    case DK_NOTE:
    case DK_ANACHRONISM:
      return "note";
    default:
      return NULL;
    }
}

/* Make a string for DIAG_KIND suitable for use a ruleId
   (SARIF v2.1.0 section 3.27.5) as a fallback for when we don't
   have anything better to use.  */

static char *
make_rule_id_for_diagnostic_kind (diagnostic_t diag_kind)
{
  static const char *const diagnostic_kind_text[] = {
#define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
#include "diagnostic.def"
#undef DEFINE_DIAGNOSTIC_KIND
    "must-not-happen"
  };
  /* Lose the trailing ": ".  */
  const char *kind_text = diagnostic_kind_text[diag_kind];
  size_t len = strlen (kind_text);
  gcc_assert (len > 2);
  gcc_assert (kind_text[len - 2] == ':');
  gcc_assert (kind_text[len - 1] == ' ');
  char *rstrip = xstrdup (kind_text);
  rstrip[len - 2] = '\0';
  return rstrip;
}

/* Make a result object (SARIF v2.1.0 section 3.27) for DIAGNOSTIC.  */

sarif_result *
sarif_builder::make_result_object (diagnostic_context *context,
				   diagnostic_info *diagnostic,
				   diagnostic_t orig_diag_kind)
{
  sarif_result *result_obj = new sarif_result ();

  /* "ruleId" property (SARIF v2.1.0 section 3.27.5).  */
  /* Ideally we'd have an option_name for these.  */
  if (char *option_text
	= context->option_name (context, diagnostic->option_index,
				orig_diag_kind, diagnostic->kind))
    {
      /* Lazily create reportingDescriptor objects for and add to m_rules_arr.
	 Set ruleId referencing them.  */
      result_obj->set ("ruleId", new json::string (option_text));
      if (m_rule_id_set.contains (option_text))
	free (option_text);
      else
	{
	  /* This is the first time we've seen this ruleId.  */
	  /* Add to set, taking ownership.  */
	  m_rule_id_set.add (option_text);

	  json::object *reporting_desc_obj
	    = make_reporting_descriptor_object_for_warning (context,
							    diagnostic,
							    orig_diag_kind,
							    option_text);
	  m_rules_arr->append (reporting_desc_obj);
	}
    }
  else
    {
      /* Otherwise, we have an "error" or a stray "note"; use the
	 diagnostic kind as the ruleId, so that the result object at least
	 has a ruleId.
	 We don't bother creating reportingDescriptor objects for these.  */
      char *rule_id = make_rule_id_for_diagnostic_kind (orig_diag_kind);
      result_obj->set ("ruleId", new json::string (rule_id));
      free (rule_id);
    }

  /* "taxa" property (SARIF v2.1.0 section 3.27.8).  */
  if (diagnostic->metadata)
    if (int cwe_id = diagnostic->metadata->get_cwe ())
      {
	json::array *taxa_arr = new json::array ();
	json::object *cwe_id_obj
	  = make_reporting_descriptor_reference_object_for_cwe_id (cwe_id);
	taxa_arr->append (cwe_id_obj);
	result_obj->set ("taxa", taxa_arr);
      }

  /* "level" property (SARIF v2.1.0 section 3.27.10).  */
  if (const char *sarif_level = maybe_get_sarif_level (diagnostic->kind))
    result_obj->set ("level", new json::string (sarif_level));

  /* "message" property (SARIF v2.1.0 section 3.27.11).  */
  json::object *message_obj
    = make_message_object (pp_formatted_text (context->printer));
  pp_clear_output_area (context->printer);
  result_obj->set ("message", message_obj);

  /* "locations" property (SARIF v2.1.0 section 3.27.12).  */
  json::array *locations_arr = new json::array ();
  const logical_location *logical_loc = NULL;
  if (m_context->m_client_data_hooks)
    logical_loc
      = m_context->m_client_data_hooks->get_current_logical_location ();

  json::object *location_obj
    = make_location_object (*diagnostic->richloc, logical_loc);
  locations_arr->append (location_obj);
  result_obj->set ("locations", locations_arr);

  /* "codeFlows" property (SARIF v2.1.0 section 3.27.18).  */
  if (const diagnostic_path *path = diagnostic->richloc->get_path ())
    {
      json::array *code_flows_arr = new json::array ();
      json::object *code_flow_obj = make_code_flow_object (*path);
      code_flows_arr->append (code_flow_obj);
      result_obj->set ("codeFlows", code_flows_arr);
    }

  /* The "relatedLocations" property (SARIF v2.1.0 section 3.27.22) is
     set up later, if any nested diagnostics occur within this diagnostic
     group.  */

  /* "fixes" property (SARIF v2.1.0 section 3.27.30).  */
  const rich_location *richloc = diagnostic->richloc;
  if (richloc->get_num_fixit_hints ())
    {
      json::array *fix_arr = new json::array ();
      json::object *fix_obj = make_fix_object (*richloc);
      fix_arr->append (fix_obj);
      result_obj->set ("fixes", fix_arr);
    }

  return result_obj;
}

/* Make a reportingDescriptor object (SARIF v2.1.0 section 3.49)
   for a GCC warning.  */

json::object *
sarif_builder::
make_reporting_descriptor_object_for_warning (diagnostic_context *context,
					      diagnostic_info *diagnostic,
					      diagnostic_t /*orig_diag_kind*/,
					      const char *option_text)
{
  json::object *reporting_desc = new json::object ();

  /* "id" property (SARIF v2.1.0 section 3.49.3).  */
  reporting_desc->set ("id", new json::string (option_text));

  /* We don't implement "name" property (SARIF v2.1.0 section 3.49.7), since
     it seems redundant compared to "id".  */

  /* "helpUri" property (SARIF v2.1.0 section 3.49.12).  */
  if (context->get_option_url)
    {
      char *option_url
	= context->get_option_url (context, diagnostic->option_index);
      if (option_url)
	{
	  reporting_desc->set ("helpUri", new json::string (option_url));
	  free (option_url);
	}
    }

  return reporting_desc;
}

/* Make a reportingDescriptor object (SARIF v2.1.0 section 3.49)
   for CWE_ID, for use within the CWE taxa array.  */

json::object *
sarif_builder::make_reporting_descriptor_object_for_cwe_id (int cwe_id) const
{
  json::object *reporting_desc = new json::object ();

  /* "id" property (SARIF v2.1.0 section 3.49.3).  */
  {
    pretty_printer pp;
    pp_printf (&pp, "%i", cwe_id);
    reporting_desc->set ("id", new json::string (pp_formatted_text (&pp)));
  }

  /* "helpUri" property (SARIF v2.1.0 section 3.49.12).  */
  {
    char *url = get_cwe_url (cwe_id);
    reporting_desc->set ("helpUri", new json::string (url));
    free (url);
  }

  return reporting_desc;
}

/* Make a reportingDescriptorReference object (SARIF v2.1.0 section 3.52)
   referencing CWE_ID, for use within a result object.
   Also, add CWE_ID to m_cwe_id_set.  */

json::object *
sarif_builder::
make_reporting_descriptor_reference_object_for_cwe_id (int cwe_id)
{
  json::object *desc_ref_obj = new json::object ();

  /* "id" property (SARIF v2.1.0 section 3.52.4).  */
  {
    pretty_printer pp;
    pp_printf (&pp, "%i", cwe_id);
    desc_ref_obj->set ("id", new json::string (pp_formatted_text (&pp)));
  }

  /* "toolComponent" property (SARIF v2.1.0 section 3.52.7).  */
  json::object *comp_ref_obj = make_tool_component_reference_object_for_cwe ();
  desc_ref_obj->set ("toolComponent", comp_ref_obj);

  /* Add CWE_ID to our set.  */
  gcc_assert (cwe_id > 0);
  m_cwe_id_set.add (cwe_id);

  return desc_ref_obj;
}

/* Make a toolComponentReference object (SARIF v2.1.0 section 3.54) that
   references the CWE taxonomy.  */

json::object *
sarif_builder::
make_tool_component_reference_object_for_cwe () const
{
  json::object *comp_ref_obj = new json::object ();

  /* "name" property  (SARIF v2.1.0 section 3.54.3).  */
  comp_ref_obj->set ("name", new json::string ("cwe"));

  return comp_ref_obj;
}

/* If LOGICAL_LOC is non-NULL, use it to create a "logicalLocations" property
   within LOCATION_OBJ (SARIF v2.1.0 section 3.28.4).  */

void
sarif_builder::
set_any_logical_locs_arr (json::object *location_obj,
			  const logical_location *logical_loc)
{
  if (!logical_loc)
    return;
  json::object *logical_loc_obj = make_logical_location_object (*logical_loc);
  json::array *location_locs_arr = new json::array ();
  location_locs_arr->append (logical_loc_obj);
  location_obj->set ("logicalLocations", location_locs_arr);
}

/* Make a location object (SARIF v2.1.0 section 3.28) for RICH_LOC
   and LOGICAL_LOC.  */

json::object *
sarif_builder::make_location_object (const rich_location &rich_loc,
				     const logical_location *logical_loc)
{
  json::object *location_obj = new json::object ();

  /* Get primary loc from RICH_LOC.  */
  location_t loc = rich_loc.get_loc ();

  /* "physicalLocation" property (SARIF v2.1.0 section 3.28.3).  */
  if (json::object *phs_loc_obj = maybe_make_physical_location_object (loc))
    location_obj->set ("physicalLocation", phs_loc_obj);

  /* "logicalLocations" property (SARIF v2.1.0 section 3.28.4).  */
  set_any_logical_locs_arr (location_obj, logical_loc);

  return location_obj;
}

/* Make a location object (SARIF v2.1.0 section 3.28) for EVENT
   within a diagnostic_path.  */

json::object *
sarif_builder::make_location_object (const diagnostic_event &event)
{
  json::object *location_obj = new json::object ();

  /* "physicalLocation" property (SARIF v2.1.0 section 3.28.3).  */
  location_t loc = event.get_location ();
  if (json::object *phs_loc_obj = maybe_make_physical_location_object (loc))
    location_obj->set ("physicalLocation", phs_loc_obj);

  /* "logicalLocations" property (SARIF v2.1.0 section 3.28.4).  */
  const logical_location *logical_loc = event.get_logical_location ();
  set_any_logical_locs_arr (location_obj, logical_loc);

  /* "message" property (SARIF v2.1.0 section 3.28.5).  */
  label_text ev_desc = event.get_desc (false);
  json::object *message_obj = make_message_object (ev_desc.get ());
  location_obj->set ("message", message_obj);

  return location_obj;
}

/* Make a physicalLocation object (SARIF v2.1.0 section 3.29) for LOC,
   or return NULL;
   Add any filename to the m_artifacts.  */

json::object *
sarif_builder::maybe_make_physical_location_object (location_t loc)
{
  if (loc <= BUILTINS_LOCATION || LOCATION_FILE (loc) == NULL)
    return NULL;

  json::object *phys_loc_obj = new json::object ();

  /* "artifactLocation" property (SARIF v2.1.0 section 3.29.3).  */
  json::object *artifact_loc_obj = make_artifact_location_object (loc);
  phys_loc_obj->set ("artifactLocation", artifact_loc_obj);
  m_filenames.add (LOCATION_FILE (loc));

  /* "region" property (SARIF v2.1.0 section 3.29.4).  */
  if (json::object *region_obj = maybe_make_region_object (loc))
    phys_loc_obj->set ("region", region_obj);

  /* "contextRegion" property (SARIF v2.1.0 section 3.29.5).  */
  if (json::object *context_region_obj
	= maybe_make_region_object_for_context (loc))
    phys_loc_obj->set ("contextRegion", context_region_obj);

  /* Instead, we add artifacts to the run as a whole,
     with artifact.contents.
     Could do both, though.  */

  return phys_loc_obj;
}

/* Make an artifactLocation object (SARIF v2.1.0 section 3.4) for LOC,
   or return NULL.  */

json::object *
sarif_builder::make_artifact_location_object (location_t loc)
{
  return make_artifact_location_object (LOCATION_FILE (loc));
}

/* The ID value for use in "uriBaseId" properties (SARIF v2.1.0 section 3.4.4)
   for when we need to express paths relative to PWD.  */

#define PWD_PROPERTY_NAME ("PWD")

/* Make an artifactLocation object (SARIF v2.1.0 section 3.4) for FILENAME,
   or return NULL.  */

json::object *
sarif_builder::make_artifact_location_object (const char *filename)
{
  json::object *artifact_loc_obj = new json::object ();

  /* "uri" property (SARIF v2.1.0 section 3.4.3).  */
  artifact_loc_obj->set ("uri", new json::string (filename));

  if (filename[0] != '/')
    {
      /* If we have a relative path, set the "uriBaseId" property
	 (SARIF v2.1.0 section 3.4.4).  */
      artifact_loc_obj->set ("uriBaseId", new json::string (PWD_PROPERTY_NAME));
      m_seen_any_relative_paths = true;
    }

  return artifact_loc_obj;
}

/* Get the PWD, or NULL, as an absolute file-based URI,
   adding a trailing forward slash (as required by SARIF v2.1.0
   section 3.14.14).  */

static char *
make_pwd_uri_str ()
{
  /* The prefix of a file-based URI, up to, but not including the path. */
#define FILE_PREFIX ("file://")

  const char *pwd = getpwd ();
  if (!pwd)
    return NULL;
  size_t len = strlen (pwd);
  if (len == 0 || pwd[len - 1] != '/')
    return concat (FILE_PREFIX, pwd, "/", NULL);
  else
    {
      gcc_assert (pwd[len - 1] == '/');
      return concat (FILE_PREFIX, pwd, NULL);
    }
}

/* Make an artifactLocation object (SARIF v2.1.0 section 3.4) for the pwd,
   for use in the "run.originalUriBaseIds" property (SARIF v2.1.0
   section 3.14.14) when we have any relative paths.  */

json::object *
sarif_builder::make_artifact_location_object_for_pwd () const
{
  json::object *artifact_loc_obj = new json::object ();

  /* "uri" property (SARIF v2.1.0 section 3.4.3).  */
  if (char *pwd = make_pwd_uri_str ())
    {
      gcc_assert (strlen (pwd) > 0);
      gcc_assert (pwd[strlen (pwd) - 1] == '/');
      artifact_loc_obj->set ("uri", new json::string (pwd));
      free (pwd);
    }

  return artifact_loc_obj;
}

/* Get the column number within EXPLOC.  */

int
sarif_builder::get_sarif_column (expanded_location exploc) const
{
  cpp_char_column_policy policy (m_tabstop, cpp_wcwidth);
  return location_compute_display_column (exploc, policy);
}

/* Make a region object (SARIF v2.1.0 section 3.30) for LOC,
   or return NULL.  */

json::object *
sarif_builder::maybe_make_region_object (location_t loc) const
{
  location_t caret_loc = get_pure_location (loc);

  if (caret_loc <= BUILTINS_LOCATION)
    return NULL;

  location_t start_loc = get_start (loc);
  location_t finish_loc = get_finish (loc);

  expanded_location exploc_caret = expand_location (caret_loc);
  expanded_location exploc_start = expand_location (start_loc);
  expanded_location exploc_finish = expand_location (finish_loc);

  if (exploc_start.file !=exploc_caret.file)
    return NULL;
  if (exploc_finish.file !=exploc_caret.file)
    return NULL;

  json::object *region_obj = new json::object ();

  /* "startLine" property (SARIF v2.1.0 section 3.30.5) */
  region_obj->set ("startLine", new json::integer_number (exploc_start.line));

  /* "startColumn" property (SARIF v2.1.0 section 3.30.6) */
  region_obj->set ("startColumn",
		   new json::integer_number (get_sarif_column (exploc_start)));

  /* "endLine" property (SARIF v2.1.0 section 3.30.7) */
  if (exploc_finish.line != exploc_start.line)
    region_obj->set ("endLine", new json::integer_number (exploc_finish.line));

  /* "endColumn" property (SARIF v2.1.0 section 3.30.8).
     This expresses the column immediately beyond the range.  */
  {
    int next_column = sarif_builder::get_sarif_column (exploc_finish) + 1;
    region_obj->set ("endColumn", new json::integer_number (next_column));
  }

  return region_obj;
}

/* Make a region object (SARIF v2.1.0 section 3.30) for the "contextRegion"
   property (SARIF v2.1.0 section 3.29.5) of a physicalLocation.

   This is similar to maybe_make_region_object, but ignores column numbers,
   covering the line(s) as a whole, and including a "snippet" property
   embedding those source lines, making it easier for consumers to show
   the pertinent source.  */

json::object *
sarif_builder::maybe_make_region_object_for_context (location_t loc) const
{
  location_t caret_loc = get_pure_location (loc);

  if (caret_loc <= BUILTINS_LOCATION)
    return NULL;

  location_t start_loc = get_start (loc);
  location_t finish_loc = get_finish (loc);

  expanded_location exploc_caret = expand_location (caret_loc);
  expanded_location exploc_start = expand_location (start_loc);
  expanded_location exploc_finish = expand_location (finish_loc);

  if (exploc_start.file !=exploc_caret.file)
    return NULL;
  if (exploc_finish.file !=exploc_caret.file)
    return NULL;

  json::object *region_obj = new json::object ();

  /* "startLine" property (SARIF v2.1.0 section 3.30.5) */
  region_obj->set ("startLine", new json::integer_number (exploc_start.line));

  /* "endLine" property (SARIF v2.1.0 section 3.30.7) */
  if (exploc_finish.line != exploc_start.line)
    region_obj->set ("endLine", new json::integer_number (exploc_finish.line));

  /* "snippet" property (SARIF v2.1.0 section 3.30.13).  */
  if (json::object *artifact_content_obj
	 = maybe_make_artifact_content_object (exploc_start.file,
					       exploc_start.line,
					       exploc_finish.line))
    region_obj->set ("snippet", artifact_content_obj);

  return region_obj;
}

/* Make a region object (SARIF v2.1.0 section 3.30) for the deletion region
   of HINT (as per SARIF v2.1.0 section 3.57.3).  */

json::object *
sarif_builder::make_region_object_for_hint (const fixit_hint &hint) const
{
  location_t start_loc = hint.get_start_loc ();
  location_t next_loc = hint.get_next_loc ();

  expanded_location exploc_start = expand_location (start_loc);
  expanded_location exploc_next = expand_location (next_loc);

  json::object *region_obj = new json::object ();

  /* "startLine" property (SARIF v2.1.0 section 3.30.5) */
  region_obj->set ("startLine", new json::integer_number (exploc_start.line));

  /* "startColumn" property (SARIF v2.1.0 section 3.30.6) */
  int start_col = get_sarif_column (exploc_start);
  region_obj->set ("startColumn",
		   new json::integer_number (start_col));

  /* "endLine" property (SARIF v2.1.0 section 3.30.7) */
  if (exploc_next.line != exploc_start.line)
    region_obj->set ("endLine", new json::integer_number (exploc_next.line));

  /* "endColumn" property (SARIF v2.1.0 section 3.30.8).
     This expresses the column immediately beyond the range.  */
  int next_col =  get_sarif_column (exploc_next);
  region_obj->set ("endColumn", new json::integer_number (next_col));

  return region_obj;
}

/* Attempt to get a string for a logicalLocation's "kind" property
   (SARIF v2.1.0 section 3.33.7).
   Return NULL if unknown.  */

static const char *
maybe_get_sarif_kind (enum logical_location_kind kind)
{
  switch (kind)
    {
    default:
      gcc_unreachable ();
    case LOGICAL_LOCATION_KIND_UNKNOWN:
      return NULL;

    case LOGICAL_LOCATION_KIND_FUNCTION:
      return "function";
    case LOGICAL_LOCATION_KIND_MEMBER:
      return "member";
    case LOGICAL_LOCATION_KIND_MODULE:
      return "module";
    case LOGICAL_LOCATION_KIND_NAMESPACE:
      return "namespace";
    case LOGICAL_LOCATION_KIND_TYPE:
      return "type";
    case LOGICAL_LOCATION_KIND_RETURN_TYPE:
      return "returnType";
    case LOGICAL_LOCATION_KIND_PARAMETER:
      return "parameter";
    case LOGICAL_LOCATION_KIND_VARIABLE:
      return "variable";
    }
}

/* Make a logicalLocation object (SARIF v2.1.0 section 3.33) for LOGICAL_LOC,
   or return NULL.  */

json::object *
sarif_builder::
make_logical_location_object (const logical_location &logical_loc) const
{
  json::object *logical_loc_obj = new json::object ();

  /* "name" property (SARIF v2.1.0 section 3.33.4).  */
  if (const char *short_name = logical_loc.get_short_name ())
    logical_loc_obj->set ("name", new json::string (short_name));

  /* "fullyQualifiedName" property (SARIF v2.1.0 section 3.33.5).  */
  if (const char *name_with_scope = logical_loc.get_name_with_scope ())
    logical_loc_obj->set ("fullyQualifiedName",
			  new json::string (name_with_scope));

  /* "decoratedName" property (SARIF v2.1.0 section 3.33.6).  */
  if (const char *internal_name = logical_loc.get_internal_name ())
    logical_loc_obj->set ("decoratedName", new json::string (internal_name));

  /* "kind" property (SARIF v2.1.0 section 3.33.7).  */
  enum logical_location_kind kind = logical_loc.get_kind ();
  if (const char *sarif_kind_str = maybe_get_sarif_kind (kind))
    logical_loc_obj->set ("kind", new json::string (sarif_kind_str));

  return logical_loc_obj;
}

/* Make a codeFlow object (SARIF v2.1.0 section 3.36) for PATH.  */

json::object *
sarif_builder::make_code_flow_object (const diagnostic_path &path)
{
  json::object *code_flow_obj = new json::object ();

  /* "threadFlows" property (SARIF v2.1.0 section 3.36.3).
     Currently we only support one thread per result.  */
  json::array *thread_flows_arr = new json::array ();
  json::object *thread_flow_obj = make_thread_flow_object (path);
  thread_flows_arr->append (thread_flow_obj);
  code_flow_obj->set ("threadFlows", thread_flows_arr);

  return code_flow_obj;
}

/* Make a threadFlow object (SARIF v2.1.0 section 3.37) for PATH.  */

json::object *
sarif_builder::make_thread_flow_object (const diagnostic_path &path)
{
  json::object *thread_flow_obj = new json::object ();

  /* "locations" property (SARIF v2.1.0 section 3.37.6).  */
  json::array *locations_arr = new json::array ();
  for (unsigned i = 0; i < path.num_events (); i++)
    {
      const diagnostic_event &event = path.get_event (i);
      json::object *thread_flow_loc_obj
	= make_thread_flow_location_object (event);
      locations_arr->append (thread_flow_loc_obj);
    }
  thread_flow_obj->set ("locations", locations_arr);

  return thread_flow_obj;
}

/* Make a threadFlowLocation object (SARIF v2.1.0 section 3.38) for EVENT.  */

json::object *
sarif_builder::make_thread_flow_location_object (const diagnostic_event &ev)
{
  json::object *thread_flow_loc_obj = new json::object ();

  /* "location" property (SARIF v2.1.0 section 3.38.3).  */
  json::object *location_obj = make_location_object (ev);
  thread_flow_loc_obj->set ("location", location_obj);

  /* "kinds" property (SARIF v2.1.0 section 3.38.8).  */
  diagnostic_event::meaning m = ev.get_meaning ();
  if (json::array *kinds_arr = maybe_make_kinds_array (m))
    thread_flow_loc_obj->set ("kinds", kinds_arr);

  /* "nestingLevel" property (SARIF v2.1.0 section 3.38.10).  */
  thread_flow_loc_obj->set ("nestingLevel",
			    new json::integer_number (ev.get_stack_depth ()));

  /* It might be nice to eventually implement the following for -fanalyzer:
     - the "stack" property (SARIF v2.1.0 section 3.38.5)
     - the "state" property (SARIF v2.1.0 section 3.38.9)
     - the "importance" property (SARIF v2.1.0 section 3.38.13).  */

  return thread_flow_loc_obj;
}

/* If M has any known meaning, make a json array suitable for the "kinds"
   property of a threadFlowLocation object (SARIF v2.1.0 section 3.38.8).

   Otherwise, return NULL.  */

json::array *
sarif_builder::maybe_make_kinds_array (diagnostic_event::meaning m) const
{
  if (m.m_verb == diagnostic_event::VERB_unknown
      && m.m_noun == diagnostic_event::NOUN_unknown
      && m.m_property == diagnostic_event::PROPERTY_unknown)
    return NULL;

  json::array *kinds_arr = new json::array ();
  if (const char *verb_str
	= diagnostic_event::meaning::maybe_get_verb_str (m.m_verb))
    kinds_arr->append (new json::string (verb_str));
  if (const char *noun_str
	= diagnostic_event::meaning::maybe_get_noun_str (m.m_noun))
    kinds_arr->append (new json::string (noun_str));
  if (const char *property_str
	= diagnostic_event::meaning::maybe_get_property_str (m.m_property))
    kinds_arr->append (new json::string (property_str));
  return kinds_arr;
}

/* Make a message object (SARIF v2.1.0 section 3.11) for MSG.  */

json::object *
sarif_builder::make_message_object (const char *msg) const
{
  json::object *message_obj = new json::object ();

  /* "text" property (SARIF v2.1.0 section 3.11.8).  */
  message_obj->set ("text", new json::string (msg));

  return message_obj;
}

/* Make a multiformatMessageString object (SARIF v2.1.0 section 3.12)
   for MSG.  */

json::object *
sarif_builder::make_multiformat_message_string (const char *msg) const
{
  json::object *message_obj = new json::object ();

  /* "text" property (SARIF v2.1.0 section 3.12.3).  */
  message_obj->set ("text", new json::string (msg));

  return message_obj;
}

#define SARIF_SCHEMA "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json"
#define SARIF_VERSION "2.1.0"

/* Make a top-level sarifLog object (SARIF v2.1.0 section 3.13).
   Take ownership of RESULTS.  */

json::object *
sarif_builder::make_top_level_object (json::array *results)
{
  json::object *log_obj = new json::object ();

  /* "$schema" property (SARIF v2.1.0 section 3.13.3) .  */
  log_obj->set ("$schema", new json::string (SARIF_SCHEMA));

  /* "version" property (SARIF v2.1.0 section 3.13.2).  */
  log_obj->set ("version", new json::string (SARIF_VERSION));

  /* "runs" property (SARIF v2.1.0 section 3.13.4).  */
  json::array *run_arr = new json::array ();
  json::object *run_obj = make_run_object (results);
  run_arr->append (run_obj);
  log_obj->set ("runs", run_arr);

  return log_obj;
}

/* Make a run object (SARIF v2.1.0 section 3.14).
   Take ownership of RESULTS.  */

json::object *
sarif_builder::make_run_object (json::array *results)
{
  json::object *run_obj = new json::object ();

  /* "tool" property (SARIF v2.1.0 section 3.14.6).  */
  json::object *tool_obj = make_tool_object ();
  run_obj->set ("tool", tool_obj);

  /* "taxonomies" property (SARIF v2.1.0 section 3.14.8).  */
  if (json::array *taxonomies_arr = maybe_make_taxonomies_array ())
    run_obj->set ("taxonomies", taxonomies_arr);

  /* "originalUriBaseIds (SARIF v2.1.0 section 3.14.14).  */
  if (m_seen_any_relative_paths)
    {
      json::object *orig_uri_base_ids = new json::object ();
      run_obj->set ("originalUriBaseIds", orig_uri_base_ids);
      json::object *pwd_art_loc_obj = make_artifact_location_object_for_pwd ();
      orig_uri_base_ids->set (PWD_PROPERTY_NAME, pwd_art_loc_obj);
    }

  /* "artifacts" property (SARIF v2.1.0 section 3.14.15).  */
  json::array *artifacts_arr = new json::array ();
  for (auto iter : m_filenames)
    {
      json::object *artifact_obj = make_artifact_object (iter);
      artifacts_arr->append (artifact_obj);
    }
  run_obj->set ("artifacts", artifacts_arr);

  /* "results" property (SARIF v2.1.0 section 3.14.23).  */
  run_obj->set ("results", results);

  return run_obj;
}

/* Make a tool object (SARIF v2.1.0 section 3.18).  */

json::object *
sarif_builder::make_tool_object () const
{
  json::object *tool_obj = new json::object ();

  /* "driver" property (SARIF v2.1.0 section 3.18.2).  */
  json::object *driver_obj = make_driver_tool_component_object ();
  tool_obj->set ("driver", driver_obj);

  /* Report plugins via the "extensions" property
     (SARIF v2.1.0 section 3.18.3).  */
  if (m_context->m_client_data_hooks)
    if (const client_version_info *vinfo
	  = m_context->m_client_data_hooks->get_any_version_info ())
      {
	class my_plugin_visitor : public client_version_info :: plugin_visitor
	{
	public:
	  void on_plugin (const diagnostic_client_plugin_info &p) final override
	  {
	    /* Create a toolComponent object (SARIF v2.1.0 section 3.19)
	       for the plugin.  */
	    json::object *plugin_obj = new json::object ();
	    m_plugin_objs.safe_push (plugin_obj);

	    /* "name" property (SARIF v2.1.0 section 3.19.8).  */
	    if (const char *short_name = p.get_short_name ())
	      plugin_obj->set ("name", new json::string (short_name));

	    /* "fullName" property (SARIF v2.1.0 section 3.19.9).  */
	    if (const char *full_name = p.get_full_name ())
	      plugin_obj->set ("fullName", new json::string (full_name));

	    /* "version" property (SARIF v2.1.0 section 3.19.13).  */
	    if (const char *version = p.get_version ())
	      plugin_obj->set ("version", new json::string (version));
	  }
	  auto_vec <json::object *> m_plugin_objs;
	};
	my_plugin_visitor v;
	vinfo->for_each_plugin (v);
	if (v.m_plugin_objs.length () > 0)
	  {
	    json::array *extensions_arr = new json::array ();
	    tool_obj->set ("extensions", extensions_arr);
	    for (auto iter : v.m_plugin_objs)
	      extensions_arr->append (iter);
	  }
      }

  /* Perhaps we could also show GMP, MPFR, MPC, isl versions as other
     "extensions" (see toplev.cc: print_version).  */

  return tool_obj;
}

/* Make a toolComponent object (SARIF v2.1.0 section 3.19) for what SARIF
   calls the "driver" (see SARIF v2.1.0 section 3.18.1).  */

json::object *
sarif_builder::make_driver_tool_component_object () const
{
  json::object *driver_obj = new json::object ();

  if (m_context->m_client_data_hooks)
    if (const client_version_info *vinfo
	  = m_context->m_client_data_hooks->get_any_version_info ())
      {
	/* "name" property (SARIF v2.1.0 section 3.19.8).  */
	if (const char *name = vinfo->get_tool_name ())
	  driver_obj->set ("name", new json::string (name));

	/* "fullName" property (SARIF v2.1.0 section 3.19.9).  */
	if (char *full_name = vinfo->maybe_make_full_name ())
	  {
	    driver_obj->set ("fullName", new json::string (full_name));
	    free (full_name);
	  }

	/* "version" property (SARIF v2.1.0 section 3.19.13).  */
	if (const char *version = vinfo->get_version_string ())
	  driver_obj->set ("version", new json::string (version));

	/* "informationUri" property (SARIF v2.1.0 section 3.19.17).  */
	if (char *version_url =  vinfo->maybe_make_version_url ())
	  {
	    driver_obj->set ("informationUri", new json::string (version_url));
	    free (version_url);
	  }
      }

  /* "rules" property (SARIF v2.1.0 section 3.19.23).  */
  driver_obj->set ("rules", m_rules_arr);

  return driver_obj;
}

/* If we've seen any CWE IDs, make an array for the "taxonomies" property
   (SARIF v2.1.0 section 3.14.8) of a run object, containting a singl
   toolComponent (3.19) as per 3.19.3, representing the CWE.

   Otherwise return NULL.  */

json::array *
sarif_builder::maybe_make_taxonomies_array () const
{
  json::object *cwe_obj = maybe_make_cwe_taxonomy_object ();
  if (!cwe_obj)
    return NULL;

  /* "taxonomies" property (SARIF v2.1.0 section 3.14.8).  */
  json::array *taxonomies_arr = new json::array ();
  taxonomies_arr->append (cwe_obj);
  return taxonomies_arr;
}

/* If we've seen any CWE IDs, make a toolComponent object
   (SARIF v2.1.0 section 3.19) representing the CWE taxonomy, as per 3.19.3.
   Populate the "taxa" property with all of the CWE IDs in m_cwe_id_set.

   Otherwise return NULL.  */

json::object *
sarif_builder::maybe_make_cwe_taxonomy_object () const
{
  if (m_cwe_id_set.is_empty ())
    return NULL;

  json::object *taxonomy_obj = new json::object ();

  /* "name" property (SARIF v2.1.0 section 3.19.8).  */
  taxonomy_obj->set ("name", new json::string ("CWE"));

  /* "version" property (SARIF v2.1.0 section 3.19.13).  */
  taxonomy_obj->set ("version", new json::string ("4.7"));

  /* "organization" property (SARIF v2.1.0 section 3.19.18).  */
  taxonomy_obj->set ("organization", new json::string ("MITRE"));

  /* "shortDescription" property (SARIF v2.1.0 section 3.19.19).  */
  json::object *short_desc
    = make_multiformat_message_string ("The MITRE"
				       " Common Weakness Enumeration");
  taxonomy_obj->set ("shortDescription", short_desc);

  /* "taxa" property (SARIF v2.1.0 3.section 3.19.25).  */
  json::array *taxa_arr = new json::array ();
  for (auto cwe_id : m_cwe_id_set)
    {
      json::object *cwe_taxon
	= make_reporting_descriptor_object_for_cwe_id (cwe_id);
      taxa_arr->append (cwe_taxon);
    }
  taxonomy_obj->set ("taxa", taxa_arr);

  return taxonomy_obj;
}

/* Make an artifact object (SARIF v2.1.0 section 3.24).  */

json::object *
sarif_builder::make_artifact_object (const char *filename)
{
  json::object *artifact_obj = new json::object ();

  /* "location" property (SARIF v2.1.0 section 3.24.2).  */
  json::object *artifact_loc_obj = make_artifact_location_object (filename);
  artifact_obj->set ("location", artifact_loc_obj);

  /* "contents" property (SARIF v2.1.0 section 3.24.8).  */
  if (json::object *artifact_content_obj
	= maybe_make_artifact_content_object (filename))
    artifact_obj->set ("contents", artifact_content_obj);

  /* "sourceLanguage" property (SARIF v2.1.0 section 3.24.10).  */
  if (m_context->m_client_data_hooks)
    if (const char *source_lang
	= m_context->m_client_data_hooks->maybe_get_sarif_source_language
	    (filename))
      artifact_obj->set ("sourceLanguage", new json::string (source_lang));

  return artifact_obj;
}

/* Read all data from F_IN until EOF.
   Return a NULL-terminated buffer containing the data, which must be
   freed by the caller.
   Return NULL on errors.  */

static char *
read_until_eof (FILE *f_in)
{
  /* Read content, allocating a buffer for it.  */
  char *result = NULL;
  size_t total_sz = 0;
  size_t alloc_sz = 0;
  char buf[4096];
  size_t iter_sz_in;

  while ( (iter_sz_in = fread (buf, 1, sizeof (buf), f_in)) )
    {
      gcc_assert (alloc_sz >= total_sz);
      size_t old_total_sz = total_sz;
      total_sz += iter_sz_in;
      /* Allow 1 extra byte for 0-termination.  */
      if (alloc_sz < (total_sz + 1))
	{
	  size_t new_alloc_sz = alloc_sz ? alloc_sz * 2: total_sz + 1;
	  result = (char *)xrealloc (result, new_alloc_sz);
	  alloc_sz = new_alloc_sz;
	}
      memcpy (result + old_total_sz, buf, iter_sz_in);
    }

  if (!feof (f_in))
    return NULL;

  /* 0-terminate the buffer.  */
  gcc_assert (total_sz < alloc_sz);
  result[total_sz] = '\0';

  return result;
}

/* Read all data from FILENAME until EOF.
   Return a NULL-terminated buffer containing the data, which must be
   freed by the caller.
   Return NULL on errors.  */

static char *
maybe_read_file (const char *filename)
{
  FILE *f_in = fopen (filename, "r");
  if (!f_in)
    return NULL;
  char *result = read_until_eof (f_in);
  fclose (f_in);
  return result;
}

/* Make an artifactContent object (SARIF v2.1.0 section 3.3) for the
   full contents of FILENAME.  */

json::object *
sarif_builder::maybe_make_artifact_content_object (const char *filename) const
{
  char *text_utf8 = maybe_read_file (filename);
  if (!text_utf8)
    return NULL;

  json::object *artifact_content_obj = new json::object ();
  artifact_content_obj->set ("text", new json::string (text_utf8));
  free (text_utf8);

  return artifact_content_obj;
}

/* Attempt to read the given range of lines from FILENAME; return
   a freshly-allocated 0-terminated buffer containing them, or NULL.  */

static char *
get_source_lines (const char *filename,
		  int start_line,
		  int end_line)
{
  auto_vec<char> result;

  for (int line = start_line; line <= end_line; line++)
    {
      char_span line_content = location_get_source_line (filename, line);
      if (!line_content.get_buffer ())
	return NULL;
      result.reserve (line_content.length () + 1);
      for (size_t i = 0; i < line_content.length (); i++)
	result.quick_push (line_content[i]);
      result.quick_push ('\n');
    }
  result.safe_push ('\0');

  return xstrdup (result.address ());
}

/* Make an artifactContent object (SARIF v2.1.0 section 3.3) for the given
   run of lines within FILENAME (including the endpoints).  */

json::object *
sarif_builder::maybe_make_artifact_content_object (const char *filename,
						   int start_line,
						   int end_line) const
{
  char *text_utf8 = get_source_lines (filename, start_line, end_line);

  if (!text_utf8)
    return NULL;

  json::object *artifact_content_obj = new json::object ();
  artifact_content_obj->set ("text", new json::string (text_utf8));
  free (text_utf8);

  return artifact_content_obj;
}

/* Make a fix object (SARIF v2.1.0 section 3.55) for RICHLOC.  */

json::object *
sarif_builder::make_fix_object (const rich_location &richloc)
{
  json::object *fix_obj = new json::object ();

  /* "artifactChanges" property (SARIF v2.1.0 section 3.55.3).  */
  /* We assume that all fix-it hints in RICHLOC affect the same file.  */
  json::array *artifact_change_arr = new json::array ();
  json::object *artifact_change_obj = make_artifact_change_object (richloc);
  artifact_change_arr->append (artifact_change_obj);
  fix_obj->set ("artifactChanges", artifact_change_arr);

  return fix_obj;
}

/* Make an artifactChange object (SARIF v2.1.0 section 3.56) for RICHLOC.  */

json::object *
sarif_builder::make_artifact_change_object (const rich_location &richloc)
{
  json::object *artifact_change_obj = new json::object ();

  /* "artifactLocation" property (SARIF v2.1.0 section 3.56.2).  */
  json::object *artifact_location_obj
    = make_artifact_location_object (richloc.get_loc ());
  artifact_change_obj->set ("artifactLocation", artifact_location_obj);

  /* "replacements" property (SARIF v2.1.0 section 3.56.3).  */
  json::array *replacement_arr = new json::array ();
  for (unsigned int i = 0; i < richloc.get_num_fixit_hints (); i++)
    {
      const fixit_hint *hint = richloc.get_fixit_hint (i);
      json::object *replacement_obj = make_replacement_object (*hint);
      replacement_arr->append (replacement_obj);
    }
  artifact_change_obj->set ("replacements", replacement_arr);

  return artifact_change_obj;
}

/* Make a replacement object (SARIF v2.1.0 section 3.57) for HINT.  */

json::object *
sarif_builder::make_replacement_object (const fixit_hint &hint) const
{
  json::object *replacement_obj = new json::object ();

  /* "deletedRegion" property (SARIF v2.1.0 section 3.57.3).  */
  json::object *region_obj = make_region_object_for_hint (hint);
  replacement_obj->set ("deletedRegion", region_obj);

  /* "insertedContent" property (SARIF v2.1.0 section 3.57.4).  */
  json::object *content_obj = make_artifact_content_object (hint.get_string ());
  replacement_obj->set ("insertedContent", content_obj);

  return replacement_obj;
}

/* Make an artifactContent object (SARIF v2.1.0 section 3.3) for TEXT.  */

json::object *
sarif_builder::make_artifact_content_object (const char *text) const
{
  json::object *content_obj = new json::object ();

  /* "text" property (SARIF v2.1.0 section 3.3.2).  */
  content_obj->set ("text", new json::string (text));

  return content_obj;
}

/* No-op implementation of "begin_diagnostic" for SARIF output.  */

static void
sarif_begin_diagnostic (diagnostic_context *, diagnostic_info *)
{
}

/* Implementation of "end_diagnostic" for SARIF output.  */

static void
sarif_end_diagnostic (diagnostic_context *context, diagnostic_info *diagnostic,
		      diagnostic_t orig_diag_kind)
{
  gcc_assert (the_builder);
  the_builder->end_diagnostic (context, diagnostic, orig_diag_kind);
}

/* No-op implementation of "begin_group_cb" for SARIF output.  */

static void
sarif_begin_group (diagnostic_context *)
{
}

/* Implementation of "end_group_cb" for SARIF output.  */

static void
sarif_end_group (diagnostic_context *)
{
  gcc_assert (the_builder);
  the_builder->end_group ();
}

/* Flush the top-level array to OUTF.  */

static void
sarif_flush_to_file (FILE *outf)
{
  gcc_assert (the_builder);
  the_builder->flush_to_file (outf);
  delete the_builder;
  the_builder = NULL;
}

/* Callback for final cleanup for SARIF output to stderr.  */

static void
sarif_stderr_final_cb (diagnostic_context *)
{
  gcc_assert (the_builder);
  sarif_flush_to_file (stderr);
}

static char *sarif_output_base_file_name;

/* Callback for final cleanup for SARIF output to a file.  */

static void
sarif_file_final_cb (diagnostic_context *)
{
  char *filename = concat (sarif_output_base_file_name, ".sarif", NULL);
  FILE *outf = fopen (filename, "w");
  if (!outf)
    {
      const char *errstr = xstrerror (errno);
      fnotice (stderr, "error: unable to open '%s' for writing: %s\n",
	       filename, errstr);
      free (filename);
      return;
    }
  gcc_assert (the_builder);
  sarif_flush_to_file (outf);
  fclose (outf);
  free (filename);
}

/* Populate CONTEXT in preparation for SARIF output (either to stderr, or
   to a file).  */

static void
diagnostic_output_format_init_sarif (diagnostic_context *context)
{
  the_builder = new sarif_builder (context);

  /* Override callbacks.  */
  context->begin_diagnostic = sarif_begin_diagnostic;
  context->end_diagnostic = sarif_end_diagnostic;
  context->begin_group_cb = sarif_begin_group;
  context->end_group_cb =  sarif_end_group;
  context->print_path = NULL; /* handled in sarif_end_diagnostic.  */

  /* The metadata is handled in SARIF format, rather than as text.  */
  context->show_cwe = false;
  context->show_rules = false;

  /* The option is handled in SARIF format, rather than as text.  */
  context->show_option_requested = false;

  /* Don't colorize the text.  */
  pp_show_color (context->printer) = false;
}

/* Populate CONTEXT in preparation for SARIF output to stderr.  */

void
diagnostic_output_format_init_sarif_stderr (diagnostic_context *context)
{
  diagnostic_output_format_init_sarif (context);
  context->final_cb = sarif_stderr_final_cb;
}

/* Populate CONTEXT in preparation for SARIF output to a file named
   BASE_FILE_NAME.sarif.  */

void
diagnostic_output_format_init_sarif_file (diagnostic_context *context,
					 const char *base_file_name)
{
  diagnostic_output_format_init_sarif (context);
  context->final_cb = sarif_file_final_cb;
  sarif_output_base_file_name = xstrdup (base_file_name);
}
