//
// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include "compiler/translator/Diagnostics.h"

#include "common/debug.h"
#include "compiler/preprocessor/SourceLocation.h"
#include "compiler/translator/Common.h"
#include "compiler/translator/InfoSink.h"

namespace sh
{

TDiagnostics::TDiagnostics(TInfoSinkBase &infoSink)
    : mInfoSink(infoSink), mNumErrors(0), mNumWarnings(0)
{
}

TDiagnostics::~TDiagnostics()
{
}

void TDiagnostics::writeInfo(Severity severity,
                             const pp::SourceLocation &loc,
                             const char *reason,
                             const char *token)
{
    switch (severity)
    {
        case SH_ERROR:
            ++mNumErrors;
            break;
        case SH_WARNING:
            ++mNumWarnings;
            break;
        default:
            UNREACHABLE();
            break;
    }

    /* VC++ format: file(linenum) : error #: 'token' : extrainfo */
    mInfoSink.prefix(severity);
    mInfoSink.location(loc.file, loc.line);
    mInfoSink << "'" << token << "' : " << reason << "\n";
}

void TDiagnostics::globalError(const char *message)
{
    ++mNumErrors;
    mInfoSink.prefix(SH_ERROR);
    mInfoSink << message << "\n";
}

void TDiagnostics::error(const pp::SourceLocation &loc, const char *reason, const char *token)
{
    writeInfo(SH_ERROR, loc, reason, token);
}

void TDiagnostics::warning(const pp::SourceLocation &loc, const char *reason, const char *token)
{
    writeInfo(SH_WARNING, loc, reason, token);
}

void TDiagnostics::error(const TSourceLoc &loc, const char *reason, const char *token)
{
    pp::SourceLocation srcLoc;
    srcLoc.file = loc.first_file;
    srcLoc.line = loc.first_line;
    error(srcLoc, reason, token);
}

void TDiagnostics::warning(const TSourceLoc &loc, const char *reason, const char *token)
{
    pp::SourceLocation srcLoc;
    srcLoc.file = loc.first_file;
    srcLoc.line = loc.first_line;
    warning(srcLoc, reason, token);
}

void TDiagnostics::print(ID id, const pp::SourceLocation &loc, const std::string &text)
{
    writeInfo(isError(id) ? SH_ERROR : SH_WARNING, loc, message(id), text.c_str());
}

void TDiagnostics::resetErrorCount()
{
    mNumErrors   = 0;
    mNumWarnings = 0;
}

}  // namespace sh
