Gaurav Agrawal
Committed by Gerrit Code Review

[ONOS-3897] Yang Listener for Enumeration Data Type

Change-Id: If257c73da8fe2dcc2f4111f103967cfcdd7fa273
......@@ -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 "ENUM" statement, which is a sub-statement to the "type"
* statement, MUST be present if the type is "enumeration". It is
......@@ -188,6 +190,23 @@ public class YangEnum implements YangCommonInfo, Parsable {
return ParsableDataType.ENUM_DATA;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof YangEnum) {
final YangEnum other = (YangEnum) obj;
return Objects.equals(this.namedValue, other.namedValue);
}
return false;
}
@Override
public int hashCode() {
return Objects.hashCode(this.namedValue);
}
/**
* Validate the data on entering the corresponding parse tree node.
*
......
......@@ -16,13 +16,12 @@
package org.onosproject.yangutils.datamodel;
import java.util.HashSet;
import java.util.Set;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.parser.ParsableDataType;
import org.onosproject.yangutils.translator.CachedFileHandle;
import java.util.HashSet;
import java.util.Set;
/*
* The enumeration built-in type represents values from a set of
......@@ -32,20 +31,19 @@ import org.onosproject.yangutils.translator.CachedFileHandle;
/**
* Maintains the enumeration data type information.
*/
public class YangEnumeration extends YangNode implements Parsable {
public class YangEnumeration implements Parsable {
/**
* Enumeration info set.
*/
// Enumeration info set.
private Set<YangEnum> enumSet;
// Enumeration name.
private String enumerationName;
/**
* Create an enumeration object.
* Creates an enumeration object.
*/
public YangEnumeration() {
super(YangNodeType.ENUMERATION_NODE);
setEnumSet(new HashSet<YangEnum>());
}
/**
......@@ -67,12 +65,33 @@ public class YangEnumeration extends YangNode implements Parsable {
}
/**
* Add ENUM value.
* Add ENUM information.
*
* @param enumInfo the ENUM value of string
* @param enumInfo the ENUM information to be added.
* @throws DataModelException due to violation in data model rules.
*/
public void addEnumInfo(YangEnum enumInfo) {
public void addEnumInfo(YangEnum enumInfo) throws DataModelException {
if (!getEnumSet().add(enumInfo)) {
throw new DataModelException("YANG ENUM already exists");
}
}
/**
* Return enumeration name.
*
* @return the enumeration name
*/
public String getEnumerationName() {
return enumerationName;
}
/**
* Set the enumeration name.
*
* @param enumerationName enumeration name
*/
public void setEnumerationName(String enumerationName) {
this.enumerationName = enumerationName;
}
/**
......@@ -104,70 +123,4 @@ public class YangEnumeration extends YangNode implements Parsable {
public void validateDataOnExit() throws DataModelException {
// TODO auto-generated method stub, to be implemented by parser
}
/* (non-Javadoc)
* @see org.onosproject.yangutils.datamodel.YangNode#getName()
*/
@Override
public String getName() {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.onosproject.yangutils.datamodel.YangNode#setName(java.lang.String)
*/
@Override
public void setName(String name) {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.onosproject.yangutils.datamodel.YangNode#getPackage()
*/
@Override
public String getPackage() {
// TODO Auto-generated method stub
return null;
}
/* (non-Javadoc)
* @see org.onosproject.yangutils.datamodel.YangNode#setPackage(java.lang.String)
*/
@Override
public void setPackage(String pkg) {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.onosproject.yangutils.translator.CodeGenerator#generateJavaCodeEntry()
*/
@Override
public void generateJavaCodeEntry() {
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see org.onosproject.yangutils.translator.CodeGenerator#generateJavaCodeExit()
*/
@Override
public void generateJavaCodeExit() {
// TODO Auto-generated method stub
}
@Override
public CachedFileHandle getFileHandle() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setFileHandle(CachedFileHandle fileHandle) {
// TODO Auto-generated method stub
}
}
......
......@@ -215,6 +215,11 @@ public enum ParsableDataType {
DEFAULT_DATA,
/**
* Identifies the YANG value element parsed data.
*/
VALUE_DATA,
/**
* Identifies the YANG organization parsed data.
*/
ORGANIZATION_DATA;
......@@ -228,88 +233,90 @@ public enum ParsableDataType {
public static String getParsableDataType(ParsableDataType parsableDataType) {
switch (parsableDataType) {
case MODULE_DATA:
return "module";
case SUB_MODULE_DATA:
return "submodule";
case TYPEDEF_DATA:
return "typedef";
case TYPE_DATA:
return "type";
case CHOICE_DATA:
return "choice";
case CASE_DATA:
return "case";
case ENUMERATION_DATA:
return "enumeration";
case GROUPING_DATA:
return "grouping";
case USES_DATA:
return "uses";
case AUGMENT_DATA:
return "augment";
case CONTAINER_DATA:
return "container";
case LIST_DATA:
return "list";
case BELONGS_TO_DATA:
return "belongs-to";
case BIT_DATA:
return "bit";
case BITS_DATA:
return "bits";
case ENUM_DATA:
return "enum";
case IMPORT_DATA:
return "import";
case INCLUDE_DATA:
return "include";
case LEAF_DATA:
return "leaf";
case LEAF_LIST_DATA:
return "leaf-list";
case MUST_DATA:
return "must";
case REVISION_DATA:
return "revision";
case REVISION_DATE_DATA:
return "revision-date";
case NAMESPACE_DATA:
return "namespace";
case CONTACT_DATA:
return "contact";
case CONFIG_DATA:
return "config";
case DESCRIPTION_DATA:
return "description";
case KEY_DATA:
return "key";
case MANDATORY_DATA:
return "mandatory";
case MAX_ELEMENT_DATA:
return "max-elements";
case MIN_ELEMENT_DATA:
return "min-elements";
case PRESENCE_DATA:
return "presence";
case REFERENCE_DATA:
return "reference";
case STATUS_DATA:
return "status";
case UNITS_DATA:
return "units";
case VERSION_DATA:
return "version";
case YANGBASE_DATA:
return "yangbase";
case PREFIX_DATA:
return "prefix";
case ORGANIZATION_DATA:
return "organization";
case DEFAULT_DATA:
return "default";
default:
return "yang";
case MODULE_DATA:
return "module";
case SUB_MODULE_DATA:
return "submodule";
case TYPEDEF_DATA:
return "typedef";
case TYPE_DATA:
return "type";
case CHOICE_DATA:
return "choice";
case CASE_DATA:
return "case";
case ENUMERATION_DATA:
return "enumeration";
case GROUPING_DATA:
return "grouping";
case USES_DATA:
return "uses";
case AUGMENT_DATA:
return "augment";
case CONTAINER_DATA:
return "container";
case LIST_DATA:
return "list";
case BELONGS_TO_DATA:
return "belongs-to";
case BIT_DATA:
return "bit";
case BITS_DATA:
return "bits";
case ENUM_DATA:
return "enum";
case IMPORT_DATA:
return "import";
case INCLUDE_DATA:
return "include";
case LEAF_DATA:
return "leaf";
case LEAF_LIST_DATA:
return "leaf-list";
case MUST_DATA:
return "must";
case REVISION_DATA:
return "revision";
case REVISION_DATE_DATA:
return "revision-date";
case NAMESPACE_DATA:
return "namespace";
case CONTACT_DATA:
return "contact";
case CONFIG_DATA:
return "config";
case DESCRIPTION_DATA:
return "description";
case KEY_DATA:
return "key";
case MANDATORY_DATA:
return "mandatory";
case MAX_ELEMENT_DATA:
return "max-elements";
case MIN_ELEMENT_DATA:
return "min-elements";
case PRESENCE_DATA:
return "presence";
case REFERENCE_DATA:
return "reference";
case STATUS_DATA:
return "status";
case UNITS_DATA:
return "units";
case VERSION_DATA:
return "version";
case YANGBASE_DATA:
return "yangbase";
case PREFIX_DATA:
return "prefix";
case ORGANIZATION_DATA:
return "organization";
case VALUE_DATA:
return "value";
case DEFAULT_DATA:
return "default";
default:
return "yang";
}
}
}
\ No newline at end of file
}
......
/*
* 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
* enum-stmt = enum-keyword sep string optsep
* (";" /
* "{" stmtsep
* ;; these stmts can appear in any order
* [value-stmt stmtsep]
* [status-stmt stmtsep]
* [description-stmt stmtsep]
* [reference-stmt stmtsep]
* "}")
*
* ANTLR grammar rule
* enumStatement : ENUM_KEYWORD string (STMTEND | LEFT_CURLY_BRACE enumStatementBody RIGHT_CURLY_BRACE);
*
* enumStatementBody : valueStatement? statusStatement? descriptionStatement? referenceStatement?
* | valueStatement? statusStatement? referenceStatement? descriptionStatement?
* | valueStatement? descriptionStatement? statusStatement? referenceStatement?
* | valueStatement? descriptionStatement? referenceStatement? statusStatement?
* | valueStatement? referenceStatement? statusStatement? descriptionStatement?
* | valueStatement? referenceStatement? descriptionStatement? statusStatement?
* | statusStatement? valueStatement? descriptionStatement? referenceStatement?
* | statusStatement? valueStatement? referenceStatement? descriptionStatement?
* | statusStatement? descriptionStatement? descriptionStatement? valueStatement?
* | statusStatement? descriptionStatement? valueStatement? descriptionStatement?
* | statusStatement? referenceStatement? valueStatement? descriptionStatement?
* | statusStatement? referenceStatement? descriptionStatement? valueStatement?
* | descriptionStatement? valueStatement? statusStatement? referenceStatement?
* | descriptionStatement? valueStatement? referenceStatement? statusStatement?
* | descriptionStatement? statusStatement? valueStatement? referenceStatement?
* | descriptionStatement? statusStatement? referenceStatement? valueStatement?
* | descriptionStatement? referenceStatement? valueStatement? statusStatement?
* | descriptionStatement? referenceStatement? statusStatement? valueStatement?
* | referenceStatement? valueStatement? descriptionStatement? statusStatement?
* | referenceStatement? valueStatement? statusStatement? descriptionStatement?
* | referenceStatement? statusStatement? descriptionStatement? valueStatement?
* | referenceStatement? statusStatement? valueStatement? descriptionStatement?
* | referenceStatement? descriptionStatement? valueStatement? statusStatement?
* | referenceStatement? descriptionStatement? statusStatement? valueStatement?
* ;
*/
import org.onosproject.yangutils.datamodel.YangEnum;
import org.onosproject.yangutils.datamodel.YangEnumeration;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.parser.Parsable;
import static org.onosproject.yangutils.parser.ParsableDataType.ENUM_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.DUPLICATE_ENTRY;
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 "enum" rule
* defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
*/
public final class EnumListener {
/**
* Creates a new enum listener.
*/
private EnumListener() {
}
/**
* It is called when parser enters grammar rule (enum), 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 processEnumEntry(TreeWalkListener listener, GeneratedYangParser.EnumStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, ENUM_DATA, ctx.string().getText(), ENTRY);
YangEnum enumNode = new YangEnum();
enumNode.setNamedValue(ctx.string().getText());
listener.getParsedDataStack().push(enumNode);
}
/**
* It is called when parser exits from grammar rule (enum), 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 processEnumExit(TreeWalkListener listener, GeneratedYangParser.EnumStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, ENUM_DATA, ctx.string().getText(), EXIT);
Parsable tmpEnumNode = listener.getParsedDataStack().peek();
if (tmpEnumNode instanceof YangEnum) {
listener.getParsedDataStack().pop();
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, ENUM_DATA, ctx.string().getText(), EXIT);
Parsable tmpNode = listener.getParsedDataStack().peek();
switch (tmpNode.getParsableDataType()) {
case ENUMERATION_DATA: {
YangEnumeration yangEnumeration = (YangEnumeration) tmpNode;
if ((ctx.enumStatementBody() == null) || (ctx.enumStatementBody().valueStatement() == null)) {
int maxValue = 0;
boolean isValuePresent = false;
for (YangEnum curEnum : yangEnumeration.getEnumSet()) {
if (maxValue <= curEnum.getValue()) {
maxValue = curEnum.getValue();
isValuePresent = true;
}
}
if (isValuePresent) {
maxValue++;
}
((YangEnum) tmpEnumNode).setValue(maxValue);
}
try {
yangEnumeration.addEnumInfo((YangEnum) tmpEnumNode);
} catch (DataModelException e) {
ParserException parserException = new ParserException(constructExtendedListenerErrorMessage(
DUPLICATE_ENTRY, ENUM_DATA, ctx.string().getText(), EXIT, e.getMessage()));
parserException.setLine(ctx.string().STRING(0).getSymbol().getLine());
parserException.setCharPosition(ctx.string().STRING(0).getSymbol().getCharPositionInLine());
throw parserException;
}
break;
}
default:
throw new ParserException(
constructListenerErrorMessage(INVALID_HOLDER, ENUM_DATA, ctx.string().getText(), EXIT));
}
} else {
throw new ParserException(
constructListenerErrorMessage(MISSING_CURRENT_HOLDER, ENUM_DATA, ctx.string().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
*
* enum-specification = 1*(enum-stmt stmtsep)
*
* ANTLR grammar rule
*
* typeBodyStatements : numericalRestrictions | stringRestrictions | enumSpecification
* | leafrefSpecification | identityrefSpecification | instanceIdentifierSpecification
* | bitsSpecification | unionSpecification;
*
* enumSpecification : enumStatement+;
*/
import org.onosproject.yangutils.datamodel.YangEnumeration;
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.ENUMERATION_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
* "enumeration" rule defined in ANTLR grammar file for corresponding ABNF rule
* in RFC 6020.
*/
public final class EnumerationListener {
/**
* Creates a new enumeration listener.
*/
private EnumerationListener() {
}
/**
* It is called when parser enters grammar rule (enumeration), 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 processEnumerationEntry(TreeWalkListener listener,
GeneratedYangParser.EnumSpecificationContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, ENUMERATION_DATA, "", ENTRY);
if (listener.getParsedDataStack().peek() instanceof YangType) {
YangEnumeration enumerationNode = new YangEnumeration();
Parsable typeData = listener.getParsedDataStack().pop();
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, ENUMERATION_DATA, "", ENTRY);
Parsable tmpData = listener.getParsedDataStack().peek();
switch (tmpData.getParsableDataType()) {
case LEAF_DATA:
enumerationNode.setEnumerationName(((YangLeaf) tmpData).getLeafName());
break;
case LEAF_LIST_DATA:
enumerationNode.setEnumerationName(((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(enumerationNode);
} else {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, ENUMERATION_DATA, "", ENTRY));
}
}
/**
* It is called when parser exits from grammar rule (enumeration), 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 processEnumerationExit(TreeWalkListener listener,
GeneratedYangParser.EnumSpecificationContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, ENUMERATION_DATA, "", EXIT);
Parsable tmpEnumerationNode = listener.getParsedDataStack().peek();
if (tmpEnumerationNode instanceof YangEnumeration) {
listener.getParsedDataStack().pop();
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, ENUMERATION_DATA, "", EXIT);
Parsable tmpNode = listener.getParsedDataStack().peek();
switch (tmpNode.getParsableDataType()) {
case TYPE_DATA: {
YangType typeNode = (YangType) tmpNode;
typeNode.setDataTypeExtendedInfo((YangEnumeration) tmpEnumerationNode);
break;
}
default:
throw new ParserException(
constructListenerErrorMessage(INVALID_HOLDER, ENUMERATION_DATA, "", EXIT));
}
} else {
throw new ParserException(
constructListenerErrorMessage(MISSING_CURRENT_HOLDER, ENUMERATION_DATA, "", EXIT));
}
}
}
......@@ -21,18 +21,18 @@ 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.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.ParsableDataType.TYPE_DATA;
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;
/*
* Reference: RFC6020 and YANG ANTLR Grammar
*
......@@ -48,8 +48,8 @@ import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidati
*/
/**
* Implements listener based call back function corresponding to the "type"
* rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
* Implements listener based call back function corresponding to the "type" rule
* defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
*/
public final class TypeListener {
......@@ -60,15 +60,14 @@ public final class TypeListener {
}
/**
* It is called when parser receives an input matching the grammar
* rule (type), performs validation and updates the data model
* tree.
* It is called when parser receives an input matching the grammar rule
* (type), performs validation and updates the data model tree.
*
* @param listener listener's object.
* @param ctx context object of the grammar rule.
*/
public static void processTypeEntry(TreeWalkListener listener,
GeneratedYangParser.TypeStatementContext ctx) {
GeneratedYangParser.TypeStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, TYPE_DATA, ctx.string().getText(), ENTRY);
......@@ -78,21 +77,46 @@ public final class TypeListener {
type.setDataTypeName(ctx.string().getText());
type.setDataType(yangDataTypes);
listener.getParsedDataStack().push(type);
}
/**
* It is called when parser exits from grammar rule (type), 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 processTypeExit(TreeWalkListener listener,
GeneratedYangParser.TypeStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_CURRENT_HOLDER, TYPE_DATA, ctx.string().getText(), EXIT);
Parsable type = listener.getParsedDataStack().pop();
if (!(type instanceof YangType)) {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
ctx.string().getText(), EXIT));
}
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, TYPE_DATA, ctx.string().getText(), EXIT);
Parsable tmpData = listener.getParsedDataStack().peek();
switch (tmpData.getParsableDataType()) {
case LEAF_DATA:
YangLeaf leaf = (YangLeaf) tmpData;
leaf.setDataType(type);
leaf.setDataType((YangType) type);
break;
case LEAF_LIST_DATA:
YangLeafList leafList = (YangLeafList) tmpData;
leafList.setDataType(type);
leafList.setDataType((YangType) type);
break;
case TYPEDEF_DATA: //TODO
break;
default:
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
ctx.string().getText(), ENTRY));
ctx.string().getText(), EXIT));
}
}
}
\ No newline at end of file
}
......
/*
* 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
* value-stmt = value-keyword sep integer-value stmtend
*
* ANTLR grammar rule
* valueStatement : VALUE_KEYWORD ((MINUS INTEGER) | INTEGER) STMTEND;
*/
import org.onosproject.yangutils.datamodel.YangEnum;
import org.onosproject.yangutils.datamodel.YangEnumeration;
import org.onosproject.yangutils.parser.Parsable;
import static org.onosproject.yangutils.parser.ParsableDataType.VALUE_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_HOLDER;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
/**
* Implements listener based call back function corresponding to the "value"
* rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
*/
public final class ValueListener {
/**
* Creates a new value listener.
*/
private ValueListener() {
}
/**
* It is called when parser receives an input matching the grammar rule
* (value), perform validations and update the data model tree.
*
* @param listener Listener's object.
* @param ctx context object of the grammar rule.
*/
public static void processValueEntry(TreeWalkListener listener, GeneratedYangParser.ValueStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, VALUE_DATA, ctx.INTEGER().getText(), ENTRY);
// Obtain the node of the stack.
Parsable tmpNode = listener.getParsedDataStack().peek();
switch (tmpNode.getParsableDataType()) {
case ENUM_DATA: {
YangEnum enumNode = (YangEnum) tmpNode;
if (!isEnumValueValid(listener, ctx)) {
ParserException parserException = new ParserException("Input version not supported");
parserException.setLine(ctx.INTEGER().getSymbol().getLine());
parserException.setCharPosition(ctx.INTEGER().getSymbol().getCharPositionInLine());
throw parserException;
}
enumNode.setValue(Integer.valueOf(ctx.INTEGER().getText()));
break;
}
default:
throw new ParserException(
constructListenerErrorMessage(INVALID_HOLDER, VALUE_DATA, ctx.INTEGER().getText(), ENTRY));
}
}
/**
* Validates ENUM value uniqueness.
*
* @param listener Listener's object.
* @param ctx context object of the grammar rule.
* @return validation result
*/
private static boolean isEnumValueValid(TreeWalkListener listener, GeneratedYangParser.ValueStatementContext ctx) {
Parsable enumNode = listener.getParsedDataStack().pop();
Parsable tmpNode = listener.getParsedDataStack().peek();
switch (tmpNode.getParsableDataType()) {
case ENUMERATION_DATA: {
YangEnumeration yangEnumeration = (YangEnumeration) tmpNode;
for (YangEnum curEnum : yangEnumeration.getEnumSet()) {
if (Integer.valueOf(ctx.INTEGER().getText()) == curEnum.getValue()) {
listener.getParsedDataStack().push(enumNode);
return false;
}
}
listener.getParsedDataStack().push(enumNode);
return true;
}
default:
listener.getParsedDataStack().push(enumNode);
throw new ParserException(
constructListenerErrorMessage(INVALID_HOLDER, VALUE_DATA, ctx.INTEGER().getText(), EXIT));
}
}
}
......@@ -21,22 +21,26 @@ package org.onosproject.yangutils.parser.impl.parserutils;
*/
public enum ListenerErrorType {
/**
* Represents the parent holder in parsable stack for given YANG construct is invalid.
* Represents the parent holder in parsable stack for given YANG construct
* is invalid.
*/
INVALID_HOLDER(),
/**
* Represents the parent holder in parsable stack for given YANG construct is missing.
* Represents the parent holder in parsable stack for given YANG construct
* is missing.
*/
MISSING_HOLDER(),
/**
* Represents the current holder in parsable stack for given YANG construct is missing.
* Represents the current holder in parsable stack for given YANG construct
* is missing.
*/
MISSING_CURRENT_HOLDER(),
/**
* Represents that the child in parsable stack for given YANG construct is invalid.
* Represents that the child in parsable stack for given YANG construct is
* invalid.
*/
INVALID_CHILD(),
......@@ -46,6 +50,11 @@ public enum ListenerErrorType {
INVALID_CARDINALITY(),
/**
* Represents that the entry is duplicate.
*/
DUPLICATE_ENTRY(),
/**
* Represents that some of earlier parsed data is not handled correctly.
*/
UNHANDLED_PARSED_DATA();
......@@ -59,20 +68,22 @@ public enum ListenerErrorType {
public static String getErrorType(ListenerErrorType errorType) {
switch (errorType) {
case INVALID_HOLDER:
return "Invalid holder for";
case MISSING_HOLDER:
return "Missing holder at";
case MISSING_CURRENT_HOLDER:
return "Missing";
case INVALID_CHILD:
return "Invalid child in";
case INVALID_CARDINALITY:
return "Invalid cardinality in";
case UNHANDLED_PARSED_DATA:
return "Unhandled parsed data at";
default:
return "Problem in";
case INVALID_HOLDER:
return "Invalid holder for";
case MISSING_HOLDER:
return "Missing holder at";
case MISSING_CURRENT_HOLDER:
return "Missing";
case INVALID_CHILD:
return "Invalid child in";
case INVALID_CARDINALITY:
return "Invalid cardinality in";
case DUPLICATE_ENTRY:
return "Duplicate";
case UNHANDLED_PARSED_DATA:
return "Unhandled parsed data at";
default:
return "Problem in";
}
}
}
\ No newline at end of file
}
......
/*
* 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.YangDataTypes;
import org.onosproject.yangutils.datamodel.YangEnum;
import org.onosproject.yangutils.datamodel.YangEnumeration;
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 enum listener.
*/
public class EnumListenerTest {
private final YangUtilsParserManager manager = new YangUtilsParserManager();
/**
* Checks enum statement without value.
*/
@Test
public void processEnumTypeStatement() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/EnumTypeStatement.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("speed"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("enumeration"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.ENUMERATION));
assertThat(((YangEnumeration) leafInfo.getDataType().getDataTypeExtendedInfo()).getEnumerationName(),
is("speed"));
Set<YangEnum> enumSet = ((YangEnumeration) leafInfo.getDataType().getDataTypeExtendedInfo()).getEnumSet();
for (YangEnum tmp : enumSet) {
if (tmp.getNamedValue().equals("10m")) {
assertThat(tmp.getValue(), is(0));
} else if (tmp.getNamedValue().equals("100m")) {
assertThat(tmp.getValue(), is(1));
} else if (tmp.getNamedValue().equals("auto")) {
assertThat(tmp.getValue(), is(2));
}
}
}
}
/*
* 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.YangDataTypes;
import org.onosproject.yangutils.datamodel.YangEnum;
import org.onosproject.yangutils.datamodel.YangEnumeration;
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 value listener.
*/
public class ValueListenerTest {
private final YangUtilsParserManager manager = new YangUtilsParserManager();
/**
* Checks explicitly configured value.
*/
@Test
public void processValueStatement() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/ValueStatement.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("speed"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("enumeration"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.ENUMERATION));
assertThat(((YangEnumeration) leafInfo.getDataType().getDataTypeExtendedInfo()).getEnumerationName(),
is("speed"));
Set<YangEnum> enumSet = ((YangEnumeration) leafInfo.getDataType().getDataTypeExtendedInfo()).getEnumSet();
for (YangEnum tmp : enumSet) {
if (tmp.getNamedValue().equals("10m")) {
assertThat(tmp.getValue(), is(10));
} else if (tmp.getNamedValue().equals("100m")) {
assertThat(tmp.getValue(), is(100));
} else if (tmp.getNamedValue().equals("auto")) {
assertThat(tmp.getValue(), is(1000));
}
}
}
/**
* Checks explicit value and auto generated value.
*/
@Test
public void processValueAndAutoStatement() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/ValueAndAutoStatement.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("speed"));
assertThat(leafInfo.getDataType().getDataTypeName(), is("enumeration"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.ENUMERATION));
assertThat(((YangEnumeration) leafInfo.getDataType().getDataTypeExtendedInfo()).getEnumerationName(),
is("speed"));
Set<YangEnum> enumSet = ((YangEnumeration) leafInfo.getDataType().getDataTypeExtendedInfo()).getEnumSet();
for (YangEnum tmp : enumSet) {
if (tmp.getNamedValue().equals("10m")) {
assertThat(tmp.getValue(), is(10));
} else if (tmp.getNamedValue().equals("100m")) {
assertThat(tmp.getValue(), is(11));
} else if (tmp.getNamedValue().equals("auto")) {
assertThat(tmp.getValue(), is(1000));
}
}
}
/**
* Checks explicit value should not be repeated.
*/
@Test(expected = ParserException.class)
public void processValueDuplication() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/ValueDuplication.yang");
}
/**
* Checks explicit or auto generated value should not be repeated.
*/
@Test(expected = ParserException.class)
public void processValueExplicitAndAutoDuplication() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/ValueExplicitAndAutoDuplication.yang");
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf speed {
type enumeration {
enum 10m;
enum 100m;
enum auto;
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf speed {
type enumeration {
enum 10m {
value 10;
}
enum 100m;
enum auto {
value 1000;
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf speed {
type enumeration {
enum 10m {
value 10;
}
enum 100m {
value 100;
}
enum auto {
value 10;
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf speed {
type enumeration {
enum 10m {
value 10;
}
enum 100m;
enum auto {
value 11;
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
leaf speed {
type enumeration {
enum 10m {
value 10;
}
enum 100m {
value 100;
}
enum auto {
value 1000;
}
}
}
}