2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
11 import com.google.common.annotations.Beta;
12 import com.google.common.base.Strings;
13 import java.util.HashSet;
14 import java.util.Iterator;
15 import java.util.Optional;
17 import org.opendaylight.yangtools.yang.common.QName;
18 import org.opendaylight.yangtools.yang.common.YangVersion;
19 import org.opendaylight.yangtools.yang.model.api.ElementCountConstraint;
20 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
21 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
22 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
23 import org.opendaylight.yangtools.yang.model.api.stmt.MaxElementsEffectiveStatement;
24 import org.opendaylight.yangtools.yang.model.api.stmt.MinElementsEffectiveStatement;
25 import org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement;
26 import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
27 import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
28 import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
29 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
30 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
33 public final class EffectiveStmtUtils {
34 // FIXME: this should reside somewhere in max_elements
35 private static final String UNBOUNDED_STR = "unbounded";
37 private EffectiveStmtUtils() {
38 throw new UnsupportedOperationException("Utility class");
41 public static SourceException createNameCollisionSourceException(final StmtContext<?, ?, ?> ctx,
42 final EffectiveStatement<?, ?> effectiveStatement) {
43 return new SourceException(ctx.getStatementSourceReference(),
44 "Error in module '%s': cannot add '%s'. Node name collision: '%s' already declared.",
45 ctx.getRoot().getStatementArgument(),
46 effectiveStatement.argument(),
47 effectiveStatement.argument());
50 public static Optional<ElementCountConstraint> createElementCountConstraint(final EffectiveStatement<?, ?> stmt) {
51 final Integer minElements;
52 final Optional<Integer> min = stmt.findFirstEffectiveSubstatementArgument(MinElementsEffectiveStatement.class);
53 if (min.isPresent()) {
54 final Integer m = min.get();
55 minElements = m > 0 ? m : null;
60 final Integer maxElements;
61 final String max = stmt.findFirstEffectiveSubstatementArgument(MaxElementsEffectiveStatement.class)
62 .orElse(UNBOUNDED_STR);
63 if (!UNBOUNDED_STR.equals(max)) {
64 final Integer m = Integer.valueOf(max);
65 maxElements = m < Integer.MAX_VALUE ? m : null;
70 return ElementCountConstraint.forNullable(minElements, maxElements);
75 * Checks whether supplied type has any of specified default values marked
76 * with an if-feature. This method creates mutable copy of supplied set of
82 * type statement which should be checked
83 * @param defaultValues
84 * set of default values which should be checked. The method
85 * creates mutable copy of this set
87 * @return true if any of specified default values is marked with an
88 * if-feature, otherwise false
90 public static boolean hasDefaultValueMarkedWithIfFeature(final YangVersion yangVersion,
91 final TypeEffectiveStatement<?> typeStmt, final Set<String> defaultValues) {
92 return !defaultValues.isEmpty() && yangVersion == YangVersion.VERSION_1_1
93 && isRelevantForIfFeatureCheck(typeStmt)
94 && isAnyDefaultValueMarkedWithIfFeature(typeStmt, new HashSet<>(defaultValues));
98 * Checks whether supplied type has specified default value marked with an
99 * if-feature. This method creates mutable set of supplied default value.
104 * type statement which should be checked
105 * @param defaultValue
106 * default value to be checked
108 * @return true if specified default value is marked with an if-feature,
111 public static boolean hasDefaultValueMarkedWithIfFeature(final YangVersion yangVersion,
112 final TypeEffectiveStatement<?> typeStmt, final String defaultValue) {
113 final HashSet<String> defaultValues = new HashSet<>();
114 defaultValues.add(defaultValue);
115 return !Strings.isNullOrEmpty(defaultValue) && yangVersion == YangVersion.VERSION_1_1
116 && isRelevantForIfFeatureCheck(typeStmt)
117 && isAnyDefaultValueMarkedWithIfFeature(typeStmt, defaultValues);
120 private static boolean isRelevantForIfFeatureCheck(final TypeEffectiveStatement<?> typeStmt) {
121 final TypeDefinition<?> typeDefinition = typeStmt.getTypeDefinition();
122 return typeDefinition instanceof EnumTypeDefinition || typeDefinition instanceof BitsTypeDefinition
123 || typeDefinition instanceof UnionTypeDefinition;
126 private static boolean isAnyDefaultValueMarkedWithIfFeature(final TypeEffectiveStatement<?> typeStmt,
127 final Set<String> defaultValues) {
128 final Iterator<? extends EffectiveStatement<?, ?>> iter = typeStmt.effectiveSubstatements().iterator();
129 while (iter.hasNext() && !defaultValues.isEmpty()) {
130 final EffectiveStatement<?, ?> effectiveSubstatement = iter.next();
131 if (YangStmtMapping.BIT.equals(effectiveSubstatement.statementDefinition())) {
132 final QName bitQName = (QName) effectiveSubstatement.argument();
133 if (defaultValues.remove(bitQName.getLocalName()) && containsIfFeature(effectiveSubstatement)) {
136 } else if (YangStmtMapping.ENUM.equals(effectiveSubstatement.statementDefinition())
137 && defaultValues.remove(effectiveSubstatement.argument())
138 && containsIfFeature(effectiveSubstatement)) {
140 } else if (effectiveSubstatement instanceof TypeEffectiveStatement && isAnyDefaultValueMarkedWithIfFeature(
141 (TypeEffectiveStatement<?>) effectiveSubstatement, defaultValues)) {
149 private static boolean containsIfFeature(final EffectiveStatement<?, ?> effectiveStatement) {
150 for (final EffectiveStatement<?, ?> effectiveSubstatement : effectiveStatement.effectiveSubstatements()) {
151 if (YangStmtMapping.IF_FEATURE.equals(effectiveSubstatement.statementDefinition())) {