blob: 2f1d7fe72c0751189002eab6b896fbab7f8cbbd5 [file] [log] [blame]
Vidyashree Ramaa2f73982016-04-12 23:33:33 +05301/*
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +05302 * Copyright 2016-present Open Networking Laboratory
Vidyashree Ramaa2f73982016-04-12 23:33:33 +05303 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.yangutils.parser.impl.listeners;
18
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053019import org.onosproject.yangutils.datamodel.YangDataTypes;
20import org.onosproject.yangutils.datamodel.YangDerivedInfo;
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +053021import org.onosproject.yangutils.datamodel.YangRangeRestriction;
22import org.onosproject.yangutils.datamodel.YangStringRestriction;
23import org.onosproject.yangutils.datamodel.YangType;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053024import org.onosproject.yangutils.parser.Parsable;
25import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
26import org.onosproject.yangutils.parser.exceptions.ParserException;
27import org.onosproject.yangutils.parser.impl.TreeWalkListener;
28import org.onosproject.yangutils.utils.YangConstructType;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053029
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +053030import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053031import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
Vidyashree Rama1db15562016-05-17 16:16:15 +053032import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053033import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
34import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
Vidyashree Rama1db15562016-05-17 16:16:15 +053035import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053036import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053037import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +053038import static org.onosproject.yangutils.utils.RestrictionResolver.processLengthRestriction;
39import static org.onosproject.yangutils.utils.YangConstructType.LENGTH_DATA;
40import static org.onosproject.yangutils.utils.YangConstructType.TYPE_DATA;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053041
42/*
43 * Reference: RFC6020 and YANG ANTLR Grammar
44 *
45 * ABNF grammar as per RFC6020
46 * length-stmt = length-keyword sep length-arg-str optsep
47 * (";" /
48 * "{" stmtsep
49 * ;; these stmts can appear in any order
50 * [error-message-stmt stmtsep]
51 * [error-app-tag-stmt stmtsep]
52 * [description-stmt stmtsep]
53 * [reference-stmt stmtsep]
54 * "}")
55 *
56 *
57 * ANTLR grammar rule
58 * lengthStatement : LENGTH_KEYWORD length
59 * (STMTEND | LEFT_CURLY_BRACE commonStatements RIGHT_CURLY_BRACE);
60 */
61
62/**
63 * Represents listener based call back function corresponding to the "length"
64 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
65 */
66public final class LengthRestrictionListener {
67
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053068 /**
69 * Creates a new length restriction listener.
70 */
71 private LengthRestrictionListener() {
72 }
73
74 /**
75 * It is called when parser receives an input matching the grammar
76 * rule (length), performs validation and updates the data model
77 * tree.
78 *
79 * @param listener listener's object
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +053080 * @param ctx context object of the grammar rule
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053081 */
82 public static void processLengthRestrictionEntry(TreeWalkListener listener,
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +053083 GeneratedYangParser.LengthStatementContext ctx) {
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053084
85 // Check for stack to be non empty.
86 checkStackIsNotEmpty(listener, MISSING_HOLDER, LENGTH_DATA, ctx.length().getText(), ENTRY);
87
88 Parsable tmpData = listener.getParsedDataStack().peek();
89 if (tmpData.getYangConstructType() == TYPE_DATA) {
90 YangType type = (YangType) tmpData;
Vidyashree Rama1db15562016-05-17 16:16:15 +053091 setLengthRestriction(listener, type, ctx);
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053092 } else {
93 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, LENGTH_DATA,
94 ctx.length().getText(), ENTRY));
95 }
96 }
97
98 /**
99 * Sets the length restriction to type.
100 *
Vidyashree Rama1db15562016-05-17 16:16:15 +0530101 * @param listener listener's object
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530102 * @param type Yang type for which length restriction to be set
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530103 * @param ctx context object of the grammar rule
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530104 */
Vidyashree Rama1db15562016-05-17 16:16:15 +0530105 private static void setLengthRestriction(TreeWalkListener listener, YangType type,
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530106 GeneratedYangParser.LengthStatementContext ctx) {
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530107
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530108 if (type.getDataType() == DERIVED) {
109 ((YangDerivedInfo<YangRangeRestriction>) type.getDataTypeExtendedInfo())
110 .setLengthRestrictionString(ctx.length().getText());
111 ((YangDerivedInfo<YangRangeRestriction>) type.getDataTypeExtendedInfo())
112 .setLineNumber(ctx.getStart().getLine());
113 ((YangDerivedInfo<YangRangeRestriction>) type.getDataTypeExtendedInfo())
114 .setCharPosition(ctx.getStart().getCharPositionInLine());
115 return;
116 }
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530117
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530118 if (type.getDataType() != YangDataTypes.STRING) {
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530119 ParserException parserException = new ParserException("YANG file error : " +
120 YangConstructType.getYangConstructType(LENGTH_DATA) + " name " + ctx.length().getText() +
121 " can be used to restrict the built-in type string or types derived from string.");
122 parserException.setLine(ctx.getStart().getLine());
123 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
124 throw parserException;
125 }
126
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530127 YangRangeRestriction lengthRestriction = processLengthRestriction(null, ctx.getStart().getLine(),
128 ctx.getStart().getCharPositionInLine(), false, ctx.length().getText());
129
130 YangStringRestriction stringRestriction = (YangStringRestriction) type.getDataTypeExtendedInfo();
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530131
132 if (stringRestriction == null) {
133 stringRestriction = new YangStringRestriction();
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530134 type.setDataTypeExtendedInfo(stringRestriction);
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530135 }
136
137 stringRestriction.setLengthRestriction(lengthRestriction);
Vidyashree Rama1db15562016-05-17 16:16:15 +0530138 listener.getParsedDataStack().push(lengthRestriction);
139 }
140
141 /**
142 * Performs validation and updates the data model tree.
143 * It is called when parser exits from grammar rule (length).
144 *
145 * @param listener listener's object
146 * @param ctx context object of the grammar rule
147 */
148 public static void processLengthRestrictionExit(TreeWalkListener listener,
149 GeneratedYangParser.LengthStatementContext ctx) {
150
151 // Check for stack to be non empty.
152 checkStackIsNotEmpty(listener, MISSING_HOLDER, LENGTH_DATA, ctx.length().getText(), EXIT);
153
154 Parsable tmpData = listener.getParsedDataStack().peek();
155 if (tmpData instanceof YangRangeRestriction) {
156 listener.getParsedDataStack().pop();
157 } else if (tmpData instanceof YangType
158 && ((YangType) tmpData).getDataType() == DERIVED) {
159 // TODO : need to handle in linker
160 } else {
161 throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, LENGTH_DATA,
162 ctx.length().getText(), EXIT));
163 }
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530164 }
165}