From fa1ed213acc06358d9b759fa871e2b360605734e Mon Sep 17 00:00:00 2001 From: Peter Kajsa Date: Thu, 1 Dec 2016 14:57:24 +0100 Subject: [PATCH] Bug 6867: Extend yang statement parser to support different yang versions This patch extends statement parser in order to support different versions of yang, yin or other statement based languages. Statement parser is able to distinguish version of each yang, yin or other source and it performs parsing of the source according to the specific version. Mixed-version schemacontext (i.e. imports across versions) is supported too. More in detail, StatementSupportBundle must be initialized by SupportedVersionBundle, which defines set of supported versions. In consequence, StatementSupportBundle allows to add version specific StatementSupport into bundle. Furthermore each RootStatementContext allows to set its version based on which corresponding StatementSupports are invoked. For yang models, RootStatementContext version is set based on a value of yang version statement. Change-Id: I06bbcbfee091a0f54480d5f5f588a9ed18a84b55 Signed-off-by: Peter Kajsa Signed-off-by: Robert Varga --- .../yangtools/yang/common/YangVersion.java | 73 ++++++ .../yang/model/api/Rfc6020Mapping.java | 11 +- .../model/api/stmt/YangVersionStatement.java | 5 +- .../spi/meta/AbstractDeclaredStatement.java | 2 +- .../spi/meta/StatementSupportBundle.java | 146 +++++++++-- .../yang/parser/spi/meta/StmtContext.java | 16 ++ .../stmt/reactor/BuildGlobalContext.java | 30 ++- .../reactor/CustomStatementParserBuilder.java | 65 ++++- .../stmt/reactor/NamespaceStorageSupport.java | 10 +- .../stmt/reactor/RootStatementContext.java | 25 ++ .../stmt/reactor/SourceSpecificContext.java | 31 ++- .../stmt/reactor/SubstatementContext.java | 11 + .../stmt/rfc6020/ContainerStatementImpl.java | 6 +- .../stmt/rfc6020/ModuleStatementSupport.java | 14 +- .../stmt/rfc6020/YangInferencePipeline.java | 17 +- .../rfc6020/YangVersionStatementImpl.java | 38 ++- .../AbstractEffectiveDataSchemaNode.java | 6 +- .../effective/AbstractEffectiveModule.java | 7 +- .../YangVersionEffectiveStatementImpl.java | 5 +- .../stmt/rfc7950/AnydataStatementImpl.java | 130 ++++++++++ .../ContainerStatementRfc7950Support.java | 41 +++ .../ModuleStatementRfc7950Support.java | 52 ++++ .../AnyDataEffectiveStatementImpl.java | 69 +++++ .../parser/stmt/rfc7950/Bug6867BasicTest.java | 92 +++++++ .../yangtools/yang/stmt/StmtTestUtils.java | 86 ++++--- .../semver/SemanticVersionComplexTest.java | 47 +++- .../rfc7950/basic-test/anydata-10.yang | 11 + .../rfc7950/basic-test/anydata-11.yang | 13 + .../rfc7950/basic-test/invalid-10.yang | 9 + .../rfc7950/basic-test/invalid-11.yang | 14 ++ .../basic-test/unsupported-version.yang | 8 + .../rfc7950/basic-test/valid-10.yang | 7 + .../rfc7950/basic-test/valid-11.yang | 10 + .../src/test/resources/rfc7950/model/bar.yang | 119 +++++++++ .../src/test/resources/rfc7950/model/baz.yang | 194 +++++++++++++++ .../src/test/resources/rfc7950/model/foo.yang | 235 ++++++++++++++++++ .../test/resources/rfc7950/model/subfoo.yang | 70 ++++++ .../complex-1/bar@2016-01-03.yang | 24 ++ .../complex-1/bar@2016-01-04.yang | 24 ++ .../semantic-version/complex-1/foo.yang | 13 + .../complex-1/foobar@2016-01-31.yang | 23 ++ .../complex-1/foobar@2016-02-28.yang | 23 ++ .../complex-1/semantic-version.yang | 47 ++++ .../complex-2/bar@2016-01-03.yang | 23 ++ .../complex-2/bar@2016-01-04.yang | 23 ++ .../semantic-version/complex-2/foo.yang | 13 + .../complex-2/foobar@2016-01-31.yang | 20 ++ .../complex-2/foobar@2016-02-27.yang | 20 ++ .../complex-2/foobar@2016-02-28.yang | 20 ++ .../complex-2/semantic-version.yang | 47 ++++ 50 files changed, 1905 insertions(+), 140 deletions(-) create mode 100644 yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/YangVersion.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/AnydataStatementImpl.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/ContainerStatementRfc7950Support.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/ModuleStatementRfc7950Support.java create mode 100644 yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/effective/AnyDataEffectiveStatementImpl.java create mode 100644 yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/Bug6867BasicTest.java create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/anydata-10.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/anydata-11.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/invalid-10.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/invalid-11.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/unsupported-version.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/valid-10.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/valid-11.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/model/bar.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/model/baz.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/model/foo.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/model/subfoo.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/bar@2016-01-03.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/bar@2016-01-04.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/foo.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/foobar@2016-01-31.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/foobar@2016-02-28.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/semantic-version.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/bar@2016-01-03.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/bar@2016-01-04.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foo.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foobar@2016-01-31.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foobar@2016-02-27.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foobar@2016-02-28.yang create mode 100644 yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/semantic-version.yang diff --git a/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/YangVersion.java b/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/YangVersion.java new file mode 100644 index 0000000000..cfde8cabc0 --- /dev/null +++ b/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/YangVersion.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.common; + +import com.google.common.annotations.Beta; +import com.google.common.base.Preconditions; +import javax.annotation.Nonnull; + +/** + * Enumeration of supported YANG versions. + * + * @author Robert Varga + */ +@Beta +public enum YangVersion { + /** + * Version 1, as defined in RFC6020. + */ + VERSION_1("1", "RFC6020"), + /** + * Version 1.1, as defined in RFC7950. + */ + VERSION_1_1("1.1", "RFC7950"); + + private final String str; + private String reference; + + private YangVersion(final String str, final String reference) { + this.str = Preconditions.checkNotNull(str); + this.reference = Preconditions.checkNotNull(reference); + } + + /** + * Parse a YANG version from its textual representation. + * + * @param str String to parse + * @return YANG version + * @throws IllegalArgumentException if the string is malformed + * @throws NullPointerException if the string is null + */ + public static YangVersion parse(@Nonnull final String str) { + switch (str) { + case "1": + return VERSION_1; + case "1.1": + return VERSION_1_1; + default: + throw new IllegalArgumentException("Invalid YANG version '" + str + "'"); + } + } + + /** + * Return the normative reference defining this YANG version. + * + * @return Normative reference. + */ + @Nonnull public String getReference() { + return reference; + } + + /** + * Return the canonical string represetation of this YANG version. + * @return Canonical string + */ + @Nonnull public String toCanonicalString() { + return str; + } +} diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/Rfc6020Mapping.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/Rfc6020Mapping.java index f1c25fcbe2..d37ebb15f6 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/Rfc6020Mapping.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/Rfc6020Mapping.java @@ -16,6 +16,7 @@ import org.opendaylight.yangtools.yang.common.YangConstants; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; +import org.opendaylight.yangtools.yang.model.api.stmt.AnydataStatement; import org.opendaylight.yangtools.yang.model.api.stmt.AnyxmlStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ArgumentStatement; import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement; @@ -82,9 +83,9 @@ import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement; import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionStatement; import org.opendaylight.yangtools.yang.model.api.stmt.YinElementStatement; - @Beta public enum Rfc6020Mapping implements StatementDefinition { + ANYDATA(AnydataStatement.class, "anydata", "name"), ANYXML(AnyxmlStatement.class, "anyxml", "name"), ARGUMENT(ArgumentStatement.class, "argument", "name"), AUGMENT(AugmentStatement.class, "augment", "target-node"), @@ -157,7 +158,7 @@ public enum Rfc6020Mapping implements StatementDefinition { private final QName argument; private final boolean yinElement; - Rfc6020Mapping(Class> clz, final String nameStr) { + Rfc6020Mapping(final Class> clz, final String nameStr) { type = Preconditions.checkNotNull(clz); //FIXME: fill up effective type correctly effectiveType = null; @@ -166,7 +167,7 @@ public enum Rfc6020Mapping implements StatementDefinition { yinElement = false; } - Rfc6020Mapping(Class> clz, final String nameStr, final String argumentStr) { + Rfc6020Mapping(final Class> clz, final String nameStr, final String argumentStr) { type = Preconditions.checkNotNull(clz); //FIXME: fill up effective type correctly effectiveType = null; @@ -175,7 +176,7 @@ public enum Rfc6020Mapping implements StatementDefinition { this.yinElement = false; } - Rfc6020Mapping(Class> clz, final String nameStr, final String argumentStr, + Rfc6020Mapping(final Class> clz, final String nameStr, final String argumentStr, final boolean yinElement) { type = Preconditions.checkNotNull(clz); //FIXME: fill up effective type correctly @@ -185,7 +186,7 @@ public enum Rfc6020Mapping implements StatementDefinition { this.yinElement = yinElement; } - @Nonnull private static QName yinQName(String nameStr) { + @Nonnull private static QName yinQName(final String nameStr) { return QName.create(YangConstants.RFC6020_YIN_MODULE, nameStr).intern(); } diff --git a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/YangVersionStatement.java b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/YangVersionStatement.java index da972c46c5..2133c7d4e1 100644 --- a/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/YangVersionStatement.java +++ b/yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/YangVersionStatement.java @@ -8,10 +8,11 @@ package org.opendaylight.yangtools.yang.model.api.stmt; import javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; -public interface YangVersionStatement extends DeclaredStatement { +public interface YangVersionStatement extends DeclaredStatement { - @Nonnull String getValue(); + @Nonnull YangVersion getValue(); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractDeclaredStatement.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractDeclaredStatement.java index 5150b8505b..6069d4b5d4 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractDeclaredStatement.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractDeclaredStatement.java @@ -43,7 +43,7 @@ public abstract class AbstractDeclaredStatement implements DeclaredStatement< * Perform an explicit copy, because Collections2.transform() is lazily transformed and retains pointer to * original collection, which may contains references to mutable context. */ - Collection> declaredSubstatements = context.declaredSubstatements(); + final Collection> declaredSubstatements = context.declaredSubstatements(); substatements = ImmutableList.copyOf(Collections2.transform(declaredSubstatements, StatementContextBase::buildDeclared)); } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupportBundle.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupportBundle.java index badd2b6bcc..3d9c9375f9 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupportBundle.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupportBundle.java @@ -8,48 +8,95 @@ package org.opendaylight.yangtools.yang.parser.spi.meta; import com.google.common.base.Preconditions; +import com.google.common.collect.HashBasedTable; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableTable; +import com.google.common.collect.Table; import java.util.HashMap; import java.util.Map; +import java.util.Set; import org.opendaylight.yangtools.concepts.Immutable; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; -public final class StatementSupportBundle implements Immutable,NamespaceBehaviour.Registry { +public final class StatementSupportBundle implements Immutable, NamespaceBehaviour.Registry { - private static final StatementSupportBundle EMPTY = new StatementSupportBundle(null, ImmutableMap.of(), ImmutableMap.of()); + private static final StatementSupportBundle EMPTY = new StatementSupportBundle(null, null, ImmutableMap.of(), + ImmutableMap.of(), ImmutableTable.of()); private final StatementSupportBundle parent; - private final ImmutableMap> definitions; + private final ImmutableMap> commonDefinitions; + private final ImmutableTable> versionSpecificDefinitions; private final ImmutableMap, NamespaceBehaviour> namespaceDefinitions; + private final Set supportedVersions; private StatementSupportBundle(final StatementSupportBundle parent, - final ImmutableMap> statements, - final ImmutableMap, NamespaceBehaviour> namespaces) { + final Set supportedVersions, + final ImmutableMap> commonStatements, + final ImmutableMap, NamespaceBehaviour> namespaces, + final ImmutableTable> versionSpecificStatements) { this.parent = parent; - this.definitions = statements; + this.supportedVersions = supportedVersions; + this.commonDefinitions = commonStatements; this.namespaceDefinitions = namespaces; + this.versionSpecificDefinitions = versionSpecificStatements; } - public ImmutableMap> getDefinitions() { - return definitions; + /** + * Returns statement definitions common for all versions + * + * @return map of common statement definitions + */ + public ImmutableMap> getCommonDefinitions() { + return commonDefinitions; + } + + /** + * Returns statement definitions specific for requested version. Result of + * this method doesn't include common statement definitions. + * + * @param version + * requested version + * @return map of statement definitions specific for requested version, it + * doesn't include common statement definitions. + */ + public ImmutableMap> getDefinitionsSpecificForVersion(final YangVersion version) { + return versionSpecificDefinitions.row(version); + } + + /** + * Returns all version specific statement definitions. Result of this method + * doesn't include common statement definitions. + * + * @return table of all version specific statement definitions, it doesn't + * include common statement definitions. + */ + public ImmutableTable> getAllVersionSpecificDefinitions() { + return versionSpecificDefinitions; } public ImmutableMap, NamespaceBehaviour> getNamespaceDefinitions() { return namespaceDefinitions; } - public static Builder builder() { - return new Builder(EMPTY); + public static Builder builder(final Set supportedVersions) { + return new Builder(supportedVersions, EMPTY); } public static Builder derivedFrom(final StatementSupportBundle parent) { - return new Builder(parent); + Preconditions.checkNotNull(parent); + return new Builder(parent.getSupportedVersions(), parent); + } + + public Set getSupportedVersions() { + return supportedVersions; } @Override - public > NamespaceBehaviour getNamespaceBehaviour(final Class namespace) - throws NamespaceNotAvailableException { + public > NamespaceBehaviour getNamespaceBehaviour( + final Class namespace) throws NamespaceNotAvailableException { final NamespaceBehaviour potential = namespaceDefinitions.get(namespace); if (potential != null) { Preconditions.checkState(namespace.equals(potential.getIdentifier())); @@ -76,33 +123,79 @@ public final class StatementSupportBundle implements Immutable,NamespaceBehaviou return false; } - public StatementSupport getStatementDefinition(final QName stmtName) { - final StatementSupport potential = definitions.get(stmtName); + public StatementSupport getStatementDefinition(final YangVersion version, final QName stmtName) { + StatementSupport result = getVersionSpecificStatementDefinition(version, stmtName); + if (result == null) { + result = getCommonStatementDefinition(stmtName); + } + + return result; + } + + private StatementSupport getCommonStatementDefinition(final QName stmtName) { + final StatementSupport potential = commonDefinitions.get(stmtName); + if (potential != null) { + return potential; + } + if (parent != null) { + return parent.getCommonStatementDefinition(stmtName); + } + return null; + } + + private StatementSupport getVersionSpecificStatementDefinition(final YangVersion version, + final QName stmtName) { + final StatementSupport potential = versionSpecificDefinitions.get(version, stmtName); if (potential != null) { return potential; } + if (parent != null) { - return parent.getStatementDefinition(stmtName); + return parent.getVersionSpecificStatementDefinition(version, stmtName); } return null; } public static class Builder implements org.opendaylight.yangtools.concepts.Builder { - private final Map> statements = new HashMap<>(); + private final Map> commonStatements = new HashMap<>(); + private final Table> versionSpecificStatements = HashBasedTable + .create(); private final Map, NamespaceBehaviour> namespaces = new HashMap<>(); + private final Set supportedVersions; private StatementSupportBundle parent; - Builder(final StatementSupportBundle parent) { - this.parent = parent; + Builder(final Set supportedVersions, final StatementSupportBundle parent) { + this.parent = Preconditions.checkNotNull(parent); + this.supportedVersions = ImmutableSet.copyOf(supportedVersions); } public Builder addSupport(final StatementSupport definition) { final QName identifier = definition.getStatementName(); - Preconditions.checkState(!statements.containsKey(identifier), "Statement %s already defined.", identifier); - Preconditions.checkState(parent.getStatementDefinition(identifier) == null, + Preconditions.checkState(!commonStatements.containsKey(identifier), + "Statement %s already defined in common statement bundle.", identifier); + Preconditions.checkState(parent.getCommonStatementDefinition(identifier) == null, "Statement %s already defined.", identifier); - statements.put(identifier, definition); + commonStatements.put(identifier, definition); + return this; + } + + public Builder addVersionSpecificSupport(final YangVersion version, + final StatementSupport definition) { + Preconditions.checkNotNull(version); + Preconditions.checkNotNull(definition); + Preconditions.checkArgument(supportedVersions.contains(version)); + + final QName identifier = definition.getStatementName(); + Preconditions.checkState(!commonStatements.containsKey(identifier), + "Statement %s already defined in common statement bundle.", identifier); + Preconditions.checkState(!versionSpecificStatements.contains(version, identifier), + "Statement %s already defined for version %s.", identifier, version); + Preconditions.checkState(parent.getCommonStatementDefinition(identifier) == null, + "Statement %s already defined in parent's common statement bundle.", identifier); + Preconditions.checkState(parent.getVersionSpecificStatementDefinition(version, identifier) == null, + "Statement %s already defined for version %s in parent's statement bundle.", identifier, version); + versionSpecificStatements.put(version, identifier, definition); return this; } @@ -115,6 +208,10 @@ public final class StatementSupportBundle implements Immutable,NamespaceBehaviou return this; } + public Set getSupportedVersions() { + return supportedVersions; + } + public Builder setParent(final StatementSupportBundle parent) { this.parent = parent; return this; @@ -122,8 +219,9 @@ public final class StatementSupportBundle implements Immutable,NamespaceBehaviou @Override public StatementSupportBundle build() { - return new StatementSupportBundle(parent, ImmutableMap.copyOf(statements), ImmutableMap.copyOf(namespaces)); + Preconditions.checkState(parent != null, "Parent must not be null"); + return new StatementSupportBundle(parent, supportedVersions, ImmutableMap.copyOf(commonStatements), + ImmutableMap.copyOf(namespaces), ImmutableTable.copyOf(versionSpecificStatements)); } } - } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java index 62b48676e5..e9828717c4 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java @@ -13,6 +13,7 @@ import java.util.Map; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; @@ -130,6 +131,13 @@ public interface StmtContext, E extends Effect ModelProcessingPhase getCompletedPhase(); + /** + * Return version of root statement context. + * + * @return version of root statement context + */ + @Nonnull YangVersion getRootVersion(); + interface Mutable, E extends EffectiveStatement> extends StmtContext { @@ -150,6 +158,14 @@ public interface StmtContext, E extends Effect Class namespace, KT key, StmtContext stmt); void setSupportedByFeatures(boolean isSupported); + + /** + * Set version of root statement context. + * + * @param version + * of root statement context + */ + void setRootVersion(YangVersion version); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java index 5947639c26..8781a3a442 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java @@ -9,8 +9,12 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor; import com.google.common.base.Preconditions; import com.google.common.base.Verify; +import com.google.common.collect.HashBasedTable; import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import com.google.common.collect.Table; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -25,6 +29,7 @@ import java.util.Set; import java.util.function.Predicate; import javax.annotation.Nonnull; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; @@ -61,7 +66,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh .add(ModelProcessingPhase.SOURCE_LINKAGE).add(ModelProcessingPhase.STATEMENT_DEFINITION) .add(ModelProcessingPhase.FULL_DECLARATION).add(ModelProcessingPhase.EFFECTIVE_MODEL).build(); - private final Map> definitions = new HashMap<>(); + private final Table> definitions = HashBasedTable.create(); private final Map, NamespaceBehaviourWithListeners> supportedNamespaces = new HashMap<>(); private final Map supports; @@ -71,16 +76,11 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh private ModelProcessingPhase finishedPhase = ModelProcessingPhase.INIT; private final boolean enabledSemanticVersions; + private final Set supportedVersions; BuildGlobalContext(final Map supports, final StatementParserMode statementParserMode, final Predicate isFeatureSupported) { - super(); - this.supports = Preconditions.checkNotNull(supports, "BuildGlobalContext#supports cannot be null"); - Preconditions.checkNotNull(statementParserMode, "Statement parser mode must not be null."); - this.enabledSemanticVersions = statementParserMode == StatementParserMode.SEMVER_MODE; - - addToNs(SupportedFeaturesNamespace.class, SupportedFeatures.SUPPORTED_FEATURES, - Preconditions.checkNotNull(isFeatureSupported, "Supported feature predicate must not be null.")); + this(supports, ImmutableMap.of(), statementParserMode, isFeatureSupported); } BuildGlobalContext(final Map supports, @@ -97,6 +97,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh addToNs(SupportedFeaturesNamespace.class, SupportedFeatures.SUPPORTED_FEATURES, Preconditions.checkNotNull(isFeatureSupported, "Supported feature predicate must not be null.")); + this.supportedVersions = ImmutableSet.copyOf(supports.get(ModelProcessingPhase.INIT).getSupportedVersions()); } boolean isEnabledSemanticVersioning() { @@ -162,13 +163,14 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh return new SimpleNamespaceContext<>(potentialRaw); } - StatementDefinitionContext getStatementDefinition(final QName name) { - StatementDefinitionContext potential = definitions.get(name); + StatementDefinitionContext getStatementDefinition(final YangVersion version, final QName name) { + StatementDefinitionContext potential = definitions.get(version, name); if (potential == null) { - final StatementSupport potentialRaw = supports.get(currentPhase).getStatementDefinition(name); + final StatementSupport potentialRaw = supports.get(currentPhase).getStatementDefinition(version, + name); if (potentialRaw != null) { potential = new StatementDefinitionContext<>(potentialRaw); - definitions.put(name, potential); + definitions.put(version, name, potential); } } return potential; @@ -343,4 +345,8 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh Set getSources() { return sources; } + + public Set getSupportedVersions() { + return supportedVersions; + } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/CustomStatementParserBuilder.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/CustomStatementParserBuilder.java index 7c648e46a9..d85044b7b1 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/CustomStatementParserBuilder.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/CustomStatementParserBuilder.java @@ -8,10 +8,15 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Table; +import com.google.common.collect.Table.Cell; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase; import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour; @@ -22,16 +27,37 @@ import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementR import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline; public class CustomStatementParserBuilder { - private final Map reactorSupportBundles = ImmutableMap - . builder() - .put(ModelProcessingPhase.INIT, StatementSupportBundle.builder()) - .put(ModelProcessingPhase.SOURCE_PRE_LINKAGE, StatementSupportBundle.builder()) - .put(ModelProcessingPhase.SOURCE_LINKAGE, StatementSupportBundle.builder()) - .put(ModelProcessingPhase.STATEMENT_DEFINITION, StatementSupportBundle.builder()) - .put(ModelProcessingPhase.FULL_DECLARATION, StatementSupportBundle.builder()) - .put(ModelProcessingPhase.EFFECTIVE_MODEL, StatementSupportBundle.builder()).build(); + private final Map reactorSupportBundles; private final Map> reactorValidationBundles = new HashMap<>(); + /** + * Creates a new CustomStatementParserBuilder object initialized by + * YangInferencePipeline.SUPPORTED_VERSION_BUNDLE. Statement parser will + * support the same versions as defined in + * YangInferencePipeline.SUPPORTED_VERSION_BUNDLE. + */ + public CustomStatementParserBuilder() { + this(YangInferencePipeline.SUPPORTED_VERSIONS); + } + + /** + * Creates a new CustomStatementParserBuilder object initialized by specific + * version bundle. Statement parser will support all versions defined in + * given version bundle. + * + * @param supportedVersions + * bundle of supported verions + */ + public CustomStatementParserBuilder(final Set supportedVersions) { + reactorSupportBundles = ImmutableMap. builder() + .put(ModelProcessingPhase.INIT, StatementSupportBundle.builder(supportedVersions)) + .put(ModelProcessingPhase.SOURCE_PRE_LINKAGE, StatementSupportBundle.builder(supportedVersions)) + .put(ModelProcessingPhase.SOURCE_LINKAGE, StatementSupportBundle.builder(supportedVersions)) + .put(ModelProcessingPhase.STATEMENT_DEFINITION, StatementSupportBundle.builder(supportedVersions)) + .put(ModelProcessingPhase.FULL_DECLARATION, StatementSupportBundle.builder(supportedVersions)) + .put(ModelProcessingPhase.EFFECTIVE_MODEL, StatementSupportBundle.builder(supportedVersions)).build(); + } + public CustomStatementParserBuilder addStatementSupport(final ModelProcessingPhase phase, final StatementSupport stmtSupport) { reactorSupportBundles.get(phase).addSupport(stmtSupport); @@ -69,7 +95,8 @@ public class CustomStatementParserBuilder { public CustomStatementParserBuilder addAllSupports(final ModelProcessingPhase phase, final StatementSupportBundle stmtSupportBundle) { - addAllStatementSupports(phase, stmtSupportBundle.getDefinitions().values()); + addAllCommonStatementSupports(phase, stmtSupportBundle.getCommonDefinitions().values()); + addAllVersionSpecificSupports(phase, stmtSupportBundle.getAllVersionSpecificDefinitions()); addAllNamespaceSupports(phase, stmtSupportBundle.getNamespaceDefinitions().values()); return this; } @@ -83,8 +110,19 @@ public class CustomStatementParserBuilder { return this; } + /** + * Use + * {@link #addAllCommonStatementSupports(ModelProcessingPhase, Collection) + * addAllCommonStatementSupports} method instead. + */ + @Deprecated public CustomStatementParserBuilder addAllStatementSupports(final ModelProcessingPhase phase, final Collection> statementSupports) { + return addAllCommonStatementSupports(phase, statementSupports); + } + + public CustomStatementParserBuilder addAllCommonStatementSupports(final ModelProcessingPhase phase, + final Collection> statementSupports) { final StatementSupportBundle.Builder stmtBundleBuilder = reactorSupportBundles.get(phase); for (final StatementSupport statementSupport : statementSupports) { stmtBundleBuilder.addSupport(statementSupport); @@ -92,6 +130,15 @@ public class CustomStatementParserBuilder { return this; } + public CustomStatementParserBuilder addAllVersionSpecificSupports(final ModelProcessingPhase phase, + final Table> versionSpecificSupports) { + final StatementSupportBundle.Builder stmtBundleBuilder = reactorSupportBundles.get(phase); + for (final Cell> cell : versionSpecificSupports.cellSet()) { + stmtBundleBuilder.addVersionSpecificSupport(cell.getRowKey(), cell.getValue()); + } + return this; + } + public CrossSourceStatementReactor build() { final StatementSupportBundle initBundle = reactorSupportBundles.get(ModelProcessingPhase.INIT).build(); final StatementSupportBundle preLinkageBundle = reactorSupportBundles diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java index 0fe03bec79..4c36df3706 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java @@ -68,7 +68,7 @@ abstract class NamespaceStorageSupport implements NamespaceStorageNode { @SuppressWarnings("unchecked") @Override public > V getFromLocalStorage(final Class type, final K key) { - Map localNamespace = (Map) namespaces.get(type); + final Map localNamespace = (Map) namespaces.get(type); V potential = null; if (localNamespace != null) { @@ -89,9 +89,9 @@ abstract class NamespaceStorageSupport implements NamespaceStorageNode { return null; } - Set> entrySet = localNamespace.entrySet(); - for (Entry entry : entrySet) { - ModuleIdentifier moduleIdentifierInMap = entry.getKey(); + final Set> entrySet = localNamespace.entrySet(); + for (final Entry entry : entrySet) { + final ModuleIdentifier moduleIdentifierInMap = entry.getKey(); if (moduleIdentifierInMap.getName().equals(key.getName())) { return entry.getValue(); } @@ -103,7 +103,7 @@ abstract class NamespaceStorageSupport implements NamespaceStorageNode { @Override public > Map getAllFromLocalStorage(final Class type) { @SuppressWarnings("unchecked") - Map localNamespace = (Map) namespaces.get(type); + final Map localNamespace = (Map) namespaces.get(type); return localNamespace; } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java index ff139209b2..7c8b2d5877 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java @@ -17,6 +17,7 @@ import java.util.Map; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; @@ -36,9 +37,13 @@ import org.opendaylight.yangtools.yang.parser.spi.source.IncludedModuleContext; public class RootStatementContext, E extends EffectiveStatement> extends StatementContextBase { + public static final YangVersion DEFAULT_VERSION = YangVersion.VERSION_1; + private final SourceSpecificContext sourceContext; private final A argument; + private YangVersion version; + /** * References to RootStatementContext of submodules which are included in this source. */ @@ -50,6 +55,12 @@ public class RootStatementContext, E extends E this.argument = builder.getDefinition().parseArgumentValue(this, builder.getRawArgument()); } + RootStatementContext(final ContextBuilder builder, final SourceSpecificContext sourceContext, + final YangVersion version) { + this(builder, sourceContext); + this.setRootVersion(version); + } + RootStatementContext(final RootStatementContext original, final QNameModule newQNameModule, final CopyType typeOfCopy) { super(original); @@ -218,4 +229,18 @@ public class RootStatementContext, E extends E } return null; } + + @Override + public YangVersion getRootVersion() { + return version == null ? DEFAULT_VERSION : version; + } + + @Override + public void setRootVersion(final YangVersion version) { + Preconditions.checkArgument(sourceContext.getSupportedVersions().contains(version), + "Unsupported yang version %s in %s", version, getStatementSourceReference()); + Preconditions.checkState(this.version == null, "Version of root %s has been already set to %s", argument, + this.version); + this.version = Preconditions.checkNotNull(version); + } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java index 7b30b53f39..680b7f379c 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java @@ -21,11 +21,13 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; import javax.annotation.Nullable; import org.opendaylight.yangtools.concepts.Mutable; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.common.YangConstants; +import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier; import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; @@ -39,6 +41,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.Namesp import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.StorageNodeType; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementDefinitionNamespace; import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport; +import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle; import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToModuleContext; import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleIdentifier; import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdentifier; @@ -82,11 +85,18 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh @Override public StatementContextBase build() { + /* + * If root is null or root version is other than default, + * we need to create new root. + */ if (root == null) { root = new RootStatementContext(this, SourceSpecificContext.this); + } else if (!RootStatementContext.DEFAULT_VERSION.equals(root.getRootVersion()) + && inProgressPhase == ModelProcessingPhase.SOURCE_LINKAGE) { + root = new RootStatementContext(this, SourceSpecificContext.this, root.getRootVersion()); } else { Preconditions.checkState(root.getIdentifier().equals(createIdentifier()), - "Root statement was already defined as %s.", root.getIdentifier()); + "Root statement was already defined as %s.", root.getIdentifier()); } root.resetLists(); return root; @@ -147,7 +157,7 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh } } - StatementDefinitionContext def = currentContext.getStatementDefinition(name); + StatementDefinitionContext def = currentContext.getStatementDefinition(getRootVersion(), name); if (def == null) { final StatementSupport extension = qNameToStmtDefMap.get(name); @@ -190,6 +200,15 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh return root; } + /** + * Return version of root statement context. + * + * @return version of root statement context + */ + YangVersion getRootVersion() { + return root != null ? root.getRootVersion() : RootStatementContext.DEFAULT_VERSION; + } + DeclaredStatement buildDeclared() { return root.buildDeclared(); } @@ -396,7 +415,9 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh private QNameToStatementDefinition stmtDef() { // regular YANG statements and extension supports added - qNameToStmtDefMap.putAll(currentContext.getSupportsForPhase(inProgressPhase).getDefinitions()); + final StatementSupportBundle supportsForPhase = currentContext.getSupportsForPhase(inProgressPhase); + qNameToStmtDefMap.putAll(supportsForPhase.getCommonDefinitions()); + qNameToStmtDefMap.putAll(supportsForPhase.getDefinitionsSpecificForVersion(getRootVersion())); // No further actions needed if (inProgressPhase != ModelProcessingPhase.FULL_DECLARATION) { @@ -419,4 +440,8 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh return qNameToStmtDefMap; } + + public Set getSupportedVersions() { + return currentContext.getSupportedVersions(); + } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java index 1c78ae16c0..aa64a55936 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SubstatementContext.java @@ -17,6 +17,7 @@ import java.util.Set; import javax.annotation.Nonnull; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; +import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; @@ -306,4 +307,14 @@ final class SubstatementContext, E extends Eff public boolean isEnabledSemanticVersioning() { return parent.isEnabledSemanticVersioning(); } + + @Override + public YangVersion getRootVersion() { + return getRoot().getRootVersion(); + } + + @Override + public void setRootVersion(final YangVersion version) { + getRoot().setRootVersion(version); + } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ContainerStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ContainerStatementImpl.java index 605ab3c28b..aadf2fd844 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ContainerStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ContainerStatementImpl.java @@ -88,7 +88,11 @@ public class ContainerStatementImpl extends AbstractDeclaredStatement imp public void onFullDefinitionDeclared(final Mutable> stmt) { super.onFullDefinitionDeclared(stmt); - SUBSTATEMENT_VALIDATOR.validate(stmt); + getSubstatementValidator().validate(stmt); + } + + protected SubstatementValidator getSubstatementValidator() { + return SUBSTATEMENT_VALIDATOR; } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ModuleStatementSupport.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ModuleStatementSupport.java index 05c390c118..0622dad4f6 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ModuleStatementSupport.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ModuleStatementSupport.java @@ -122,7 +122,7 @@ public class ModuleStatementSupport extends revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV); } - QNameModule qNameModule = QNameModule.create(moduleNs, revisionDate.orElse(null)).intern(); + final QNameModule qNameModule = QNameModule.create(moduleNs, revisionDate.orElse(null)).intern(); stmt.addToNs(ModuleCtxToModuleQName.class, stmt, qNameModule); } @@ -130,7 +130,7 @@ public class ModuleStatementSupport extends @Override public void onLinkageDeclared(final Mutable> stmt) { - Optional moduleNs = Optional.ofNullable(firstAttributeOf(stmt.declaredSubstatements(), + final Optional moduleNs = Optional.ofNullable(firstAttributeOf(stmt.declaredSubstatements(), NamespaceStatement.class)); SourceException.throwIf(!moduleNs.isPresent(), stmt.getStatementSourceReference(), "Namespace of the module [%s] is missing", stmt.getStatementArgument()); @@ -140,8 +140,8 @@ public class ModuleStatementSupport extends revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV); } - QNameModule qNameModule = QNameModule.create(moduleNs.get(), revisionDate.orElse(null)).intern(); - ModuleIdentifier moduleIdentifier = ModuleIdentifierImpl.create(stmt.getStatementArgument(), + final QNameModule qNameModule = QNameModule.create(moduleNs.get(), revisionDate.orElse(null)).intern(); + final ModuleIdentifier moduleIdentifier = ModuleIdentifierImpl.create(stmt.getStatementArgument(), Optional.empty(), revisionDate); stmt.addContext(ModuleNamespace.class, moduleIdentifier, stmt); @@ -185,6 +185,10 @@ public class ModuleStatementSupport extends public void onFullDefinitionDeclared(final Mutable> stmt) { super.onFullDefinitionDeclared(stmt); - SUBSTATEMENT_VALIDATOR.validate(stmt); + getSubstatementValidator().validate(stmt); + } + + protected SubstatementValidator getSubstatementValidator() { + return SUBSTATEMENT_VALIDATOR; } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java index a24dd487d5..98f04c6e18 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java @@ -12,8 +12,11 @@ import static org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour import static org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour.treeScoped; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Sets; import java.util.Collection; import java.util.Map; +import java.util.Set; +import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; import org.opendaylight.yangtools.yang.parser.spi.ExtensionNamespace; import org.opendaylight.yangtools.yang.parser.spi.GroupingNamespace; @@ -55,17 +58,23 @@ import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamesp import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace; import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType; import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; +import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.AnydataStatementImpl; +import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.ContainerStatementRfc7950Support; +import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.ModuleStatementRfc7950Support; public final class YangInferencePipeline { + public static final Set SUPPORTED_VERSIONS = + Sets.immutableEnumSet(YangVersion.VERSION_1, YangVersion.VERSION_1_1); public static final StatementSupportBundle INIT_BUNDLE = StatementSupportBundle - .builder().addSupport(global(ValidationBundlesNamespace.class)) + .builder(SUPPORTED_VERSIONS).addSupport(global(ValidationBundlesNamespace.class)) .addSupport(global(SupportedFeaturesNamespace.class)) .build(); public static final StatementSupportBundle PRE_LINKAGE_BUNDLE = StatementSupportBundle .derivedFrom(INIT_BUNDLE) - .addSupport(new ModuleStatementSupport()) + .addVersionSpecificSupport(YangVersion.VERSION_1, new ModuleStatementSupport()) + .addVersionSpecificSupport(YangVersion.VERSION_1_1, new ModuleStatementRfc7950Support()) .addSupport(new SubmoduleStatementImpl.Definition()) .addSupport(new NamespaceStatementImpl.Definition()) .addSupport(new ImportStatementDefinition()) @@ -135,7 +144,8 @@ public final class YangInferencePipeline { .addSupport(new LengthStatementImpl.Definition()) .addSupport(new PatternStatementImpl.Definition()) .addSupport(new RangeStatementImpl.Definition()) - .addSupport(new ContainerStatementImpl.Definition()) + .addVersionSpecificSupport(YangVersion.VERSION_1, new ContainerStatementImpl.Definition()) + .addVersionSpecificSupport(YangVersion.VERSION_1_1, new ContainerStatementRfc7950Support()) .addSupport(new GroupingStatementImpl.Definition()) .addSupport(new ListStatementImpl.Definition()) .addSupport(new UniqueStatementImpl.Definition()) @@ -160,6 +170,7 @@ public final class YangInferencePipeline { .addSupport(new MustStatementImpl.Definition()) .addSupport(new MandatoryStatementImpl.Definition()) .addSupport(new AnyxmlStatementImpl.Definition()) + .addVersionSpecificSupport(YangVersion.VERSION_1_1, new AnydataStatementImpl.Definition()) .addSupport(new IfFeatureStatementImpl.Definition()) .addSupport(new UsesStatementImpl.Definition()) .addSupport(treeScoped(GroupingNamespace.class)) //treeScoped diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangVersionStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangVersionStatementImpl.java index 2a6a14a54e..34619c698d 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangVersionStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangVersionStatementImpl.java @@ -8,6 +8,7 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020; import javax.annotation.Nonnull; +import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionStatement; @@ -15,50 +16,61 @@ import org.opendaylight.yangtools.yang.parser.spi.SubstatementValidator; import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.YangVersionEffectiveStatementImpl; -public class YangVersionStatementImpl extends AbstractDeclaredStatement implements YangVersionStatement { +public class YangVersionStatementImpl extends AbstractDeclaredStatement implements YangVersionStatement { private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(Rfc6020Mapping .YANG_VERSION) .build(); - protected YangVersionStatementImpl(StmtContext context) { + protected YangVersionStatementImpl(final StmtContext context) { super(context); } - public static class Definition extends AbstractStatementSupport> { + public static class Definition extends AbstractStatementSupport> { public Definition() { super(Rfc6020Mapping.YANG_VERSION); } @Override - public String parseArgumentValue(StmtContext ctx, String value) { - return value; + public YangVersion parseArgumentValue(final StmtContext ctx, final String value) { + try { + return YangVersion.parse(value); + } catch (IllegalArgumentException e) { + throw new SourceException("Unsupported YANG version " + value, ctx.getStatementSourceReference(), e); + } } @Override - public YangVersionStatement createDeclared(StmtContext ctx) { + public YangVersionStatement createDeclared(final StmtContext ctx) { return new YangVersionStatementImpl(ctx); } @Override - public EffectiveStatement createEffective - (StmtContext> ctx) { + public void onPreLinkageDeclared( + final StmtContext.Mutable> stmt) { + stmt.setRootVersion(stmt.getStatementArgument()); + } + + @Override + public EffectiveStatement createEffective + (final StmtContext> ctx) { return new YangVersionEffectiveStatementImpl(ctx); } @Override - public void onFullDefinitionDeclared(StmtContext.Mutable> stmt) { + public void onFullDefinitionDeclared(final StmtContext.Mutable> stmt) { super.onFullDefinitionDeclared(stmt); SUBSTATEMENT_VALIDATOR.validate(stmt); } } @Nonnull @Override - public String getValue() { - return rawArgument(); + public YangVersion getValue() { + return argument(); } } diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDataSchemaNode.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDataSchemaNode.java index c82beb5a1e..37a3557562 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDataSchemaNode.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveDataSchemaNode.java @@ -12,13 +12,13 @@ import org.opendaylight.yangtools.yang.model.api.ConstraintDefinition; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.CopyHistory; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -abstract class AbstractEffectiveDataSchemaNode> extends +public abstract class AbstractEffectiveDataSchemaNode> extends AbstractEffectiveSchemaNode implements DataSchemaNode { - // :FIXME should be private and final + // :FIXME Bug-7277 boolean augmenting; private final boolean addedByUses; private final boolean configuration; diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveModule.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveModule.java index 117392261f..7ae2adc552 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveModule.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AbstractEffectiveModule.java @@ -26,6 +26,7 @@ import org.opendaylight.yangtools.concepts.SemVer; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; +import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.AugmentationSchema; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.Deviation; @@ -57,7 +58,7 @@ abstract class AbstractEffectiveModule> exte private final String name; private final String sourcePath; private final String prefix; - private final String yangVersion; + private final YangVersion yangVersion; private final String organization; private final String contact; private final Set imports; @@ -86,7 +87,7 @@ abstract class AbstractEffectiveModule> exte this.prefix = (prefixStmt == null) ? null : prefixStmt.argument(); YangVersionEffectiveStatementImpl yangVersionStmt = firstEffective(YangVersionEffectiveStatementImpl.class); - this.yangVersion = (yangVersionStmt == null) ? "1" : yangVersionStmt.argument(); + this.yangVersion = (yangVersionStmt == null) ? YangVersion.VERSION_1 : yangVersionStmt.argument(); SemanticVersionEffectiveStatementImpl semanticVersionStmt = firstEffective(SemanticVersionEffectiveStatementImpl.class); this.semanticVersion = (semanticVersionStmt == null) ? DEFAULT_SEMANTIC_VERSION : semanticVersionStmt.argument(); @@ -285,7 +286,7 @@ abstract class AbstractEffectiveModule> exte @Override public String getYangVersion() { - return yangVersion; + return yangVersion.toCanonicalString(); } @Override diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/YangVersionEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/YangVersionEffectiveStatementImpl.java index 835e2cbc3a..b4dace9c49 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/YangVersionEffectiveStatementImpl.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/YangVersionEffectiveStatementImpl.java @@ -7,11 +7,12 @@ */ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective; +import org.opendaylight.yangtools.yang.common.YangVersion; import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionStatement; import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -public final class YangVersionEffectiveStatementImpl extends DeclaredEffectiveStatementBase { - public YangVersionEffectiveStatementImpl(final StmtContext ctx) { +public final class YangVersionEffectiveStatementImpl extends DeclaredEffectiveStatementBase { + public YangVersionEffectiveStatementImpl(final StmtContext ctx) { super(ctx); } } \ No newline at end of file diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/AnydataStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/AnydataStatementImpl.java new file mode 100644 index 0000000000..da20a49845 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/AnydataStatementImpl.java @@ -0,0 +1,130 @@ +/** + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.stmt.rfc7950; + +import java.util.Collection; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.AnydataStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ConfigStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.IfFeatureStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.MandatoryStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.MustStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.StatusStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.WhenStatement; +import org.opendaylight.yangtools.yang.parser.spi.SubstatementValidator; +import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.ChildSchemaNodes; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils; +import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.effective.AnyDataEffectiveStatementImpl; + +public class AnydataStatementImpl extends AbstractDeclaredStatement implements AnydataStatement { + private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(Rfc6020Mapping + .ANYDATA) + .addOptional(Rfc6020Mapping.CONFIG) + .addOptional(Rfc6020Mapping.DESCRIPTION) + .addAny(Rfc6020Mapping.IF_FEATURE) + .addOptional(Rfc6020Mapping.MANDATORY) + .addAny(Rfc6020Mapping.MUST) + .addOptional(Rfc6020Mapping.REFERENCE) + .addOptional(Rfc6020Mapping.STATUS) + .addOptional(Rfc6020Mapping.WHEN) + .build(); + + protected AnydataStatementImpl(final StmtContext context) { + super(context); + } + + public static class Definition extends + AbstractStatementSupport> { + + public Definition() { + super(Rfc6020Mapping.ANYDATA); + } + + @Override + public QName parseArgumentValue(final StmtContext ctx, final String value) { + return Utils.qNameFromArgument(ctx, value); + } + + @Override + public void onStatementAdded(final Mutable> stmt) { + stmt.getParentContext().addToNs(ChildSchemaNodes.class, stmt.getStatementArgument(), stmt); + } + + @Override + public AnydataStatement createDeclared(final StmtContext ctx) { + return new AnydataStatementImpl(ctx); + } + + @Override + public EffectiveStatement createEffective( + final StmtContext> ctx) { + return new AnyDataEffectiveStatementImpl(ctx); + } + + @Override + public void onFullDefinitionDeclared(final Mutable> stmt) { + super.onFullDefinitionDeclared(stmt); + SUBSTATEMENT_VALIDATOR.validate(stmt); + } + } + + @Override + public QName getName() { + return argument(); + } + + @Override + public WhenStatement getWhenStatement() { + return firstDeclared(WhenStatement.class); + } + + @Override + public Collection getIfFeatures() { + return allDeclared(IfFeatureStatement.class); + } + + @Override + public Collection getMusts() { + return allDeclared(MustStatement.class); + } + + @Override + public ConfigStatement getConfig() { + return firstDeclared(ConfigStatement.class); + } + + @Override + public StatusStatement getStatus() { + return firstDeclared(StatusStatement.class); + } + + @Override + public DescriptionStatement getDescription() { + return firstDeclared(DescriptionStatement.class); + } + + @Override + public ReferenceStatement getReference() { + return firstDeclared(ReferenceStatement.class); + } + + @Override + public MandatoryStatement getMandatory() { + return firstDeclared(MandatoryStatement.class); + } + +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/ContainerStatementRfc7950Support.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/ContainerStatementRfc7950Support.java new file mode 100644 index 0000000000..9208e3715d --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/ContainerStatementRfc7950Support.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.stmt.rfc7950; + +import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; +import org.opendaylight.yangtools.yang.parser.spi.SubstatementValidator; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.ContainerStatementImpl; + +public class ContainerStatementRfc7950Support extends ContainerStatementImpl.Definition { + private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(Rfc6020Mapping + .CONTAINER) + .addAny(Rfc6020Mapping.ANYXML) + .addAny(Rfc6020Mapping.CHOICE) + .addOptional(Rfc6020Mapping.CONFIG) + .addAny(Rfc6020Mapping.CONTAINER) + .addOptional(Rfc6020Mapping.DESCRIPTION) + .addAny(Rfc6020Mapping.GROUPING) + .addAny(Rfc6020Mapping.IF_FEATURE) + .addAny(Rfc6020Mapping.LEAF) + .addAny(Rfc6020Mapping.LEAF_LIST) + .addAny(Rfc6020Mapping.LIST) + .addAny(Rfc6020Mapping.MUST) + .addOptional(Rfc6020Mapping.PRESENCE) + .addOptional(Rfc6020Mapping.REFERENCE) + .addOptional(Rfc6020Mapping.STATUS) + .addAny(Rfc6020Mapping.TYPEDEF) + .addAny(Rfc6020Mapping.USES) + .addOptional(Rfc6020Mapping.WHEN) + .addAny(Rfc6020Mapping.NOTIFICATION) + .build(); + + @Override + protected SubstatementValidator getSubstatementValidator() { + return SUBSTATEMENT_VALIDATOR; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/ModuleStatementRfc7950Support.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/ModuleStatementRfc7950Support.java new file mode 100644 index 0000000000..70623f6264 --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/ModuleStatementRfc7950Support.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.stmt.rfc7950; + +import org.opendaylight.yangtools.yang.model.api.Rfc6020Mapping; +import org.opendaylight.yangtools.yang.parser.spi.SubstatementValidator; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.ModuleStatementSupport; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.SupportedExtensionsMapping; + +public class ModuleStatementRfc7950Support extends ModuleStatementSupport { + private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(Rfc6020Mapping + .MODULE) + .addAny(Rfc6020Mapping.ANYXML) + .addAny(Rfc6020Mapping.ANYDATA) + .addAny(Rfc6020Mapping.AUGMENT) + .addAny(Rfc6020Mapping.CHOICE) + .addOptional(Rfc6020Mapping.CONTACT) + .addAny(Rfc6020Mapping.CONTAINER) + .addOptional(Rfc6020Mapping.DESCRIPTION) + .addAny(Rfc6020Mapping.DEVIATION) + .addAny(Rfc6020Mapping.EXTENSION) + .addAny(Rfc6020Mapping.FEATURE) + .addAny(Rfc6020Mapping.GROUPING) + .addAny(Rfc6020Mapping.IDENTITY) + .addAny(Rfc6020Mapping.IMPORT) + .addAny(Rfc6020Mapping.INCLUDE) + .addAny(Rfc6020Mapping.LEAF) + .addAny(Rfc6020Mapping.LEAF_LIST) + .addAny(Rfc6020Mapping.LIST) + .addMandatory(Rfc6020Mapping.NAMESPACE) + .addAny(Rfc6020Mapping.NOTIFICATION) + .addOptional(Rfc6020Mapping.ORGANIZATION) + .addMandatory(Rfc6020Mapping.PREFIX) + .addOptional(Rfc6020Mapping.REFERENCE) + .addAny(Rfc6020Mapping.REVISION) + .addAny(Rfc6020Mapping.RPC) + .addAny(Rfc6020Mapping.TYPEDEF) + .addAny(Rfc6020Mapping.USES) + .addMandatory(Rfc6020Mapping.YANG_VERSION) + .addOptional(SupportedExtensionsMapping.SEMANTIC_VERSION) + .build(); + + @Override + protected SubstatementValidator getSubstatementValidator() { + return SUBSTATEMENT_VALIDATOR; + } +} diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/effective/AnyDataEffectiveStatementImpl.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/effective/AnyDataEffectiveStatementImpl.java new file mode 100644 index 0000000000..7b1920d3cb --- /dev/null +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/effective/AnyDataEffectiveStatementImpl.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.stmt.rfc7950.effective; + +import com.google.common.base.MoreObjects; +import com.google.common.base.Optional; +import java.util.Objects; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; +import org.opendaylight.yangtools.yang.model.api.DerivableSchemaNode; +import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.AnydataStatement; +import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.AbstractEffectiveDataSchemaNode; + +public class AnyDataEffectiveStatementImpl extends AbstractEffectiveDataSchemaNode implements + AnyDataSchemaNode, DerivableSchemaNode { + + private final AnyDataSchemaNode original; + + public AnyDataEffectiveStatementImpl( + final StmtContext> ctx) { + super(ctx); + this.original = ctx.getOriginalCtx() == null ? null : (AnyDataSchemaNode) ctx.getOriginalCtx().buildEffective(); + } + + @Override + public Optional getOriginal() { + return Optional.fromNullable(original); + } + + @Override + public int hashCode() { + return Objects.hash(getQName(),getPath()); + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + + final AnyDataEffectiveStatementImpl other = (AnyDataEffectiveStatementImpl) obj; + return Objects.equals(getQName(), other.getQName()) && Objects.equals(getPath(), other.getPath()); + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this).add("qname", getQName()).add("path", getPath()).toString(); + } + + @Override + public ContainerSchemaNode getSchemaOfAnyData() { + // TODO Auto-generated method stub + return null; + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/Bug6867BasicTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/Bug6867BasicTest.java new file mode 100644 index 0000000000..54cc314a04 --- /dev/null +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/Bug6867BasicTest.java @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * 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.stmt.rfc7950; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.io.FileNotFoundException; +import java.net.URISyntaxException; +import org.junit.Test; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; +import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException; +import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; +import org.opendaylight.yangtools.yang.stmt.StmtTestUtils; + +public class Bug6867BasicTest { + + @Test + public void valid10Test() throws ReactorException, SourceException, FileNotFoundException, URISyntaxException { + final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/basic-test/valid-10.yang"); + assertNotNull(schemaContext); + } + + @Test + public void valid11Test() throws ReactorException, SourceException, FileNotFoundException, URISyntaxException { + final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/basic-test/valid-11.yang"); + assertNotNull(schemaContext); + } + + @Test + public void invalid10Test() throws ReactorException, SourceException, FileNotFoundException, URISyntaxException { + try { + StmtTestUtils.parseYangSource("/rfc7950/basic-test/invalid-10.yang"); + fail("Test should fail due to invalid Yang 1.0"); + } catch (final SomeModifiersUnresolvedException e) { + assertTrue(e.getCause().getMessage().startsWith("NOTIFICATION is not valid for CONTAINER")); + } + } + + @Test + public void invalid11Test() throws ReactorException, SourceException, FileNotFoundException, URISyntaxException { + try { + StmtTestUtils.parseYangSource("/rfc7950/basic-test/invalid-11.yang"); + fail("Test should fail due to invalid Yang 1.1"); + } catch (final SomeModifiersUnresolvedException e) { + assertTrue(e.getCause().getMessage().startsWith("RPC is not valid for CONTAINER")); + } + } + + @Test + public void anyData11Test() throws ReactorException, SourceException, FileNotFoundException, URISyntaxException { + final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/rfc7950/basic-test/anydata-11.yang"); + assertNotNull(schemaContext); + } + + @Test + public void anyData10Test() throws ReactorException, SourceException, FileNotFoundException, URISyntaxException { + try { + StmtTestUtils.parseYangSource("/rfc7950/basic-test/anydata-10.yang"); + fail("Test should fail due to invalid Yang 1.0"); + } catch (final SomeModifiersUnresolvedException e) { + assertTrue(e.getCause().getMessage().startsWith("anydata is not a YANG statement or use of extension")); + } + } + + @Test + public void yangModelTest() throws ReactorException, SourceException, FileNotFoundException, URISyntaxException { + final SchemaContext schemaContext = StmtTestUtils.parseYangSources("/rfc7950/model"); + assertNotNull(schemaContext); + } + + @Test + public void unsupportedVersionTest() throws ReactorException, SourceException, FileNotFoundException, + URISyntaxException { + try { + StmtTestUtils.parseYangSource("/rfc7950/basic-test/unsupported-version.yang"); + fail("Test should fail due to unsupported Yang version"); + } catch (final SomeModifiersUnresolvedException e) { + final Throwable cause = e.getCause(); + assertNotNull(cause); + assertTrue(cause.getMessage().startsWith("Unsupported YANG version 2.3")); + } + } +} diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/StmtTestUtils.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/StmtTestUtils.java index 5ee2476471..e6336f273b 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/StmtTestUtils.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/StmtTestUtils.java @@ -37,12 +37,12 @@ import org.slf4j.LoggerFactory; public class StmtTestUtils { final public static FileFilter YANG_FILE_FILTER = file -> { - String name = file.getName().toLowerCase(); + final String name = file.getName().toLowerCase(); return name.endsWith(".yang") && file.isFile(); }; final public static FileFilter YIN_FILE_FILTER = file -> { - String name = file.getName().toLowerCase(); + final String name = file.getName().toLowerCase(); return name.endsWith(".xml") && file.isFile(); }; @@ -52,18 +52,18 @@ public class StmtTestUtils { } - public static void log(Throwable e, String indent) { + public static void log(final Throwable e, final String indent) { LOG.debug(indent + e.getMessage()); - Throwable[] suppressed = e.getSuppressed(); - for (Throwable throwable : suppressed) { + final Throwable[] suppressed = e.getSuppressed(); + for (final Throwable throwable : suppressed) { log(throwable, indent + " "); } } public static List findModules(final Set modules, final String moduleName) { - List result = new ArrayList<>(); - for (Module module : modules) { + final List result = new ArrayList<>(); + for (final Module module : modules) { if (module.getName().equals(moduleName)) { result.add(module); } @@ -71,24 +71,24 @@ public class StmtTestUtils { return result; } - public static void addSources(CrossSourceStatementReactor.BuildAction reactor, YangStatementSourceImpl... sources) { - for (YangStatementSourceImpl source : sources) { + public static void addSources(final CrossSourceStatementReactor.BuildAction reactor, final YangStatementSourceImpl... sources) { + for (final YangStatementSourceImpl source : sources) { reactor.addSource(source); } } - public static void printReferences(Module module, boolean isSubmodule, String indent) { + public static void printReferences(final Module module, final boolean isSubmodule, final String indent) { LOG.debug(indent + (isSubmodule ? "Submodule " : "Module ") + module.getName()); - Set submodules = module.getSubmodules(); - for (Module submodule : submodules) { + final Set submodules = module.getSubmodules(); + for (final Module submodule : submodules) { printReferences(submodule, true, indent + " "); printChilds(submodule.getChildNodes(), indent + " "); } } - public static void printChilds(Collection childNodes, String indent) { + public static void printChilds(final Collection childNodes, final String indent) { - for (DataSchemaNode child : childNodes) { + for (final DataSchemaNode child : childNodes) { LOG.debug(indent + "Child " + child.getQName().getLocalName()); if (child instanceof DataNodeContainer) { printChilds(((DataNodeContainer) child).getChildNodes(), indent + " "); @@ -96,29 +96,29 @@ public class StmtTestUtils { } } - public static SchemaContext parseYangSources(StatementStreamSource... sources) throws SourceException, + public static SchemaContext parseYangSources(final StatementStreamSource... sources) throws SourceException, ReactorException { return parseYangSources(StatementParserMode.DEFAULT_MODE, sources); } - public static SchemaContext parseYangSources(StatementParserMode statementParserMode, StatementStreamSource... sources) + public static SchemaContext parseYangSources(final StatementParserMode statementParserMode, final StatementStreamSource... sources) throws SourceException, ReactorException { - CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(statementParserMode); + final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(statementParserMode); reactor.addSources(sources); return reactor.buildEffective(); } - public static SchemaContext parseYangSources(File... files) throws SourceException, ReactorException, + public static SchemaContext parseYangSources(final File... files) throws SourceException, ReactorException, FileNotFoundException { return parseYangSources(StatementParserMode.DEFAULT_MODE, files); } - public static SchemaContext parseYangSources(StatementParserMode statementParserMode, File... files) throws SourceException, + public static SchemaContext parseYangSources(final StatementParserMode statementParserMode, final File... files) throws SourceException, ReactorException, FileNotFoundException { - StatementStreamSource[] sources = new StatementStreamSource[files.length]; + final StatementStreamSource[] sources = new StatementStreamSource[files.length]; for (int i = 0; i < files.length; i++) { sources[i] = new YangStatementSourceImpl(new NamedFileInputStream(files[i], files[i].getPath())); @@ -127,43 +127,55 @@ public class StmtTestUtils { return parseYangSources(statementParserMode, sources); } - public static SchemaContext parseYangSources(Collection files) throws SourceException, ReactorException, + public static SchemaContext parseYangSources(final Collection files) throws SourceException, ReactorException, FileNotFoundException { return parseYangSources(files, StatementParserMode.DEFAULT_MODE); } - public static SchemaContext parseYangSources(Collection files, StatementParserMode statementParserMode) + public static SchemaContext parseYangSources(final Collection files, final StatementParserMode statementParserMode) throws SourceException, ReactorException, FileNotFoundException { return parseYangSources(statementParserMode, files.toArray(new File[files.size()])); } - public static SchemaContext parseYangSources(String yangSourcesDirectoryPath) throws SourceException, + public static SchemaContext parseYangSources(final String yangSourcesDirectoryPath) throws SourceException, ReactorException, FileNotFoundException, URISyntaxException { return parseYangSources(yangSourcesDirectoryPath, StatementParserMode.DEFAULT_MODE); } - public static SchemaContext parseYangSources(String yangSourcesDirectoryPath, StatementParserMode statementParserMode) + public static SchemaContext parseYangSource(final String yangSourcePath) throws SourceException, ReactorException, + FileNotFoundException, URISyntaxException { + return parseYangSource(yangSourcePath, StatementParserMode.DEFAULT_MODE); + } + + public static SchemaContext parseYangSource(final String yangSourcePath, final StatementParserMode statementParserMode) + throws SourceException, ReactorException, FileNotFoundException, URISyntaxException { + final URL source = StmtTestUtils.class.getResource(yangSourcePath); + final File sourceFile = new File(source.toURI()); + return parseYangSources(statementParserMode, sourceFile); + } + + public static SchemaContext parseYangSources(final String yangSourcesDirectoryPath, final StatementParserMode statementParserMode) throws SourceException, ReactorException, FileNotFoundException, URISyntaxException { - URL resourceDir = StmtTestUtils.class.getResource(yangSourcesDirectoryPath); - File testSourcesDir = new File(resourceDir.toURI()); + final URL resourceDir = StmtTestUtils.class.getResource(yangSourcesDirectoryPath); + final File testSourcesDir = new File(resourceDir.toURI()); return parseYangSources(statementParserMode, testSourcesDir.listFiles(YANG_FILE_FILTER)); } - public static SchemaContext parseYinSources(String yinSourcesDirectoryPath, StatementParserMode statementParserMode) + public static SchemaContext parseYinSources(final String yinSourcesDirectoryPath, final StatementParserMode statementParserMode) throws SourceException, ReactorException, FileNotFoundException, URISyntaxException { - URL resourceDir = StmtTestUtils.class.getResource(yinSourcesDirectoryPath); - File testSourcesDir = new File(resourceDir.toURI()); + final URL resourceDir = StmtTestUtils.class.getResource(yinSourcesDirectoryPath); + final File testSourcesDir = new File(resourceDir.toURI()); return parseYinSources(statementParserMode, testSourcesDir.listFiles(YIN_FILE_FILTER)); } - public static SchemaContext parseYinSources(StatementParserMode statementParserMode, File... files) throws SourceException, + public static SchemaContext parseYinSources(final StatementParserMode statementParserMode, final File... files) throws SourceException, ReactorException, FileNotFoundException { - StatementStreamSource[] sources = new StatementStreamSource[files.length]; + final StatementStreamSource[] sources = new StatementStreamSource[files.length]; for (int i = 0; i < files.length; i++) { sources[i] = new YinStatementSourceImpl(new NamedFileInputStream(files[i], files[i].getPath())); @@ -172,26 +184,26 @@ public class StmtTestUtils { return parseYinSources(statementParserMode, sources); } - public static SchemaContext parseYinSources(StatementParserMode statementParserMode, StatementStreamSource... sources) + public static SchemaContext parseYinSources(final StatementParserMode statementParserMode, final StatementStreamSource... sources) throws SourceException, ReactorException { - CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(statementParserMode); + final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(statementParserMode); reactor.addSources(sources); return reactor.buildEffective(); } - public static Module findImportedModule(SchemaContext context, Module rootModule, String importedModuleName) { + public static Module findImportedModule(final SchemaContext context, final Module rootModule, final String importedModuleName) { ModuleImport requestedModuleImport = null; - Set rootImports = rootModule.getImports(); - for (ModuleImport moduleImport : rootImports) { + final Set rootImports = rootModule.getImports(); + for (final ModuleImport moduleImport : rootImports) { if (moduleImport.getModuleName().equals(importedModuleName)) { requestedModuleImport = moduleImport; break; } } - Module importedModule = context.findModuleByName(requestedModuleImport.getModuleName(), + final Module importedModule = context.findModuleByName(requestedModuleImport.getModuleName(), requestedModuleImport.getRevision()); return importedModule; } diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/semver/SemanticVersionComplexTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/semver/SemanticVersionComplexTest.java index 44205743c6..6a04bf1fdf 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/semver/SemanticVersionComplexTest.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/semver/SemanticVersionComplexTest.java @@ -11,8 +11,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode; - import java.io.FileNotFoundException; import java.net.URI; import java.net.URISyntaxException; @@ -21,6 +19,7 @@ import org.junit.Test; import org.opendaylight.yangtools.concepts.SemVer; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; +import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode; import org.opendaylight.yangtools.yang.model.util.RevisionAwareXPathImpl; import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil; import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException; @@ -32,22 +31,34 @@ public class SemanticVersionComplexTest { @Test public void complexTest1() throws SourceException, FileNotFoundException, ReactorException, URISyntaxException, ParseException { - SchemaContext context = StmtTestUtils.parseYangSources("/semantic-version/complex/complex-1", + final SchemaContext context = StmtTestUtils.parseYangSources("/semantic-version/complex/complex-1", StatementParserMode.SEMVER_MODE); + verifySchemaContextTest1(context); + } + + @Test + public void complexTest1Yang1_1() throws SourceException, FileNotFoundException, ReactorException, URISyntaxException, + ParseException { + final SchemaContext context = StmtTestUtils.parseYangSources("/rfc7950/semantic-version/complex-1", + StatementParserMode.SEMVER_MODE); + verifySchemaContextTest1(context); + } + + private void verifySchemaContextTest1(final SchemaContext context) throws URISyntaxException { assertNotNull(context); - Module foo = context.findModuleByNamespace(new URI("foo")).iterator().next(); - Module semVer = context.findModuleByNamespace(new URI("urn:opendaylight:yang:extension:semantic-version")) + final Module foo = context.findModuleByNamespace(new URI("foo")).iterator().next(); + final Module semVer = context.findModuleByNamespace(new URI("urn:opendaylight:yang:extension:semantic-version")) .iterator().next(); // check module versions assertEquals(SemVer.valueOf("1.3.95"), semVer.getSemanticVersion()); assertEquals(SemVer.valueOf("1.50.2"), foo.getSemanticVersion()); - Module bar = StmtTestUtils.findImportedModule(context, foo, "bar"); + final Module bar = StmtTestUtils.findImportedModule(context, foo, "bar"); assertEquals(SemVer.valueOf("1.2.6"), bar.getSemanticVersion()); - Module foobar = StmtTestUtils.findImportedModule(context, bar, "foobar"); + final Module foobar = StmtTestUtils.findImportedModule(context, bar, "foobar"); assertEquals(SemVer.valueOf("2.26.465"), foobar.getSemanticVersion()); // check imported components @@ -68,22 +79,34 @@ public class SemanticVersionComplexTest { @Test public void complexTest2() throws SourceException, FileNotFoundException, ReactorException, URISyntaxException, ParseException { - SchemaContext context = StmtTestUtils.parseYangSources("/semantic-version/complex/complex-2", + final SchemaContext context = StmtTestUtils.parseYangSources("/semantic-version/complex/complex-2", + StatementParserMode.SEMVER_MODE); + verifySchemaContextTest2(context); + } + + @Test + public void complexTest2Yang1_1() throws SourceException, FileNotFoundException, ReactorException, URISyntaxException, + ParseException { + final SchemaContext context = StmtTestUtils.parseYangSources("/rfc7950/semantic-version/complex-2", StatementParserMode.SEMVER_MODE); + verifySchemaContextTest2(context); + } + + private void verifySchemaContextTest2(final SchemaContext context) throws URISyntaxException { assertNotNull(context); - Module foo = context.findModuleByNamespace(new URI("foo")).iterator().next(); - Module semVer = context.findModuleByNamespace(new URI("urn:opendaylight:yang:extension:semantic-version")) + final Module foo = context.findModuleByNamespace(new URI("foo")).iterator().next(); + final Module semVer = context.findModuleByNamespace(new URI("urn:opendaylight:yang:extension:semantic-version")) .iterator().next(); // check module versions assertEquals(SemVer.valueOf("2.5.50"), semVer.getSemanticVersion()); assertEquals(SemVer.valueOf("2.32.2"), foo.getSemanticVersion()); - Module bar = StmtTestUtils.findImportedModule(context, foo, "bar"); + final Module bar = StmtTestUtils.findImportedModule(context, foo, "bar"); assertEquals(SemVer.valueOf("4.9.8"), bar.getSemanticVersion()); - Module foobar = StmtTestUtils.findImportedModule(context, bar, "foobar"); + final Module foobar = StmtTestUtils.findImportedModule(context, bar, "foobar"); assertEquals(SemVer.valueOf("7.13.99"), foobar.getSemanticVersion()); // check used augmentations diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/anydata-10.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/anydata-10.yang new file mode 100644 index 0000000000..7bbeac5073 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/anydata-10.yang @@ -0,0 +1,11 @@ +module anydata-10 { + namespace "anydata-10"; + prefix a; + yang-version 1; + + anydata my-data { + } + + container root { + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/anydata-11.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/anydata-11.yang new file mode 100644 index 0000000000..72011506c0 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/anydata-11.yang @@ -0,0 +1,13 @@ +module anydata-11 { + namespace "anydata-11"; + prefix a; + yang-version 1.1; + + anydata my-data { + } + + container root { + notification root-notification { + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/invalid-10.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/invalid-10.yang new file mode 100644 index 0000000000..b0cc012d9a --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/invalid-10.yang @@ -0,0 +1,9 @@ +module invalid-10 { + namespace "invalid-10"; + prefix v; + + container root { + notification root-notification { + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/invalid-11.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/invalid-11.yang new file mode 100644 index 0000000000..8ccc3ada2d --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/invalid-11.yang @@ -0,0 +1,14 @@ +module invalid-11 { + namespace "invalid-11"; + prefix v; + yang-version 1.1; + + container root { + rpc root-rpc { + input { + } + output { + } + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/unsupported-version.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/unsupported-version.yang new file mode 100644 index 0000000000..1785f93ac6 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/unsupported-version.yang @@ -0,0 +1,8 @@ +module unsupported-version { + namespace "version-test"; + prefix un; + yang-version 2.3; + + container root { + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/valid-10.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/valid-10.yang new file mode 100644 index 0000000000..8cdabef94d --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/valid-10.yang @@ -0,0 +1,7 @@ +module valid-10 { + namespace "valid-10"; + prefix v; + + container root { + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/valid-11.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/valid-11.yang new file mode 100644 index 0000000000..9fa196272b --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/basic-test/valid-11.yang @@ -0,0 +1,10 @@ +module valid-11 { + namespace "valid-11"; + prefix v; + yang-version 1.1; + + container root { + notification root-notification { + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/model/bar.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/model/bar.yang new file mode 100644 index 0000000000..aa8643a110 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/model/bar.yang @@ -0,0 +1,119 @@ +module bar { + yang-version 1.1; + namespace "urn:opendaylight.bar"; + prefix "bar"; + + organization "opendaylight"; + contact "http://www.opendaylight.org/"; + description "This model define custom type definitions"; + + revision "2013-07-03" { + reference " WILL BE DEFINED LATER"; + } + + typedef int32-ext1 { + type int32 { + range "2..20"; + } + } + + typedef int32-ext2 { + type int32-ext1 { + range "3..9|11..max"; + } + units "mile"; + default "11"; + } + + typedef string-ext1 { + type string { + pattern "[a-k]*"; + length "5..11"; + } + } + + typedef string-ext2 { + type string-ext1 { + length "6..10"; + } + } + + typedef string-ext3 { + type string-ext2 { + pattern "[b-u]*"; + } + } + + typedef string-ext4 { + type string-ext3 { + pattern "[e-z]*"; + } + } + + typedef invalid-string-pattern { + type string { + pattern "[[A-1*-%22!^^}"; + } + } + + typedef multiple-pattern-string { + type string { + pattern "[[A-1*-%22!^^}"; + pattern "[e-z]*"; + } + } + + typedef my-decimal-type { + type decimal64 { + fraction-digits 6; + } + } + + typedef my-union { + type union { + type int16 { + range "1..100"; + } + type int32; + } + } + + typedef my-union-ext { + type my-union; + } + + typedef nested-union2 { + type union { + type my-union-ext; + type string; + } + } + + container interfaces { + grouping ifEntry { + container augment-holder; + } + list ifEntry { + key "ifIndex"; + + leaf ifIndex { + type uint32; + units minutes; + } + + leaf ifMtu { + type int32; + } + + min-elements 1; + max-elements 11; + } + } + + extension opendaylight { + argument "name" { + yin-element "true"; + } + } + +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/model/baz.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/model/baz.yang new file mode 100644 index 0000000000..b7b9c02934 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/model/baz.yang @@ -0,0 +1,194 @@ +module baz { + yang-version 1.1; + namespace "urn:opendaylight.baz"; + prefix "baz"; + + import bar { + prefix "br"; + revision-date 2013-07-03; + } + + organization "opendaylight"; + contact "http://www.opendaylight.org/"; + + revision "2013-02-27" { + reference " WILL BE DEFINED LATER"; + } + + typedef union1 { + type union2; + } + + typedef union2 { + type union { + type int32; + type br:nested-union2; + } + } + + augment "/br:interfaces/br:ifEntry" { + when "if:ifType='ds0'"; + container augment-holder { + description "Description for augment holder"; + } + } + + augment "/br:interfaces/br:ifEntry" { + when "if:ifType='ds2'"; + container augment-holder2 { + description "Description for augment holder"; + } + } + + container network { + baz:c-define point { + } + + description "network-description"; + reference "network-reference"; + status obsolete; + config true; + presence "some presence text"; + } + + feature local-storage { + description + "This feature means the device supports local + storage (memory, flash or disk) that can be used to + store syslog messages."; + } + + extension c-define { + description "Takes as argument a name string. Makes the code generator use the given name in the #define."; + argument "name" { + yin-element "true"; + } + } + + notification event { + leaf event-class { + type string; + } + anyxml reporting-entity; + leaf severity { + type string; + } + } + + rpc get-config { + description "Retrieve all or part of a specified configuration."; + reference "RFC 6241, Section 7.1"; + + input { + container source { + description + "Particular configuration to retrieve."; + + choice config-source { + mandatory true; + description + "The configuration to retrieve."; + case a { + leaf candidate { + if-feature candidate; + type empty; + description + "The candidate configuration is the config source."; + } + } + case b { + leaf running { + type empty; + description + "The running configuration is the config source."; + } + } + case c { + leaf startup { + if-feature startup; + type empty; + description + "The startup configuration is the config source. + This is optional-to-implement on the server because + not all servers will support filtering for this + datastore."; + } + } + } + } + + anyxml filter { + description "Subtree or XPath filter to use."; + baz:c-define element-attributes; + } + } + + output { + anyxml data { + description + "Copy of the source datastore subset that matched + the filter criteria (if any). An empty data container + indicates that the request did not produce any results."; + } + } + } + + grouping target { + anyxml data { + config true; + description "Copy of the source datastore subset."; + mandatory false; + must "test-condition-text"; + reference "test-no-reference"; + status "obsolete"; + when "test-when-text"; + } + choice how { + description "test choice description"; + default interval; + case interval { + leaf interval { + type uint16; + default 30; + units minutes; + } + } + case daily { + leaf daily { + type empty; + } + leaf time-of-day { + type string; + units 24-hour-clock; + default 1am; + } + } + } + leaf address { + type string; + description "Target IP address"; + mandatory true; + } + container port { + description "Target port container"; + } + list addresses { + key "id"; + leaf id { + type int8; + } + } + grouping target-inner { + description "target-inner default description"; + leaf inner-grouping-id { + type int8; + } + } + typedef group-type { + type br:my-decimal-type; + } + + br:opendaylight; + } + +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/model/foo.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/model/foo.yang new file mode 100644 index 0000000000..83ced678e8 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/model/foo.yang @@ -0,0 +1,235 @@ +module foo { + yang-version 1.1; + namespace "urn:opendaylight.foo"; + prefix "foo"; + + import bar { + prefix "br"; + revision-date 2013-07-03; + } + + import baz { + prefix "bz"; + revision-date 2013-02-27; + } + + include subfoo { + revision-date "2013-02-27"; + } + + organization "opendaylight"; + contact "http://www.opendaylight.org/"; + + revision "2013-02-27" { + reference " WILL BE DEFINED LATER"; + } + + typedef identifier { + type int32; + } + + leaf int32-leaf { + type br:int32-ext2 { + range "12..max"; + } + } + + leaf string-leaf { + type br:string-ext4; + } + + leaf invalid-pattern-string-leaf { + type br:invalid-string-pattern; + } + + leaf invalid-direct-string-pattern-def-leaf { + type string { + pattern "[[A-1*-%22!^^}"; + } + } + + leaf multiple-pattern-string-leaf { + type br:multiple-pattern-string; + } + + leaf multiple-pattern-direct-string-def-leaf { + type string { + pattern "[e-z]*"; + pattern "[[A-1*-%22!^^}"; + pattern "[a-d]*"; + } + } + + leaf length-leaf { + type br:string-ext2 { + length "7..max"; + } + } + + leaf decimal-leaf { + type br:my-decimal-type { + fraction-digits 4; + } + } + + leaf decimal-leaf2 { + type br:my-decimal-type; + } + + container ext { + bz:c-define "MY_INTERFACES"; + } + + leaf union-leaf { + type br:my-union-ext; + } + + deviation /br:interfaces/br:ifEntry { + deviate add { + default "admin"; + config "true"; + } + reference "system/user ref"; + } + + leaf custom-union-leaf { + type bz:union1; + } + + container transfer { + choice how { + default interval; + container input { + } + list output { + leaf id { + type string; + } + } + case interval { + leaf interval { + type uint16; + default 30; + units minutes; + } + } + case daily { + leaf daily { + type empty; + } + leaf time-of-day { + type string; + units 24-hour-clock; + default 1am; + } + } + case manual { + leaf manual { + type empty; + } + } + } + } + + anyxml datas { + description + "Copy of the source typesstore subset that matched + the filter criteria (if any). An empty types container + indicates that the request did not produce any results."; + status obsolete; + } + + augment "/br:interfaces/br:ifEntry/bz:augment-holder" { + when "if:ifType='ds0'"; + leaf ds0ChannelNumber { + type string; + } + leaf interface-id { + type leafref { + path "/if:interfaces/if:interface/if:name"; + } + } + leaf my-type { + type br:int32-ext2; + } + container schemas { + } + choice odl { + leaf id { + type int8; + } + case node1 { + description "node1"; + } + case node2 { + description "node2"; + } + container node3 { + description "node3"; + } + } + } + + container mycont { + container innercont { + typedef mytype { + type string; + } + leaf myleaf { + type mytype; + } + } + } + + uses bz:target { + augment "how/interval" { + description "inner augment"; + leaf name { + type string; + } + } + } + + container peer { + container destination { + uses bz:target { + refine address { + default "1.2.3.4"; + description "IP address of target node"; + reference "address reference added by refine"; + config false; + mandatory false; + must "ifType != 'ethernet' or " + + "(ifType = 'ethernet' and ifMTU = 1500)" { + error-message "An ethernet MTU must be 1500"; + } + foo:mountpoint "mnt-extension"; + } + refine port { + description "description of port defined by refine"; + reference "port reference added by refine"; + config false; + presence "presence is required"; + } + refine "addresses" { + description "description of addresses defined by refine"; + reference "addresses reference added by refine"; + config false; + min-elements 2; + max-elements unbounded; + } + refine addresses/id { + description "id of address"; + } + } + } + } + + extension mountpoint { + description "enter point"; + argument "name" { + yin-element "true"; + } + } + +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/model/subfoo.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/model/subfoo.yang new file mode 100644 index 0000000000..e0008dee11 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/model/subfoo.yang @@ -0,0 +1,70 @@ +submodule subfoo { + yang-version 1.1; + + belongs-to foo { + prefix f; + } + + import bar { + prefix "br"; + revision-date 2013-07-03; + } + + import baz { + prefix "bz"; + revision-date 2013-02-27; + } + + revision "2013-02-27" { + } + + leaf id { + type br:int32-ext2 { + range "12..max"; + } + } + + leaf foo-id { + type f:identifier; + } + + container sub-ext { + bz:c-define "MY_INTERFACES"; + } + + container sub-transfer { + choice how { + default interval; + container input { + } + list output { + leaf id { + type string; + } + } + case manual { + leaf manual { + type empty; + } + } + } + } + + anyxml sub-datas { + status obsolete; + } + + augment "/br:interfaces/br:ifEntry/bz:augment-holder" { + when "if:ifType='ds0'"; + leaf subleaf { + type string; + } + } + + extension sub-mountpoint { + argument "name" { + yin-element "true"; + } + } + +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/bar@2016-01-03.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/bar@2016-01-03.yang new file mode 100644 index 0000000000..207b4bdb84 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/bar@2016-01-03.yang @@ -0,0 +1,24 @@ +module bar { + namespace "bar"; + prefix bar; + yang-version 1.1; + + import semantic-version { prefix sv; sv:semantic-version "1.2.012"; } + import foobar { prefix foobar; sv:semantic-version "2.25.3"; } + + revision "2016-01-03" { + description "Imported version"; + } + sv:semantic-version "1.2.6"; + + container root { + container test-container { + uses foobar:test-grouping; + } + } + + leaf-list should-present { + type string; + description "List of strings"; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/bar@2016-01-04.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/bar@2016-01-04.yang new file mode 100644 index 0000000000..8328cbecca --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/bar@2016-01-04.yang @@ -0,0 +1,24 @@ +module bar { + namespace "bar"; + prefix bar; + yang-version 1.1; + + import semantic-version { prefix sv; sv:semantic-version "1.2.210"; } + import foobar { prefix foobar; sv:semantic-version "2.25.3"; } + + revision "2016-01-04" { + description "Not-imported version"; + } + sv:semantic-version "2.200.200"; + + container root { + container test-container { + uses foobar:test-grouping; + } + } + + leaf-list should-not-be-present { + type uint32; + description "List of integers"; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/foo.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/foo.yang new file mode 100644 index 0000000000..e3828f085f --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/foo.yang @@ -0,0 +1,13 @@ +module foo { + namespace "foo"; + prefix foo; + yang-version 1.1; + + import semantic-version { prefix sv; sv:semantic-version "1.0.0"; } + import bar { prefix bar; sv:semantic-version "1.2.5"; } + + revision "2016-02-01" { + description "Initial version"; + } + sv:semantic-version "1.50.02"; +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/foobar@2016-01-31.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/foobar@2016-01-31.yang new file mode 100644 index 0000000000..773bc65a7a --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/foobar@2016-01-31.yang @@ -0,0 +1,23 @@ +module foobar { + namespace "foobar"; + prefix foobar; + yang-version 1.1; + + import semantic-version { prefix sv; sv:semantic-version "1.2.95"; } + + revision "2016-01-31" { + description "Not-imported version"; + } + sv:semantic-version "2.25.2"; + + grouping test-grouping { + leaf name { + type string; + description "Name"; + } + leaf oldnumber { + type uint8; + description "Old number"; + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/foobar@2016-02-28.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/foobar@2016-02-28.yang new file mode 100644 index 0000000000..4c92e9f30f --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/foobar@2016-02-28.yang @@ -0,0 +1,23 @@ +module foobar { + namespace "foobar"; + prefix foobar; + yang-version 1.1; + + import semantic-version { prefix sv; sv:semantic-version "1.3.95"; } + + revision "2016-02-28" { + description "Imported version"; + } + sv:semantic-version "2.26.465"; + + grouping test-grouping { + leaf name { + type string; + description "Name"; + } + leaf number { + type uint32; + description "Number"; + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/semantic-version.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/semantic-version.yang new file mode 100644 index 0000000000..14dc274ebe --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-1/semantic-version.yang @@ -0,0 +1,47 @@ +module semantic-version { + namespace "urn:opendaylight:yang:extension:semantic-version"; + prefix sv; + yang-version 1.1; + + revision 2016-02-02 { + description "Initial verison"; + } + sv:semantic-version "1.3.95"; + + extension semantic-version { + argument "semantic-version" { + yin-element false; + } + description + "The OpenConfig version number for the module. This is + expressed as a semantic version number of the form: + x.y.z + where: + * x corresponds to the major version, + * y corresponds to a minor version, + * z corresponds to a patch version. + This version corresponds to the model file within which it is + defined, and does not cover the whole set of OpenConfig models. + Where several modules are used to build up a single block of + functionality, the same module version is specified across each + file that makes up the module. + + A major version number of 0 indicates that this model is still + in development (whether within OpenConfig or with industry + partners), and is potentially subject to change. + + Following a release of major version 1, all modules will + increment major revision number where backwards incompatible + changes to the model are made. + + The minor version is changed when features are added to the + model that do not impact current clients use of the model. + + The patch-level version is incremented when non-feature changes + (such as bugfixes or clarifications to human-readable + descriptions that do not impact model functionality) are made + that maintain backwards compatibility. + + The version number is stored in the module meta-data."; + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/bar@2016-01-03.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/bar@2016-01-03.yang new file mode 100644 index 0000000000..f11bdb0943 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/bar@2016-01-03.yang @@ -0,0 +1,23 @@ +module bar { + namespace "bar"; + prefix bar; + yang-version 1; + + import semantic-version { prefix sv; sv:semantic-version "2.0.40"; } + import foobar { prefix foobar; sv:semantic-version "7.12.54"; } + + revision "2016-01-03" { + description "Imported version"; + } + sv:semantic-version "4.9.8"; + + augment "/foobar:root/foobar:test-container" { + leaf should-present-leaf-1 { + type string; + } + leaf should-present-leaf-2 { + type uint8; + default 0; + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/bar@2016-01-04.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/bar@2016-01-04.yang new file mode 100644 index 0000000000..712b379c01 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/bar@2016-01-04.yang @@ -0,0 +1,23 @@ +module bar { + namespace "bar"; + prefix bar; + yang-version 1.1; + + import semantic-version { prefix sv; sv:semantic-version "2.0.50"; } + import foobar { prefix foobar; sv:semantic-version "7.12.54"; } + + revision "2016-01-04" { + description "Not-imported version"; + } + sv:semantic-version "3.0.5"; + + augment "/foobar:root/foobar:test-container" { + leaf should-not-be-present-leaf-1 { + type string; + } + leaf should-not-be-present-leaf-2 { + type uint8; + default 0; + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foo.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foo.yang new file mode 100644 index 0000000000..3955eb50f4 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foo.yang @@ -0,0 +1,13 @@ +module foo { + namespace "foo"; + prefix foo; + yang-version 1.1; + + import semantic-version { prefix sv; sv:semantic-version "2.5.40"; } + import bar { prefix bar; sv:semantic-version "4.1.1"; } + + revision "2016-02-01" { + description "Initial version"; + } + sv:semantic-version "2.32.2"; +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foobar@2016-01-31.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foobar@2016-01-31.yang new file mode 100644 index 0000000000..435bea628d --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foobar@2016-01-31.yang @@ -0,0 +1,20 @@ +module foobar { + namespace "foobar"; + prefix foobar; + yang-version 1; + + import semantic-version { prefix sv; sv:semantic-version "2.1.950"; } + + revision "2016-01-31" { + description "Not-imported version"; + } + sv:semantic-version "8.0.0"; + + container root { + leaf included-not-correct-mark { + type empty; + } + container test-container { + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foobar@2016-02-27.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foobar@2016-02-27.yang new file mode 100644 index 0000000000..8b8f48e1a7 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foobar@2016-02-27.yang @@ -0,0 +1,20 @@ +module foobar { + namespace "foobar"; + prefix foobar; + yang-version 1; + + import semantic-version { prefix sv; sv:semantic-version "2.5.50"; } + + revision "2016-02-27" { + description "Not-imported version"; + } + sv:semantic-version "7.13.0"; + + container root { + leaf included-not-correct-mark { + type empty; + } + container test-container { + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foobar@2016-02-28.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foobar@2016-02-28.yang new file mode 100644 index 0000000000..c45a020a52 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/foobar@2016-02-28.yang @@ -0,0 +1,20 @@ +module foobar { + namespace "foobar"; + prefix foobar; + yang-version 1; + + import semantic-version { prefix sv; sv:semantic-version "2.5.50"; } + + revision "2016-02-28" { + description "Imported version"; + } + sv:semantic-version "7.13.99"; + + container root { + leaf included-correct-mark { + type empty; + } + container test-container { + } + } +} diff --git a/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/semantic-version.yang b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/semantic-version.yang new file mode 100644 index 0000000000..a7e5ba2a62 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/rfc7950/semantic-version/complex-2/semantic-version.yang @@ -0,0 +1,47 @@ +module semantic-version { + namespace "urn:opendaylight:yang:extension:semantic-version"; + prefix sv; + yang-version 1; + + revision 2016-02-02 { + description "Initial verison"; + } + sv:semantic-version "2.5.50"; + + extension semantic-version { + argument "semantic-version" { + yin-element false; + } + description + "The OpenConfig version number for the module. This is + expressed as a semantic version number of the form: + x.y.z + where: + * x corresponds to the major version, + * y corresponds to a minor version, + * z corresponds to a patch version. + This version corresponds to the model file within which it is + defined, and does not cover the whole set of OpenConfig models. + Where several modules are used to build up a single block of + functionality, the same module version is specified across each + file that makes up the module. + + A major version number of 0 indicates that this model is still + in development (whether within OpenConfig or with industry + partners), and is potentially subject to change. + + Following a release of major version 1, all modules will + increment major revision number where backwards incompatible + changes to the model are made. + + The minor version is changed when features are added to the + model that do not impact current clients use of the model. + + The patch-level version is incremented when non-feature changes + (such as bugfixes or clarifications to human-readable + descriptions that do not impact model functionality) are made + that maintain backwards compatibility. + + The version number is stored in the module meta-data."; + } +} -- 2.36.6