/* 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)
    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);
}
