blob: bd65855c2b4624e16f5f7fa622e8018a71d5e2c8 [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
Gaurav Agrawal8d0ad2f2016-05-20 14:40:50 +053019import java.util.regex.Pattern;
20import java.util.regex.PatternSyntaxException;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053021import org.onosproject.yangutils.datamodel.YangDataTypes;
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +053022import org.onosproject.yangutils.datamodel.YangDerivedInfo;
23import org.onosproject.yangutils.datamodel.YangPatternRestriction;
24import org.onosproject.yangutils.datamodel.YangStringRestriction;
25import org.onosproject.yangutils.datamodel.YangType;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053026import org.onosproject.yangutils.parser.Parsable;
27import org.onosproject.yangutils.parser.antlrgencode.GeneratedYangParser;
28import org.onosproject.yangutils.parser.exceptions.ParserException;
29import org.onosproject.yangutils.parser.impl.TreeWalkListener;
30import org.onosproject.yangutils.utils.YangConstructType;
31
Vidyashree Rama1db15562016-05-17 16:16:15 +053032import static org.onosproject.yangutils.datamodel.YangDataTypes.DERIVED;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053033import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.ENTRY;
Vidyashree Rama1db15562016-05-17 16:16:15 +053034import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorLocation.EXIT;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053035import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorMessageConstruction.constructListenerErrorMessage;
36import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.INVALID_HOLDER;
Vidyashree Rama1db15562016-05-17 16:16:15 +053037import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_CURRENT_HOLDER;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053038import static org.onosproject.yangutils.parser.impl.parserutils.ListenerErrorType.MISSING_HOLDER;
39import static org.onosproject.yangutils.parser.impl.parserutils.ListenerValidation.checkStackIsNotEmpty;
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +053040import static org.onosproject.yangutils.utils.YangConstructType.PATTERN_DATA;
41import static org.onosproject.yangutils.utils.YangConstructType.TYPE_DATA;
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053042
43/*
44 * Reference: RFC6020 and YANG ANTLR Grammar
45 *
46 * ABNF grammar as per RFC6020
47 * pattern-stmt = pattern-keyword sep string optsep
48 * (";" /
49 * "{" stmtsep
50 * ;; these stmts can appear in any order
51 * [error-message-stmt stmtsep]
52 * [error-app-tag-stmt stmtsep]
53 * [description-stmt stmtsep]
54 * [reference-stmt stmtsep]
55 * "}")
56 *
57 * ANTLR grammar rule
58 * patternStatement : PATTERN_KEYWORD string (STMTEND | LEFT_CURLY_BRACE commonStatements RIGHT_CURLY_BRACE);
59 */
60
61/**
62 * Represents listener based call back function corresponding to the "pattern"
63 * rule defined in ANTLR grammar file for corresponding ABNF rule in RFC 6020.
64 */
65public final class PatternRestrictionListener {
66
67 private static final String EMPTY_STRING = "";
68
69 /**
70 * Creates a new pattern restriction listener.
71 */
72 private PatternRestrictionListener() {
73 }
74
75 /**
76 * It is called when parser receives an input matching the grammar
77 * rule (pattern), performs validation and updates the data model
78 * tree.
79 *
80 * @param listener listener's object
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +053081 * @param ctx context object of the grammar rule
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053082 */
83 public static void processPatternRestrictionEntry(TreeWalkListener listener,
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +053084 GeneratedYangParser.PatternStatementContext ctx) {
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053085
86 // Check for stack to be non empty.
87 checkStackIsNotEmpty(listener, MISSING_HOLDER, PATTERN_DATA, ctx.string().getText(), ENTRY);
88
89 Parsable tmpData = listener.getParsedDataStack().peek();
90 if (tmpData.getYangConstructType() == TYPE_DATA) {
91 YangType type = (YangType) tmpData;
Vidyashree Rama1db15562016-05-17 16:16:15 +053092 setPatternRestriction(listener, type, ctx);
Vidyashree Ramaa2f73982016-04-12 23:33:33 +053093 } else {
94 throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, PATTERN_DATA,
95 ctx.string().getText(), ENTRY));
96 }
97 }
98
99 /**
100 * Sets the pattern restriction to type.
101 *
Vidyashree Rama1db15562016-05-17 16:16:15 +0530102 * @param listener listener's object
Gaurav Agrawal8d0ad2f2016-05-20 14:40:50 +0530103 * @param type Yang type for which pattern restriction to be set
104 * @param ctx context object of the grammar rule
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530105 */
Vidyashree Rama1db15562016-05-17 16:16:15 +0530106 private static void setPatternRestriction(TreeWalkListener listener, YangType type,
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530107 GeneratedYangParser.PatternStatementContext ctx) {
108
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530109 if (type.getDataType() != YangDataTypes.STRING && type.getDataType() != YangDataTypes.DERIVED) {
110
111 ParserException parserException = new ParserException("YANG file error : " +
112 YangConstructType.getYangConstructType(PATTERN_DATA) + " name " + ctx.string().getText() +
113 " can be used to restrict the built-in type string or types derived from string.");
114 parserException.setLine(ctx.getStart().getLine());
115 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
116 throw parserException;
117 }
118
Gaurav Agrawal8d0ad2f2016-05-20 14:40:50 +0530119 // Validate and get valid pattern restriction string.
120 String patternArgument = getValidPattern(ctx);
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530121
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530122 if (type.getDataType() == YangDataTypes.STRING) {
123 YangStringRestriction stringRestriction = (YangStringRestriction) type.getDataTypeExtendedInfo();
124 if (stringRestriction == null) {
125 stringRestriction = new YangStringRestriction();
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530126 type.setDataTypeExtendedInfo(stringRestriction);
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530127 stringRestriction.addPattern(patternArgument);
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530128 } else {
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530129 stringRestriction.addPattern(patternArgument);
130 }
Vidyashree Rama1db15562016-05-17 16:16:15 +0530131 listener.getParsedDataStack().push(stringRestriction);
Gaurav Agrawalcfa1c412016-05-03 00:41:48 +0530132 } else {
133 YangPatternRestriction patternRestriction = (YangPatternRestriction) ((YangDerivedInfo<?>) type
134 .getDataTypeExtendedInfo()).getPatternRestriction();
135 if (patternRestriction == null) {
136 patternRestriction = new YangPatternRestriction();
137 ((YangDerivedInfo<?>) type.getDataTypeExtendedInfo()).setPatternRestriction(patternRestriction);
138 patternRestriction.addPattern(patternArgument);
139 } else {
140 ((YangDerivedInfo<?>) type.getDataTypeExtendedInfo()).setPatternRestriction(patternRestriction);
141 patternRestriction.addPattern(patternArgument);
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530142 }
143 }
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530144 }
Vidyashree Rama1db15562016-05-17 16:16:15 +0530145
146 /**
147 * Performs validation and updates the data model tree.
148 * It is called when parser exits from grammar rule (pattern).
149 *
150 * @param listener listener's object
Gaurav Agrawal8d0ad2f2016-05-20 14:40:50 +0530151 * @param ctx context object of the grammar rule
Vidyashree Rama1db15562016-05-17 16:16:15 +0530152 */
153 public static void processPatternRestrictionExit(TreeWalkListener listener,
VinodKumarS-Huawei2ee9e7e2016-06-01 14:30:22 +0530154 GeneratedYangParser.PatternStatementContext ctx) {
Vidyashree Rama1db15562016-05-17 16:16:15 +0530155
156 // Check for stack to be non empty.
157 checkStackIsNotEmpty(listener, MISSING_HOLDER, PATTERN_DATA, ctx.string().getText(), EXIT);
158
159 Parsable tmpData = listener.getParsedDataStack().peek();
160 if (tmpData instanceof YangStringRestriction) {
161 listener.getParsedDataStack().pop();
162 } else if (tmpData instanceof YangType
163 && ((YangType) tmpData).getDataType() == DERIVED) {
164 // TODO : need to handle in linker
165 } else {
166 throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, PATTERN_DATA,
167 ctx.string().getText(), EXIT));
168 }
169 }
Gaurav Agrawal8d0ad2f2016-05-20 14:40:50 +0530170
171 /**
172 * Validates and return the valid pattern.
173 *
174 * @param ctx context object of the grammar rule
175 * @return validated string
176 */
177 private static String getValidPattern(GeneratedYangParser.PatternStatementContext ctx) {
178 String userInputPattern = ctx.string().getText().replace("\"", EMPTY_STRING);
179 try {
180 Pattern.compile(userInputPattern);
181 } catch (PatternSyntaxException exception) {
182 ParserException parserException = new ParserException("YANG file error : " +
183 YangConstructType.getYangConstructType(PATTERN_DATA) + " name " + ctx.string().getText() +
184 " is not a valid regular expression");
185 parserException.setLine(ctx.getStart().getLine());
186 parserException.setCharPosition(ctx.getStart().getCharPositionInLine());
187 throw parserException;
188 }
189 return userInputPattern;
190 }
Vidyashree Ramaa2f73982016-04-12 23:33:33 +0530191}