blob: 59e744e97f66aaf4a9ed03779a0d7494215dfff2 [file] [log] [blame]
Gaurav Agrawalbd804472016-03-25 11:25:36 +05301package org.onosproject.yangutils.parser.impl.listeners;
2
3import org.onosproject.yangutils.datamodel.YangAugment;
4import org.onosproject.yangutils.datamodel.YangCase;
5import org.onosproject.yangutils.datamodel.YangContainer;
6import org.onosproject.yangutils.datamodel.YangGrouping;
7import org.onosproject.yangutils.datamodel.YangInput;
8import org.onosproject.yangutils.datamodel.YangList;
9import org.onosproject.yangutils.datamodel.YangModule;
10import org.onosproject.yangutils.datamodel.YangNode;
11import org.onosproject.yangutils.datamodel.YangNotification;
12import org.onosproject.yangutils.datamodel.YangOutput;
13import org.onosproject.yangutils.datamodel.YangSubModule;
14import org.onosproject.yangutils.datamodel.YangUses;
15import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
16import org.onosproject.yangutils.parser.Parsable;
17import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
18import org.onosproject.yangutils.parser.exceptions.ParserException;
19import org.onosproject.yangutils.parser.impl.TreeWalkListener;
20
21import static org.onosproject.yangutils.datamodel.utils.GeneratedLanguage.JAVA_GENERATION;
22import static org.onosproject.yangutils.datamodel.utils.YangDataModelFactory.getYangUsesNode;
23import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
24import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
25import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructExtendedListenerErrorMessage;
26import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
27import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
28import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
29import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
30import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.UNHANDLED_PARSED_DATA;
31import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
32import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.validateCardinalityMaxOne;
33import static org.onosproject.yangutils.utils.YangConstructType.DESCRIPTION_DATA;
34import static org.onosproject.yangutils.utils.YangConstructType.REFERENCE_DATA;
35import static org.onosproject.yangutils.utils.YangConstructType.STATUS_DATA;
36import static org.onosproject.yangutils.utils.YangConstructType.USES_DATA;
37import static org.onosproject.yangutils.utils.YangConstructType.WHEN_DATA;
38
39/*
40 * Reference: RFC6020 and YANG ANTLR Grammar
41 *
42 * ABNF grammar as per RFC6020
43 * data-def-stmt = container-stmt /
44 * leaf-stmt /
45 * leaf-list-stmt /
46 * list-stmt /
47 * choice-stmt /
48 * anyxml-stmt /
49 * uses-stmt
50 *
51 * uses-stmt = uses-keyword sep identifier-ref-arg-str optsep
52 * (";" /
53 * "{" stmtsep
54 * ;; these stmts can appear in any order
55 * [when-stmt stmtsep]
56 * *(if-feature-stmt stmtsep)
57 * [status-stmt stmtsep]
58 * [description-stmt stmtsep]
59 * [reference-stmt stmtsep]
60 * *(refine-stmt stmtsep)
61 * *(uses-augment-stmt stmtsep)
62 * "}")
63 *
64 * ANTLR grammar rule
65 * dataDefStatement : containerStatement
66 * | leafStatement
67 * | leafListStatement
68 * | listStatement
69 * | choiceStatement
70 * | usesStatement;
71 *
72 * usesStatement : USES_KEYWORD string (STMTEND | LEFT_CURLY_BRACE (whenStatement | ifFeatureStatement
73 * | statusStatement | descriptionStatement | referenceStatement | refineStatement
74 * | usesAugmentStatement)* RIGHT_CURLY_BRACE);
75 */
76
77/**
78 * Implements listener based call back function corresponding to the "uses"
79 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
80 */
81public final class UsesListener {
82
83 /**
84 * Creates a new uses listener.
85 */
86 private UsesListener() {
87 }
88
89 /**
90 * It is called when parser enters grammar rule (uses), it perform
91 * validations and updates the data model tree.
92 *
93 * @param listener listener's object
94 * @param ctx context object of the grammar rule
95 */
96 public static void processUsesEntry(TreeWalkListener listener, GeneratedYangParser.UsesStatementContext ctx) {
97
98 // Check for stack to be non empty.
99 checkStackIsNotEmpty(listener, MISSING_HOLDER, USES_DATA, ctx.string().getText(), ENTRY);
100
101 // Validate sub statement cardinality.
102 validateSubStatementsCardinality(ctx);
103
104 Parsable curData = listener.getParsedDataStack().peek();
105
106 if (curData instanceof YangModule || curData instanceof YangSubModule
107 || curData instanceof YangContainer || curData instanceof YangList
108 || curData instanceof YangUses || curData instanceof YangAugment
109 || curData instanceof YangCase || curData instanceof YangGrouping
110 || curData instanceof YangInput || curData instanceof YangOutput
111 || curData instanceof YangNotification) {
112
113 YangUses usesNode = getYangUsesNode(JAVA_GENERATION);
114 usesNode.setName(ctx.string().getText());
115
116 YangNode curNode = (YangNode) curData;
117
118 try {
119 curNode.addChild(usesNode);
120 } catch (DataModelException e) {
121 throw new ParserException(constructExtendedListenerErrorMessage(UNHANDLED_PARSED_DATA,
122 USES_DATA, ctx.string().getText(), ENTRY, e.getMessage()));
123 }
124 listener.getParsedDataStack().push(usesNode);
125 } else {
126 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER,
127 USES_DATA, ctx.string().getText(), ENTRY));
128 }
129 }
130
131 /**
132 * It is called when parser exits from grammar rule (uses), it perform
133 * validations and update the data model tree.
134 *
135 * @param listener Listener's object
136 * @param ctx context object of the grammar rule
137 */
138 public static void processUsesExit(TreeWalkListener listener,
139 GeneratedYangParser.UsesStatementContext ctx) {
140
141 // Check for stack to be non empty.
142 checkStackIsNotEmpty(listener, MISSING_HOLDER, USES_DATA, ctx.string().getText(), EXIT);
143
144 if (listener.getParsedDataStack().peek() instanceof YangUses) {
145 listener.getParsedDataStack().pop();
146 } else {
147 throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, USES_DATA,
148 ctx.string().getText(), EXIT));
149 }
150 }
151
152 // TODO linker to handle collision scenarios like leaf obtained by uses, conflicts with some existing leaf.
153
154 /**
155 * Validates the cardinality of case sub-statements as per grammar.
156 *
157 * @param ctx context object of the grammar rule
158 */
159 private static void validateSubStatementsCardinality(GeneratedYangParser.UsesStatementContext ctx) {
160 validateCardinalityMaxOne(ctx.whenStatement(), WHEN_DATA, USES_DATA, ctx.string().getText());
161 validateCardinalityMaxOne(ctx.statusStatement(), STATUS_DATA, USES_DATA, ctx.string().getText());
162 validateCardinalityMaxOne(ctx.descriptionStatement(), DESCRIPTION_DATA, USES_DATA, ctx.string().getText());
163 validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, USES_DATA, ctx.string().getText()); }
164}