/*******************************************************************************
* Copyright (c) 2014, 2015 Cisco Systems, Inc. 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
*
*******************************************************************************/
package com.cisco.yangide.core.dom;
import java.util.Collection;
/**
* @author Konstantin Zaitsev
* @date Jun 26, 2014
*/
public abstract class ASTNode {
/** Common field "description" for Yang statement. */
private SimpleNode<String> descriptionNode;
/** Common field "reference" for Yang statement. */
private SimpleNode<String> referenceNode;
/** Common field "status" for Yang statement. */
private SimpleNode<String> statusNode;
/**
* A character index into the original source string, or <code>-1</code> if no source position
* information is available for this node; <code>-1</code> by default.
*/
private int startPosition = -1;
/**
* A character length, or <code>0</code> if no source position information is recorded for this
* node; <code>0</code> by default.
*/
private int length = 0;
/** Line number. */
private int lineNumber = -1;
/** Start position of AST node body '{' or '"'. */
private int bodyStartPosition = -1;
/** Parent AST node. */
private ASTNode parent = null;
/**
* Flag constant (bit mask, value 1) indicating that there is something not quite right with
* this AST node.
* <p>
* The standard parser (<code>ASTParser</code>) SHOULD set this flag on a node to indicate a
* syntax error detected in the vicinity.
* </p>
*/
public static final int MALFORMED = 1;
public static final int VALID = 0;
/**
* int containing the node type in the top 16 bits and flags in the bottom 16 bits; none set by
* default.
* <p>
* N.B. This is a private field, but declared as package-visible for more efficient access from
* inner classes.
* </p>
*
* @see #MALFORMED
*/
int typeAndFlags = 0;
/**
* Returns the flags associated with this node.
* <p>
* No flags are associated with newly created nodes.
* </p>
* <p>
* The flags are the bitwise-or of individual flags. The following flags are currently defined:
* <ul>
* <li>{@link #MALFORMED} - indicates node is syntactically malformed</li>
* </ul>
* Other bit positions are reserved for future use.
* </p>
*
* @return the bitwise-or of individual flags
* @see #setFlags(int)
*/
public final int getFlags() {
return this.typeAndFlags & 0xFFFF;
}
/**
* Sets the flags associated with this node to the given value.
* <p>
* The flags are the bitwise-or of individual flags. The following flags are currently defined:
* <ul>
* <li>{@link #MALFORMED} - indicates node is syntactically malformed</li>
* </ul>
* Other bit positions are reserved for future use.
* </p>
* <p>
* Note that the flags are <em>not</em> considered a structural property of the node, and can be
* changed even if the node is marked as protected.
* </p>
*
* @param flags the bitwise-or of individual flags
* @see #getFlags()
*/
public final void setFlags(int flags) {
int old = this.typeAndFlags & 0xFFFF0000;
this.typeAndFlags = old | (flags & 0xFFFF);
}
public ASTNode(ASTNode parent) {
this.parent = parent;
if (parent instanceof ASTCompositeNode) {
((ASTCompositeNode) parent).getChildren().add(this);
}
}
/**
* @return the startPosition
*/
public int getStartPosition() {
return startPosition;
}
/**
* @param startPosition the startPosition to set
*/
public void setStartPosition(int startPosition) {
this.startPosition = startPosition;
}
/**
* @return the length
*/
public int getLength() {
return length;
}
/**
* @param length the length to set
*/
public void setLength(int length) {
this.length = length;
}
public int getEndPosition() {
return this.startPosition + this.length;
}
/**
* @return the parent
*/
public ASTNode getParent() {
return parent;
}
/**
* @return the parent module of this node
*/
public ASTNode getModule() {
ASTNode module = this;
while (module.getParent() != null) {
module = module.getParent();
}
if (module instanceof Module) {
return module;
}
return null;
}
/**
* @return the description
*/
public String getDescription() {
return descriptionNode != null ? descriptionNode.getValue() : null;
}
/**
* @return the reference
*/
public String getReference() {
return referenceNode != null ? referenceNode.getValue() : null;
}
/**
* @return the status
*/
public String getStatus() {
return statusNode != null ? statusNode.getValue() : null;
}
/**
* @return the lineNumber
*/
public int getLineNumber() {
return lineNumber;
}
/**
* @param lineNumber the lineNumber to set
*/
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
/**
* @return the bodyStartPosition
*/
public int getBodyStartPosition() {
return bodyStartPosition;
}
/**
* @param bodyStartPosition the bodyStartPosition to set
*/
public void setBodyStartPosition(int bodyStartPosition) {
this.bodyStartPosition = bodyStartPosition;
}
/**
* @return the bodyLenght
*/
public int getBodyLength() {
return (bodyStartPosition >= 0 && startPosition >= 0) ? (length - (bodyStartPosition - startPosition) + 1) : 0;
}
/**
* @return the bodyEndPosition
*/
public int getBodyEndPosition() {
return bodyStartPosition + getBodyLength();
}
/**
* @return the name
*/
public abstract String getNodeName();
public abstract void accept(ASTVisitor visitor);
final void acceptChild(ASTVisitor visitor, ASTNode child) {
if (child == null) {
return;
}
child.accept(visitor);
}
final void acceptChildren(ASTVisitor visitor, Collection<? extends ASTNode> children) {
for (ASTNode child : children) {
child.accept(visitor);
}
}
public boolean isShowedInOutline() {
return true;
}
/**
* @return the descriptionNode
*/
public SimpleNode<String> getDescriptionNode() {
return descriptionNode;
}
/**
* @param descriptionNode the descriptionNode to set
*/
public void setDescriptionNode(SimpleNode<String> descriptionNode) {
this.descriptionNode = descriptionNode;
}
/**
* @return the referenceNode
*/
public SimpleNode<String> getReferenceNode() {
return referenceNode;
}
/**
* @param referenceNode the referenceNode to set
*/
public void setReferenceNode(SimpleNode<String> referenceNode) {
this.referenceNode = referenceNode;
}
/**
* @return the statusNode
*/
public SimpleNode<String> getStatusNode() {
return statusNode;
}
/**
* @param statusNode the statusNode to set
*/
public void setStatusNode(SimpleNode<String> statusNode) {
this.statusNode = statusNode;
}
}