* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.yangtools.yang.parser.rfc7950.stmt;
import com.google.common.annotations.Beta;
import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Optional;
import java.util.Set;
-import org.opendaylight.yangtools.yang.common.QName;
+import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.common.YangVersion;
import org.opendaylight.yangtools.yang.model.api.ElementCountConstraint;
+import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.MaxElementsEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.MinElementsEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.type.BitsTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.EnumTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.UnionTypeDefinition;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
@Beta
public final class EffectiveStmtUtils {
private static final String UNBOUNDED_STR = "unbounded";
private EffectiveStmtUtils() {
- throw new UnsupportedOperationException("Utility class");
+ // Hidden on purpose
}
public static SourceException createNameCollisionSourceException(final StmtContext<?, ?, ?> ctx,
- final EffectiveStatement<?, ?> effectiveStatement) {
- return new SourceException(ctx.getStatementSourceReference(),
+ final StatementSourceReference ref, final EffectiveStatement<?, ?> effectiveStatement) {
+ return new SourceException(ref,
"Error in module '%s': cannot add '%s'. Node name collision: '%s' already declared.",
- ctx.getRoot().getStatementArgument(),
- effectiveStatement.argument(),
- effectiveStatement.argument());
+ ctx.getRoot().rawStatementArgument(), effectiveStatement.argument(), effectiveStatement.argument());
}
public static Optional<ElementCountConstraint> createElementCountConstraint(final EffectiveStatement<?, ?> stmt) {
+ return createElementCountConstraint(
+ stmt.findFirstEffectiveSubstatementArgument(MinElementsEffectiveStatement.class).orElse(null),
+ stmt.findFirstEffectiveSubstatementArgument(MaxElementsEffectiveStatement.class).orElse(null));
+ }
+
+ public static Optional<ElementCountConstraint> createElementCountConstraint(
+ final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+ return createElementCountConstraint(
+ BaseQNameStatementSupport.findFirstArgument(substatements, MinElementsEffectiveStatement.class, null),
+ BaseQNameStatementSupport.findFirstArgument(substatements, MaxElementsEffectiveStatement.class, null));
+ }
+
+ private static Optional<ElementCountConstraint> createElementCountConstraint(
+ final @Nullable Integer min, final @Nullable String max) {
final Integer minElements;
- final Optional<Integer> min = stmt.findFirstEffectiveSubstatementArgument(MinElementsEffectiveStatement.class);
- if (min.isPresent()) {
- final Integer m = min.get();
- minElements = m > 0 ? m : null;
+ if (min != null) {
+ minElements = min > 0 ? min : null;
} else {
minElements = null;
}
final Integer maxElements;
- final String max = stmt.findFirstEffectiveSubstatementArgument(MaxElementsEffectiveStatement.class)
- .orElse(UNBOUNDED_STR);
- if (!UNBOUNDED_STR.equals(max)) {
+ if (max != null && !UNBOUNDED_STR.equals(max)) {
final Integer m = Integer.valueOf(max);
maxElements = m < Integer.MAX_VALUE ? m : null;
} else {
return ElementCountConstraint.forNullable(minElements, maxElements);
}
-
/**
* Checks whether supplied type has any of specified default values marked
* with an if-feature. This method creates mutable copy of supplied set of
while (iter.hasNext() && !defaultValues.isEmpty()) {
final EffectiveStatement<?, ?> effectiveSubstatement = iter.next();
if (YangStmtMapping.BIT.equals(effectiveSubstatement.statementDefinition())) {
- final QName bitQName = (QName) effectiveSubstatement.argument();
- if (defaultValues.remove(bitQName.getLocalName()) && containsIfFeature(effectiveSubstatement)) {
+ final String bitName = (String) effectiveSubstatement.argument();
+ if (defaultValues.remove(bitName) && containsIfFeature(effectiveSubstatement)) {
return true;
}
} else if (YangStmtMapping.ENUM.equals(effectiveSubstatement.statementDefinition())
}
return false;
}
+
+ public static void checkUniqueGroupings(final StmtContext<?, ?, ?> ctx,
+ final Collection<? extends EffectiveStatement<?, ?>> statements, final StatementSourceReference ref) {
+ checkUniqueNodes(ctx, statements, GroupingDefinition.class, ref);
+ }
+
+ public static void checkUniqueTypedefs(final StmtContext<?, ?, ?> ctx,
+ final Collection<? extends EffectiveStatement<?, ?>> statements, final StatementSourceReference ref) {
+ final Set<Object> typedefs = new HashSet<>();
+ for (EffectiveStatement<?, ?> stmt : statements) {
+ if (stmt instanceof TypedefEffectiveStatement
+ && !typedefs.add(((TypedefEffectiveStatement) stmt).getTypeDefinition())) {
+ throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, ref, stmt);
+ }
+ }
+ }
+
+ public static void checkUniqueUses(final StmtContext<?, ?, ?> ctx,
+ final Collection<? extends EffectiveStatement<?, ?>> statements, final StatementSourceReference ref) {
+ checkUniqueNodes(ctx, statements, UsesNode.class, ref);
+ }
+
+ private static void checkUniqueNodes(final StmtContext<?, ?, ?> ctx,
+ final Collection<? extends EffectiveStatement<?, ?>> statements, final Class<?> type,
+ final StatementSourceReference ref) {
+ final Set<Object> nodes = new HashSet<>();
+ for (EffectiveStatement<?, ?> stmt : statements) {
+ if (type.isInstance(stmt) && !nodes.add(stmt)) {
+ throw EffectiveStmtUtils.createNameCollisionSourceException(ctx, ref, stmt);
+ }
+ }
+ }
}