Gaurav Agrawal
Committed by Gerrit Code Review

[ONOS-3894, 4071] YANG Advanced Construct Union & Grouping

Change-Id: I0f828adb5884c2d7b6e4120f9843c416608ae5e7
Showing 39 changed files with 1562 additions and 111 deletions
......@@ -17,11 +17,12 @@ package org.onosproject.yangutils.datamodel;
import java.util.LinkedList;
import java.util.List;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.utils.YangConstructType;
import static org.onosproject.yangutils.datamodel.utils.DataModelUtils.detectCollidingChildUtil;
/*-
* Reference RFC 6020.
*
......@@ -76,7 +77,7 @@ import org.onosproject.yangutils.utils.YangConstructType;
* Data model node to maintain information defined in YANG grouping.
*/
public class YangGrouping extends YangNode
implements YangLeavesHolder, YangCommonInfo, Parsable {
implements YangLeavesHolder, YangCommonInfo, Parsable, CollisionDetector {
/**
* Name of the grouping.
......@@ -113,6 +114,8 @@ public class YangGrouping extends YangNode
*/
public YangGrouping() {
super(YangNodeType.GROUPING_NODE);
listOfLeaf = new LinkedList<YangLeaf>();
listOfLeafList = new LinkedList<YangLeafList>();
}
/**
......@@ -181,10 +184,6 @@ public class YangGrouping extends YangNode
*/
@Override
public void addLeaf(YangLeaf leaf) {
if (getListOfLeaf() == null) {
setListOfLeaf(new LinkedList<YangLeaf>());
}
getListOfLeaf().add(leaf);
}
......@@ -214,10 +213,6 @@ public class YangGrouping extends YangNode
*/
@Override
public void addLeafList(YangLeafList leafList) {
if (getListOfLeafList() == null) {
setListOfLeafList(new LinkedList<YangLeafList>());
}
getListOfLeafList().add(leafList);
}
......@@ -290,4 +285,31 @@ public class YangGrouping extends YangNode
public void validateDataOnExit() throws DataModelException {
// TODO auto-generated method stub, to be implemented by parser
}
/*
* Reference RFC6020
*
* Once a grouping is defined, it can be referenced in a "uses"
* statement (see Section 7.12). A grouping MUST NOT reference itself,
* neither directly nor indirectly through a chain of other groupings.
*
* If the grouping is defined at the top level of a YANG module or
* submodule, the grouping's identifier MUST be unique within the
* module.
*/
@Override
public void detectCollidingChild(String identifierName, YangConstructType dataType) throws DataModelException {
// Asks helper to detect colliding child.
detectCollidingChildUtil(identifierName, dataType, this);
}
@Override
public void detectSelfCollision(String identifierName, YangConstructType dataType) throws DataModelException {
if (getName().equals(identifierName)) {
throw new DataModelException("YANG file error: Duplicate input identifier detected, same as grouping \"" +
getName() + "\"");
}
}
// TODO A grouping MUST NOT reference itself, neither directly nor indirectly through a chain of other groupings.
}
......
/*
* Copyright 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.datamodel;
/**
* YANG node identifier which is a combination of prefix and name.
*/
public class YangNodeIdentifier {
// Name of the node.
String name;
// Prefix of the node.
String prefix;
/**
* Creates an instance of YANG node identifier.
*/
public YangNodeIdentifier() {
}
/**
* Returns name of the node identifier.
*
* @return name of the node identifier
*/
public String getName() {
return name;
}
/**
* Set name of the node identifier.
*
* @param name node identifier name
*/
public void setName(String name) {
this.name = name;
}
/**
* Returns prefix of the node identifier.
*
* @return prefix of the node identifier
*/
public String getPrefix() {
return prefix;
}
/**
* Set prefix of the node identifier.
*
* @param prefix prefix of the node identifier
*/
public void setPrefix(String prefix) {
this.prefix = prefix;
}
}
......@@ -20,6 +20,7 @@ import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.utils.YangConstructType;
import java.util.LinkedList;
import java.util.List;
/*
......@@ -52,13 +53,14 @@ public class YangUnion implements Parsable {
// List of YANG type.
private List<YangType<?>> typeList;
// Name of the union.
// Name of union.
private String unionName;
/**
* Create a YANG union node.
*/
public YangUnion() {
typeList = new LinkedList<>();
}
/**
......@@ -89,6 +91,21 @@ public class YangUnion implements Parsable {
}
/**
* Add YANG type to type list.
*
* @param yangType YANG type to be added to list
* @throws DataModelException union member type must not be one of the
* built-in types "empty" or "leafref"
*/
public void addToTypeList(YangType<?> yangType) throws DataModelException {
if (yangType.getDataType() == YangDataTypes.EMPTY || yangType.getDataType() == YangDataTypes.LEAFREF) {
throw new DataModelException("Union member type must not be one of the built-in types \"empty\" or " +
"\"leafref\"");
}
getTypeList().add(yangType);
}
/**
* Set the union name.
*
* @param unionName name of the union.
......
......@@ -55,17 +55,17 @@ import org.onosproject.yangutils.utils.YangConstructType;
public class YangUses extends YangNode implements YangCommonInfo, Parsable {
/**
* Name.
* Name of YANG uses.
*/
private String name;
/**
* referred group.
* Referred group.
*/
private YangGrouping refGroup;
/**
* description.
* Description of YANG uses.
*/
private String description;
......@@ -75,7 +75,7 @@ public class YangUses extends YangNode implements YangCommonInfo, Parsable {
private String reference;
/**
* Status.
* Status of YANG uses.
*/
private YangStatusType status;
......@@ -87,7 +87,7 @@ public class YangUses extends YangNode implements YangCommonInfo, Parsable {
}
/**
* Get the name.
* Returns the name.
*
* @return the name
*/
......@@ -105,7 +105,7 @@ public class YangUses extends YangNode implements YangCommonInfo, Parsable {
}
/**
* Get the referred group.
* Returns the referred group.
*
* @return the referred group
*/
......@@ -123,7 +123,7 @@ public class YangUses extends YangNode implements YangCommonInfo, Parsable {
}
/**
* Get the description.
* Returns the description.
*
* @return the description
*/
......@@ -143,7 +143,7 @@ public class YangUses extends YangNode implements YangCommonInfo, Parsable {
}
/**
* Get the textual reference.
* Returns the textual reference.
*
* @return the reference
*/
......@@ -163,7 +163,7 @@ public class YangUses extends YangNode implements YangCommonInfo, Parsable {
}
/**
* Get the status.
* Returns the status.
*
* @return the status
*/
......@@ -212,26 +212,14 @@ public class YangUses extends YangNode implements YangCommonInfo, Parsable {
// TODO auto-generated method stub, to be implemented by parser
}
/**
* Get uses name.
*
* @return uses name
*/
@Override
public String getName() {
// TODO Auto-generated method stub
return null;
return name;
}
/**
* Set uses name.
*
* @param name uses name
*/
@Override
public void setName(String name) {
// TODO Auto-generated method stub
this.name = name;
}
}
......
......@@ -38,6 +38,7 @@ import org.onosproject.yangutils.parser.impl.listeners.DefaultListener;
import org.onosproject.yangutils.parser.impl.listeners.DescriptionListener;
import org.onosproject.yangutils.parser.impl.listeners.EnumListener;
import org.onosproject.yangutils.parser.impl.listeners.EnumerationListener;
import org.onosproject.yangutils.parser.impl.listeners.GroupingListener;
import org.onosproject.yangutils.parser.impl.listeners.ImportListener;
import org.onosproject.yangutils.parser.impl.listeners.IncludeListener;
import org.onosproject.yangutils.parser.impl.listeners.KeyListener;
......@@ -61,7 +62,9 @@ import org.onosproject.yangutils.parser.impl.listeners.StatusListener;
import org.onosproject.yangutils.parser.impl.listeners.SubModuleListener;
import org.onosproject.yangutils.parser.impl.listeners.TypeDefListener;
import org.onosproject.yangutils.parser.impl.listeners.TypeListener;
import org.onosproject.yangutils.parser.impl.listeners.UnionListener;
import org.onosproject.yangutils.parser.impl.listeners.UnitsListener;
import org.onosproject.yangutils.parser.impl.listeners.UsesListener;
import org.onosproject.yangutils.parser.impl.listeners.ValueListener;
import org.onosproject.yangutils.parser.impl.listeners.VersionListener;
......@@ -687,12 +690,12 @@ public class TreeWalkListener implements GeneratedYangListener {
@Override
public void enterUnionSpecification(GeneratedYangParser.UnionSpecificationContext ctx) {
// TODO: implement the method.
UnionListener.processUnionEntry(this, ctx);
}
@Override
public void exitUnionSpecification(GeneratedYangParser.UnionSpecificationContext ctx) {
// TODO: implement the method.
UnionListener.processUnionExit(this, ctx);
}
@Override
......@@ -847,12 +850,12 @@ public class TreeWalkListener implements GeneratedYangListener {
@Override
public void enterGroupingStatement(GeneratedYangParser.GroupingStatementContext ctx) {
// TODO: implement the method.
GroupingListener.processGroupingEntry(this, ctx);
}
@Override
public void exitGroupingStatement(GeneratedYangParser.GroupingStatementContext ctx) {
// TODO: implement the method.
GroupingListener.processGroupingExit(this, ctx);
}
@Override
......@@ -947,12 +950,12 @@ public class TreeWalkListener implements GeneratedYangListener {
@Override
public void enterUsesStatement(GeneratedYangParser.UsesStatementContext ctx) {
// TODO: implement the method.
UsesListener.processUsesEntry(this, ctx);
}
@Override
public void exitUsesStatement(GeneratedYangParser.UsesStatementContext ctx) {
// TODO: implement the method.
UsesListener.processUsesExit(this, ctx);
}
@Override
......
......@@ -16,6 +16,7 @@
package org.onosproject.yangutils.parser.impl.listeners;
import org.onosproject.yangutils.datamodel.YangCase;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangModule;
......@@ -126,7 +127,7 @@ public final class ContainerListener {
Parsable curData = listener.getParsedDataStack().peek();
if (curData instanceof YangModule || curData instanceof YangContainer
|| curData instanceof YangList) {
|| curData instanceof YangList || curData instanceof YangCase) {
YangNode curNode = (YangNode) curData;
try {
curNode.addChild(container);
......
......@@ -45,6 +45,7 @@ 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.datamodel.YangUnion;
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
import org.onosproject.yangutils.parser.exceptions.ParserException;
......@@ -102,7 +103,10 @@ public final class EnumerationListener {
case LEAF_LIST_DATA:
enumerationNode.setEnumerationName(((YangLeafList) tmpData).getLeafName());
break;
// TODO typedef, union, deviate.
case UNION_DATA:
enumerationNode.setEnumerationName(((YangUnion) tmpData).getUnionName());
break;
// TODO typedef, deviate.
default:
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
((YangType<?>) typeData).getDataTypeName(), ENTRY));
......
/*
* 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 org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.YangGrouping;
import org.onosproject.yangutils.datamodel.YangInput;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNotification;
import org.onosproject.yangutils.datamodel.YangOutput;
import org.onosproject.yangutils.datamodel.YangRpc;
import org.onosproject.yangutils.datamodel.YangSubModule;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.parser.Parsable;
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.datamodel.utils.GeneratedLanguage.JAVA_GENERATION;
import static org.onosproject.yangutils.datamodel.utils.YangDataModelFactory.getYangGroupingNode;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerCollisionDetector.detectCollidingChildUtil;
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_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.ListenerErrorType.UNHANDLED_PARSED_DATA;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerUtil.getValidIdentifier;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateCardinalityMaxOne;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateMutuallyExclusiveChilds;
import static org.onosproject.yangutils.utils.YangConstructType.DESCRIPTION_DATA;
import static org.onosproject.yangutils.utils.YangConstructType.GROUPING_DATA;
import static org.onosproject.yangutils.utils.YangConstructType.REFERENCE_DATA;
import static org.onosproject.yangutils.utils.YangConstructType.STATUS_DATA;
import static org.onosproject.yangutils.utils.YangConstructType.TYPEDEF_DATA;
/*
* Reference: RFC6020 and YANG ANTLR Grammar
*
* ABNF grammar as per RFC6020
* grouping-stmt = grouping-keyword sep identifier-arg-str optsep
* (";" /
* "{" stmtsep
* ;; these stmts can appear in any order
* [status-stmt stmtsep]
* [description-stmt stmtsep]
* [reference-stmt stmtsep]
* *((typedef-stmt /
* grouping-stmt) stmtsep)
* *(data-def-stmt stmtsep)
* "}")
*
* ANTLR grammar rule
* groupingStatement : GROUPING_KEYWORD identifier (STMTEND | LEFT_CURLY_BRACE
* (statusStatement | descriptionStatement | referenceStatement | typedefStatement | groupingStatement
* | dataDefStatement)* RIGHT_CURLY_BRACE);
*/
/**
* Implements listener based call back function corresponding to the "grouping"
* rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
*/
public final class GroupingListener {
/**
* Creates a new grouping listener.
*/
private GroupingListener() {
}
/**
* It is called when parser enters grammar rule (grouping), 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 processGroupingEntry(TreeWalkListener listener,
GeneratedYangParser.GroupingStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, GROUPING_DATA, ctx.identifier().getText(), ENTRY);
// Check validity of identifier and remove double quotes.
String identifier = getValidIdentifier(ctx.identifier().getText(), GROUPING_DATA, ctx);
// Validate sub statement cardinality.
validateSubStatementsCardinality(ctx);
Parsable curData = listener.getParsedDataStack().peek();
// Check for identifier collision
int line = ctx.getStart().getLine();
int charPositionInLine = ctx.getStart().getCharPositionInLine();
detectCollidingChildUtil(listener, line, charPositionInLine, identifier, GROUPING_DATA);
if (curData instanceof YangModule || curData instanceof YangSubModule
|| curData instanceof YangContainer || curData instanceof YangNotification
|| curData instanceof YangList || curData instanceof YangGrouping
|| curData instanceof YangRpc || curData instanceof YangInput
|| curData instanceof YangOutput) {
YangGrouping groupingNode = getYangGroupingNode(JAVA_GENERATION);
groupingNode.setName(identifier);
YangNode curNode = (YangNode) curData;
try {
curNode.addChild(groupingNode);
} catch (DataModelException e) {
throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
GROUPING_DATA, ctx.identifier().getText(), ENTRY, e.getMessage()));
}
listener.getParsedDataStack().push(groupingNode);
} else {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
GROUPING_DATA, ctx.identifier().getText(), ENTRY));
}
}
/**
* It is called when parser exits from grammar rule (grouping), 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 processGroupingExit(TreeWalkListener listener,
GeneratedYangParser.GroupingStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, GROUPING_DATA, ctx.identifier().getText(), EXIT);
if (listener.getParsedDataStack().peek() instanceof YangGrouping) {
listener.getParsedDataStack().pop();
} else {
throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, GROUPING_DATA,
ctx.identifier().getText(), EXIT));
}
}
/**
* Validates the cardinality of case sub-statements as per grammar.
*
* @param ctx context object of the grammar rule
*/
private static void validateSubStatementsCardinality(GeneratedYangParser.GroupingStatementContext ctx) {
validateCardinalityMaxOne(ctx.statusStatement(), STATUS_DATA, GROUPING_DATA, ctx.identifier().getText());
validateCardinalityMaxOne(ctx.descriptionStatement(), DESCRIPTION_DATA, GROUPING_DATA,
ctx.identifier().getText());
validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, GROUPING_DATA, ctx.identifier().getText());
validateMutuallyExclusiveChilds(ctx.typedefStatement(), TYPEDEF_DATA, ctx.groupingStatement(), GROUPING_DATA,
GROUPING_DATA, ctx.identifier().getText());
}
}
......@@ -16,6 +16,7 @@
package org.onosproject.yangutils.parser.impl.listeners;
import org.onosproject.yangutils.datamodel.YangCase;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangModule;
......@@ -133,7 +134,7 @@ public final class ListListener {
Parsable curData = listener.getParsedDataStack().peek();
if (curData instanceof YangModule || curData instanceof YangContainer
|| curData instanceof YangList) {
|| curData instanceof YangList || curData instanceof YangCase) {
curNode = (YangNode) curData;
try {
curNode.addChild(yangList);
......
......@@ -22,6 +22,8 @@ import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.YangTypeDef;
import org.onosproject.yangutils.datamodel.YangUnion;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.parser.Parsable;
import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
import org.onosproject.yangutils.parser.exceptions.ParserException;
......@@ -116,6 +118,17 @@ public final class TypeListener {
YangLeafList leafList = (YangLeafList) tmpData;
leafList.setDataType((YangType<?>) type);
break;
case UNION_DATA:
YangUnion unionNode = (YangUnion) tmpData;
try {
unionNode.addToTypeList((YangType<?>) type);
} catch (DataModelException e) {
ParserException parserException = new ParserException(e.getMessage());
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
break;
case TYPEDEF_DATA:
/* Prepare the base type info and set in derived type */
......
/*
* Copyright 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
*
* union-specification = 1*(type-stmt stmtsep)
*
* ANTLR grammar rule
* typeBodyStatements : numericalRestrictions | stringRestrictions | enumSpecification
* | leafrefSpecification | identityrefSpecification | instanceIdentifierSpecification
* | bitsSpecification | unionSpecification;
*
* unionSpecification : typeStatement+;
*/
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.YangUnion;
import org.onosproject.yangutils.parser.Parsable;
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;
import static org.onosproject.yangutils.utils.YangConstructType.TYPE_DATA;
import static org.onosproject.yangutils.utils.YangConstructType.UNION_DATA;
/**
* Implements listener based call back function corresponding to the "union" rule
* defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
*/
public final class UnionListener {
/**
* Creates a new union listener.
*/
private UnionListener() {
}
/**
* It is called when parser enters grammar rule (union), 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 processUnionEntry(TreeWalkListener listener,
GeneratedYangParser.UnionSpecificationContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, UNION_DATA, "", ENTRY);
if (listener.getParsedDataStack().peek() instanceof YangType) {
YangUnion unionNode = new YangUnion();
Parsable typeData = listener.getParsedDataStack().pop();
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, UNION_DATA, "", ENTRY);
Parsable tmpData = listener.getParsedDataStack().peek();
switch (tmpData.getYangConstructType()) {
case LEAF_DATA:
unionNode.setUnionName(((YangLeaf) tmpData).getLeafName());
break;
case LEAF_LIST_DATA:
unionNode.setUnionName(((YangLeafList) tmpData).getLeafName());
break;
case UNION_DATA:
unionNode.setUnionName(((YangUnion) tmpData).getUnionName());
break;
// TODO typedef, deviate.
default:
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, TYPE_DATA,
((YangType<?>) typeData).getDataTypeName(), ENTRY));
}
listener.getParsedDataStack().push(typeData);
listener.getParsedDataStack().push(unionNode);
} else {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, UNION_DATA, "", ENTRY));
}
}
/**
* It is called when parser exits from grammar rule (union), 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 processUnionExit(TreeWalkListener listener,
GeneratedYangParser.UnionSpecificationContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, UNION_DATA, "", EXIT);
Parsable tmpUnionNode = listener.getParsedDataStack().peek();
if (tmpUnionNode instanceof YangUnion) {
YangUnion unionNode = (YangUnion) tmpUnionNode;
listener.getParsedDataStack().pop();
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, UNION_DATA, "", EXIT);
Parsable tmpNode = listener.getParsedDataStack().peek();
switch (tmpNode.getYangConstructType()) {
case TYPE_DATA: {
YangType<YangUnion> typeNode = (YangType<YangUnion>) tmpNode;
typeNode.setDataTypeExtendedInfo(unionNode);
break;
}
default:
throw new ParserException(
constructListenerErrorMessage(INVALID_HOLDER, UNION_DATA, "", EXIT));
}
} else {
throw new ParserException(
constructListenerErrorMessage(MISSING_CURRENT_HOLDER, UNION_DATA, "", EXIT));
}
}
}
\ No newline at end of file
package org.onosproject.yangutils.parser.impl.listeners;
import org.onosproject.yangutils.datamodel.YangAugment;
import org.onosproject.yangutils.datamodel.YangCase;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.YangGrouping;
import org.onosproject.yangutils.datamodel.YangInput;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNotification;
import org.onosproject.yangutils.datamodel.YangOutput;
import org.onosproject.yangutils.datamodel.YangSubModule;
import org.onosproject.yangutils.datamodel.YangUses;
import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.parser.Parsable;
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.datamodel.utils.GeneratedLanguage.JAVA_GENERATION;
import static org.onosproject.yangutils.datamodel.utils.YangDataModelFactory.getYangUsesNode;
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_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.ListenerErrorType.UNHANDLED_PARSED_DATA;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateCardinalityMaxOne;
import static org.onosproject.yangutils.utils.YangConstructType.DESCRIPTION_DATA;
import static org.onosproject.yangutils.utils.YangConstructType.REFERENCE_DATA;
import static org.onosproject.yangutils.utils.YangConstructType.STATUS_DATA;
import static org.onosproject.yangutils.utils.YangConstructType.USES_DATA;
import static org.onosproject.yangutils.utils.YangConstructType.WHEN_DATA;
/*
* Reference: RFC6020 and YANG ANTLR Grammar
*
* ABNF grammar as per RFC6020
* data-def-stmt = container-stmt /
* leaf-stmt /
* leaf-list-stmt /
* list-stmt /
* choice-stmt /
* anyxml-stmt /
* uses-stmt
*
* uses-stmt = uses-keyword sep identifier-ref-arg-str optsep
* (";" /
* "{" stmtsep
* ;; these stmts can appear in any order
* [when-stmt stmtsep]
* *(if-feature-stmt stmtsep)
* [status-stmt stmtsep]
* [description-stmt stmtsep]
* [reference-stmt stmtsep]
* *(refine-stmt stmtsep)
* *(uses-augment-stmt stmtsep)
* "}")
*
* ANTLR grammar rule
* dataDefStatement : containerStatement
* | leafStatement
* | leafListStatement
* | listStatement
* | choiceStatement
* | usesStatement;
*
* usesStatement : USES_KEYWORD string (STMTEND | LEFT_CURLY_BRACE (whenStatement | ifFeatureStatement
* | statusStatement | descriptionStatement | referenceStatement | refineStatement
* | usesAugmentStatement)* RIGHT_CURLY_BRACE);
*/
/**
* Implements listener based call back function corresponding to the "uses"
* rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
*/
public final class UsesListener {
/**
* Creates a new uses listener.
*/
private UsesListener() {
}
/**
* It is called when parser enters grammar rule (uses), 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 processUsesEntry(TreeWalkListener listener, GeneratedYangParser.UsesStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, USES_DATA, ctx.string().getText(), ENTRY);
// Validate sub statement cardinality.
validateSubStatementsCardinality(ctx);
Parsable curData = listener.getParsedDataStack().peek();
if (curData instanceof YangModule || curData instanceof YangSubModule
|| curData instanceof YangContainer || curData instanceof YangList
|| curData instanceof YangUses || curData instanceof YangAugment
|| curData instanceof YangCase || curData instanceof YangGrouping
|| curData instanceof YangInput || curData instanceof YangOutput
|| curData instanceof YangNotification) {
YangUses usesNode = getYangUsesNode(JAVA_GENERATION);
usesNode.setName(ctx.string().getText());
YangNode curNode = (YangNode) curData;
try {
curNode.addChild(usesNode);
} catch (DataModelException e) {
throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
USES_DATA, ctx.string().getText(), ENTRY, e.getMessage()));
}
listener.getParsedDataStack().push(usesNode);
} else {
throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
USES_DATA, ctx.string().getText(), ENTRY));
}
}
/**
* It is called when parser exits from grammar rule (uses), 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 processUsesExit(TreeWalkListener listener,
GeneratedYangParser.UsesStatementContext ctx) {
// Check for stack to be non empty.
checkStackIsNotEmpty(listener, MISSING_HOLDER, USES_DATA, ctx.string().getText(), EXIT);
if (listener.getParsedDataStack().peek() instanceof YangUses) {
listener.getParsedDataStack().pop();
} else {
throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, USES_DATA,
ctx.string().getText(), EXIT));
}
}
// TODO linker to handle collision scenarios like leaf obtained by uses, conflicts with some existing leaf.
/**
* Validates the cardinality of case sub-statements as per grammar.
*
* @param ctx context object of the grammar rule
*/
private static void validateSubStatementsCardinality(GeneratedYangParser.UsesStatementContext ctx) {
validateCardinalityMaxOne(ctx.whenStatement(), WHEN_DATA, USES_DATA, ctx.string().getText());
validateCardinalityMaxOne(ctx.statusStatement(), STATUS_DATA, USES_DATA, ctx.string().getText());
validateCardinalityMaxOne(ctx.descriptionStatement(), DESCRIPTION_DATA, USES_DATA, ctx.string().getText());
validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, USES_DATA, ctx.string().getText()); }
}
......@@ -23,6 +23,7 @@ import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.regex.Pattern;
import org.onosproject.yangutils.datamodel.YangNodeIdentifier;
import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
import org.onosproject.yangutils.utils.YangConstructType;
import org.onosproject.yangutils.parser.exceptions.ParserException;
......@@ -43,6 +44,7 @@ public final class ListenerUtil {
private static final String HYPHEN = "-";
private static final String SLASH = "/";
private static final String SPACE = " ";
private static final String COLON = ":";
/**
* Creates a new listener util.
......@@ -204,4 +206,35 @@ public final class ListenerUtil {
EMPTY_STRING);
return dateForRevision;
}
/**
* Checks and return valid node identifier.
*
* @param nodeIdentifierString string from yang file
* @param yangConstruct yang construct for creating error message
* @param ctx yang construct's context to get the line number and character position
* @return valid node identifier
*/
public static YangNodeIdentifier getValidNodeIdentifier(String nodeIdentifierString, YangConstructType
yangConstruct, ParserRuleContext ctx) {
String tmpIdentifierString = removeQuotesAndHandleConcat(nodeIdentifierString);
String[] tmpData = tmpIdentifierString.split(Pattern.quote(COLON));
if (tmpData.length == 1) {
YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
nodeIdentifier.setName(getValidIdentifier(tmpData[0], yangConstruct, ctx));
return nodeIdentifier;
} else if (tmpData.length == 2) {
YangNodeIdentifier nodeIdentifier = new YangNodeIdentifier();
nodeIdentifier.setPrefix(getValidIdentifier(tmpData[0], yangConstruct, ctx));
nodeIdentifier.setName(getValidIdentifier(tmpData[1], yangConstruct, ctx));
return nodeIdentifier;
} else {
ParserException parserException = new ParserException("YANG file error : " +
YangConstructType.getYangConstructType(yangConstruct) + " name " + nodeIdentifierString +
" is not valid.");
parserException.setLine(ctx.getStart().getLine());
parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
throw parserException;
}
}
}
\ No newline at end of file
......
/*
* Copyright 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 java.io.IOException;
import java.util.ListIterator;
import org.junit.Test;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.YangGrouping;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeType;
import org.onosproject.yangutils.datamodel.YangStatusType;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
/**
* Test cases for testing grouping listener.
*/
public class GroupingListenerTest {
private final YangUtilsParserManager manager = new YangUtilsParserManager();
/**
* Checks grouping statement inside module.
*/
@Test
public void processGroupingInModule() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/GroupingInModule.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"));
YangGrouping yangGrouping = (YangGrouping) yangNode.getChild();
assertThat(yangGrouping.getName(), is("endpoint"));
ListIterator<YangLeaf> leafIterator = yangGrouping.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getLeafName(), is("address"));
}
/**
* Checks grouping statement inside container.
*/
@Test
public void processGroupingInContainer() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/GroupingInContainer.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"));
YangContainer yangContainer = (YangContainer) yangNode.getChild();
assertThat(yangContainer.getName(), is("valid"));
YangGrouping yangGrouping = (YangGrouping) yangContainer.getChild();
assertThat(yangGrouping.getName(), is("endpoint"));
ListIterator<YangLeaf> leafIterator = yangGrouping.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getLeafName(), is("address"));
}
/**
* Checks grouping statement inside list.
*/
@Test
public void processGroupingInList() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/GroupingInList.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"));
YangList yangList = (YangList) yangNode.getChild();
assertThat(yangList.getName(), is("valid"));
YangGrouping yangGrouping = (YangGrouping) yangList.getChild();
assertThat(yangGrouping.getName(), is("endpoint"));
ListIterator<YangLeaf> leafIterator = yangGrouping.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getLeafName(), is("address"));
}
/**
* Checks grouping with attributes.
*/
@Test
public void processGroupingAttributes() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/GroupingAttributes.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"));
YangList yangList = (YangList) yangNode.getChild();
assertThat(yangList.getName(), is("valid"));
YangGrouping yangGrouping = (YangGrouping) yangList.getChild();
assertThat(yangGrouping.getName(), is("endpoint"));
assertThat(yangGrouping.getStatus(), is(YangStatusType.CURRENT));
assertThat(yangGrouping.getReference(), is("\"RFC 6020\""));
assertThat(yangGrouping.getDescription(), is("\"grouping under test\""));
ListIterator<YangLeaf> leafIterator = yangGrouping.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getLeafName(), is("address"));
}
/**
* Checks duplicate grouping in list.
*/
@Test(expected = ParserException.class)
public void processDuplicateGroupingInList() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/DuplicateGroupingInList.yang");
}
/**
* Checks duplicate grouping in container.
*/
@Test (expected = ParserException.class)
public void processDuplicateGroupingInContainer() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/DuplicateGroupingInContainer.yang");
}
/**
* Checks duplicate grouping in module.
*/
@Test (expected = ParserException.class)
public void processDuplicateGroupingInModule() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/DuplicateGroupingInModule.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.YangCase;
import org.onosproject.yangutils.datamodel.YangChoice;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.YangList;
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;
/**
* Test cases for short case listener.
*/
public class ShortCaseListenerTest {
private final YangUtilsParserManager manager = new YangUtilsParserManager();
/**
* Checks short case listener with container.
*/
@Test
public void processShortCaseListenerWithContainer() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/ShortCaseListenerWithContainer.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"));
YangContainer yangContainer = (YangContainer) yangNode.getChild();
assertThat(yangContainer.getName(), is("food"));
YangChoice yangChoice = (YangChoice) yangContainer.getChild();
assertThat(yangChoice.getName(), is("snack"));
YangCase yangCase = (YangCase) yangChoice.getChild();
assertThat(yangCase.getName(), is("sports-arena"));
YangContainer yangContainer1 = (YangContainer) yangCase.getChild();
assertThat(yangContainer1.getName(), is("sports-arena"));
}
/**
* Checks short case listener with list.
*/
@Test
public void processShortCaseListenerWithList() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/ShortCaseListenerWithList.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"));
YangContainer yangContainer = (YangContainer) yangNode.getChild();
assertThat(yangContainer.getName(), is("food"));
YangChoice yangChoice = (YangChoice) yangContainer.getChild();
assertThat(yangChoice.getName(), is("snack"));
YangCase yangCase = (YangCase) yangChoice.getChild();
assertThat(yangCase.getName(), is("sports-arena"));
YangList yangList = (YangList) yangCase.getChild();
assertThat(yangList.getName(), is("sports-arena"));
}
}
/*
* Copyright 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 java.io.IOException;
import java.util.List;
import java.util.ListIterator;
import org.junit.Test;
import org.onosproject.yangutils.datamodel.YangDataTypes;
import org.onosproject.yangutils.datamodel.YangLeaf;
import org.onosproject.yangutils.datamodel.YangLeafList;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeType;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.YangUnion;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
/**
* Test cases for testing union listener.
*/
public class UnionListenerTest {
private final YangUtilsParserManager manager = new YangUtilsParserManager();
/**
* Checks union when type is in leaf.
*/
@Test
public void processUnionWhenTypeInLeaf() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/UnionWhenTypeInLeaf.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"));
YangList yangList = (YangList) yangNode.getChild();
assertThat(yangList.getName(), is("valid"));
ListIterator<YangLeaf> leafIterator = yangList.getListOfLeaf().listIterator();
YangLeaf leafInfo = leafIterator.next();
assertThat(leafInfo.getLeafName(), is("invalid-interval"));
assertThat(leafInfo.getDataType().getDataType(), is(YangDataTypes.UNION));
assertThat(leafInfo.getDataType().getDataTypeName(), is("union"));
YangUnion yangUnion = (YangUnion) leafInfo.getDataType().getDataTypeExtendedInfo();
List<YangType<?>> typeList = yangUnion.getTypeList();
ListIterator<YangType<?>> typeListIterator = typeList.listIterator();
YangType<?> yangType = typeListIterator.next();
assertThat(yangType.getDataTypeName(), is("int32"));
assertThat(yangType.getDataType(), is(YangDataTypes.INT32));
YangType<?> yangTypeEnum = typeListIterator.next();
assertThat(yangTypeEnum.getDataTypeName(), is("enumeration"));
assertThat(yangTypeEnum.getDataType(), is(YangDataTypes.ENUMERATION));
}
/**
* Checks union when type is in leaflist.
*/
@Test
public void processUnionWhenTypeInLeafList() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/UnionWhenTypeInLeafList.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"));
YangList yangList = (YangList) yangNode.getChild();
assertThat(yangList.getName(), is("valid"));
ListIterator<YangLeafList> leafListIterator = yangList.getListOfLeafList().listIterator();
YangLeafList leafListInfo = leafListIterator.next();
assertThat(leafListInfo.getLeafName(), is("invalid-interval"));
assertThat(leafListInfo.getDataType().getDataType(), is(YangDataTypes.UNION));
assertThat(leafListInfo.getDataType().getDataTypeName(), is("union"));
YangUnion yangUnion = (YangUnion) leafListInfo.getDataType().getDataTypeExtendedInfo();
List<YangType<?>> typeList = yangUnion.getTypeList();
ListIterator<YangType<?>> typeListIterator = typeList.listIterator();
YangType<?> yangType = typeListIterator.next();
assertThat(yangType.getDataTypeName(), is("int32"));
assertThat(yangType.getDataType(), is(YangDataTypes.INT32));
YangType<?> yangTypeEnum = typeListIterator.next();
assertThat(yangTypeEnum.getDataTypeName(), is("enumeration"));
assertThat(yangTypeEnum.getDataType(), is(YangDataTypes.ENUMERATION));
}
/**
* Checks union with empty type.
*/
@Test (expected = ParserException.class)
public void processUnionWithEmptyType() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/UnionWithEmptyType.yang");
}
}
/*
* Copyright 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 java.io.IOException;
import org.junit.Test;
import org.onosproject.yangutils.datamodel.YangContainer;
import org.onosproject.yangutils.datamodel.YangList;
import org.onosproject.yangutils.datamodel.YangModule;
import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangNodeType;
import org.onosproject.yangutils.datamodel.YangStatusType;
import org.onosproject.yangutils.datamodel.YangUses;
import org.onosproject.yangutils.parser.exceptions.ParserException;
import org.onosproject.yangutils.parser.impl.YangUtilsParserManager;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
/**
* Test cases for testing uses listener.
*/
public class UsesListenerTest {
private final YangUtilsParserManager manager = new YangUtilsParserManager();
/**
* Checks uses statement inside module.
*/
@Test
public void processUsesInModule() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/UsesInModule.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"));
YangUses yangUses = (YangUses) yangNode.getChild();
assertThat(yangUses.getName(), is("endpoint"));
}
/**
* Checks uses statement inside container.
*/
@Test
public void processUsesInContainer() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/UsesInContainer.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"));
YangContainer yangContainer = (YangContainer) yangNode.getChild();
assertThat(yangContainer.getName(), is("valid"));
YangUses yangUses = (YangUses) yangContainer.getChild();
assertThat(yangUses.getName(), is("endpoint"));
// Check attributes associated with uses.
assertThat(yangUses.getStatus(), is(YangStatusType.CURRENT));
assertThat(yangUses.getReference(), is("\"RFC 6020\""));
assertThat(yangUses.getDescription(), is("\"grouping under test\""));
}
/**
* Checks uses statement inside list.
*/
@Test
public void processUsesInList() throws IOException, ParserException {
YangNode node = manager.getDataModel("src/test/resources/UsesInList.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"));
YangList yangList = (YangList) yangNode.getChild();
assertThat(yangList.getName(), is("valid"));
YangUses yangUses = (YangUses) yangList.getChild();
assertThat(yangUses.getName(), is("endpoint"));
// Check attributes associated with uses.
assertThat(yangUses.getStatus(), is(YangStatusType.CURRENT));
assertThat(yangUses.getReference(), is("\"RFC 6020\""));
assertThat(yangUses.getDescription(), is("\"grouping under test\""));
}
}
......@@ -2,22 +2,22 @@ module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
container food {
choice snack {
case sports-arena {
leaf pretzel {
type empty;
}
}
case late-night {
choice dinner {
case late-night {
leaf beer {
type empty;
}
}
}
}
container food {
choice snack {
case sports-arena {
leaf pretzel {
type empty;
}
}
case late-night {
choice dinner {
case late-night {
leaf beer {
type empty;
}
}
}
}
}
}
}
}
......
......@@ -4,7 +4,7 @@ module Test {
prefix Ant;
container valid {
config false;
list valid {
list valid {
key "invalid-interval";
config true;
leaf invalid-interval {
......
......@@ -11,7 +11,7 @@ module Test {
status current;
reference "RFC 6020";
}
container valid {
container valid {
config true;
leaf invalid-interval {
type "uint16";
......@@ -19,6 +19,6 @@ module Test {
status current;
reference "RFC 6020";
}
}
}
}
}
\ No newline at end of file
......
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
container valid {
grouping endpoint {
leaf address {
type ip-address;
}
leaf port {
type port-number;
}
}
grouping endpoint {
leaf address {
type ip-address;
}
leaf port {
type port-number;
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key address;
grouping endpoint {
description "grouping under test";
status current;
reference "RFC 6020";
leaf address {
type ip-address;
}
leaf port {
type port-number;
}
}
leaf address {
type ip;
}
grouping endpoint {
description "grouping under test";
status current;
reference "RFC 6020";
leaf address {
type ip-address;
}
leaf port {
type port-number;
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
grouping endpoint {
leaf address {
type ip-address;
}
leaf port {
type port-number;
}
}
grouping endpoint {
leaf address {
type ip-address;
}
leaf port {
type port-number;
}
}
}
......@@ -2,22 +2,22 @@ module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
container food {
choice snack {
case sports-arena {
leaf pretzel {
type empty;
}
}
case late-night {
choice lunch {
case late {
leaf pretzel {
type empty;
}
}
}
}
container food {
choice snack {
case sports-arena {
leaf pretzel {
type empty;
}
}
case late-night {
choice lunch {
case late {
leaf pretzel {
type empty;
}
}
}
}
}
}
}
}
......
......@@ -4,11 +4,11 @@ module Test {
prefix Ant;
leaf speed {
type enumeration {
enum 10m;
enum 100m;
enum 10m {
value 11;
}
enum 10m;
enum 100m;
enum 10m {
value 11;
}
}
}
}
......
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key address;
leaf address {
type ip;
}
grouping endpoint {
description "grouping under test";
status current;
reference "RFC 6020";
leaf address {
type ip-address;
}
leaf port {
type port-number;
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
container valid {
grouping endpoint {
leaf address {
type ip-address;
}
leaf port {
type port-number;
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key address;
leaf address {
type ip;
}
grouping endpoint {
leaf address {
type ip-address;
}
leaf port {
type port-number;
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
grouping endpoint {
leaf address {
type ip-address;
}
leaf port {
type port-number;
}
}
}
......@@ -2,14 +2,14 @@ module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
container food {
choice snack {
container sports-arena {
leaf pretzel {
type empty;
}
}
}
container food {
choice snack {
container sports-arena {
leaf pretzel {
type empty;
}
}
}
}
}
}
}
......
......@@ -2,15 +2,15 @@ module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
container food {
choice snack {
list sports-arena {
key "pretzel";
leaf pretzel {
type int32;
}
}
}
container food {
choice snack {
list sports-arena {
key "pretzel";
leaf pretzel {
type int32;
}
}
}
}
}
}
}
......
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key "invalid-interval";
leaf invalid-interval {
type union {
type int32;
type enumeration {
enum "unbounded";
}
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key "invalid-interval";
leaf-list invalid-interval {
type union {
type int32;
type enumeration {
enum "unbounded";
}
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key "invalid-interval";
leaf invalid-interval {
type union {
type empty;
type enumeration {
enum "unbounded";
}
}
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
container valid {
uses endpoint {
description "grouping under test";
status current;
reference "RFC 6020";
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
list valid {
key address;
leaf address {
type ip;
}
uses endpoint {
description "grouping under test";
status current;
reference "RFC 6020";
}
}
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
uses endpoint;
}
module Test {
yang-version 1;
namespace http://huawei.com;
prefix Ant;
grouping endpoint {
leaf address {
type ip-address;
}
leaf port {
type port-number;
}
}
container valid {
grouping endpoint {
leaf address {
type ip-address;
}
leaf port {
type port-number;
}
}
}
}
......@@ -4,13 +4,13 @@ module Test {
prefix Ant;
leaf speed {
type enumeration {
enum 10m {
value 10;
}
enum 100m;
enum auto {
value 1000;
}
enum 10m {
value 10;
}
enum 100m;
enum auto {
value 1000;
}
}
}
}
......