/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.parser;

/**
 * Internal field structure for parsing recovery
 */
import java.util.HashSet;
import java.util.Set;

import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.ArrayQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;

public class RecoveredField extends RecoveredElement {

	public FieldDeclaration fieldDeclaration;
	boolean alreadyCompletedFieldInitialization;

	public RecoveredAnnotation[] annotations;
	public int annotationCount;
	
	public int modifiers;
	public int modifiersStart;

	public RecoveredType[] anonymousTypes;
	public int anonymousTypeCount;
public RecoveredField(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance){
	this(fieldDeclaration, parent, bracketBalance, null);
}
public RecoveredField(FieldDeclaration fieldDeclaration, RecoveredElement parent, int bracketBalance, Parser parser){
	super(parent, bracketBalance, parser);
	this.fieldDeclaration = fieldDeclaration;
	this.alreadyCompletedFieldInitialization = fieldDeclaration.initialization != null;
}
/*
 * Record a local declaration
 */
@Override
public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue) {
	if (this.lambdaNestLevel > 0) // current element is really the lambda which is recovered in full elsewhere.
		return this;
	return super.add(localDeclaration, bracketBalanceValue);
}
/*
 * Record a field declaration
 */
@Override
public RecoveredElement add(FieldDeclaration addedfieldDeclaration, int bracketBalanceValue) {

	/* default behavior is to delegate recording to parent if any */
	resetPendingModifiers();
	if (this.parent == null) return this; // ignore
	
	if (this.fieldDeclaration.declarationSourceStart == addedfieldDeclaration.declarationSourceStart) {
		if (this.fieldDeclaration.initialization != null) {
			this.updateSourceEndIfNecessary(this.fieldDeclaration.initialization.sourceEnd);
		} else {
			this.updateSourceEndIfNecessary(this.fieldDeclaration.sourceEnd);
		}
	} else {
		this.updateSourceEndIfNecessary(previousAvailableLineEnd(addedfieldDeclaration.declarationSourceStart - 1));
	}
	return this.parent.add(addedfieldDeclaration, bracketBalanceValue);
}
/*
 * Record an expression statement if field is expecting an initialization expression,
 * used for completion inside field initializers.
 */
@Override
public RecoveredElement add(Statement statement, int bracketBalanceValue) {

	if (this.alreadyCompletedFieldInitialization || !(statement instanceof Expression &&  ((Expression) statement).isTrulyExpression())) {
		return super.add(statement, bracketBalanceValue);
	} else {
		if (statement.sourceEnd > 0)
				this.alreadyCompletedFieldInitialization = true;
		// else we may still be inside the initialization, having parsed only a part of it yet
		if (!(statement instanceof AllocationExpression) && 
				this.fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
			AllocationExpression alloc = new AllocationExpression();
			alloc.arguments = new Expression[] {(Expression) statement};
			this.fieldDeclaration.initialization = alloc;
		} else {
			this.fieldDeclaration.initialization = (Expression) statement;
			this.fieldDeclaration.declarationSourceEnd = statement.sourceEnd;
			this.fieldDeclaration.declarationEnd = statement.sourceEnd;
		}
		return this;
	}
}
/*
 * Record a type declaration if this field is expecting an initialization expression
 * and the type is an anonymous type.
 * Used for completion inside field initializers.
 */
@Override
public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {

	if (this.alreadyCompletedFieldInitialization
			|| ((typeDeclaration.bits & ASTNode.IsAnonymousType) == 0)
			|| (this.fieldDeclaration.declarationSourceEnd != 0 && typeDeclaration.sourceStart > this.fieldDeclaration.declarationSourceEnd)) {
		return super.add(typeDeclaration, bracketBalanceValue);
	} else {
		// Prepare anonymous type list
		if (this.anonymousTypes == null) {
			this.anonymousTypes = new RecoveredType[5];
			this.anonymousTypeCount = 0;
		} else {
			if (this.anonymousTypeCount == this.anonymousTypes.length) {
				System.arraycopy(
					this.anonymousTypes,
					0,
					(this.anonymousTypes = new RecoveredType[2 * this.anonymousTypeCount]),
					0,
					this.anonymousTypeCount);
			}
		}
		// Store type declaration as an anonymous type
		RecoveredType element = new RecoveredType(typeDeclaration, this, bracketBalanceValue);
		this.anonymousTypes[this.anonymousTypeCount++] = element;
		return element;
	}
}
public void attach(RecoveredAnnotation[] annots, int annotCount, int mods, int modsSourceStart) {
	if (annotCount > 0) {
		Annotation[] existingAnnotations = this.fieldDeclaration.annotations;
		if (existingAnnotations != null) {
			this.annotations = new RecoveredAnnotation[annotCount];
			this.annotationCount = 0;
			next : for (int i = 0; i < annotCount; i++) {
				for (int j = 0; j < existingAnnotations.length; j++) {
					if (annots[i].annotation == existingAnnotations[j]) continue next;
				}
				this.annotations[this.annotationCount++] = annots[i];
			}
		} else {
			this.annotations = annots;
			this.annotationCount = annotCount;
		}
	}

	if (mods != 0) {
		this.modifiers = mods;
		this.modifiersStart = modsSourceStart;
	}
}
/*
 * Answer the associated parsed structure
 */
@Override
public ASTNode parseTree(){
	return this.fieldDeclaration;
}
/*
 * Answer the very source end of the corresponding parse node
 */
@Override
public int sourceEnd(){
	return this.fieldDeclaration.declarationSourceEnd;
}
@Override
public String toString(int tab){
	StringBuffer buffer = new StringBuffer(tabString(tab));
	buffer.append("Recovered field:\n"); //$NON-NLS-1$
	this.fieldDeclaration.print(tab + 1, buffer);
	if (this.annotations != null) {
		for (int i = 0; i < this.annotationCount; i++) {
			buffer.append("\n"); //$NON-NLS-1$
			buffer.append(this.annotations[i].toString(tab + 1));
		}
	}
	if (this.anonymousTypes != null) {
		for (int i = 0; i < this.anonymousTypeCount; i++){
			buffer.append("\n"); //$NON-NLS-1$
			buffer.append(this.anonymousTypes[i].toString(tab + 1));
		}
	}
	return buffer.toString();
}
public FieldDeclaration updatedFieldDeclaration(int depth, Set<TypeDeclaration> knownTypes){
	/* update annotations */
	if (this.modifiers != 0) {
		this.fieldDeclaration.modifiers |= this.modifiers;
		if (this.modifiersStart < this.fieldDeclaration.declarationSourceStart) {
			this.fieldDeclaration.declarationSourceStart = this.modifiersStart;
		}
	}
	/* update annotations */
	if (this.annotationCount > 0){
		int existingCount = this.fieldDeclaration.annotations == null ? 0 : this.fieldDeclaration.annotations.length;
		Annotation[] annotationReferences = new Annotation[existingCount + this.annotationCount];
		if (existingCount > 0){
			System.arraycopy(this.fieldDeclaration.annotations, 0, annotationReferences, this.annotationCount, existingCount);
		}
		for (int i = 0; i < this.annotationCount; i++){
			annotationReferences[i] = this.annotations[i].updatedAnnotationReference();
		}
		this.fieldDeclaration.annotations = annotationReferences;

		int start = this.annotations[0].annotation.sourceStart;
		if (start < this.fieldDeclaration.declarationSourceStart) {
			this.fieldDeclaration.declarationSourceStart = start;
		}
	}

	if (this.anonymousTypes != null) {
		if(this.fieldDeclaration.initialization == null) {
			ArrayInitializer recoveredInitializers = null;
			int recoveredInitializersCount = 0;
			if (this.anonymousTypeCount > 1) {
				recoveredInitializers = new ArrayInitializer();
				recoveredInitializers.expressions = new Expression[this.anonymousTypeCount];
			}
			for (int i = 0; i < this.anonymousTypeCount; i++){
				RecoveredType recoveredType = this.anonymousTypes[i];
				TypeDeclaration typeDeclaration = recoveredType.typeDeclaration;
				if(typeDeclaration.declarationSourceEnd == 0) {
					typeDeclaration.declarationSourceEnd = this.fieldDeclaration.declarationSourceEnd;
					typeDeclaration.bodyEnd = this.fieldDeclaration.declarationSourceEnd;
				}
				if (recoveredType.preserveContent){
					TypeDeclaration anonymousType = recoveredType.updatedTypeDeclaration(depth + 1, knownTypes);
					if (anonymousType != null) {
						if (this.anonymousTypeCount > 1) {
							if (recoveredInitializersCount == 0) {
								this.fieldDeclaration.initialization = recoveredInitializers;
							}
							recoveredInitializers.expressions[recoveredInitializersCount++] = anonymousType.allocation;
						}
						else {
							this.fieldDeclaration.initialization = anonymousType.allocation;							
						}
						int end = anonymousType.declarationSourceEnd;
						if (end > this.fieldDeclaration.declarationSourceEnd) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=307337
							this.fieldDeclaration.declarationSourceEnd = end;
							this.fieldDeclaration.declarationEnd = end;
						}
					}
				}
			}
			if (this.anonymousTypeCount > 0) {
				this.fieldDeclaration.bits |= ASTNode.HasLocalType;
				if (recoveredInitializers != null) {
					recoveredInitializers.sourceStart = this.anonymousTypes[0].typeDeclaration.sourceStart;
					recoveredInitializers.sourceEnd = this.anonymousTypes[this.anonymousTypeCount-1].
							typeDeclaration.sourceEnd;
				}
			}
		}
		else if(this.fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
			// fieldDeclaration is an enum constant
			for (int i = 0; i < this.anonymousTypeCount; i++){
				RecoveredType recoveredType = this.anonymousTypes[i];
				TypeDeclaration typeDeclaration = recoveredType.typeDeclaration;
				if(typeDeclaration.declarationSourceEnd == 0) {
					typeDeclaration.declarationSourceEnd = this.fieldDeclaration.declarationSourceEnd;
					typeDeclaration.bodyEnd = this.fieldDeclaration.declarationSourceEnd;
				}
				// if the enum is recovered then enum constants must be recovered too.
				// depth is considered as the same as the depth of the enum
				recoveredType.updatedTypeDeclaration(depth, knownTypes);
			}
		}
	}
	return this.fieldDeclaration;
}
/*
 * A closing brace got consumed, might have closed the current element,
 * in which case both the currentElement is exited.
 *
 * Fields have no associated braces, thus if matches, then update parent.
 */
@Override
public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
	if (this.bracketBalance > 0){ // was an array initializer
		this.bracketBalance--;
		if (this.bracketBalance == 0) {
			if(this.fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT) {
				updateSourceEndIfNecessary(braceEnd);
				return this.parent;
			} else {
				if (this.fieldDeclaration.declarationSourceEnd > 0)
					this.alreadyCompletedFieldInitialization = true;
			}
		}
		return this;
	} else if (this.bracketBalance == 0) {
		this.alreadyCompletedFieldInitialization = true;
		updateSourceEndIfNecessary(braceEnd - 1);
	}
	if (this.parent != null){
		return this.parent.updateOnClosingBrace(braceStart, braceEnd);
	}
	return this;
}
/*
 * An opening brace got consumed, might be the expected opening one of the current element,
 * in which case the bodyStart is updated.
 */
@Override
public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
	if (this.fieldDeclaration.declarationSourceEnd == 0) {
		if (this.fieldDeclaration.type instanceof ArrayTypeReference || this.fieldDeclaration.type instanceof ArrayQualifiedTypeReference) {
			if (!this.alreadyCompletedFieldInitialization) {
				this.bracketBalance++;
				return null; // no update is necessary	(array initializer)
			}
		} else {  // https://bugs.eclipse.org/bugs/show_bug.cgi?id=308980
			// in case an initializer bracket is opened in a non-array field
			// e.g. int field = {..
			this.bracketBalance++;
			return null; // no update is necessary	(array initializer)
		}
	}
	if (this.fieldDeclaration.declarationSourceEnd == 0
		&& this.fieldDeclaration.getKind() == AbstractVariableDeclaration.ENUM_CONSTANT){
		this.bracketBalance++;
		return null; // no update is necessary	(enum constant)
	}
	// might be an array initializer
	this.updateSourceEndIfNecessary(braceStart - 1, braceEnd - 1);
	return this.parent.updateOnOpeningBrace(braceStart, braceEnd);
}
@Override
public void updateParseTree(){
	updatedFieldDeclaration(0, new HashSet<TypeDeclaration>());
}
/*
 * Update the declarationSourceEnd of the corresponding parse node
 */
@Override
public void updateSourceEndIfNecessary(int bodyStart, int bodyEnd){
	if (this.fieldDeclaration.declarationSourceEnd == 0) {
		this.fieldDeclaration.declarationSourceEnd = bodyEnd;
		this.fieldDeclaration.declarationEnd = bodyEnd;
	}
}
}
