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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * SPDX-License-Identifier: Apache-2.0
19 * ============LICENSE_END=========================================================
21 package org.oran.smo.yangtools.parser.model.statements;
23 import java.util.List;
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;
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).
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.
40 * @author Mark Hollmann
42 public class ExtensionStatement extends SimpleStatement {
44 public ExtensionStatement(final AbstractStatement parentStatement, final YangDomElement domNode) {
45 super(parentStatement, domNode);
49 public StatementArgumentType getArgumentType() {
50 return StatementArgumentType.NO_ARG;
54 * Returns the prefix of the extension.
56 public String getExtensionModulePrefix() {
57 return domElement.getName().split(":")[0];
61 * Returns the name of the extension
63 public String getExtensionStatementName() {
64 return domElement.getName().split(":")[1];
68 * Returns the value (argument) of the extension, if any (ie. can be null).
70 public String getValue() {
71 return domElement.getValue();
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.
80 public boolean argumentIsMandatory() {
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.
89 public MaxCardinality getMaxCardinalityUnderParent() {
90 return MaxCardinality.ONE;
93 public enum MaxCardinality {
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.
103 * Since we don't know any better here, the default assumption is that the extension can
106 public boolean canBeChildOf(final StatementModuleAndName parentStatement) {
111 protected void validate(ParserExecutionContext context) {
113 * Validation will always be extension-specific. The assumption
114 * that these all need arguments is wrong, of course.
118 protected void checkParent(final ParserExecutionContext context) {
119 final AbstractStatement parent = getParentStatement();
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()));
128 protected void checkParentAlsoAllowDeviateOrRefine(final ParserExecutionContext context) {
129 final AbstractStatement parent = getParentStatement();
131 if (parent.is(CY.STMT_DEVIATE) || parent.is(CY.STMT_REFINE)) {
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()));
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 + "."));