// rust-diagnostics.cc -- GCC implementation of rust diagnostics interface.
// Copyright (C) 2016-2024 Free Software Foundation, Inc.
// Contributed by Than McIntosh, Google.

// 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 "rust-system.h"
#include "rust-diagnostics.h"

#include "options.h"
#include "diagnostic-metadata.h"

static std::string
mformat_value ()
{
  return std::string (xstrerror (errno));
}

// Rewrite a format string to expand any extensions not
// supported by sprintf(). See comments in rust-diagnostics.h
// for list of supported format specifiers.

static std::string
expand_format (const char *fmt)
{
  std::stringstream ss;
  for (const char *c = fmt; *c; ++c)
    {
      if (*c != '%')
	{
	  ss << *c;
	  continue;
	}
      c++;
      switch (*c)
	{
	  case '\0': {
	    // malformed format string
	    rust_unreachable ();
	  }
	  case '%': {
	    ss << "%";
	    break;
	  }
	  case 'm': {
	    ss << mformat_value ();
	    break;
	  }
	  case '<': {
	    ss << rust_open_quote ();
	    break;
	  }
	  case '>': {
	    ss << rust_close_quote ();
	    break;
	  }
	  case 'q': {
	    ss << rust_open_quote ();
	    c++;
	    if (*c == 'm')
	      {
		ss << mformat_value ();
	      }
	    else
	      {
		ss << "%" << *c;
	      }
	    ss << rust_close_quote ();
	    break;
	  }
	  default: {
	    ss << "%" << *c;
	  }
	}
    }
  return ss.str ();
}

// Expand message format specifiers, using a combination of
// expand_format above to handle extensions (ex: %m, %q) and vasprintf()
// to handle regular printf-style formatting. A pragma is being used here to
// suppress this warning:
//
//   warning: function ‘std::__cxx11::string expand_message(const char*,
//   __va_list_tag*)’ might be a candidate for ‘gnu_printf’ format attribute
//   [-Wsuggest-attribute=format]
//
// What appears to be happening here is that the checker is deciding that
// because of the call to vasprintf() (which has attribute gnu_printf), the
// calling function must need to have attribute gnu_printf as well, even
// though there is already an attribute declaration for it.

static std::string
expand_message (const char *fmt, va_list ap) RUST_ATTRIBUTE_GCC_DIAG (1, 0);

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"

static std::string
expand_message (const char *fmt, va_list ap)
{
  char *mbuf = 0;
  std::string expanded_fmt = expand_format (fmt);
  int nwr = vasprintf (&mbuf, expanded_fmt.c_str (), ap);
  if (nwr == -1)
    {
      // memory allocation failed
      rust_be_error_at (UNKNOWN_LOCATION,
			"memory allocation failed in vasprintf");
      rust_assert (0);
    }
  std::string rval = std::string (mbuf);
  free (mbuf);
  return rval;
}

#pragma GCC diagnostic pop

static const char *cached_open_quote = NULL;
static const char *cached_close_quote = NULL;

void
rust_be_get_quotechars (const char **open_qu, const char **close_qu)
{
  *open_qu = open_quote;
  *close_qu = close_quote;
}

const char *
rust_open_quote ()
{
  if (cached_open_quote == NULL)
    rust_be_get_quotechars (&cached_open_quote, &cached_close_quote);
  return cached_open_quote;
}

const char *
rust_close_quote ()
{
  if (cached_close_quote == NULL)
    rust_be_get_quotechars (&cached_open_quote, &cached_close_quote);
  return cached_close_quote;
}

void
rust_be_internal_error_at (const location_t location, const std::string &errmsg)
{
  std::string loc_str = Linemap::location_to_string (location);
  if (loc_str.empty ())
    internal_error ("%s", errmsg.c_str ());
  else
    internal_error ("at %s, %s", loc_str.c_str (), errmsg.c_str ());
}

void
rust_internal_error_at (const location_t location, const char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);
  rust_be_internal_error_at (location, expand_message (fmt, ap));
  va_end (ap);
}

void
rust_be_error_at (const location_t location, const std::string &errmsg)
{
  error_at (location, "%s", errmsg.c_str ());
}

void
rust_error_at (const location_t location, const char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);
  rust_be_error_at (location, expand_message (fmt, ap));
  va_end (ap);
}

class rust_error_code_rule : public diagnostic_metadata::rule
{
public:
  rust_error_code_rule (const ErrorCode code) : m_code (code) {}

  void format_error_code (char *buffer) const
  {
    // we can use the `u` format specifier because the `ErrorCode` enum class
    // "inherits" from `unsigned int` - add a static assertion to make sure
    // that's the case before we do the formatting
    static_assert (
      std::is_same<std::underlying_type<ErrorCode>::type, unsigned int>::value,
      "invalid format specifier for ErrorCode's underlying type");

    snprintf (buffer, 6, "E%04u",
	      (std::underlying_type<ErrorCode>::type) m_code);
  }

  char *make_description () const final override
  {
    // 'E' + 4 characters + \0
    char *buffer = static_cast<char *> (xcalloc (6, sizeof (char)));

    format_error_code (buffer);

    return buffer;
  }

  char *make_url () const final override
  {
    char buffer[6] = {0};
    format_error_code (buffer);

    return concat ("https://doc.rust-lang.org/error-index.html#", buffer, NULL);
  }

private:
  const ErrorCode m_code;
};

void
rust_be_error_at (const location_t location, const ErrorCode code,
		  const std::string &errmsg)
{
  rich_location gcc_loc (line_table, location);
  diagnostic_metadata m;
  rust_error_code_rule rule (code);
  m.add_rule (rule);
  error_meta (&gcc_loc, m, "%s", errmsg.c_str ());
}

void
rust_error_at (const location_t location, const ErrorCode code, const char *fmt,
	       ...)
{
  va_list ap;

  va_start (ap, fmt);
  rust_be_error_at (location, code, expand_message (fmt, ap));
  va_end (ap);
}

void
rust_be_error_at (const rich_location &location, const ErrorCode code,
		  const std::string &errmsg)
{
  /* TODO: 'error_at' would like a non-'const' 'rich_location *'.  */
  rich_location &gcc_loc = const_cast<rich_location &> (location);
  diagnostic_metadata m;
  rust_error_code_rule rule (code);
  m.add_rule (rule);
  error_meta (&gcc_loc, m, "%s", errmsg.c_str ());
}

void
rust_error_at (const rich_location &location, const ErrorCode code,
	       const char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);
  rust_be_error_at (location, code, expand_message (fmt, ap));
  va_end (ap);
}

void
rust_be_error_at (rich_location *richloc, const ErrorCode code,
		  const std::string &errmsg)
{
  diagnostic_metadata m;
  rust_error_code_rule rule (code);
  m.add_rule (rule);
  error_meta (richloc, m, "%s", errmsg.c_str ());
}

void
rust_error_at (rich_location *richloc, const ErrorCode code, const char *fmt,
	       ...)
{
  /* TODO: Refactoring diagnostics to this overload */
  va_list ap;

  va_start (ap, fmt);
  rust_be_error_at (richloc, code, expand_message (fmt, ap));
  va_end (ap);
}

void
rust_be_warning_at (const location_t location, int opt,
		    const std::string &warningmsg)
{
  warning_at (location, opt, "%s", warningmsg.c_str ());
}

void
rust_warning_at (const location_t location, int opt, const char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);
  rust_be_warning_at (location, opt, expand_message (fmt, ap));
  va_end (ap);
}

void
rust_be_fatal_error (const location_t location, const std::string &fatalmsg)
{
  fatal_error (location, "%s", fatalmsg.c_str ());
}

void
rust_fatal_error (const location_t location, const char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);
  rust_be_fatal_error (location, expand_message (fmt, ap));
  va_end (ap);
}

void
rust_be_inform (const location_t location, const std::string &infomsg)
{
  inform (location, "%s", infomsg.c_str ());
}

void
rust_inform (const location_t location, const char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);
  rust_be_inform (location, expand_message (fmt, ap));
  va_end (ap);
}

// Rich Locations
void
rust_be_error_at (const rich_location &location, const std::string &errmsg)
{
  /* TODO: 'error_at' would like a non-'const' 'rich_location *'.  */
  rich_location &gcc_loc = const_cast<rich_location &> (location);
  error_at (&gcc_loc, "%s", errmsg.c_str ());
}

void
rust_error_at (const rich_location &location, const char *fmt, ...)
{
  va_list ap;

  va_start (ap, fmt);
  rust_be_error_at (location, expand_message (fmt, ap));
  va_end (ap);
}

void
rust_be_error_at (rich_location *richloc, const std::string &errmsg)
{
  error_at (richloc, "%s", errmsg.c_str ());
}

void
rust_error_at (rich_location *richloc, const char *fmt, ...)
{
  /* TODO: Refactoring diagnostics to this overload */
  va_list ap;

  va_start (ap, fmt);
  rust_be_error_at (richloc, expand_message (fmt, ap));
  va_end (ap);
}

bool
rust_be_debug_p (void)
{
  return !!flag_rust_debug;
}

void
rust_debug_loc (const location_t location, const char *fmt, ...)
{
  if (!rust_be_debug_p ())
    return;

  va_list ap;

  va_start (ap, fmt);
  char *mbuf = NULL;
  int nwr = vasprintf (&mbuf, fmt, ap);
  va_end (ap);
  if (nwr == -1)
    {
      rust_be_error_at (UNKNOWN_LOCATION,
			"memory allocation failed in vasprintf");
      rust_assert (0);
    }
  std::string rval = std::string (mbuf);
  free (mbuf);
  rust_be_inform (location, rval);
}

namespace Rust {

/**
 * This function takes ownership of `args` and calls `va_end` on it
 */

// simple location
static Error
va_constructor (Error::Kind kind, location_t locus, const char *fmt,
		va_list args) RUST_ATTRIBUTE_GCC_DIAG (3, 0);

// simple location + error code
static Error
va_constructor (Error::Kind kind, location_t locus, const ErrorCode code,
		const char *fmt, va_list args) RUST_ATTRIBUTE_GCC_DIAG (4, 0);

// rich location
static Error
va_constructor (Error::Kind kind, rich_location *r_locus, const char *fmt,
		va_list args) RUST_ATTRIBUTE_GCC_DIAG (3, 0);

// rich location + error code
static Error
va_constructor (Error::Kind kind, rich_location *r_locus, const ErrorCode code,
		const char *fmt, va_list args) RUST_ATTRIBUTE_GCC_DIAG (4, 0);

// simple location
static Error
va_constructor (Error::Kind kind, location_t locus, const char *fmt,
		va_list args)
{
  std::string message = expand_message (fmt, args);
  message.shrink_to_fit ();
  va_end (args);

  return Error (kind, locus, message);
}

// simple location + error code
static Error
va_constructor (Error::Kind kind, location_t locus, const ErrorCode code,
		const char *fmt, va_list args)
{
  std::string message = expand_message (fmt, args);
  message.shrink_to_fit ();
  va_end (args);

  return Error (kind, locus, code, message);
}

// rich location
static Error
va_constructor (Error::Kind kind, rich_location *r_locus, const char *fmt,
		va_list args)
{
  std::string message = expand_message (fmt, args);
  message.shrink_to_fit ();
  va_end (args);

  return Error (kind, r_locus, message);
}

// rich location + error code
static Error
va_constructor (Error::Kind kind, rich_location *r_locus, const ErrorCode code,
		const char *fmt, va_list args)
{
  std::string message = expand_message (fmt, args);
  message.shrink_to_fit ();
  va_end (args);

  return Error (kind, r_locus, code, message);
}

// simple location
Error::Error (const location_t location, const char *fmt, ...)
  : kind (Kind::Err), locus (location)
{
  va_list ap;
  va_start (ap, fmt);

  *this = va_constructor (Kind::Err, location, fmt, ap);
}

// simple location + error code
Error::Error (const location_t location, const ErrorCode code, const char *fmt,
	      ...)
  : kind (Kind::Err), locus (location), errorcode (code)
{
  va_list ap;
  va_start (ap, fmt);

  *this = va_constructor (Kind::Err, location, code, fmt, ap);
}

// rich location
Error::Error (rich_location *r_locus, const char *fmt, ...)
  : kind (Kind::Err), richlocus (r_locus)
{
  va_list ap;
  va_start (ap, fmt);

  *this = va_constructor (Kind::Err, r_locus, fmt, ap);
}

// rich location + error code
Error::Error (rich_location *r_locus, const ErrorCode code, const char *fmt,
	      ...)
  : kind (Kind::Err), richlocus (r_locus), errorcode (code)
{
  va_list ap;
  va_start (ap, fmt);

  *this = va_constructor (Kind::Err, r_locus, code, fmt, ap);
}

Error
Error::Hint (const location_t location, const char *fmt, ...)
{
  va_list ap;
  va_start (ap, fmt);

  return va_constructor (Kind::Hint, location, fmt, ap);
}

Error
Error::Fatal (const location_t location, const char *fmt, ...)
{
  va_list ap;
  va_start (ap, fmt);

  return va_constructor (Kind::FatalErr, location, fmt, ap);
}

} // namespace Rust
