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.yang;
23 import java.util.Arrays;
24 import java.util.HashSet;
25 import java.util.List;
28 import org.oran.smo.yangtools.parser.ParserExecutionContext;
29 import org.oran.smo.yangtools.parser.findings.Finding;
30 import org.oran.smo.yangtools.parser.findings.ParserFindingType;
31 import org.oran.smo.yangtools.parser.model.statements.AbstractStatement;
32 import org.oran.smo.yangtools.parser.model.statements.StatementModuleAndName;
33 import org.oran.smo.yangtools.parser.model.yangdom.YangDomElement;
36 * Type-safe Yang core statement.
38 * @author Mark Hollmann
40 public class YDeviate extends AbstractStatement {
42 public YDeviate(final AbstractStatement parentStatement, final YangDomElement domNode) {
43 super(parentStatement, domNode);
46 public String getDeviateOperation() {
47 return domElement.getTrimmedValueOrEmpty();
51 public StatementArgumentType getArgumentType() {
52 return StatementArgumentType.VALUE;
56 public StatementModuleAndName getStatementModuleAndName() {
57 return CY.STMT_DEVIATE;
61 * Returns the deviate type or null if the deviate type is unknown / wrong.
63 public DeviateType getDeviateType() {
65 switch (getDeviateOperation()) {
67 return DeviateType.NOT_SUPPORTED;
69 return DeviateType.ADD;
71 return DeviateType.REPLACE;
73 return DeviateType.DELETE;
80 public YConfig getConfig() {
81 return getChild(CY.STMT_CONFIG);
84 public List<YDefault> getDefaults() {
85 return getChildren(CY.STMT_DEFAULT);
88 public YMandatory getMandatory() {
89 return getChild(CY.STMT_MANDATORY);
92 public YMaxElements getMaxElements() {
93 return getChild(CY.STMT_MAX_ELEMENTS);
96 public YMinElements getMinElements() {
97 return getChild(CY.STMT_MIN_ELEMENTS);
100 public List<YMust> getMusts() {
101 return getChildren(CY.STMT_MUST);
104 public YType getType() {
105 return getChild(CY.STMT_TYPE);
108 public List<YUnique> getUniques() {
109 return getChildren(CY.STMT_UNIQUE);
112 public YUnits getUnits() {
113 return getChild(CY.STMT_UNITS);
116 protected void validate(final ParserExecutionContext context) {
117 if (!validateArgumentNotNullNotEmpty(context)) {
118 /* no point trying to perform more validation */
122 final DeviateType deviateType = getDeviateType();
123 if (deviateType == null) {
124 context.addFinding(new Finding(this, ParserFindingType.P015_INVALID_SYNTAX_IN_DOCUMENT, "'" + domElement
125 .getValue() + "' is not valid as argument for deviate. Use one of: not-supported, add, replace, delete."));
129 private static final Set<String> NOT_ALLOWED_FOR_ADD_OR_DELETE = new HashSet<>(Arrays.asList(CY.CONFIG, CY.MANDATORY,
130 CY.TYPE, CY.MAX_ELEMENTS, CY.MIN_ELEMENTS));
133 protected void subtreeProcessed(final ParserExecutionContext context) {
135 final DeviateType deviateType = getDeviateType();
136 if (deviateType == null) {
140 final List<AbstractStatement> nonExtensionChildStatements = getNonExtensionChildStatements();
142 switch (deviateType) {
144 if (!nonExtensionChildStatements.isEmpty()) {
145 for (final AbstractStatement child : nonExtensionChildStatements) {
146 context.addFinding(new Finding(child, ParserFindingType.P018_ILLEGAL_CHILD_STATEMENT,
147 "Statement '" + child
148 .getStatementName() + "' cannot occur under 'deviate not-supported'."));
155 if (getChildStatements().isEmpty()) {
156 context.addFinding(new Finding(this, ParserFindingType.P019_MISSING_REQUIRED_CHILD_STATEMENT,
157 "Statements are required under " + this.getDomElement().getNameValue() + "."));
163 * After some discussion on the IETF netmod mailing list, a decision was made that some
164 * properties always exist and hence can never be ADDed or DELETEd:
166 * "I think that config, mandatory, type, max-elements, min-elements cannot be added or
167 * deleted, only replaced, because they always exist."
169 * "default, must, unique, units are all optional, and hence may be added, replaced,
172 if (deviateType == DeviateType.ADD || deviateType == DeviateType.DELETE) {
173 for (final AbstractStatement nonExtensionChild : nonExtensionChildStatements) {
174 if (NOT_ALLOWED_FOR_ADD_OR_DELETE.contains(nonExtensionChild.getStatementName())) {
175 context.addFinding(new Finding(nonExtensionChild,
176 ParserFindingType.P167_CANNOT_USE_UNDER_DEVIATE_ADD_OR_DELETE,
177 "This statement cannot be used under 'deviate add/delete' as it refers to a property that always exists. Use a 'deviate replace' instead."));
183 public enum DeviateType {