/*
 * [The "BSD license"]
 *  Copyright (c) 2010 Terence Parr
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *      derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package org.antlr.tool;

import org.stringtemplate.v4.ST;

/** The ANTLR code calls methods on ErrorManager to report errors etc...
 *  Rather than simply pass these arguments to the ANTLRErrorListener directly,
 *  create an object that encapsulates everything.  In this way, the error
 *  listener interface does not have to change when I add a new kind of
 *  error message.  I don't want to break a GUI for example every time
 *  I update the error system in ANTLR itself.
 *
 *  To get a printable error/warning message, call toString().
 */
public abstract class Message {
	// msgST is the actual text of the message
	public ST msgST;
	// these are for supporting different output formats
	public ST locationST;
	public ST reportST;
	public ST messageFormatST;

	public int msgID;
	public Object arg;
	public Object arg2;
	public Throwable e;
	// used for location template
	public String file;
	public int line = -1;
	public int column = -1;

	public Message() {
	}

	public Message(int msgID) {
		this(msgID, null, null);
	}

	public Message(int msgID, Object arg, Object arg2) {
		setMessageID(msgID);
		this.arg = arg;
		this.arg2 = arg2;
	}

	public void setLine(int line) {
		this.line = line;
	}

	public void setColumn(int column) {
		this.column = column;
	}

	public void setMessageID(int msgID) {
		this.msgID = msgID;
		msgST = ErrorManager.getMessage(msgID);
	}

	/** Return a new template instance every time someone tries to print
	 *  a Message.
	 */
	public ST getMessageTemplate() { return new ST(msgST); }

	/** Return a new template instance for the location part of a Message.
	 *  TODO: Is this really necessary? -Kay
	 */
	public ST getLocationTemplate() { return new ST(locationST); }

	public String toString(ST messageST) {
		// setup the location
		locationST = ErrorManager.getLocationFormat();
		reportST = ErrorManager.getReportFormat();
		messageFormatST = ErrorManager.getMessageFormat();
		boolean locationValid = false;
		if (line != -1) {
			locationST.add("line", line);
			locationValid = true;
		}
		if (column != -1) {
			locationST.add("column", column+1);
			locationValid = true;
		}
		if (file != null) {
			locationST.add("file", file);
			locationValid = true;
		}

		messageFormatST.add("id", msgID);
		messageFormatST.add("text", messageST);

		if (locationValid) {
			reportST.add("location", locationST);
		}
		reportST.add("message", messageFormatST);
		reportST.add("type", ErrorManager.getMessageType(msgID));

		return reportST.render();
	}
}
