Yang Listener for BITS Data Type
Change-Id: I81e7f7e8de38ce20addd63548414a486b7e2ffb8
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangBit.java b/src/main/java/org/onosproject/yangutils/datamodel/YangBit.java
index 5e33e36..77f19c1 100644
--- a/src/main/java/org/onosproject/yangutils/datamodel/YangBit.java
+++ b/src/main/java/org/onosproject/yangutils/datamodel/YangBit.java
@@ -20,6 +20,8 @@
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.parser.ParsableDataType;
+import java.util.Objects;
+
/*-
* The "bit" statement, which is a sub-statement to the "type" statement,
* MUST be present if the type is "bits". It is repeatedly used to
@@ -57,7 +59,7 @@
private String description;
/**
- * reference info of the bit field.
+ * Reference info of the bit field.
*/
private String reference;
@@ -67,7 +69,7 @@
private YangStatusType status;
/**
- * position of the bit whose name bit is described.
+ * Position of the bit whose name bit is described.
*/
private int position;
@@ -79,7 +81,7 @@
}
/**
- * Get the bit name.
+ * Returns bit name.
*
* @return the bit name.
*/
@@ -97,7 +99,7 @@
}
/**
- * Get the description.
+ * Returns description.
*
* @return the description.
*/
@@ -117,7 +119,7 @@
}
/**
- * Get the textual reference.
+ * Returns textual reference.
*
* @return the reference.
*/
@@ -137,7 +139,7 @@
}
/**
- * Get the status.
+ * Returns status.
*
* @return the status.
*/
@@ -157,7 +159,7 @@
}
/**
- * Get the bit position.
+ * Returns bit position.
*
* @return the position
*/
@@ -184,6 +186,23 @@
return ParsableDataType.BIT_DATA;
}
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj instanceof YangBit) {
+ final YangBit other = (YangBit) obj;
+ return Objects.equals(this.bitName, other.bitName);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.bitName);
+ }
+
/**
* Validate the data on entering the corresponding parse tree node.
*
diff --git a/src/main/java/org/onosproject/yangutils/datamodel/YangBits.java b/src/main/java/org/onosproject/yangutils/datamodel/YangBits.java
index d519925..54898a4 100644
--- a/src/main/java/org/onosproject/yangutils/datamodel/YangBits.java
+++ b/src/main/java/org/onosproject/yangutils/datamodel/YangBits.java
@@ -36,8 +36,12 @@
*/
public class YangBits implements Parsable {
+ // Bits information set.
private Set<YangBit> bitSet;
+ // BITS name.
+ private String bitsName;
+
/**
* Create a YANG bits type object.
*/
@@ -46,7 +50,7 @@
}
/**
- * Get the bit set.
+ * Returns the bit set.
*
* @return the bit set
*/
@@ -55,7 +59,7 @@
}
/**
- * set the bit set.
+ * Set the bit set.
*
* @param bitSet the bit set
*/
@@ -66,10 +70,13 @@
/**
* Add bit info.
*
- * @param bitInfo the bit Info to add.
+ * @param bitInfo the bit information to be added.
+ * @throws DataModelException due to violation in data model rules.
*/
- public void addBitInfo(YangBit bitInfo) {
- getBitSet().add(bitInfo);
+ public void addBitInfo(YangBit bitInfo) throws DataModelException {
+ if (!getBitSet().add(bitInfo)) {
+ throw new DataModelException("YANG Bit already exists");
+ }
}
/**
@@ -83,6 +90,24 @@
}
/**
+ * Returns the bits name.
+ *
+ * @return name of the bits.
+ */
+ public String getBitsName() {
+ return bitsName;
+ }
+
+ /**
+ * Set bits name.
+ *
+ * @param bitsName bit name to be set.
+ */
+ public void setBitsName(String bitsName) {
+ this.bitsName = bitsName;
+ }
+
+ /**
* Validate the data on entering the corresponding parse tree node.
*
* @throws DataModelException a violation of data model rules.
diff --git a/src/main/java/org/onosproject/yangutils/parser/ParsableDataType.java b/src/main/java/org/onosproject/yangutils/parser/ParsableDataType.java
index 9d2cfb0..046a214 100644
--- a/src/main/java/org/onosproject/yangutils/parser/ParsableDataType.java
+++ b/src/main/java/org/onosproject/yangutils/parser/ParsableDataType.java
@@ -225,6 +225,11 @@
ORGANIZATION_DATA,
/**
+ * Identifies the YANG position element parsed data.
+ */
+ POSITION_DATA,
+
+ /**
* Identifies the derived data type.
*/
DERIVED;
@@ -318,6 +323,8 @@
return "organization";
case VALUE_DATA:
return "value";
+ case POSITION_DATA:
+ return "position";
case DEFAULT_DATA:
return "default";
case DERIVED:
diff --git a/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java b/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java
index 20e086f..e2f4d70 100644
--- a/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java
+++ b/src/main/java/org/onosproject/yangutils/parser/impl/TreeWalkListener.java
@@ -27,6 +27,8 @@
import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
import org.onosproject.yangutils.parser.impl.listeners.BaseFileListener;
import org.onosproject.yangutils.parser.impl.listeners.BelongsToListener;
+import org.onosproject.yangutils.parser.impl.listeners.BitListener;
+import org.onosproject.yangutils.parser.impl.listeners.BitsListener;
import org.onosproject.yangutils.parser.impl.listeners.ConfigListener;
import org.onosproject.yangutils.parser.impl.listeners.ContactListener;
import org.onosproject.yangutils.parser.impl.listeners.ContainerListener;
@@ -46,6 +48,7 @@
import org.onosproject.yangutils.parser.impl.listeners.ModuleListener;
import org.onosproject.yangutils.parser.impl.listeners.NamespaceListener;
import org.onosproject.yangutils.parser.impl.listeners.OrganizationListener;
+import org.onosproject.yangutils.parser.impl.listeners.PositionListener;
import org.onosproject.yangutils.parser.impl.listeners.PrefixListener;
import org.onosproject.yangutils.parser.impl.listeners.PresenceListener;
import org.onosproject.yangutils.parser.impl.listeners.ReferenceListener;
@@ -691,22 +694,22 @@
@Override
public void enterBitsSpecification(GeneratedYangParser.BitsSpecificationContext ctx) {
- // TODO: implement the method.
+ BitsListener.processBitsEntry(this, ctx);
}
@Override
public void exitBitsSpecification(GeneratedYangParser.BitsSpecificationContext ctx) {
- // TODO: implement the method.
+ BitsListener.processBitsExit(this, ctx);
}
@Override
public void enterBitStatement(GeneratedYangParser.BitStatementContext ctx) {
- // TODO: implement the method.
+ BitListener.processBitEntry(this, ctx);
}
@Override
public void exitBitStatement(GeneratedYangParser.BitStatementContext ctx) {
- // TODO: implement the method.
+ BitListener.processBitExit(this, ctx);
}
@Override
@@ -721,7 +724,7 @@
@Override
public void enterPositionStatement(GeneratedYangParser.PositionStatementContext ctx) {
- // TODO: implement the method.
+ PositionListener.processPositionEntry(this, ctx);
}
@Override
diff --git a/src/main/java/org/onosproject/yangutils/parser/impl/listeners/BitListener.java b/src/main/java/org/onosproject/yangutils/parser/impl/listeners/BitListener.java
new file mode 100644
index 0000000..a574091
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/parser/impl/listeners/BitListener.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2014-2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yangutils.parser.impl.listeners;
+
+/*
+ * Reference: RFC6020 and YANG ANTLR Grammar
+ *
+ * ABNF grammar as per RFC6020
+ * bit-stmt = bit-keyword sep identifier-arg-str optsep
+ * (";" /
+ * "{" stmtsep
+ * ;; these stmts can appear in any order
+ * [position-stmt stmtsep]
+ * [status-stmt stmtsep]
+ * [description-stmt stmtsep]
+ * [reference-stmt stmtsep]
+ * "}"
+ * "}")
+ *
+ * ANTLR grammar rule
+ * bitStatement : BIT_KEYWORD IDENTIFIER (STMTEND | LEFT_CURLY_BRACE bitBodyStatement RIGHT_CURLY_BRACE);
+ *
+ * bitBodyStatement : positionStatement? statusStatement? descriptionStatement? referenceStatement?
+ * | positionStatement? statusStatement? referenceStatement? descriptionStatement?
+ * | positionStatement? descriptionStatement? statusStatement? referenceStatement?
+ * | positionStatement? descriptionStatement? referenceStatement? statusStatement?
+ * | positionStatement? referenceStatement? statusStatement? descriptionStatement?
+ * | positionStatement? referenceStatement? descriptionStatement? statusStatement?
+ * | statusStatement? positionStatement? descriptionStatement? referenceStatement?
+ * | statusStatement? positionStatement? referenceStatement? descriptionStatement?
+ * | statusStatement? descriptionStatement? descriptionStatement? positionStatement?
+ * | statusStatement? descriptionStatement? positionStatement? descriptionStatement?
+ * | statusStatement? referenceStatement? positionStatement? descriptionStatement?
+ * | statusStatement? referenceStatement? descriptionStatement? positionStatement?
+ * | descriptionStatement? positionStatement? statusStatement? referenceStatement?
+ * | descriptionStatement? positionStatement? referenceStatement? statusStatement?
+ * | descriptionStatement? statusStatement? positionStatement? referenceStatement?
+ * | descriptionStatement? statusStatement? referenceStatement? positionStatement?
+ * | descriptionStatement? referenceStatement? positionStatement? statusStatement?
+ * | descriptionStatement? referenceStatement? statusStatement? positionStatement?
+ * | referenceStatement? positionStatement? descriptionStatement? statusStatement?
+ * | referenceStatement? positionStatement? statusStatement? descriptionStatement?
+ * | referenceStatement? statusStatement? descriptionStatement? positionStatement?
+ * | referenceStatement? statusStatement? positionStatement? descriptionStatement?
+ * | referenceStatement? descriptionStatement? positionStatement? statusStatement?
+ * | referenceStatement? descriptionStatement? statusStatement? positionStatement?
+ * ;
+ */
+
+import org.onosproject.yangutils.datamodel.YangBit;
+import org.onosproject.yangutils.datamodel.YangBits;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
+import org.onosproject.yangutils.parser.Parsable;
+import static org.onosproject.yangutils.parser.ParsableDataType.BIT_DATA;
+import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.TreeWalkListener;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_CONTENT;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
+
+/**
+ * Implements listener based call back function corresponding to the "bit"
+ * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
+ */
+public final class BitListener {
+
+ /**
+ * Creates a new bit listener.
+ */
+ private BitListener() {
+ }
+
+ /**
+ * It is called when parser enters grammar rule (bit), it perform
+ * validations and updates the data model tree.
+ *
+ * @param listener listener's object.
+ * @param ctx context object of the grammar rule.
+ */
+ public static void processBitEntry(TreeWalkListener listener,
+ GeneratedYangParser.BitStatementContext ctx) {
+
+ // Check for stack to be non empty.
+ checkStackIsNotEmpty(listener, MISSING_HOLDER, BIT_DATA, ctx.IDENTIFIER().getText(), ENTRY);
+
+ YangBit bitNode = new YangBit();
+ bitNode.setBitName(ctx.IDENTIFIER().getText());
+ listener.getParsedDataStack().push(bitNode);
+ }
+
+ /**
+ * It is called when parser exits from grammar rule (bit), it perform
+ * validations and update the data model tree.
+ *
+ * @param listener Listener's object.
+ * @param ctx context object of the grammar rule.
+ */
+ public static void processBitExit(TreeWalkListener listener,
+ GeneratedYangParser.BitStatementContext ctx) {
+
+ // Check for stack to be non empty.
+ checkStackIsNotEmpty(listener, MISSING_HOLDER, BIT_DATA, ctx.IDENTIFIER().getText(), EXIT);
+
+ Parsable tmpBitNode = listener.getParsedDataStack().peek();
+ if (tmpBitNode instanceof YangBit) {
+ listener.getParsedDataStack().pop();
+
+ // Check for stack to be non empty.
+ checkStackIsNotEmpty(listener, MISSING_HOLDER, BIT_DATA, ctx.IDENTIFIER().getText(), EXIT);
+
+ Parsable tmpNode = listener.getParsedDataStack().peek();
+ switch (tmpNode.getParsableDataType()) {
+ case BITS_DATA: {
+ YangBits yangBits = (YangBits) tmpNode;
+ if ((ctx.bitBodyStatement() == null) || (ctx.bitBodyStatement().positionStatement() == null)) {
+ int maxPosition = 0;
+ boolean isPositionPresent = false;
+
+ for (YangBit curBit : yangBits.getBitSet()) {
+ if (maxPosition <= curBit.getPosition()) {
+ maxPosition = curBit.getPosition();
+ isPositionPresent = true;
+ }
+ }
+ if (isPositionPresent) {
+ maxPosition++;
+ }
+ ((YangBit) tmpBitNode).setPosition(maxPosition);
+ }
+ try {
+ yangBits.addBitInfo((YangBit) tmpBitNode);
+ } catch (DataModelException e) {
+ ParserException parserException = new ParserException(constructExtendedListenerErrorMessage(
+ INVALID_CONTENT, BIT_DATA, ctx.IDENTIFIER().getText(), EXIT, e.getMessage()));
+ parserException.setLine(ctx.IDENTIFIER().getSymbol().getLine());
+ parserException.setCharPosition(ctx.IDENTIFIER().getSymbol().getCharPositionInLine());
+ throw parserException;
+ }
+ break;
+ }
+ default:
+ throw new ParserException(
+ constructListenerErrorMessage(INVALID_HOLDER, BIT_DATA, ctx.IDENTIFIER().getText(), EXIT));
+ }
+ } else {
+ throw new ParserException(
+ constructListenerErrorMessage(MISSING_CURRENT_HOLDER, BIT_DATA, ctx.IDENTIFIER().getText(), EXIT));
+ }
+ }
+}
diff --git a/src/main/java/org/onosproject/yangutils/parser/impl/listeners/BitsListener.java b/src/main/java/org/onosproject/yangutils/parser/impl/listeners/BitsListener.java
new file mode 100644
index 0000000..d8f8467
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/parser/impl/listeners/BitsListener.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright 2014-2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yangutils.parser.impl.listeners;
+
+/*
+ * Reference: RFC6020 and YANG ANTLR Grammar
+ *
+ * ABNF grammar as per RFC6020
+ * type-body-stmts = numerical-restrictions /
+ * decimal64-specification /
+ * string-restrictions /
+ * enum-specification /
+ * leafref-specification /
+ * identityref-specification /
+ * instance-identifier-specification /
+ * bits-specification /
+ * union-specification
+ *
+ * bits-specification = 1*(bit-stmt stmtsep)
+ *
+ * ANTLR grammar rule
+ *
+ * typeBodyStatements : numericalRestrictions | stringRestrictions | enumSpecification
+ * | leafrefSpecification | identityrefSpecification | instanceIdentifierSpecification
+ * | bitsSpecification | unionSpecification;
+ *
+ * bitsSpecification : bitStatement+;
+ */
+
+import org.onosproject.yangutils.datamodel.YangBits;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangLeafList;
+import org.onosproject.yangutils.datamodel.YangType;
+import org.onosproject.yangutils.parser.Parsable;
+import static org.onosproject.yangutils.parser.ParsableDataType.BITS_DATA;
+import static org.onosproject.yangutils.parser.ParsableDataType.TYPE_DATA;
+import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.TreeWalkListener;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
+
+/**
+ * Implements listener based call back function corresponding to the "bits"
+ * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
+ */
+public final class BitsListener {
+
+ /**
+ * Creates a new bits listener.
+ */
+ private BitsListener() {
+ }
+
+ /**
+ * It is called when parser enters grammar rule (bits), it perform
+ * validations and updates the data model tree.
+ *
+ * @param listener listener's object.
+ * @param ctx context object of the grammar rule.
+ */
+ public static void processBitsEntry(TreeWalkListener listener,
+ GeneratedYangParser.BitsSpecificationContext ctx) {
+
+ // Check for stack to be non empty.
+ checkStackIsNotEmpty(listener, MISSING_HOLDER, BITS_DATA, "", ENTRY);
+
+ if (listener.getParsedDataStack().peek() instanceof YangType) {
+ YangBits bitsNode = new YangBits();
+ Parsable typeData = listener.getParsedDataStack().pop();
+
+ // Check for stack to be non empty.
+ checkStackIsNotEmpty(listener, MISSING_HOLDER, BITS_DATA, "", ENTRY);
+
+ Parsable tmpData = listener.getParsedDataStack().peek();
+
+ switch (tmpData.getParsableDataType()) {
+ case LEAF_DATA:
+ bitsNode.setBitsName(((YangLeaf) tmpData).getLeafName());
+ break;
+ case LEAF_LIST_DATA:
+ bitsNode.setBitsName(((YangLeafList) tmpData).getLeafName());
+ break;
+ // TODO typedef, union, deviate.
+ default:
+ throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
+ ((YangType) typeData).getDataTypeName(), ENTRY));
+ }
+ listener.getParsedDataStack().push(typeData);
+ listener.getParsedDataStack().push(bitsNode);
+ } else {
+ throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, BITS_DATA, "", ENTRY));
+ }
+ }
+
+ /**
+ * It is called when parser exits from grammar rule (bits), it perform
+ * validations and update the data model tree.
+ *
+ * @param listener Listener's object.
+ * @param ctx context object of the grammar rule.
+ */
+ public static void processBitsExit(TreeWalkListener listener,
+ GeneratedYangParser.BitsSpecificationContext ctx) {
+
+ // Check for stack to be non empty.
+ checkStackIsNotEmpty(listener, MISSING_HOLDER, BITS_DATA, "", EXIT);
+
+ Parsable tmpBitsNode = listener.getParsedDataStack().peek();
+ if (tmpBitsNode instanceof YangBits) {
+ listener.getParsedDataStack().pop();
+
+ // Check for stack to be non empty.
+ checkStackIsNotEmpty(listener, MISSING_HOLDER, BITS_DATA, "", EXIT);
+
+ Parsable tmpNode = listener.getParsedDataStack().peek();
+ switch (tmpNode.getParsableDataType()) {
+ case TYPE_DATA: {
+ YangType typeNode = (YangType) tmpNode;
+ typeNode.setDataTypeExtendedInfo((YangBits) tmpBitsNode);
+ break;
+ }
+ default:
+ throw new ParserException(
+ constructListenerErrorMessage(INVALID_HOLDER, BITS_DATA, "", EXIT));
+ }
+ } else {
+ throw new ParserException(
+ constructListenerErrorMessage(MISSING_CURRENT_HOLDER, BITS_DATA, "", EXIT));
+ }
+ }
+}
diff --git a/src/main/java/org/onosproject/yangutils/parser/impl/listeners/PositionListener.java b/src/main/java/org/onosproject/yangutils/parser/impl/listeners/PositionListener.java
new file mode 100644
index 0000000..92b3e68
--- /dev/null
+++ b/src/main/java/org/onosproject/yangutils/parser/impl/listeners/PositionListener.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2014-2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yangutils.parser.impl.listeners;
+
+/*
+ * Reference: RFC6020 and YANG ANTLR Grammar
+ *
+ * ABNF grammar as per RFC6020
+ * position-stmt = position-keyword sep
+ * position-value-arg-str stmtend
+ * position-value-arg-str = < a string that matches the rule
+ * position-value-arg >
+ * position-value-arg = non-negative-integer-value
+ * non-negative-integer-value = "0" / positive-integer-value
+ * positive-integer-value = (non-zero-digit *DIGIT)
+ * zero-integer-value = 1*DIGIT
+ *
+ * ANTLR grammar rule
+ * positionStatement : POSITION_KEYWORD INTEGER STMTEND;
+ */
+
+import org.onosproject.yangutils.datamodel.YangBit;
+import org.onosproject.yangutils.datamodel.YangBits;
+import org.onosproject.yangutils.parser.Parsable;
+import static org.onosproject.yangutils.parser.ParsableDataType.POSITION_DATA;
+import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.TreeWalkListener;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
+import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
+
+/**
+ * Implements listener based call back function corresponding to the "position"
+ * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
+ */
+public final class PositionListener {
+
+ // Exact message in case position is invalid.
+ private static String errMsg;
+
+ /**
+ * Creates a new position listener.
+ */
+ private PositionListener() {
+ }
+
+ /**
+ * It is called when parser receives an input matching the grammar rule
+ * (position), perform validations and update the data model tree.
+ *
+ * @param listener Listener's object.
+ * @param ctx context object of the grammar rule.
+ */
+ public static void processPositionEntry(TreeWalkListener listener,
+ GeneratedYangParser.PositionStatementContext ctx) {
+
+ // Check for stack to be non empty.
+ checkStackIsNotEmpty(listener, MISSING_HOLDER, POSITION_DATA, ctx.INTEGER().getText(), ENTRY);
+
+ // Obtain the node of the stack.
+ Parsable tmpNode = listener.getParsedDataStack().peek();
+ switch (tmpNode.getParsableDataType()) {
+ case BIT_DATA: {
+ YangBit bitNode = (YangBit) tmpNode;
+ if (!isBitPositionValid(listener, ctx)) {
+ ParserException parserException = new ParserException(errMsg);
+ parserException.setLine(ctx.INTEGER().getSymbol().getLine());
+ parserException.setCharPosition(ctx.INTEGER().getSymbol().getCharPositionInLine());
+ throw parserException;
+ }
+ bitNode.setPosition(Integer.valueOf(ctx.INTEGER().getText()));
+ break;
+ }
+ default:
+ throw new ParserException(
+ constructListenerErrorMessage(INVALID_HOLDER, POSITION_DATA, ctx.INTEGER().getText(), ENTRY));
+ }
+ }
+
+ /**
+ * Validates BITS position value correctness and uniqueness.
+ *
+ * @param listener Listener's object.
+ * @param ctx context object of the grammar rule.
+ * @return validation result
+ */
+ private static boolean isBitPositionValid(TreeWalkListener listener,
+ GeneratedYangParser.PositionStatementContext ctx) {
+ Parsable bitNode = listener.getParsedDataStack().pop();
+
+ // Check for stack to be non empty.
+ checkStackIsNotEmpty(listener, MISSING_HOLDER, POSITION_DATA, ctx.INTEGER().getText(), ENTRY);
+
+ if (Integer.valueOf(ctx.INTEGER().getText()) < 0) {
+ errMsg = "Negative value of position is invalid";
+ listener.getParsedDataStack().push(bitNode);
+ return false;
+ }
+
+ Parsable tmpNode = listener.getParsedDataStack().peek();
+ switch (tmpNode.getParsableDataType()) {
+ case BITS_DATA: {
+ YangBits yangBits = (YangBits) tmpNode;
+ for (YangBit curBit : yangBits.getBitSet()) {
+ if (Integer.valueOf(ctx.INTEGER().getText()) == curBit.getPosition()) {
+ errMsg = "Duplicate value of position is invalid";
+ listener.getParsedDataStack().push(bitNode);
+ return false;
+ }
+ }
+ listener.getParsedDataStack().push(bitNode);
+ return true;
+ }
+ default:
+ listener.getParsedDataStack().push(bitNode);
+ throw new ParserException(
+ constructListenerErrorMessage(INVALID_HOLDER, POSITION_DATA, ctx.INTEGER().getText(), ENTRY));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ValueListener.java b/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ValueListener.java
index 07ada45..7c050dc 100644
--- a/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ValueListener.java
+++ b/src/main/java/org/onosproject/yangutils/parser/impl/listeners/ValueListener.java
@@ -34,7 +34,6 @@
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.TreeWalkListener;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
-import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
@@ -70,7 +69,7 @@
case ENUM_DATA: {
YangEnum enumNode = (YangEnum) tmpNode;
if (!isEnumValueValid(listener, ctx)) {
- ParserException parserException = new ParserException("Input version not supported");
+ ParserException parserException = new ParserException("Duplicate Value Entry");
parserException.setLine(ctx.INTEGER().getSymbol().getLine());
parserException.setCharPosition(ctx.INTEGER().getSymbol().getCharPositionInLine());
throw parserException;
@@ -93,6 +92,10 @@
*/
private static boolean isEnumValueValid(TreeWalkListener listener, GeneratedYangParser.ValueStatementContext ctx) {
Parsable enumNode = listener.getParsedDataStack().pop();
+
+ // Check for stack to be non empty.
+ checkStackIsNotEmpty(listener, MISSING_HOLDER, VALUE_DATA, ctx.INTEGER().getText(), ENTRY);
+
Parsable tmpNode = listener.getParsedDataStack().peek();
switch (tmpNode.getParsableDataType()) {
case ENUMERATION_DATA: {
@@ -109,7 +112,7 @@
default:
listener.getParsedDataStack().push(enumNode);
throw new ParserException(
- constructListenerErrorMessage(INVALID_HOLDER, VALUE_DATA, ctx.INTEGER().getText(), EXIT));
+ constructListenerErrorMessage(INVALID_HOLDER, VALUE_DATA, ctx.INTEGER().getText(), ENTRY));
}
}
}
diff --git a/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerErrorType.java b/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerErrorType.java
index e28d186..1d061d7 100644
--- a/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerErrorType.java
+++ b/src/main/java/org/onosproject/yangutils/parser/impl/parserutils/ListenerErrorType.java
@@ -55,6 +55,11 @@
DUPLICATE_ENTRY(),
/**
+ * Represents that the content is invalid.
+ */
+ INVALID_CONTENT(),
+
+ /**
* Represents that some of earlier parsed data is not handled correctly.
*/
UNHANDLED_PARSED_DATA();
@@ -80,6 +85,8 @@
return "Invalid cardinality in";
case DUPLICATE_ENTRY:
return "Duplicate";
+ case INVALID_CONTENT:
+ return "Invalid content in";
case UNHANDLED_PARSED_DATA:
return "Unhandled parsed data at";
default:
diff --git a/src/test/java/org/onosproject/yangutils/parser/impl/listeners/BitListenerTest.java b/src/test/java/org/onosproject/yangutils/parser/impl/listeners/BitListenerTest.java
new file mode 100644
index 0000000..d741ac3
--- /dev/null
+++ b/src/test/java/org/onosproject/yangutils/parser/impl/listeners/BitListenerTest.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2014-2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yangutils.parser.impl.listeners;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import org.junit.Test;
+import org.onosproject.yangutils.datamodel.YangBit;
+import org.onosproject.yangutils.datamodel.YangBits;
+import org.onosproject.yangutils.datamodel.YangDataTypes;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNodeType;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
+
+import java.io.IOException;
+import java.util.ListIterator;
+import java.util.Set;
+
+/**
+ * Test cases for bit listener.
+ */
+public class BitListenerTest {
+
+ private final YangUtilsParserManager manager = new YangUtilsParserManager();
+
+ /**
+ * Checks bit statement without position.
+ */
+ @Test
+ public void processBitTypeStatement() throws IOException, ParserException {
+
+ YangNode node = manager.getDataModel("src/test/resources/BitTypeStatement.yang");
+
+ // Check whether the data model tree returned is of type module.
+ assertThat((node instanceof YangModule), is(true));
+
+ // Check whether the node type is set properly to module.
+ assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
+
+ // Check whether the module name is set correctly.
+ YangModule yangNode = (YangModule) node;
+ assertThat(yangNode.getName(), is("Test"));
+
+ ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+ YangLeaf leafInfo = leafIterator.next();
+
+ assertThat(leafInfo.getLeafName(), is("mybits"));
+ assertThat(leafInfo.getDataType().getDataTypeName(), is("bits"));
+ assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.BITS));
+ assertThat(((YangBits) leafInfo.getDataType().getDataTypeExtendedInfo()).getBitsName(),
+ is("mybits"));
+
+ Set<YangBit> bitSet = ((YangBits) leafInfo.getDataType().getDataTypeExtendedInfo()).getBitSet();
+ for (YangBit tmp : bitSet) {
+ if (tmp.getBitName().equals("disable-nagle")) {
+ assertThat(tmp.getPosition(), is(0));
+ } else if (tmp.getBitName().equals("auto-sense-speed")) {
+ assertThat(tmp.getPosition(), is(1));
+ } else if (tmp.getBitName().equals("Ten-Mb-only")) {
+ assertThat(tmp.getPosition(), is(2));
+ }
+ }
+ }
+
+ /**
+ * Checks if enum with same name is not allowed.
+ */
+ @Test(expected = ParserException.class)
+ public void processBitWithDuplicateName() throws IOException, ParserException {
+
+ YangNode node = manager.getDataModel("src/test/resources/BitWithDuplicateName.yang");
+ }
+}
diff --git a/src/test/java/org/onosproject/yangutils/parser/impl/listeners/EnumListenerTest.java b/src/test/java/org/onosproject/yangutils/parser/impl/listeners/EnumListenerTest.java
index 60de57f..7041fdf 100644
--- a/src/test/java/org/onosproject/yangutils/parser/impl/listeners/EnumListenerTest.java
+++ b/src/test/java/org/onosproject/yangutils/parser/impl/listeners/EnumListenerTest.java
@@ -78,4 +78,13 @@
}
}
}
+
+ /**
+ * Checks if enum with same name is not allowed.
+ */
+ @Test(expected = ParserException.class)
+ public void processEnumWithDuplicateName() throws IOException, ParserException {
+
+ YangNode node = manager.getDataModel("src/test/resources/EnumWithDuplicateName.yang");
+ }
}
diff --git a/src/test/java/org/onosproject/yangutils/parser/impl/listeners/PositionListenerTest.java b/src/test/java/org/onosproject/yangutils/parser/impl/listeners/PositionListenerTest.java
new file mode 100644
index 0000000..7033ddd
--- /dev/null
+++ b/src/test/java/org/onosproject/yangutils/parser/impl/listeners/PositionListenerTest.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2014-2016 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yangutils.parser.impl.listeners;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.core.Is.is;
+import org.junit.Test;
+import org.onosproject.yangutils.datamodel.YangBit;
+import org.onosproject.yangutils.datamodel.YangBits;
+import org.onosproject.yangutils.datamodel.YangDataTypes;
+import org.onosproject.yangutils.datamodel.YangLeaf;
+import org.onosproject.yangutils.datamodel.YangModule;
+import org.onosproject.yangutils.datamodel.YangNode;
+import org.onosproject.yangutils.datamodel.YangNodeType;
+import org.onosproject.yangutils.parser.exceptions.ParserException;
+import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
+
+import java.io.IOException;
+import java.util.ListIterator;
+import java.util.Set;
+
+/**
+ * Test cases for position listener.
+ */
+public class PositionListenerTest {
+
+ private final YangUtilsParserManager manager = new YangUtilsParserManager();
+
+ /**
+ * Checks explicitly configured value.
+ */
+ @Test
+ public void processPositionStatement() throws IOException, ParserException {
+
+ YangNode node = manager.getDataModel("src/test/resources/PositionStatement.yang");
+
+ // Check whether the data model tree returned is of type module.
+ assertThat((node instanceof YangModule), is(true));
+
+ // Check whether the node type is set properly to module.
+ assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
+
+ // Check whether the module name is set correctly.
+ YangModule yangNode = (YangModule) node;
+ assertThat(yangNode.getName(), is("Test"));
+
+ ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+ YangLeaf leafInfo = leafIterator.next();
+
+ assertThat(leafInfo.getLeafName(), is("mybits"));
+ assertThat(leafInfo.getDataType().getDataTypeName(), is("bits"));
+ assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.BITS));
+ assertThat(((YangBits) leafInfo.getDataType().getDataTypeExtendedInfo()).getBitsName(),
+ is("mybits"));
+
+ Set<YangBit> bitSet = ((YangBits) leafInfo.getDataType().getDataTypeExtendedInfo()).getBitSet();
+ for (YangBit tmp : bitSet) {
+ if (tmp.getBitName().equals("disable-nagle")) {
+ assertThat(tmp.getPosition(), is(0));
+ } else if (tmp.getBitName().equals("auto-sense-speed")) {
+ assertThat(tmp.getPosition(), is(1));
+ } else if (tmp.getBitName().equals("Ten-Mb-only")) {
+ assertThat(tmp.getPosition(), is(2));
+ }
+ }
+ }
+
+ /**
+ * Checks explicit value and auto generated value.
+ */
+ @Test
+ public void processPositionImplicitAndExplicit() throws IOException, ParserException {
+
+ YangNode node = manager.getDataModel("src/test/resources/PositionImplicitAndExplicit.yang");
+
+ // Check whether the data model tree returned is of type module.
+ assertThat((node instanceof YangModule), is(true));
+
+ // Check whether the node type is set properly to module.
+ assertThat(node.getNodeType(), is(YangNodeType.MODULE_NODE));
+
+ // Check whether the module name is set correctly.
+ YangModule yangNode = (YangModule) node;
+ assertThat(yangNode.getName(), is("Test"));
+
+ ListIterator<YangLeaf> leafIterator = yangNode.getListOfLeaf().listIterator();
+ YangLeaf leafInfo = leafIterator.next();
+
+ assertThat(leafInfo.getLeafName(), is("mybits"));
+ assertThat(leafInfo.getDataType().getDataTypeName(), is("bits"));
+ assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.BITS));
+ assertThat(((YangBits) leafInfo.getDataType().getDataTypeExtendedInfo()).getBitsName(),
+ is("mybits"));
+
+ Set<YangBit> bitSet = ((YangBits) leafInfo.getDataType().getDataTypeExtendedInfo()).getBitSet();
+ for (YangBit tmp : bitSet) {
+ if (tmp.getBitName().equals("disable-nagle")) {
+ assertThat(tmp.getPosition(), is(0));
+ } else if (tmp.getBitName().equals("auto-sense-speed")) {
+ assertThat(tmp.getPosition(), is(1));
+ } else if (tmp.getBitName().equals("Ten-Mb-only")) {
+ assertThat(tmp.getPosition(), is(2));
+ }
+ }
+ }
+
+ /**
+ * Checks explicit value should not be repeated.
+ */
+ @Test(expected = ParserException.class)
+ public void processPositionDuplication() throws IOException, ParserException {
+
+ YangNode node = manager.getDataModel("src/test/resources/PositionDuplication.yang");
+ }
+
+ /**
+ * Checks explicit or auto generated value should not be repeated.
+ */
+ @Test(expected = ParserException.class)
+ public void processPositionImplicitAndExplicitDuplication() throws IOException, ParserException {
+
+ YangNode node = manager.getDataModel("src/test/resources/PositionImplicitAndExplicitDuplication.yang");
+ }
+
+ /**
+ * Checks if negative value of position is not allowed.
+ */
+ @Test(expected = ParserException.class)
+ public void processPositionNegativeValue() throws IOException, ParserException {
+
+ YangNode node = manager.getDataModel("src/test/resources/PositionNegativeValue.yang");
+ }
+}
diff --git a/src/test/resources/BitTypeStatement.yang b/src/test/resources/BitTypeStatement.yang
new file mode 100644
index 0000000..9d13495
--- /dev/null
+++ b/src/test/resources/BitTypeStatement.yang
@@ -0,0 +1,12 @@
+module Test {
+ yang-version 1;
+ namespace http://huawei.com;
+ prefix Ant;
+ leaf mybits {
+ type bits {
+ bit disable-nagle;
+ bit auto-sense-speed;
+ bit Ten-Mb-only;
+ }
+ }
+}
diff --git a/src/test/resources/BitWithDuplicateName.yang b/src/test/resources/BitWithDuplicateName.yang
new file mode 100644
index 0000000..ed5cc32
--- /dev/null
+++ b/src/test/resources/BitWithDuplicateName.yang
@@ -0,0 +1,12 @@
+module Test {
+ yang-version 1;
+ namespace http://huawei.com;
+ prefix Ant;
+ leaf mybits {
+ type bits {
+ bit disable-nagle;
+ bit disable-nagle;
+ bit Ten-Mb-only;
+ }
+ }
+}
diff --git a/src/test/resources/EnumWithDuplicateName.yang b/src/test/resources/EnumWithDuplicateName.yang
new file mode 100644
index 0000000..d81558f
--- /dev/null
+++ b/src/test/resources/EnumWithDuplicateName.yang
@@ -0,0 +1,14 @@
+module Test {
+ yang-version 1;
+ namespace http://huawei.com;
+ prefix Ant;
+ leaf speed {
+ type enumeration {
+ enum 10m;
+ enum 100m;
+ enum 10m {
+ value 11;
+ }
+ }
+ }
+}
diff --git a/src/test/resources/PositionDuplication.yang b/src/test/resources/PositionDuplication.yang
new file mode 100644
index 0000000..81eeb16
--- /dev/null
+++ b/src/test/resources/PositionDuplication.yang
@@ -0,0 +1,18 @@
+module Test {
+ yang-version 1;
+ namespace http://huawei.com;
+ prefix Ant;
+ leaf mybits {
+ type bits {
+ bit disable-nagle {
+ position 0;
+ }
+ bit auto-sense-speed {
+ position 1;
+ }
+ bit Ten-Mb-only {
+ position 1;
+ }
+ }
+ }
+}
diff --git a/src/test/resources/PositionImplicitAndExplicit.yang b/src/test/resources/PositionImplicitAndExplicit.yang
new file mode 100644
index 0000000..5be4cbb
--- /dev/null
+++ b/src/test/resources/PositionImplicitAndExplicit.yang
@@ -0,0 +1,15 @@
+module Test {
+ yang-version 1;
+ namespace http://huawei.com;
+ prefix Ant;
+ leaf mybits {
+ type bits {
+ bit disable-nagle;
+ bit auto-sense-speed {
+ position 1;
+ }
+ bit Ten-Mb-only;
+ }
+ }
+ }
+}
diff --git a/src/test/resources/PositionImplicitAndExplicitDuplication.yang b/src/test/resources/PositionImplicitAndExplicitDuplication.yang
new file mode 100644
index 0000000..30b81ab
--- /dev/null
+++ b/src/test/resources/PositionImplicitAndExplicitDuplication.yang
@@ -0,0 +1,15 @@
+module Test {
+ yang-version 1;
+ namespace http://huawei.com;
+ prefix Ant;
+ leaf mybits {
+ type bits {
+ bit disable-nagle;
+ bit auto-sense-speed {
+ position 0;
+ }
+ bit Ten-Mb-only;
+ }
+ }
+ }
+}
diff --git a/src/test/resources/PositionNegativeValue.yang b/src/test/resources/PositionNegativeValue.yang
new file mode 100644
index 0000000..60330e0
--- /dev/null
+++ b/src/test/resources/PositionNegativeValue.yang
@@ -0,0 +1,15 @@
+module Test {
+ yang-version 1;
+ namespace http://huawei.com;
+ prefix Ant;
+ leaf mybits {
+ type bits {
+ bit disable-nagle;
+ bit auto-sense-speed {
+ position -2;
+ }
+ bit Ten-Mb-only;
+ }
+ }
+ }
+}
diff --git a/src/test/resources/PositionStatement.yang b/src/test/resources/PositionStatement.yang
new file mode 100644
index 0000000..76c204d
--- /dev/null
+++ b/src/test/resources/PositionStatement.yang
@@ -0,0 +1,18 @@
+module Test {
+ yang-version 1;
+ namespace http://huawei.com;
+ prefix Ant;
+ leaf mybits {
+ type bits {
+ bit disable-nagle {
+ position 0;
+ }
+ bit auto-sense-speed {
+ position 1;
+ }
+ bit Ten-Mb-only {
+ position 2;
+ }
+ }
+ }
+}