Gaurav Agrawal
Committed by Gerrit Code Review

Yang Listener for BITS Data Type

Change-Id: I81e7f7e8de38ce20addd63548414a486b7e2ffb8
Showing 20 changed files with 908 additions and 20 deletions
......@@ -20,6 +20,8 @@ import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
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 @@ public class YangBit implements YangCommonInfo, Parsable {
private String description;
/**
* reference info of the bit field.
* Reference info of the bit field.
*/
private String reference;
......@@ -67,7 +69,7 @@ public class YangBit implements YangCommonInfo, Parsable {
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 @@ public class YangBit implements YangCommonInfo, Parsable {
}
/**
* Get the bit name.
* Returns bit name.
*
* @return the bit name.
*/
......@@ -97,7 +99,7 @@ public class YangBit implements YangCommonInfo, Parsable {
}
/**
* Get the description.
* Returns description.
*
* @return the description.
*/
......@@ -117,7 +119,7 @@ public class YangBit implements YangCommonInfo, Parsable {
}
/**
* Get the textual reference.
* Returns textual reference.
*
* @return the reference.
*/
......@@ -137,7 +139,7 @@ public class YangBit implements YangCommonInfo, Parsable {
}
/**
* Get the status.
* Returns status.
*
* @return the status.
*/
......@@ -157,7 +159,7 @@ public class YangBit implements YangCommonInfo, Parsable {
}
/**
* Get the bit position.
* Returns bit position.
*
* @return the position
*/
......@@ -184,6 +186,23 @@ public class YangBit implements YangCommonInfo, Parsable {
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.
*
......
......@@ -36,8 +36,12 @@ import org.onosproject.yangutils.parser.ParsableDataType;
*/
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 @@ public class YangBits implements Parsable {
}
/**
* Get the bit set.
* Returns the bit set.
*
* @return the bit set
*/
......@@ -55,7 +59,7 @@ public class YangBits implements Parsable {
}
/**
* set the bit set.
* Set the bit set.
*
* @param bitSet the bit set
*/
......@@ -66,10 +70,13 @@ public class YangBits implements Parsable {
/**
* 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 @@ public class YangBits implements Parsable {
}
/**
* 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.
......
......@@ -225,6 +225,11 @@ public enum ParsableDataType {
ORGANIZATION_DATA,
/**
* Identifies the YANG position element parsed data.
*/
POSITION_DATA,
/**
* Identifies the derived data type.
*/
DERIVED;
......@@ -318,6 +323,8 @@ public enum ParsableDataType {
return "organization";
case VALUE_DATA:
return "value";
case POSITION_DATA:
return "position";
case DEFAULT_DATA:
return "default";
case DERIVED:
......
......@@ -27,6 +27,8 @@ import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangListener;
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.MinElementsListener;
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 @@ public class TreeWalkListener implements GeneratedYangListener {
@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 @@ public class TreeWalkListener implements GeneratedYangListener {
@Override
public void enterPositionStatement(GeneratedYangParser.PositionStatementContext ctx) {
// TODO: implement the method.
PositionListener.processPositionEntry(this, ctx);
}
@Override
......
/*
* 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));
}
}
}
/*
* 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));
}
}
}
/*
* 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
......@@ -34,7 +34,6 @@ 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_HOLDER;
......@@ -70,7 +69,7 @@ public final class ValueListener {
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 @@ public final class ValueListener {
*/
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 @@ public final class ValueListener {
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));
}
}
}
......
......@@ -55,6 +55,11 @@ public enum ListenerErrorType {
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 @@ public enum ListenerErrorType {
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:
......
/*
* 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");
}
}
......@@ -78,4 +78,13 @@ public class EnumListenerTest {
}
}
}
/**
* 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");
}
}
......
/*
* 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");
}
}
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;
}
}
}
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;
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf speed {
type enumeration {
enum 10m;
enum 100m;
enum 10m {
value 11;
}
}
}
}
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;
}
}
}
}
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;
}
}
}
}
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;
}
}
}
}
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;
}
}
}
}
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;
}
}
}
}