/* SARIF output for diagnostics
   Copyright (C) 2018-2024 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"
#define INCLUDE_VECTOR
#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"
#include "diagnostic-diagram.h"
#include "text-art/canvas.h"
#include "diagnostic-format-sarif.h"
#include "ordered-hash-map.h"
#include "sbitmap.h"

class sarif_builder;

/* Subclass of json::object for SARIF invocation objects
   (SARIF v2.1.0 section 3.20).  */

class sarif_invocation : public sarif_object
{
public:
  sarif_invocation ()
  : m_notifications_arr (new json::array ()),
    m_success (true)
  {}

  void add_notification_for_ice (diagnostic_context *context,
				 const diagnostic_info &diagnostic,
				 sarif_builder *builder);
  void prepare_to_flush (diagnostic_context *context);

private:
  json::array *m_notifications_arr;
  bool m_success;
};

/* Corresponds to values for the SARIF artifact objects "roles" property.
   (SARIF v2.1.0 section 3.24.6).  */

enum class diagnostic_artifact_role
{
  analysis_target, /* "analysisTarget".  */
  debug_output_file, /* "debugOutputFile".  */
  result_file, /* "resultFile".  */
  traced_file, /* "tracedFile".  */

  NUM_ROLES
};

/* Subclass of sarif_object for SARIF artifact objects
   (SARIF v2.1.0 section 3.24).  */

class sarif_artifact : public sarif_object
{
public:
  sarif_artifact (const char *filename)
  : m_filename (filename),
    m_roles ((unsigned)diagnostic_artifact_role::NUM_ROLES),
    m_embed_contents (false)
  {
    bitmap_clear (m_roles);
  }

  void add_role (enum diagnostic_artifact_role role,
		 bool embed_contents);

  bool embed_contents_p () const { return m_embed_contents; }
  void populate_contents (sarif_builder &builder);
  void populate_roles ();

private:
  const char *m_filename;
  auto_sbitmap m_roles;

  /* Flag to track whether this artifact should have a "contents" property
     (SARIF v2.1.0 section 3.24.8).
     We only add the contents for those artifacts that have a location
     referencing them (so that a consumer might want to quote the source).   */
  bool m_embed_contents;
};

/* Subclass of sarif_object for SARIF result objects
   (SARIF v2.1.0 section 3.27).  */

class sarif_result : public sarif_object
{
public:
  sarif_result () : m_related_locations_arr (NULL) {}

  void
  on_nested_diagnostic (diagnostic_context *context,
			const diagnostic_info &diagnostic,
			diagnostic_t orig_diag_kind,
			sarif_builder *builder);
  void on_diagram (diagnostic_context *context,
		   const diagnostic_diagram &diagram,
		   sarif_builder *builder);

private:
  void add_related_location (json::object *location_obj);

  json::array *m_related_locations_arr;
};

/* Subclass of sarif_object for SARIF notification objects
   (SARIF v2.1.0 section 3.58).

   This subclass is specifically for notifying when an
   internal compiler error occurs.  */

class sarif_ice_notification : public sarif_object
{
public:
  sarif_ice_notification (diagnostic_context *context,
			  const diagnostic_info &diagnostic,
			  sarif_builder *builder);
};

/* Subclass of sarif_object for SARIF threadFlow objects
   (SARIF v2.1.0 section 3.37) for PATH.  */

class sarif_thread_flow : public sarif_object
{
public:
  sarif_thread_flow (const diagnostic_thread &thread);

  void add_location (json::object *thread_flow_loc_obj)
  {
    m_locations_arr->append (thread_flow_loc_obj);
  }

private:
  json::array *m_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,
		 const char *main_input_filename_,
		 bool formatted);

  void end_diagnostic (diagnostic_context *context,
		       const diagnostic_info &diagnostic,
		       diagnostic_t orig_diag_kind);
  void emit_diagram (diagnostic_context *context,
		     const diagnostic_diagram &diagram);
  void end_group ();

  void flush_to_file (FILE *outf);

  json::array *make_locations_arr (const diagnostic_info &diagnostic,
				   enum diagnostic_artifact_role role);
  json::object *make_location_object (const rich_location &rich_loc,
				      const logical_location *logical_loc,
				      enum diagnostic_artifact_role role);
  json::object *make_message_object (const char *msg) const;
  json::object *
  make_message_object_for_diagram (diagnostic_context *context,
				   const diagnostic_diagram &diagram);
  json::object *maybe_make_artifact_content_object (const char *filename) const;

private:
  sarif_result *make_result_object (diagnostic_context *context,
				    const 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,
				      enum diagnostic_artifact_role role);
  json::object *make_code_flow_object (const diagnostic_path &path);
  json::object *
  make_thread_flow_location_object (const diagnostic_event &event,
				    int path_event_idx);
  json::array *maybe_make_kinds_array (diagnostic_event::meaning m) const;
  json::object *
  maybe_make_physical_location_object (location_t loc,
				       enum diagnostic_artifact_role role,
				       int column_override);
  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,
					  int column_override) 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 (sarif_invocation *invocation_obj,
				       json::array *results);
  json::object *make_run_object (sarif_invocation *invocation_obj,
				 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,
						const 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);
  sarif_artifact &get_or_create_artifact (const char *filename,
					  enum diagnostic_artifact_role role,
					  bool embed_contents);
  char *get_source_lines (const char *filename,
			  int start_line,
			  int end_line) 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 object for the invocation object.  */
  sarif_invocation *m_invocation_obj;

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

  ordered_hash_map <nofree_string_hash,
		    sarif_artifact *> m_filename_to_artifact_map;
  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;

  bool m_formatted;
};

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

sarif_property_bag &
sarif_object::get_or_create_properties ()
{
  json::value *properties_val = get ("properties");
  if (properties_val)
    {
      if (properties_val->get_kind () == json::JSON_OBJECT)
	return *static_cast <sarif_property_bag *> (properties_val);
    }

  sarif_property_bag *bag = new sarif_property_bag ();
  set ("properties", bag);
  return *bag;
}

/* class sarif_invocation : public sarif_object.  */

/* Handle an internal compiler error DIAGNOSTIC occurring on CONTEXT.
   Add an object representing the ICE to the notifications array.  */

void
sarif_invocation::add_notification_for_ice (diagnostic_context *context,
					    const diagnostic_info &diagnostic,
					    sarif_builder *builder)
{
  m_success = false;

  sarif_ice_notification *notification_obj
    = new sarif_ice_notification (context, diagnostic, builder);
  m_notifications_arr->append (notification_obj);
}

void
sarif_invocation::prepare_to_flush (diagnostic_context *context)
{
  /* "executionSuccessful" property (SARIF v2.1.0 section 3.20.14).  */
  set_bool ("executionSuccessful", m_success);

  /* "toolExecutionNotifications" property (SARIF v2.1.0 section 3.20.21).  */
  set ("toolExecutionNotifications", m_notifications_arr);

  /* Call client hook, allowing it to create a custom property bag for
     this object (SARIF v2.1.0 section 3.8) e.g. for recording time vars.  */
  if (auto client_data_hooks = context->get_client_data_hooks ())
    client_data_hooks->add_sarif_invocation_properties (*this);
}

/* class sarif_artifact : public sarif_object.  */

/* Add ROLE to this artifact's roles.
   If EMBED_CONTENTS is true, then flag that we will attempt to embed the
   contents of this artifact when writing it out.  */

void
sarif_artifact::add_role (enum diagnostic_artifact_role role,
			  bool embed_contents)
{
  if (embed_contents)
    m_embed_contents = true;

  /* In SARIF v2.1.0 section 3.24.6 "roles" property:
     "resultFile" is for an artifact
     "which the analysis tool was not explicitly instructed to scan",
     whereas "analysisTarget" is for one where the
     "analysis tool was instructed to scan this artifact".
     Hence the latter excludes the former.  */
  if (role == diagnostic_artifact_role::result_file)
    if (bitmap_bit_p (m_roles, (int)diagnostic_artifact_role::analysis_target))
	return;

  bitmap_set_bit (m_roles, (int)role);
}

/* Populate the "contents" property (SARIF v2.1.0 section 3.24.8).
   We do this after initialization to
   (a) ensure that any charset options have been set
   (b) only populate it for artifacts that are referenced by a location.  */

void
sarif_artifact::populate_contents (sarif_builder &builder)
{
  if (json::object *artifact_content_obj
	= builder.maybe_make_artifact_content_object (m_filename))
    set ("contents", artifact_content_obj);
}

/* Get a string for ROLE corresponding to the
   SARIF v2.1.0 section 3.24.6 "roles" property.  */

static const char *
get_artifact_role_string (enum diagnostic_artifact_role role)
{
  switch (role)
    {
    default:
      gcc_unreachable ();
    case diagnostic_artifact_role::analysis_target:
      return "analysisTarget";
    case diagnostic_artifact_role::debug_output_file:
      return "debugOutputFile";
    case diagnostic_artifact_role::result_file:
      return "resultFile";
    case diagnostic_artifact_role::traced_file:
      return "tracedFile";
    }
}

/* Populate the "roles" property of this json::object with a new
   json::array for the artifact.roles property (SARIF v2.1.0 section 3.24.6)
   containing strings such as "analysisTarget", "resultFile"
   and/or "tracedFile".  */

void
sarif_artifact::populate_roles ()
{
  if (bitmap_empty_p (m_roles))
    return;
  json::array *roles_arr = new json::array ();
  for (int i = 0; i < (int)diagnostic_artifact_role::NUM_ROLES; i++)
    if (bitmap_bit_p (m_roles, i))
      {
	enum diagnostic_artifact_role role = (enum diagnostic_artifact_role)i;
	roles_arr->append (new json::string (get_artifact_role_string (role)));
      }
  set ("roles", roles_arr);
}

/* class sarif_result : public sarif_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,
				    const diagnostic_info &diagnostic,
				    diagnostic_t /*orig_diag_kind*/,
				    sarif_builder *builder)
{
  /* 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,
				     diagnostic_artifact_role::result_file);
  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);

  add_related_location (location_obj);
}

/* Handle diagrams that occur within a diagnostic group.
   The closest thing in SARIF seems to be to add a location to the
   "releatedLocations" property  (SARIF v2.1.0 section 3.27.22),
   and to put the diagram into the "message" property of that location
   (SARIF v2.1.0 section 3.28.5).  */

void
sarif_result::on_diagram (diagnostic_context *context,
			  const diagnostic_diagram &diagram,
			  sarif_builder *builder)
{
  json::object *location_obj = new json::object ();
  json::object *message_obj
    = builder->make_message_object_for_diagram (context, diagram);
  location_obj->set ("message", message_obj);

  add_related_location (location_obj);
}

/* Add LOCATION_OBJ to this result's "relatedLocations" array,
   creating it if it doesn't yet exist.  */

void
sarif_result::add_related_location (json::object *location_obj)
{
  if (!m_related_locations_arr)
    {
      m_related_locations_arr = new json::array ();
      set ("relatedLocations", m_related_locations_arr);
    }
  m_related_locations_arr->append (location_obj);
}

/* class sarif_ice_notification : public sarif_object.  */

/* sarif_ice_notification's ctor.
   DIAGNOSTIC is an internal compiler error.  */

sarif_ice_notification::sarif_ice_notification (diagnostic_context *context,
						const diagnostic_info &diagnostic,
						sarif_builder *builder)
{
  /* "locations" property (SARIF v2.1.0 section 3.58.4).  */
  json::array *locations_arr
    = builder->make_locations_arr (diagnostic,
				   diagnostic_artifact_role::result_file);
  set ("locations", locations_arr);

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

  /* "level" property (SARIF v2.1.0 section 3.58.6).  */
  set_string ("level", "error");
}

/* class sarif_thread_flow : public sarif_object.  */

sarif_thread_flow::sarif_thread_flow (const diagnostic_thread &thread)
{
  /* "id" property (SARIF v2.1.0 section 3.37.2).  */
  label_text name (thread.get_name (false));
  set_string ("id", name.get ());

  /* "locations" property (SARIF v2.1.0 section 3.37.6).  */
  m_locations_arr = new json::array ();
  set ("locations", m_locations_arr);
}

/* class sarif_builder.  */

/* sarif_builder's ctor.  */

sarif_builder::sarif_builder (diagnostic_context *context,
			      const char *main_input_filename_,
			      bool formatted)
: m_context (context),
  m_invocation_obj (new sarif_invocation ()),
  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->m_tabstop),
  m_formatted (formatted)
{
  /* Mark MAIN_INPUT_FILENAME_ as the artifact that the tool was
     instructed to scan.
     Only quote the contents if it gets referenced by physical locations,
     since otherwise the "no diagnostics" case would quote the main input
     file, and doing so noticeably bloated the output seen in analyzer
     integration testing (build directory went from 20G -> 21G).  */
  get_or_create_artifact (main_input_filename_,
			  diagnostic_artifact_role::analysis_target,
			  false);
}

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

void
sarif_builder::end_diagnostic (diagnostic_context *context,
			       const diagnostic_info &diagnostic,
			       diagnostic_t orig_diag_kind)
{
  if (diagnostic.kind == DK_ICE || diagnostic.kind == DK_ICE_NOBT)
    {
      m_invocation_obj->add_notification_for_ice (context, diagnostic, this);
      return;
    }

  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 diagnostic_context::m_diagrams.m_emission_cb
   for SARIF output.  */

void
sarif_builder::emit_diagram (diagnostic_context *context,
			     const diagnostic_diagram &diagram)
{
  /* We must be within the emission of a top-level diagnostic.  */
  gcc_assert (m_cur_group_result);
  m_cur_group_result->on_diagram (context, diagram, this);
}

/* 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)
{
  m_invocation_obj->prepare_to_flush (m_context);
  json::object *top = make_top_level_object (m_invocation_obj, m_results_array);
  top->dump (outf, m_formatted);
  m_invocation_obj = NULL;
  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,
				   const 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->make_option_name (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_string ("ruleId", 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_string ("ruleId", rule_id);
      free (rule_id);
    }

  if (diagnostic.metadata)
    {
      /* "taxa" property (SARIF v2.1.0 section 3.27.8).  */
      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);
	}

      diagnostic.metadata->maybe_add_sarif_properties (*result_obj);
    }

  /* "level" property (SARIF v2.1.0 section 3.27.10).  */
  if (const char *sarif_level = maybe_get_sarif_level (diagnostic.kind))
    result_obj->set_string ("level", 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
    = make_locations_arr (diagnostic,
			  diagnostic_artifact_role::result_file);
  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,
					      const 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_string ("id", 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 (char *option_url = context->make_option_url (diagnostic.option_index))
    {
      reporting_desc->set_string ("helpUri", 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_string ("id", pp_formatted_text (&pp));
  }

  /* "helpUri" property (SARIF v2.1.0 section 3.49.12).  */
  {
    char *url = get_cwe_url (cwe_id);
    reporting_desc->set_string ("helpUri", 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_string ("id", 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_string ("name", "cwe");

  return comp_ref_obj;
}

/* Make an array suitable for use as the "locations" property of:
   - a "result" object (SARIF v2.1.0 section 3.27.12), or
   - a "notification" object (SARIF v2.1.0 section 3.58.4).  */

json::array *
sarif_builder::make_locations_arr (const diagnostic_info &diagnostic,
				   enum diagnostic_artifact_role role)
{
  json::array *locations_arr = new json::array ();
  const logical_location *logical_loc = NULL;
  if (auto client_data_hooks = m_context->get_client_data_hooks ())
    logical_loc = client_data_hooks->get_current_logical_location ();

  json::object *location_obj
    = make_location_object (*diagnostic.richloc, logical_loc, role);
  locations_arr->append (location_obj);
  return locations_arr;
}

/* 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_sarif_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,
				     enum diagnostic_artifact_role role)
{
  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, role,
					       rich_loc.get_column_override ()))
    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,
				     enum diagnostic_artifact_role role)
{
  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, role, 0))
    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.

   If COLUMN_OVERRIDE is non-zero, then use it as the column number
   if LOC has no column information.

   Ensure that we have an artifact object for the file, adding ROLE to it,
   and flagging that we will attempt to embed the contents of the artifact
   when writing it out.  */

json::object *
sarif_builder::
maybe_make_physical_location_object (location_t loc,
				     enum diagnostic_artifact_role role,
				     int column_override)
{
  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);
  get_or_create_artifact (LOCATION_FILE (loc), role, true);

  /* "region" property (SARIF v2.1.0 section 3.29.4).  */
  if (json::object *region_obj = maybe_make_region_object (loc,
							   column_override))
    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_string ("uri", 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_string ("uriBaseId", 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_string ("uri", 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 (m_context->get_file_cache (),
					  exploc, policy);
}

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

   If COLUMN_OVERRIDE is non-zero, then use it as the column number
   if LOC has no column information.  */

json::object *
sarif_builder::maybe_make_region_object (location_t loc,
					 int column_override) 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) */
  if (exploc_start.line > 0)
    region_obj->set_integer ("startLine", exploc_start.line);

  /* "startColumn" property (SARIF v2.1.0 section 3.30.6).

     We use column == 0 to mean the whole line, so omit the column
     information for this case, unless COLUMN_OVERRIDE is non-zero,
     (for handling certain awkward lexer diagnostics)  */

  if (exploc_start.column == 0 && column_override)
    /* Use the provided column number.  */
    exploc_start.column = column_override;

  if (exploc_start.column > 0)
    {
      int start_column = get_sarif_column (exploc_start);
      region_obj->set_integer ("startColumn", start_column);
    }

  /* "endLine" property (SARIF v2.1.0 section 3.30.7) */
  if (exploc_finish.line != exploc_start.line
      && exploc_finish.line > 0)
    region_obj->set_integer ("endLine", exploc_finish.line);

  /* "endColumn" property (SARIF v2.1.0 section 3.30.8).
     This expresses the column immediately beyond the range.

     We use column == 0 to mean the whole line, so omit the column
     information for this case.  */
  if (exploc_finish.column > 0)
    {
      int next_column = get_sarif_column (exploc_finish) + 1;
      region_obj->set_integer ("endColumn", 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) */
  if (exploc_start.line > 0)
    region_obj->set_integer ("startLine", exploc_start.line);

  /* "endLine" property (SARIF v2.1.0 section 3.30.7) */
  if (exploc_finish.line != exploc_start.line
      && exploc_finish.line > 0)
    region_obj->set_integer ("endLine", 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_integer ("startLine", exploc_start.line);

  /* "startColumn" property (SARIF v2.1.0 section 3.30.6) */
  int start_col = get_sarif_column (exploc_start);
  region_obj->set_integer ("startColumn", start_col);

  /* "endLine" property (SARIF v2.1.0 section 3.30.7) */
  if (exploc_next.line != exploc_start.line)
    region_obj->set_integer ("endLine", 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_integer ("endColumn", 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 *
make_sarif_logical_location_object (const logical_location &logical_loc)
{
  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_string ("name", 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_string ("fullyQualifiedName", 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_string ("decoratedName", 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_string ("kind", 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).  */
  json::array *thread_flows_arr = new json::array ();

  /* Walk the events, consolidating into per-thread threadFlow objects,
     using the index with PATH as the overall executionOrder.  */
  hash_map<int_hash<diagnostic_thread_id_t, -1, -2>,
	   sarif_thread_flow *> thread_id_map;
  for (unsigned i = 0; i < path.num_events (); i++)
    {
      const diagnostic_event &event = path.get_event (i);
      const diagnostic_thread_id_t thread_id = event.get_thread_id ();
      sarif_thread_flow *thread_flow_obj;

      if (sarif_thread_flow **slot = thread_id_map.get (thread_id))
	thread_flow_obj = *slot;
      else
	{
	  const diagnostic_thread &thread = path.get_thread (thread_id);
	  thread_flow_obj = new sarif_thread_flow (thread);
	  thread_flows_arr->append (thread_flow_obj);
	  thread_id_map.put (thread_id, thread_flow_obj);
	}

      /* Add event to thread's threadFlow object.  */
      json::object *thread_flow_loc_obj
	= make_thread_flow_location_object (event, i);
      thread_flow_obj->add_location (thread_flow_loc_obj);
    }
  code_flow_obj->set ("threadFlows", thread_flows_arr);

  return code_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,
						 int path_event_idx)
{
  sarif_object *thread_flow_loc_obj = new sarif_object ();

  /* Give diagnostic_event subclasses a chance to add custom properties
     via a property bag.  */
  ev.maybe_add_sarif_properties (*thread_flow_loc_obj);

  /* "location" property (SARIF v2.1.0 section 3.38.3).  */
  json::object *location_obj
    = make_location_object (ev, diagnostic_artifact_role::traced_file);
  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_integer ("nestingLevel", ev.get_stack_depth ());

  /* "executionOrder" property (SARIF v2.1.0 3.38.11).
     Offset by 1 to match the human-readable values emitted by %@.  */
  thread_flow_loc_obj->set_integer ("executionOrder", path_event_idx + 1);

  /* 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_string ("text", msg);

  return message_obj;
}

/* Make a message object (SARIF v2.1.0 section 3.11) for DIAGRAM.
   We emit the diagram as a code block within the Markdown part
   of the message.  */

json::object *
sarif_builder::make_message_object_for_diagram (diagnostic_context *context,
						const diagnostic_diagram &diagram)
{
  json::object *message_obj = new json::object ();

  /* "text" property (SARIF v2.1.0 section 3.11.8).  */
  message_obj->set_string ("text", diagram.get_alt_text ());

  char *saved_prefix = pp_take_prefix (context->printer);
  pp_set_prefix (context->printer, NULL);

  /* "To produce a code block in Markdown, simply indent every line of
     the block by at least 4 spaces or 1 tab."
     Here we use 4 spaces.  */
  diagram.get_canvas ().print_to_pp (context->printer, "    ");
  pp_set_prefix (context->printer, saved_prefix);

  /* "markdown" property (SARIF v2.1.0 section 3.11.9).  */
  message_obj->set_string ("markdown", pp_formatted_text (context->printer));

  pp_clear_output_area (context->printer);

  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_string ("text", 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 INVOCATION_OBJ and RESULTS.  */

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

  /* "$schema" property (SARIF v2.1.0 section 3.13.3) .  */
  log_obj->set_string ("$schema", SARIF_SCHEMA);

  /* "version" property (SARIF v2.1.0 section 3.13.2).  */
  log_obj->set_string ("version", 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 (invocation_obj, 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 INVOCATION_OBJ and RESULTS.  */

json::object *
sarif_builder::make_run_object (sarif_invocation *invocation_obj,
				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);

  /* "invocations" property (SARIF v2.1.0 section 3.14.11).  */
  {
    json::array *invocations_arr = new json::array ();
    invocations_arr->append (invocation_obj);
    run_obj->set ("invocations", invocations_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_filename_to_artifact_map)
    {
      sarif_artifact *artifact_obj = iter.second;
      if (artifact_obj->embed_contents_p ())
	artifact_obj->populate_contents (*this);
      artifact_obj->populate_roles ();
      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 (auto client_data_hooks = m_context->get_client_data_hooks ())
    if (const client_version_info *vinfo
	  = 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_string ("name", short_name);

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

	    /* "version" property (SARIF v2.1.0 section 3.19.13).  */
	    if (const char *version = p.get_version ())
	      plugin_obj->set_string ("version", 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 (auto client_data_hooks = m_context->get_client_data_hooks ())
    if (const client_version_info *vinfo
	  = 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_string ("name", name);

	/* "fullName" property (SARIF v2.1.0 section 3.19.9).  */
	if (char *full_name = vinfo->maybe_make_full_name ())
	  {
	    driver_obj->set_string ("fullName", 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_string ("version", version);

	/* "informationUri" property (SARIF v2.1.0 section 3.19.17).  */
	if (char *version_url =  vinfo->maybe_make_version_url ())
	  {
	    driver_obj->set_string ("informationUri", 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_string ("name", "CWE");

  /* "version" property (SARIF v2.1.0 section 3.19.13).  */
  taxonomy_obj->set_string ("version", "4.7");

  /* "organization" property (SARIF v2.1.0 section 3.19.18).  */
  taxonomy_obj->set_string ("organization", "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;
}

/* Ensure that we have an artifact object (SARIF v2.1.0 section 3.24)
   for FILENAME, adding it to m_filename_to_artifact_map if not already
   found, and adding ROLE to it.
   If EMBED_CONTENTS is true, then flag that we will attempt to embed the
   contents of this artifact when writing it out.  */

sarif_artifact &
sarif_builder::get_or_create_artifact (const char *filename,
				       enum diagnostic_artifact_role role,
				       bool embed_contents)
{
  if (auto *slot = m_filename_to_artifact_map.get (filename))
    {
      (*slot)->add_role (role, embed_contents);
      return **slot;
    }

  sarif_artifact *artifact_obj = new sarif_artifact (filename);
  artifact_obj->add_role (role, embed_contents);
  m_filename_to_artifact_map.put (filename, artifact_obj);

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

  /* "sourceLanguage" property (SARIF v2.1.0 section 3.24.10).  */
  switch (role)
    {
    default:
      gcc_unreachable ();
    case diagnostic_artifact_role::analysis_target:
    case diagnostic_artifact_role::result_file:
    case diagnostic_artifact_role::traced_file:
      /* Assume that these are in the source language.  */
      if (auto client_data_hooks = m_context->get_client_data_hooks ())
	if (const char *source_lang
	    = client_data_hooks->maybe_get_sarif_source_language (filename))
	  artifact_obj->set_string ("sourceLanguage", source_lang);
      break;

    case diagnostic_artifact_role::debug_output_file:
      /* Assume that these are not in the source language.  */
      break;
    }

  return *artifact_obj;
}

/* 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
{
  /* Let input.cc handle any charset conversion.  */
  char_span utf8_content
    = m_context->get_file_cache ().get_source_file_content (filename);
  if (!utf8_content)
    return NULL;

  /* Don't add it if it's not valid UTF-8.  */
  if (!cpp_valid_utf8_p(utf8_content.get_buffer (), utf8_content.length ()))
    return NULL;

  json::object *artifact_content_obj = new json::object ();
  artifact_content_obj->set ("text",
			     new json::string (utf8_content.get_buffer (),
					       utf8_content.length ()));
  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.  */

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

  for (int line = start_line; line <= end_line; line++)
    {
      char_span line_content
	= m_context->get_file_cache ().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;

  /* Don't add it if it's not valid UTF-8.  */
  if (!cpp_valid_utf8_p(text_utf8, strlen(text_utf8)))
    {
      free (text_utf8);
      return NULL;
    }

  json::object *artifact_content_obj = new json::object ();
  artifact_content_obj->set_string ("text", 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_string ("text", text);

  return content_obj;
}

/* Callback for diagnostic_context::ice_handler_cb for when an ICE
   occurs.  */

static void
sarif_ice_handler (diagnostic_context *context)
{
  /* Attempt to ensure that a .sarif file is written out.  */
  diagnostic_finish (context);

  /* Print a header for the remaining output to stderr, and
     return, attempting to print the usual ICE messages to
     stderr.  Hopefully this will be helpful to the user in
     indicating what's gone wrong (also for DejaGnu, for pruning
     those messages).   */
  fnotice (stderr, "Internal compiler error:\n");
}

class sarif_output_format : public diagnostic_output_format
{
public:
  void on_begin_group () final override
  {
    /* No-op,  */
  }
  void on_end_group () final override
  {
    m_builder.end_group ();
  }
  void
  on_begin_diagnostic (const diagnostic_info &) final override
  {
    /* No-op,  */
  }
  void
  on_end_diagnostic (const diagnostic_info &diagnostic,
		     diagnostic_t orig_diag_kind) final override
  {
    m_builder.end_diagnostic (&m_context, diagnostic, orig_diag_kind);
  }
  void on_diagram (const diagnostic_diagram &diagram) final override
  {
    m_builder.emit_diagram (&m_context, diagram);
  }

protected:
  sarif_output_format (diagnostic_context &context,
		       const char *main_input_filename_,
		       bool formatted)
  : diagnostic_output_format (context),
    m_builder (&context, main_input_filename_, formatted)
  {}

  sarif_builder m_builder;
};

class sarif_stream_output_format : public sarif_output_format
{
public:
  sarif_stream_output_format (diagnostic_context &context,
			      const char *main_input_filename_,
			      bool formatted,
			      FILE *stream)
  : sarif_output_format (context, main_input_filename_, formatted),
    m_stream (stream)
  {
  }
  ~sarif_stream_output_format ()
  {
    m_builder.flush_to_file (m_stream);
  }
  bool machine_readable_stderr_p () const final override
  {
    return m_stream == stderr;
  }
private:
  FILE *m_stream;
};

class sarif_file_output_format : public sarif_output_format
{
public:
  sarif_file_output_format (diagnostic_context &context,
			    const char *main_input_filename_,
			    bool formatted,
			    const char *base_file_name)
  : sarif_output_format (context, main_input_filename_, formatted),
    m_base_file_name (xstrdup (base_file_name))
  {
  }
  ~sarif_file_output_format ()
  {
    char *filename = concat (m_base_file_name, ".sarif", NULL);
    free (m_base_file_name);
    m_base_file_name = nullptr;
    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;
      }
    m_builder.flush_to_file (outf);
    fclose (outf);
    free (filename);
  }
  bool machine_readable_stderr_p () const final override
  {
    return false;
  }

private:
  char *m_base_file_name;
};

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

static void
diagnostic_output_format_init_sarif (diagnostic_context *context)
{
  /* Suppress normal textual path output.  */
  context->set_path_format (DPF_NONE);

  /* Override callbacks.  */
  context->set_ice_handler_callback (sarif_ice_handler);

  /* The metadata is handled in SARIF format, rather than as text.  */
  context->set_show_cwe (false);
  context->set_show_rules (false);

  /* The option is handled in SARIF format, rather than as text.  */
  context->set_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,
					    const char *main_input_filename_,
					    bool formatted)
{
  diagnostic_output_format_init_sarif (context);
  context->set_output_format
    (new sarif_stream_output_format (*context,
				     main_input_filename_,
				     formatted,
				     stderr));
}

/* 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 *main_input_filename_,
					  bool formatted,
					  const char *base_file_name)
{
  diagnostic_output_format_init_sarif (context);
  context->set_output_format
    (new sarif_file_output_format (*context,
				   main_input_filename_,
				   formatted,
				   base_file_name));
}

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

void
diagnostic_output_format_init_sarif_stream (diagnostic_context *context,
					    const char *main_input_filename_,
					    bool formatted,
					    FILE *stream)
{
  diagnostic_output_format_init_sarif (context);
  context->set_output_format
    (new sarif_stream_output_format (*context,
				     main_input_filename_,
				     formatted,
				     stream));
}
