8e8e07dcec3f59351c83f7365614b413bfe23587
[smo/teiv.git] /
1 /*
2  *  ============LICENSE_START=======================================================
3  *  Copyright (C) 2024 Ericsson
4  *  Modifications Copyright (C) 2024 OpenInfra Foundation Europe
5  *  ================================================================================
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *        http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License.
17  *
18  *  SPDX-License-Identifier: Apache-2.0
19  *  ============LICENSE_END=========================================================
20  */
21 package org.oran.smo.yangtools.parser.model.statements;
22
23 import java.util.List;
24
25 import org.oran.smo.yangtools.parser.ParserExecutionContext;
26 import org.oran.smo.yangtools.parser.findings.Finding;
27 import org.oran.smo.yangtools.parser.findings.ParserFindingType;
28 import org.oran.smo.yangtools.parser.model.statements.yang.CY;
29 import org.oran.smo.yangtools.parser.model.statements.yang.YExtension;
30 import org.oran.smo.yangtools.parser.model.yangdom.YangDomElement;
31
32 /**
33  * Represents an instance of an extension statement; that is, <i>usage</i> of an extension (as
34  * opposed to <i>definition</i> of an extension - extensions are defined by means of the
35  * {@link YExtension} class).
36  * <p/>
37  * This is a generic catch-all class for extension instances. Implementations of {@link StatementClassSupplier}
38  * are typically used to create instances of type-safe classes representing extensions.
39  *
40  * @author Mark Hollmann
41  */
42 public class ExtensionStatement extends SimpleStatement {
43
44     public ExtensionStatement(final AbstractStatement parentStatement, final YangDomElement domNode) {
45         super(parentStatement, domNode);
46     }
47
48     @Override
49     public StatementArgumentType getArgumentType() {
50         return StatementArgumentType.NO_ARG;
51     }
52
53     /**
54      * Returns the prefix of the extension.
55      */
56     public String getExtensionModulePrefix() {
57         return domElement.getName().split(":")[0];
58     }
59
60     /**
61      * Returns the name of the extension
62      */
63     public String getExtensionStatementName() {
64         return domElement.getName().split(":")[1];
65     }
66
67     /**
68      * Returns the value (argument) of the extension, if any (ie. can be null).
69      */
70     public String getValue() {
71         return domElement.getValue();
72     }
73
74     /**
75      * Denotes whether a possible argument to the extension is mandatory to be supplied.
76      * By default this method this method will return FALSE as it is not possible to
77      * predict the semantics of each extensions. Sub-classes that require their argument
78      * to be present should override this method accordingly.
79      */
80     public boolean argumentIsMandatory() {
81         return false;
82     }
83
84     /**
85      * Returns the number of instances this extension can possible have under its parent
86      * statement. By default, this method will return ONE as this is typically the case
87      * with extensions. Sub-types may override.
88      */
89     public MaxCardinality getMaxCardinalityUnderParent() {
90         return MaxCardinality.ONE;
91     }
92
93     public enum MaxCardinality {
94         ONE,
95         MULTIPLE
96     }
97
98     /**
99      * Returns whether the extension can be a valid child of the supplied parent statement
100      * (which is usually a core Yang statement, but could be another extension). Type-safe
101      * extension subclasses should override this method.
102      * <p/>
103      * Since we don't know any better here, the default assumption is that the extension can
104      * sit anywhere.
105      */
106     public boolean canBeChildOf(final StatementModuleAndName parentStatement) {
107         return true;
108     }
109
110     @Override
111     protected void validate(ParserExecutionContext context) {
112         /*
113          * Validation will always be extension-specific. The assumption
114          * that these all need arguments is wrong, of course.
115          */
116     }
117
118     protected void checkParent(final ParserExecutionContext context) {
119         final AbstractStatement parent = getParentStatement();
120
121         if (!canBeChildOf(parent.getStatementModuleAndName())) {
122             context.addFinding(new Finding(this, ParserFindingType.P025_INVALID_EXTENSION,
123                     "Extension statement '" + getExtensionStatementName() + "' is not allowed under '" + parent
124                             .getStatementName()));
125         }
126     }
127
128     protected void checkParentAlsoAllowDeviateOrRefine(final ParserExecutionContext context) {
129         final AbstractStatement parent = getParentStatement();
130
131         if (parent.is(CY.STMT_DEVIATE) || parent.is(CY.STMT_REFINE)) {
132             return;
133         }
134         if (!canBeChildOf(parent.getStatementModuleAndName())) {
135             context.addFinding(new Finding(this, ParserFindingType.P025_INVALID_EXTENSION,
136                     "Extension statement '" + getExtensionStatementName() + "' is not allowed under '" + parent
137                             .getStatementName()));
138         }
139     }
140
141     protected void checkCardinalityUnderParent(final ParserExecutionContext context, final int max) {
142         final AbstractStatement parentStatement = getParentStatement();
143         final List<? extends AbstractStatement> childrenOfThisType = parentStatement.getChildren(this
144                 .getStatementModuleAndName());
145         if (childrenOfThisType.size() > max) {
146             context.addFinding(new Finding(this, ParserFindingType.P025_INVALID_EXTENSION,
147                     "The allowed maximum cardinality for this extension statement is " + max + "."));
148         }
149     }
150 }