/*******************************************************************************
 * Copyright (c) 2000, 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.formatter;

import java.util.List;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.InvalidInputException;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.parser.JavadocParser;
import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
import org.eclipse.jdt.internal.formatter.comment.IJavaDocTagConstants;

/**
 * Internal parser used for formatting javadoc comments.
 */
public class FormatterCommentParser extends JavadocParser implements IJavaDocTagConstants {
	char[][] htmlTags;
	int htmlTagsPtr = -1;
	int inlineHtmlTagsPtr = -1;
	private boolean invalidTagName;
	public boolean parseHtmlTags;

public FormatterCommentParser(long sourceLevel) {
	super(null);
	this.kind = FORMATTER_COMMENT_PARSER | TEXT_PARSE;
	this.reportProblems = false;
	this.checkDocComment = true;
	this.sourceLevel = sourceLevel;
}

public boolean parse(int start, int end) {

	// Init
	this.javadocStart = start;
	this.javadocEnd = end;
	this.firstTagPosition = this.javadocStart;
	// Need to flush html tags stack in case of unclosed ones in previous javadoc comments
	// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=239941
	this.htmlTagsPtr = -1;

	// parse comment
	boolean valid = commentParse();

	return valid && this.docComment != null;
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#createArgumentReference(char[], int, boolean, java.lang.Object, long[], long)
 */
protected Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object ref, long[] dimPositions, long argNamePos) throws InvalidInputException {
	FormatJavadocReference typeRef = (FormatJavadocReference) ref;
	if (dim > 0) {
		typeRef.sourceEnd = (int) dimPositions[dim-1];
	}
	if (argNamePos >= 0) typeRef.sourceEnd = (int) argNamePos;
	return ref;
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#createFakeReference(int)
 */
protected boolean createFakeReference(int start) {
	// synch scanner and parser positions
	this.scanner.currentPosition = this.index;
	// create reference in order to be able to format it
	int lineStart = this.scanner.getLineNumber(start);
	FormatJavadocReference reference = new FormatJavadocReference(start, this.index-1, lineStart);
	return pushSeeRef(reference);
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#createFieldReference(java.lang.Object)
 */
protected Object createFieldReference(Object receiver) throws InvalidInputException {
	int start = receiver == null ? this.memberStart : ((FormatJavadocReference)receiver).sourceStart;
	int lineStart = this.scanner.getLineNumber(start);
	return new FormatJavadocReference(start, (int) this.identifierPositionStack[0], lineStart);
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#createMethodReference(java.lang.Object, java.util.List)
 */
protected Object createMethodReference(Object receiver, List arguments) throws InvalidInputException {
	int start = receiver == null ? this.memberStart : ((FormatJavadocReference) receiver).sourceStart;
	int lineStart = this.scanner.getLineNumber(start);
	return new FormatJavadocReference(start, this.scanner.getCurrentTokenEndPosition(), lineStart);
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#createTag()
 */
protected void createTag() {
	int lineStart = this.scanner.getLineNumber(this.tagSourceStart);
	if (this.inlineTagStarted) {
		FormatJavadocBlock block = new FormatJavadocBlock(this.inlineTagStart, this.tagSourceEnd, lineStart, this.tagValue);
		FormatJavadocBlock previousBlock = null;
		if (this.astPtr == -1) {
			previousBlock = new FormatJavadocBlock(this.inlineTagStart, this.tagSourceEnd, lineStart, NO_TAG_VALUE);
			pushOnAstStack(previousBlock, true);
		} else {
			previousBlock = (FormatJavadocBlock) this.astStack[this.astPtr];
		}
		previousBlock.addBlock(block, this.htmlTagsPtr == -1 ? 0 : this.htmlTagsPtr);
	} else {
		FormatJavadocBlock block = new FormatJavadocBlock(this.tagSourceStart, this.tagSourceEnd, lineStart, this.tagValue);
		pushOnAstStack(block, true);
	}
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#createTypeReference(int)
 */
protected Object createTypeReference(int primitiveToken) {
	int size = this.identifierLengthStack[this.identifierLengthPtr];
	if (size == 0) return null;
	int start = (int) (this.identifierPositionStack[this.identifierPtr] >>> 32);
	int lineStart = this.scanner.getLineNumber(start);
	if (size == 1) {
		return new FormatJavadocReference(this.identifierPositionStack[this.identifierPtr], lineStart);
	}
	long[] positions = new long[size];
	System.arraycopy(this.identifierPositionStack, this.identifierPtr - size + 1, positions, 0, size);
	return new FormatJavadocReference((int) (positions[0] >>> 32), (int) positions[positions.length-1], lineStart);
}

/*
 * Return the html tag index in the various arrays of IJavaDocTagConstants.
 * The returned int is set as follow:
 * 	- the array index is set on bits 0 to 7
 * 	- the tag category is set on bit 8 to 15 (0xFF00 if no array includes the tag)
 */
private int getHtmlTagIndex(char[] htmlTag) {
	int length = htmlTag == null ? 0 : htmlTag.length;
	int tagId = 0;
	if (length > 0) {
		for (int i=0, max=JAVADOC_SINGLE_BREAK_TAG.length; i<max; i++) {
			char[] tag = JAVADOC_SINGLE_BREAK_TAG[i];
			if (length == tag.length && CharOperation.equals(htmlTag, tag, false)) {
				return (tagId | JAVADOC_SINGLE_BREAK_TAG_ID) + i;
			}
		}
		for (int i=0, max=JAVADOC_CODE_TAGS.length; i<max; i++) {
			char[] tag = JAVADOC_CODE_TAGS[i];
			if (length == tag.length && CharOperation.equals(htmlTag, tag, false)) {
				return (tagId | JAVADOC_CODE_TAGS_ID) + i;
			}
		}
		for (int i=0, max=JAVADOC_BREAK_TAGS.length; i<max; i++) {
			char[] tag = JAVADOC_BREAK_TAGS[i];
			if (length == tag.length && CharOperation.equals(htmlTag, tag, false)) {
				return (tagId | JAVADOC_BREAK_TAGS_ID) + i;
			}
		}
		for (int i=0, max=JAVADOC_IMMUTABLE_TAGS.length; i<max; i++) {
			char[] tag = JAVADOC_IMMUTABLE_TAGS[i];
			if (length == tag.length && CharOperation.equals(htmlTag, tag, false)) {
				return (tagId | JAVADOC_IMMUTABLE_TAGS_ID) + i;
			}
		}
		for (int i=0, max=JAVADOC_SEPARATOR_TAGS.length; i<max; i++) {
			char[] tag = JAVADOC_SEPARATOR_TAGS[i];
			if (length == tag.length && CharOperation.equals(htmlTag, tag, false)) {
				return (tagId | JAVADOC_SEPARATOR_TAGS_ID) + i;
			}
		}
	}
	return JAVADOC_TAGS_ID_MASK;
}

/*
 * Parse an HTML tag expected to be either opening (e.g. <tag_name> ) or
 * closing (e.g. </tag_name>).
 */
protected boolean parseHtmlTag(int previousPosition, int endTextPosition) throws InvalidInputException {
	if (!this.parseHtmlTags) return false;
    boolean closing = false;
    boolean valid = false;
    boolean incremented = false;
    int start = this.scanner.currentPosition;
    int currentPosition = start;
    int htmlPtr = this.htmlTagsPtr;
    char firstChar = peekChar();
    boolean hasWhitespaces = firstChar == ' ' || ScannerHelper.isWhitespace(firstChar);
	try {
	    int token = readTokenAndConsume();
	    char[] htmlTag;
	    int htmlIndex;
	    switch (token) {
	    	case TerminalTokens.TokenNameIdentifier:
	    		// HTML tag opening
				htmlTag = this.scanner.getCurrentIdentifierSource();
				htmlIndex = getHtmlTagIndex(htmlTag);
				if (htmlIndex == JAVADOC_TAGS_ID_MASK) return false;
				if (htmlPtr >= 0) {
		    		int lastHtmlTagIndex = getHtmlTagIndex(this.htmlTags[htmlPtr]);
					if ((lastHtmlTagIndex & JAVADOC_TAGS_ID_MASK) == JAVADOC_IMMUTABLE_TAGS_ID) {
						// Do not accept tags inside immutable tags except the <pre> tag
						if ((htmlIndex & JAVADOC_TAGS_ID_MASK) == JAVADOC_CODE_TAGS_ID) {
							FormatJavadocBlock previousBlock = (FormatJavadocBlock) this.astStack[this.astPtr];
							FormatJavadocNode parentNode = previousBlock;
							FormatJavadocNode lastNode = parentNode;
							while (lastNode.getLastNode() != null) {
								parentNode = lastNode;
								lastNode = lastNode.getLastNode();
							}
							if (lastNode.isText()) {
								FormatJavadocText text = (FormatJavadocText) lastNode;
								if (text.separatorsPtr == -1) {
									break;
								}
							}
						}
		    			return false;
					}
	    		}
				if ((htmlIndex & JAVADOC_TAGS_ID_MASK) > JAVADOC_SINGLE_TAGS_ID) {
		    		if (this.htmlTagsPtr == -1 || !CharOperation.equals(this.htmlTags[this.htmlTagsPtr], htmlTag, false)) {
						if (++this.htmlTagsPtr == 0) { // lazy initialization
							this.htmlTags = new char[AST_STACK_INCREMENT][];
						} else { // resize if needed
							if (this.htmlTagsPtr == this.htmlTags.length) {
								System.arraycopy(this.htmlTags, 0, (this.htmlTags = new char[this.htmlTags.length + AST_STACK_INCREMENT][]), 0, this.htmlTagsPtr);
							}
						}
						this.htmlTags[this.htmlTagsPtr] = htmlTag;
						incremented = true;
		    		}
				}
				// Accept xhtml syntax
				currentPosition = this.scanner.currentPosition;
				if (readToken() == TerminalTokens.TokenNameDIVIDE) {
					consumeToken();
				}
		    	break;
	    	case TerminalTokens.TokenNameDIVIDE:
	    		// HTML tag closing
	    		if (this.htmlTagsPtr == -1) return false;
	    		htmlTag = this.htmlTags[this.htmlTagsPtr];
	    		if ((token = readTokenAndConsume()) != TerminalTokens.TokenNameIdentifier) {
	    			// not a closing html tag
	    			return false;
	    		}
				char[] identifier = this.scanner.getCurrentIdentifierSource();
				htmlIndex = getHtmlTagIndex(identifier);
				if (htmlIndex == JAVADOC_TAGS_ID_MASK) return false;
				int ptr = this.htmlTagsPtr;
	    		while (!CharOperation.equals(htmlTag, identifier, false)) {
	    			if (this.htmlTagsPtr <= 0) {
	    				// consider the closing tag as invalid
	    				this.htmlTagsPtr = ptr;
	    				return false;
	    			}
	    			this.htmlTagsPtr--;
		    		htmlTag = this.htmlTags[this.htmlTagsPtr];
	    		}
				// set closing flag
				htmlIndex |= JAVADOC_CLOSED_TAG;
				closing = true;
				currentPosition = this.scanner.currentPosition;
	    		break;
	    	default:
    			return false;
	    }
	    
	    // Looking for tag closing
	    switch (readTokenAndConsume()) {
	    	case TerminalTokens.TokenNameLESS:
	    	case TerminalTokens.TokenNameLESS_EQUAL:
	    		// consider that the closing '>' is missing
	    		return false;
	    	case TerminalTokens.TokenNameGREATER:
	    		// simple tag without attributes
	    		break;
	    	case TerminalTokens.TokenNameGREATER_EQUAL:
	    	case TerminalTokens.TokenNameRIGHT_SHIFT:
	    	case TerminalTokens.TokenNameRIGHT_SHIFT_EQUAL:
	    		// simple tag without attributes, but the closing '>' is followed by an '=' or '>'
	    		break;
	    	default:
	    		this.index = currentPosition;
	    		loop: while (true) {
//	    			currentPosition = this.index;
				    switch (readChar()) {
				    	case '<':
				    		if (hasWhitespaces) {
				    			// not 100% sure this is a tag definition => give up
				    			return false;
				    		}
				    		// opening tag => consider the current one as closed
				    		this.index = currentPosition;
				    		this.scanner.startPosition = currentPosition;
				    		this.scanner.currentPosition = currentPosition;
				    		this.scanner.currentCharacter = '<';
				    		break loop;
				    	case '>':
				    		// simple tag without attributes
				    		this.scanner.startPosition = this.index;
				    		this.scanner.currentPosition = this.index;
				    		this.scanner.currentCharacter = peekChar();
				    		break loop;
			    		default:
			    			break;
				    }
				    if (this.index >= this.javadocTextEnd) {
		    			// the end of the comment is reached => consider current tag as closed
			    		this.index = currentPosition;
			    		this.scanner.startPosition = currentPosition;
			    		this.scanner.currentPosition = currentPosition;
			    		break;
				    }
	    		}
		}

	    // Push texts
		if (this.lineStarted && this.textStart != -1 && this.textStart < endTextPosition) {
			pushText(this.textStart, endTextPosition, -1, htmlPtr);
		}
		pushText(previousPosition, this.index, htmlIndex, this.htmlTagsPtr);
		this.textStart = -1;
		valid = true;
	}
	finally {
		if (valid) {
			if (closing) {
				this.htmlTagsPtr--;
			}
		} else if (!this.abort) {
	    	if (incremented) {
	    		this.htmlTagsPtr--;
	    		if (this.htmlTagsPtr == -1) this.htmlTags = null;
	    	}
	    	this.scanner.resetTo(start, this.scanner.eofPosition-1);
	    	this.index = start;
		}
	}
    return valid;
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#parseIdentifierTag(boolean)
 */
protected boolean parseIdentifierTag(boolean report) {
	if (super.parseIdentifierTag(report)) {
		createTag();
		this.index = this.tagSourceEnd+1;
		this.scanner.resetTo(this.index, this.javadocEnd);
		return true;
	}
	this.tagValue = TAG_OTHERS_VALUE; // tag is invalid, do not keep the parsed tag value
	return false;
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#parseParam()
 */
protected boolean parseParam() throws InvalidInputException {
	boolean valid = super.parseParam();
	if (!valid) {
		this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
		this.index = this.tagSourceEnd+1;
		char ch = peekChar();
		// Try to push an identifier in the stack, otherwise restart from the end tag position
		if (ch == ' ' || ScannerHelper.isWhitespace(ch)) {
			int token = this.scanner.getNextToken();
			if (token == TerminalTokens.TokenNameIdentifier) {
				ch = peekChar();
				if (ch == ' ' || ScannerHelper.isWhitespace(ch)) {
					pushIdentifier(true, false);
					pushParamName(false);
					this.index = this.scanner.currentPosition;
					valid = true;
				}
			}
			this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
		}
		this.tagValue = TAG_OTHERS_VALUE; // tag is invalid, do not keep the parsed tag value
	}
	return valid;
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#parseReference()
 */
protected boolean parseReference() throws InvalidInputException {
	boolean valid = super.parseReference();
	if (!valid) {
		this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
		this.index = this.tagSourceEnd+1;
		this.tagValue = TAG_OTHERS_VALUE; // tag is invalid, do not keep the parsed tag value
	}
	return valid;
}

/*
 * Parse @return tag declaration
 */
protected boolean parseReturn() {
	createTag();
	return true;
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#parseTag(int)
 */
protected boolean parseTag(int previousPosition) throws InvalidInputException {

	// Do not parse javadoc tag inside <pre>...</pre> tags
	if (this.htmlTagsPtr >= 0) {
		int ptr = this.htmlTagsPtr;
   		while (ptr >= 0) {
			if (getHtmlTagIndex(this.htmlTags[ptr--]) == JAVADOC_CODE_TAGS_ID) {
				if (this.textStart == -1) this.textStart = this.inlineTagStarted ? this.inlineTagStart : previousPosition;
				this.inlineTagStarted = false;
				return true;
			}
		}
	}

	// Read tag name
	int ptr = this.astPtr;
	this.tagSourceStart = previousPosition;
	this.scanner.startPosition = this.index;
	this.scanner.currentCharacter = readChar();
	switch (this.scanner.currentCharacter) {
		case ' ':
		case '*':
		case '}':
			// tag name is empty
			this.tagSourceEnd = previousPosition;
			if (this.textStart == -1) this.textStart = previousPosition;
			return true;
		default:
			if (ScannerHelper.isWhitespace(this.scanner.currentCharacter)) {
				// tag name is empty
				this.tagSourceEnd = previousPosition;
				if (this.textStart == -1) this.textStart = previousPosition;
				return true;
			}
			break;
	}
	int currentPosition = this.index;
	char currentChar = this.scanner.currentCharacter;
	while (currentChar != ' ' && currentChar != '*' && currentChar != '}' && !ScannerHelper.isWhitespace(currentChar)) {
		currentPosition = this.index;
		currentChar = readChar();
	}
	this.tagSourceEnd = currentPosition - 1;
	this.scanner.currentCharacter = currentChar;
	this.scanner.currentPosition = currentPosition;
	char[] tagName = this.scanner.getCurrentIdentifierSource();
	int length = tagName.length;
	this.index = this.tagSourceEnd+1;

	// Decide which parse to perform depending on tag name
	this.tagValue = TAG_OTHERS_VALUE;
	boolean valid = false;
	switch (tagName[0]) {
		case 'a':
			if (length == TAG_AUTHOR_LENGTH && CharOperation.equals(TAG_AUTHOR, tagName)) {
				this.tagValue = TAG_AUTHOR_VALUE;
			}
			break;
		case 'c':
			if (length == TAG_CATEGORY_LENGTH && CharOperation.equals(TAG_CATEGORY, tagName)) {
				this.tagValue = TAG_CATEGORY_VALUE;
				valid = parseIdentifierTag(false); // TODO (frederic) reconsider parameter value when @category will be significant in spec
			} else if (length == TAG_CODE_LENGTH && this.inlineTagStarted && CharOperation.equals(TAG_CODE, tagName)) {
				this.tagValue = TAG_CODE_VALUE;
			}
			break;
		case 'd':
			if (length == TAG_DEPRECATED_LENGTH && CharOperation.equals(TAG_DEPRECATED, tagName)) {
				this.deprecated = true;
				valid = true;
				this.tagValue = TAG_DEPRECATED_VALUE;
			} else if (length == TAG_DOC_ROOT_LENGTH && CharOperation.equals(TAG_DOC_ROOT, tagName)) {
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=227730
				// identify @docRoot tag as a base tag that does not expect any argument
				valid = true;
				this.tagValue = TAG_DOC_ROOT_VALUE;
			}
			break;
		case 'e':
			if (length == TAG_EXCEPTION_LENGTH && CharOperation.equals(TAG_EXCEPTION, tagName)) {
				this.tagValue = TAG_EXCEPTION_VALUE;
				valid = parseThrows();
			}
			break;
		case 'i':
			if (length == TAG_INHERITDOC_LENGTH && CharOperation.equals(TAG_INHERITDOC, tagName)) {
				if (this.reportProblems) {
					recordInheritedPosition((((long) this.tagSourceStart) << 32) + this.tagSourceEnd);
				}
				valid = true;
				this.tagValue = TAG_INHERITDOC_VALUE;
			}
			break;
		case 'l':
			if (length == TAG_LINK_LENGTH && CharOperation.equals(TAG_LINK, tagName)) {
				this.tagValue = TAG_LINK_VALUE;
				if (this.inlineTagStarted || (this.kind & COMPLETION_PARSER) != 0) {
					valid = parseReference();
				} else {
					// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
					// Cannot have @link outside inline comment
					valid = false;
					if (this.reportProblems) {
						this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
					}
				}
			} else if (length == TAG_LINKPLAIN_LENGTH && CharOperation.equals(TAG_LINKPLAIN, tagName)) {
				this.tagValue = TAG_LINKPLAIN_VALUE;
				if (this.inlineTagStarted) {
					valid = parseReference();
				} else {
					valid = false;
					if (this.reportProblems) {
						this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
					}
				}
			} else if (length == TAG_LITERAL_LENGTH && this.inlineTagStarted && CharOperation.equals(TAG_LITERAL, tagName)) {
				this.tagValue = TAG_LITERAL_VALUE;
			}
			break;
		case 'p':
			if (length == TAG_PARAM_LENGTH && CharOperation.equals(TAG_PARAM, tagName)) {
				this.tagValue = TAG_PARAM_VALUE;
				valid = parseParam();
			}
			break;
		case 's':
			if (length == TAG_SEE_LENGTH && CharOperation.equals(TAG_SEE, tagName)) {
				if (this.inlineTagStarted) {
					// bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=53290
					// Cannot have @see inside inline comment
					valid = false;
					if (this.reportProblems) {
						this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
					}
				} else {
					this.tagValue = TAG_SEE_VALUE;
					valid = parseReference();
				}
			} else if (length == TAG_SERIAL_LENGTH && CharOperation.equals(TAG_SERIAL, tagName)) {
				this.tagValue = TAG_SERIAL_VALUE;
			} else if (length == TAG_SERIAL_DATA_LENGTH && CharOperation.equals(TAG_SERIAL_DATA, tagName)) {
				this.tagValue = TAG_SERIAL_DATA_VALUE;
			} else if (length == TAG_SERIAL_FIELD_LENGTH && CharOperation.equals(TAG_SERIAL_FIELD, tagName)) {
				this.tagValue = TAG_SERIAL_FIELD_VALUE;
			} else if (length == TAG_SINCE_LENGTH && CharOperation.equals(TAG_SINCE, tagName)) {
				this.tagValue = TAG_SINCE_VALUE;
			}
			break;
		case 'v':
			if (length == TAG_VALUE_LENGTH && CharOperation.equals(TAG_VALUE, tagName)) {
				this.tagValue = TAG_VALUE_VALUE;
				if (this.sourceLevel >= ClassFileConstants.JDK1_5) {
					if (this.inlineTagStarted) {
						valid = parseReference();
					} else {
						valid = false;
						if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd);
					}
				}
			} else if (length == TAG_VERSION_LENGTH && CharOperation.equals(TAG_VERSION, tagName)) {
				this.tagValue = TAG_VERSION_VALUE;
			} else {
				createTag();
			}
			break;
		case 'r':
			if (length == TAG_RETURN_LENGTH && CharOperation.equals(TAG_RETURN, tagName)) {
				this.tagValue = TAG_RETURN_VALUE;
				valid = parseReturn();
			}
			break;
		case 't':
			if (length == TAG_THROWS_LENGTH && CharOperation.equals(TAG_THROWS, tagName)) {
				this.tagValue = TAG_THROWS_VALUE;
				valid = parseThrows();
			}
			break;
		default:
			createTag();
			break;
	}
	consumeToken();
	this.textStart = -1;

	// the javadoc parser may not create tag for some valid tags: force tag creation for such tag.
	if (valid) {
		switch (this.tagValue) {
			case TAG_INHERITDOC_VALUE:
			case TAG_DEPRECATED_VALUE:
				createTag();
				break;
		}
	} else if (this.invalidTagName) {
		this.textStart = previousPosition;
	} else if (this.astPtr == ptr) {
		createTag();
	}
	return true;
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#parseThrows()
 */
protected boolean parseThrows() {
	boolean valid = super.parseThrows();
	if (!valid) {
		// If invalid, restart from the end tag position
		this.scanner.resetTo(this.tagSourceEnd+1, this.javadocEnd);
		this.index = this.tagSourceEnd+1;
		this.tagValue = TAG_OTHERS_VALUE; // tag is invalid, do not keep the parsed tag value
	}
	return valid;
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#pushParamName(boolean)
 */
protected boolean pushParamName(boolean isTypeParam) {
	int lineTagStart = this.scanner.getLineNumber(this.tagSourceStart);
	FormatJavadocBlock block = new FormatJavadocBlock(this.tagSourceStart, this.tagSourceEnd, lineTagStart, TAG_PARAM_VALUE);
	int start = (int) (this.identifierPositionStack[0] >>> 32);
	int lineStart = this.scanner.getLineNumber(start);
	FormatJavadocReference reference;
	reference = new FormatJavadocReference(start, (int) this.identifierPositionStack[isTypeParam ? 2 : 0], lineStart);
	block.reference = reference;
	block.sourceEnd = reference.sourceEnd;
	pushOnAstStack(block, true);
	return true;
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.JavadocParser#pushSeeRef(java.lang.Object)
 */
protected boolean pushSeeRef(Object statement) {
	FormatJavadocReference reference = (FormatJavadocReference) statement;
	int lineTagStart = this.scanner.getLineNumber(this.tagSourceStart);
	FormatJavadocBlock block = new FormatJavadocBlock(this.tagSourceStart, this.tagSourceEnd, lineTagStart, this.tagValue);
	block.reference = reference;
	block.sourceEnd = reference.sourceEnd;
	if (this.inlineTagStarted) {
		block.sourceStart = this.inlineTagStart;
		FormatJavadocBlock previousBlock = null;
		if (this.astPtr == -1) {
			int lineStart = this.scanner.getLineNumber(this.inlineTagStart);
			previousBlock = new FormatJavadocBlock(this.inlineTagStart, this.tagSourceEnd, lineStart, NO_TAG_VALUE);
			previousBlock.sourceEnd = reference.sourceEnd;
			pushOnAstStack(previousBlock, true);
		} else {
			previousBlock = (FormatJavadocBlock) this.astStack[this.astPtr];
		}
		previousBlock.addBlock(block, this.htmlTagsPtr == -1 ? 0 : this.htmlTagsPtr);
		block.flags |= FormatJavadocBlock.INLINED;
	} else {
		pushOnAstStack(block, true);
	}

	return true;
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#pushText(int, int)
 */
protected void pushText(int start, int end) {
	pushText(start, end, -1, this.htmlTagsPtr == -1 ? 0 : this.htmlTagsPtr);
}

private void pushText(int start, int end, int htmlIndex, int htmlDepth) {

	// Search previous tag on which to add the text element
	FormatJavadocBlock previousBlock = null;
	int previousStart = start;
	int lineStart = this.scanner.getLineNumber(start);
	if (this.astPtr == -1) {
		previousBlock = new FormatJavadocBlock(start, start, lineStart, NO_TAG_VALUE);
		pushOnAstStack(previousBlock, true);
	} else {
		previousBlock = (FormatJavadocBlock) this.astStack[this.astPtr];
		previousStart = previousBlock.sourceStart;
	}

	// If we're in a inline tag, then retrieve previous tag in its fragments
	if (this.inlineTagStarted) {
		if (previousBlock.nodes == null) {
			// no existing fragment => just add the element
		} else {
			// If last fragment is a tag, then use it as previous tag
			FormatJavadocNode lastNode = previousBlock.nodes[previousBlock.nodesPtr];
			while (lastNode != null && lastNode.isText()) {
				lastNode = lastNode.getLastNode();
			}
			if (lastNode != null) {
				previousBlock = (FormatJavadocBlock) lastNode;
				previousStart = previousBlock.sourceStart;
			}
		}
	}

	// Add the text
	FormatJavadocText text = new FormatJavadocText(start, end-1, lineStart, htmlIndex, htmlDepth==-1 ? 0 : htmlDepth);
	previousBlock.addText(text);
	previousBlock.sourceStart = previousStart;
	if (lineStart == previousBlock.lineStart) {
		previousBlock.flags |= FormatJavadocBlock.TEXT_ON_TAG_LINE;
	}
	this.textStart = -1;
}

/*
 * (non-Javadoc)
 *
 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#pushThrowName(java.lang.Object)
 */
protected boolean pushThrowName(Object typeRef) {
	int lineStart = this.scanner.getLineNumber(this.tagSourceStart);
	FormatJavadocBlock block = new FormatJavadocBlock(this.tagSourceStart, this.tagSourceEnd, lineStart, this.tagValue);
	block.reference = (FormatJavadocReference) typeRef;
	block.sourceEnd = block.reference.sourceEnd;
	pushOnAstStack(block, true);
	return true;
}

/*
 * (non-Javadoc)
 * Will update the inline tag position (end position) once tag was fully parsed.
 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#refreshInlineTagPosition(int)
 */
protected void refreshInlineTagPosition(int previousPosition) {
	if (this.astPtr != -1) {
		FormatJavadocNode previousBlock = (FormatJavadocNode) this.astStack[this.astPtr];
		if (this.inlineTagStarted) {
			FormatJavadocNode lastNode = previousBlock;
			while (lastNode != null) {
				lastNode.sourceEnd = previousPosition;
				lastNode = lastNode.getLastNode();
			}
		}
	}
}

/*
 * Store the html tags level when entering an inline tag in case a wrong sequence
 * of opening/closing tags is defined inside it. Then, when leaving the inline tag
 * the level is reset to the entering value and avoid to wrongly attach subsequent
 * html tags to node inside the inline tag last node...
 */
protected void setInlineTagStarted(boolean started) {
	super.setInlineTagStarted(started);
	if (started) {
		this.inlineHtmlTagsPtr = this.htmlTagsPtr;
	} else {
		if (this.htmlTagsPtr > this.inlineHtmlTagsPtr) {
			this.htmlTagsPtr = this.inlineHtmlTagsPtr;
		}
	}
}

public String toString() {
	StringBuffer buffer = new StringBuffer();
	buffer.append("FormatterCommentParser\n"); //$NON-NLS-1$
	buffer.append(super.toString());
	return buffer.toString();
}

public String toDebugString() {
	if (this.docComment == null) {
		return "No javadoc!";	//$NON-NLS-1$
	}
	return ((FormatJavadoc)this.docComment).toDebugString(this.source);
}

/*
 * Add stored tag elements to associated comment.
 * Clean all blocks (i.e. resize arrays to avoid null slots)
 * Set extra information on block about line relative positions.
 */
protected void updateDocComment() {
	int length = this.astPtr + 1;
	FormatJavadoc formatJavadoc = new FormatJavadoc(this.javadocStart, this.javadocEnd, length);
	if (length > 0) {
		formatJavadoc.blocks = new FormatJavadocBlock[length];
		for (int i=0; i<length; i++) {
			FormatJavadocBlock block = (FormatJavadocBlock) this.astStack[i];
			block.clean();
			block.update(this.scanner);
			formatJavadoc.blocks[i] = block;
			if (i== 0) {
				block.flags |= FormatJavadocBlock.FIRST;
			}
		}
	}
	formatJavadoc.textStart = this.javadocTextStart;
	formatJavadoc.textEnd = this.javadocTextEnd;
	formatJavadoc.lineStart = this.scanner.getLineNumber(this.javadocTextStart);
	formatJavadoc.lineEnd = this.scanner.getLineNumber(this.javadocTextEnd);
	FormatJavadocBlock firstBlock = formatJavadoc.getFirstBlock();
	if (firstBlock != null) {
		firstBlock.setHeaderLine(formatJavadoc.lineStart);
	}
	this.docComment = formatJavadoc;
	if (DefaultCodeFormatter.DEBUG) {
		System.out.println(toDebugString());
	}
}

/* (non-Javadoc)
 * @see org.eclipse.jdt.internal.compiler.parser.AbstractCommentParser#verifyEndLine(int)
 */
protected boolean verifyEndLine(int textPosition) {
	// do not verify anything at end of line while formatting
	return true;
}

protected boolean verifySpaceOrEndComment() {
	// Don't care if there's no spaces after a reference...
	return true;
}
}
