Bug 3670 (part 3/5): Use of new statement parser in yang-maven-plugin 24/25524/3
authorPeter Kajsa <pkajsa@cisco.com>
Thu, 20 Aug 2015 10:51:25 +0000 (12:51 +0200)
committerPeter Kajsa <pkajsa@cisco.com>
Mon, 31 Aug 2015 13:31:42 +0000 (13:31 +0000)
(original header: Yangtools changes-fixes necessary for parser switch in Controller)

Parser fixes:
- bug4136 fix
- enhanced javadoc comments
- mapped effective build implementation and test
- Module source and sourcePath implementation and test
- EffectiveSchemaContext IdentifierToSources implementation and test
- EffectiveSchemaContext resolveSchemaContext from modules implementation
- Bug3799 test
- Antlr4 identifier vs. string fix
sal-dom-broker fix
- QName parsing for unknown nodes
- QName prefix parsing for unknown nodes from augmentation
- uses nodes reusing
- uses nodes reusing skip on top level
- uses nodes dont copy description and reference of grouping to target node (TODO? add other not to copy)

Change-Id: Iab104439f9b03977850c4d05b9ab933382919a09
Signed-off-by: Peter Kajsa <pkajsa@cisco.com>
82 files changed:
yang/yang-model-api/src/main/java/org/opendaylight/yangtools/yang/model/api/stmt/UnknownStatement.java
yang/yang-parser-impl/src/main/antlr/YangStatementLexer.g4
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/AugmentationSchemaBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/Builder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/ConstraintsBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/DataNodeContainerBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/DataSchemaNodeBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/DocumentedNodeBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/GroupingMember.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/SchemaNodeBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/TypeDefinitionBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/api/UsesNodeBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/BuilderUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/builder/impl/ModuleIdentifierImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangParserListenerImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/YangStatementParserListenerImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/impl/util/URLSchemaContextResolver.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/repo/URLSchemaContextResolver.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/ModelActionBuilder.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/NamespaceBehaviour.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StmtContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/DeclarationInTextSource.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/CrossSourceStatementReactor.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceBehaviourWithListeners.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/NamespaceStorageSupport.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/RootStatementContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementContextBase.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/AugmentUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/GroupingUtils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ImportStatementDefinition.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ModuleStatementSupport.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/SubmoduleStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/UnknownStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/Utils.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/EffectiveSchemaContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/ModuleEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/UnknownEffectiveStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ASTSchemaSource.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ModuleDependencySort.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/TopologicalSort.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/MappedEffectiveBuildTest.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/retest/AugmentToExtensionTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/Bug3799Test.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ControllerStmtParserTest.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ModuleSourceTest.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/MoreRevisionsTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/StmtTestUtils.java
yang/yang-parser-impl/src/test/resources/bugs/bug3799/test_module.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug3799/test_submodule.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/mapped-build/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/mapped-build/foo.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/mapped-build/sub-bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/mapped-build/sub-foo.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/module-source/simple-module.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/sal-broker-impl/config.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/sal-broker-impl/ietf-yang-types.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-config-dom-datastore.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-dom-broker-impl.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-md-sal-common.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-md-sal-dom.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-operational-dom-datastore.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-pingpong-broker.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/sal-broker-impl/rpc-context.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-inet-types.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-interfaces.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-netconf-monitoring.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-yang-types.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-yang-types@2013-05-16.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-yang-types@2013-07-15.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/importedtestrev@2015-05-02.yang
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/importedtestrev@2015-06-02.yang
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/importedtestrev@2015-08-02.yang
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/importedtestrev@2015-09-02.yang
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/importedtestrev@z2015-04-02.yang [moved from yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/importedtestrev.yang with 67% similarity]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-interfaces.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-netconf-monitoring.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-yang-types.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-yang-types@2013-05-16.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-yang-types@2013-07-15.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/testrev.yang

index 9ec4d1c7797af44e022feb8e3ddc429a6d7ee52c..e057cf7aff377c91cb2163245fff85ec947e5f7f 100644 (file)
@@ -12,5 +12,6 @@ import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 
 public interface UnknownStatement<S> extends DeclaredStatement<S> {
 
-    @Nullable String getArgument();
+    @Nullable S getArgument();
+
 }
index b5fc095a4cd2c88157e1dac9872834ca4c755527..b717fbc8c56368875795c6e30c6d3edb5e11f60b 100644 (file)
@@ -39,7 +39,7 @@ fragment ESC : '\\' (["\\/bfnrt] | UNICODE);
 fragment UNICODE : 'u' HEX HEX HEX HEX;
 fragment HEX : [0-9a-fA-F] ;
 
-STRING : ((~( '\r' | '\n' | '\t' | ' ' | ';' | '{' | '"' | '\'' | ':' | '/' | '=' | '[' | ']' | '+' )~( '\r' | '\n' | '\t' | ' ' | ';' | '{' | ':' | '/' | '=' | '[' | ']')* ) | SUB_STRING );
+STRING : ((~( '\r' | '\n' | '\t' | ' ' | ';' | '{' | '"' | '\'' | '/' | '=' | '[' | ']' | '+' )~( '\r' | '\n' | '\t' | ' ' | ';' | '{' | '/' | '=' | '[' | ']')* ) | SUB_STRING );
 
 mode BLOCK_COMMENT_MODE;
 END_BLOCK_COMMENT : '*/' -> popMode, skip;
index a3eab72ba12e9006f8b7da789ff13a3934008e15..58beef0e872872b61e1a9512096f58fb116232ad 100644 (file)
@@ -36,7 +36,7 @@ public interface AugmentationSchemaBuilder extends DataNodeContainerBuilder,Docu
      * for a particular instance, then the node defined by the parent data
      * definition statement is valid; otherwise, it is not.
      *
-     * @param whenCondition
+     * @param whenCondition string representation of when condition
      */
     void addWhenCondition(String whenCondition);
 
@@ -72,7 +72,7 @@ public interface AugmentationSchemaBuilder extends DataNodeContainerBuilder,Docu
     /**
      * Set information about augmentation process.
      *
-     * @param resolved
+     * @param resolved information about augmentation process
      */
     void setResolved(boolean resolved);
 
@@ -88,12 +88,16 @@ public interface AugmentationSchemaBuilder extends DataNodeContainerBuilder,Docu
     /**
      *  Set true if target of augment is unsupported (e.g. node in body of extension).
      *  In such case, augmentation is skipped and AugmentationSchema is not built.
+     *
+     *  @param unsupportedTarget information about target of augment statement
      */
     void setUnsupportedTarget(boolean unsupportedTarget);
 
     /**
      *  Return true if target of augment is unsupported (e.g. node in body of extension).
      *  In such case, augmentation is skipped and AugmentationSchema is not built.
+     *
+     *  @return information about target of augment statement
      */
     boolean isUnsupportedTarget();
 }
index 5270396c579cc6662c60241e2e01e810d6366ac4..b208c8a31462268aa66227813c74734e2cf1d8ab 100644 (file)
@@ -26,7 +26,7 @@ public interface Builder extends Mutable {
     /**
      * Set name of module in which this node is declared.
      *
-     * @param moduleName
+     * @param moduleName name of module
      * @deprecated Module name should be set during creation of builder.
      */
     @Deprecated
@@ -62,7 +62,7 @@ public interface Builder extends Mutable {
      * method, this builder is also built and unknown node is added
      * as child to the product of this builder.
      *
-     * @param unknownNode
+     * @param unknownNode an unknown node builder
      */
     void addUnknownNodeBuilder(UnknownSchemaNodeBuilder unknownNode);
 
index c03406d9f7e9d515e4e62440fdba3d26637fb84b..b15966294e61840c55c3e1cb0acea3d3799eb83d 100644 (file)
@@ -113,7 +113,7 @@ public interface ConstraintsBuilder extends Builder<ConstraintDefinition> {
     /**
      * Sets mandatory status of parent node
      *
-     * @param mandatory
+     * @param mandatory mandatory status
      */
     void setMandatory(boolean mandatory);
 
index d7367acab35d87a75c3a37c419bd3871fbfd5ce2..f72afed490d7495bf3a8cfb867e393522db0d314 100644 (file)
@@ -61,14 +61,15 @@ public interface DataNodeContainerBuilder extends Builder {
     /**
      * Add builder of child node to this node.
      *
-     * @param childNode
+     * @param childNode name of child node to add
      */
     void addChildNode(DataSchemaNodeBuilder childNode);
 
     /**
      * Add builder of child node to this node at specified position.
      *
-     * @param childNode
+     * @param index position at which the child node will be added
+     * @param childNode name of child node to add at specified position
      */
     void addChildNode(int index, DataSchemaNodeBuilder childNode);
 
@@ -93,7 +94,7 @@ public interface DataNodeContainerBuilder extends Builder {
     /**
      * Add builder of grouping statement to this node.
      *
-     * @param groupingBuilder
+     * @param groupingBuilder grouping statement builder
      */
     void addGrouping(GroupingBuilder groupingBuilder);
 
@@ -107,7 +108,7 @@ public interface DataNodeContainerBuilder extends Builder {
     /**
      * Add builder of uses statement to this node.
      *
-     * @param usesBuilder
+     * @param usesBuilder uses statement builder
      */
     void addUsesNode(UsesNodeBuilder usesBuilder);
 
index 8d86c1d3b9483ef7267480ddaeda42b7f89a2a22..fe230e898fd7e0b0096c84706fe7d5eb82036bc8 100644 (file)
@@ -42,7 +42,7 @@ public interface DataSchemaNodeBuilder extends SchemaNodeBuilder, GroupingMember
     /**
      * Set if the product of the builder node is introduced by augmentation.
      *
-     * @param augmenting
+     * @param augmenting information about augmentation
      */
     void setAugmenting(boolean augmenting);
 
index 4ff4fb87eeeab83bde1d92c0bb3d02396c08e164..72a3c510edeb84566adb38cd2a3c928d7bc6c37b 100644 (file)
@@ -26,7 +26,7 @@ public interface DocumentedNodeBuilder {
     /**
      * Set description to this node.
      *
-     * @param description
+     * @param description description of this node
      */
     void setDescription(String description);
 
@@ -40,7 +40,7 @@ public interface DocumentedNodeBuilder {
     /**
      * Set reference to this node.
      *
-     * @param reference
+     * @param reference reference to this node
      */
     void setReference(String reference);
 
@@ -54,7 +54,7 @@ public interface DocumentedNodeBuilder {
     /**
      * Set status to this node.
      *
-     * @param status
+     * @param status status of this node
      */
     void setStatus(Status status);
 }
index 3e2eea30e3e068ff6b495b370be6d747c286f416..b6137fd036beedfb080b578546b786b0c17faf63 100644 (file)
@@ -22,7 +22,7 @@ public interface GroupingMember extends Builder {
     /**
      * Set if this node is added by uses.
      *
-     * @param addedByUses
+     * @param addedByUses information about uses statement
      */
     void setAddedByUses(boolean addedByUses);
 
index 2c9fe3aa1b8f56f5f35ce1d6d98bdfacdfdc236c..f81813c45484b46e52bf28e6de8bfdd8bd6e9507 100644 (file)
@@ -33,7 +33,7 @@ public interface SchemaNodeBuilder extends DocumentedNodeBuilder, Builder {
     /**
      * Updates schema path to resulting {@link SchemaNode}.
      *
-     * @param path
+     * @param path schema path
      */
     void setPath(SchemaPath path);
 
index 6ca496b8ad3b4a9e95716a727341b15ac44ba1a2..dff64b38cc31924c9ec179f5d32f60e10283762a 100644 (file)
@@ -89,6 +89,8 @@ public interface TypeDefinitionBuilder extends TypeAwareBuilder, SchemaNodeBuild
     /**
      * Sets fractions digits of resulting type if it is derived from
      * <code>decimal</code> built-in type.
+     *
+     * @param fractionDigits fraction digits
      */
     void setFractionDigits(Integer fractionDigits);
 
index 268ca0cd2a938a211659821821b3bfe89a983aaa..5b17b1a9dfa4e22ddb0df5320a23330212463755 100644 (file)
@@ -81,7 +81,7 @@ public interface UsesNodeBuilder extends GroupingMember {
     /**
      * Set information if this uses node is defined in augment.
      *
-     * @param augmenting
+     * @param augmenting information about augmentation
      */
     void setAugmenting(boolean augmenting);
 
@@ -155,6 +155,8 @@ public interface UsesNodeBuilder extends GroupingMember {
      *
      * @deprecated Do not use this, this should be internal to the implementation
      *  and public API contract.
+     *
+     *  @param resolved resolved
      */
     @Deprecated
     void setResolved(boolean resolved);
index e98553e8009013e5b4f5c2bc2c60123fdd147630..9bf130e884272a391ecf9991e48d83853422e484 100644 (file)
@@ -343,7 +343,7 @@ public final class BuilderUtils {
     /**
      * Set addedByUses flag to true for node and all its child nodes.
      *
-     * @param node
+     * @param node grouping member node
      */
     public static void setNodeAddedByUses(final GroupingMember node) {
         node.setAddedByUses(true);
@@ -693,7 +693,7 @@ public final class BuilderUtils {
     /**
      * Get module in which this node is defined.
      *
-     * @param node
+     * @param node node
      * @return builder of module where this node is defined
      */
     public static ModuleBuilder getParentModule(final Builder node) {
index 6e825dd666473fe878c46deb8bbc85f41c732517..5a32774036a56b0809a68863a893c9e5a8f43020 100644 (file)
@@ -9,8 +9,6 @@ package org.opendaylight.yangtools.yang.parser.builder.impl;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
-import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
-
 import com.google.common.base.Optional;
 import java.net.URI;
 import java.util.Date;
@@ -79,29 +77,8 @@ public class ModuleIdentifierImpl implements ModuleIdentifier {
         if (getNamespace() != null && !getNamespace().equals(that.getNamespace())) {
             return false;
         }
-
-        Date defaultRev = SimpleDateFormatUtil.DEFAULT_DATE_REV;
-        Date defaultImp = SimpleDateFormatUtil.DEFAULT_DATE_IMP;
-
-        // if revision is in import only, spec says that it is undefined which
-        // revision to take
-        if (getRevision() == defaultImp ^ that.getRevision() == defaultImp) {
-            return true;
-        }
-
-        // default and none revisions taken as equal
-        if ((defaultRev.equals(getRevision()) && that.getRevision() == null)
-                || (defaultRev.equals(that.getRevision()) && getRevision() == null)) {
-            return true;
-        }
-
-        // else if none of them is default and one null
-        if (getRevision() == null ^ that.getRevision() == null) {
-            return false;
-        }
-
         // only fail if this revision is non-null
-        if (getRevision() != null && that.getRevision() != null && !getRevision().equals(that.getRevision())) {
+        if (getRevision() != null && !getRevision().equals(that.getRevision())) {
             return false;
         }
 
index d41a2f4ea35c2e1652b75caf67d5eb8f73298382..25abb54e83246d971d94a42dfee8bb8d4cc0cf0c 100644 (file)
@@ -666,6 +666,8 @@ public final class YangParserImpl implements YangContextParser {
      * Mini parser: This parsing context does not validate full YANG module,
      * only parses header up to the revisions and imports.
      *
+     * @param yangStream input stream containing a yang module
+     * @return new instance of YangContext
      * @see org.opendaylight.yangtools.yang.parser.impl.util.YangModelDependencyInfo
      */
     public static YangContext parseStreamWithoutErrorListeners(final InputStream yangStream) {
index 1e71e4d2c58a454ee610d62eb4bdf63d5abaa25c..0a3c7fe6ef196db780268b21a9783437fc5a82ff 100644 (file)
@@ -138,10 +138,10 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
      * the "BaseListener" aspect, which need not be exposed to the user. Maybe
      * factor out a base class into repo.spi?
      *
-     * @param namespaceContext
-     * @param sourcePath
-     * @param walker
-     * @param tree
+     * @param namespaceContext namespaceContext
+     * @param sourcePath sourcePath
+     * @param walker walker
+     * @param tree tree
      * @return new instance of YangParserListenerImpl
      */
     public static YangParserListenerImpl create(final Map<String, NavigableMap<Date, URI>> namespaceContext,
index 526f9d1adcbdec90ddc4ee95d33e46510d999a2a..da76c3aec926ec250c614ad9f60cd3116d496a8d 100644 (file)
@@ -57,7 +57,7 @@ public class YangStatementParserListenerImpl extends YangStatementParserBaseList
 
     @Override
     public void enterStatement(YangStatementParser.StatementContext ctx) {
-        final StatementSourceReference ref = DeclarationInTextSource.atPosition(sourceName, ctx
+        final StatementSourceReference ref = DeclarationInTextSource.atPosition(sourceName, ctx.getText(), ctx
                 .getStart().getLine(), ctx.getStart().getCharPositionInLine());
         boolean action = true;
         QName identifier;
@@ -112,7 +112,7 @@ public class YangStatementParserListenerImpl extends YangStatementParserBaseList
 
     @Override
     public void exitStatement(YangStatementParser.StatementContext ctx) {
-        final StatementSourceReference ref = DeclarationInTextSource.atPosition(sourceName, ctx.getStart().getLine(), ctx
+        final StatementSourceReference ref = DeclarationInTextSource.atPosition(sourceName, ctx.getText(), ctx.getStart().getLine(), ctx
                 .getStart().getCharPositionInLine());
         for (int i = 0; i < ctx.getChildCount(); i++) {
             ParseTree child = ctx.getChild(i);
index 91c5c18028ffd58f9d232006868055c6b96d8ab1..440df89299cc1128e208003b149986bf9fd71d22 100644 (file)
@@ -54,6 +54,8 @@ public class URLSchemaContextResolver implements AdvancedSchemaSourceProvider<In
 
     /**
      * Register new yang schema when it appears.
+     * @param source URL of a yang file
+     * @return new instance of SourceContext if the source is not null
      */
     public synchronized ObjectRegistration<URL> registerSource(final URL source) {
         checkArgument(source != null, "Supplied source must not be null");
index 97d0c64c51128af9f2798b4af83b5bae5bcbcc9b..deb13e1f99fe7f8b71ea2bd22359bc1a3fb8a7e5 100644 (file)
@@ -83,6 +83,7 @@ public class URLSchemaContextResolver implements AutoCloseable, SchemaSourceProv
      * @throws YangSyntaxErrorException When the YANG file is syntactically invalid
      * @throws IOException when the URL is not readable
      * @throws SchemaSourceException When parsing encounters general error
+     * @return new instance of AbstractURLRegistration if the URL is not null
      */
     public URLRegistration registerSource(final URL url) throws SchemaSourceException, IOException, YangSyntaxErrorException {
         checkArgument(url != null, "Supplied URL must not be null");
index a16e36a30618122497fcac6f4e067e2cbbc97a7e..41d22500e432eb3acb41ae7f7f58d1c05c92d39f 100644 (file)
@@ -129,6 +129,8 @@ public interface ModelActionBuilder {
          * @throws InferenceException If inference action can not be processed.
          *      Note that this exception be used for user to debug YANG sources,
          *      so should provide helpful context to fix issue in sources.
+         *
+         * @param failed collection of prerequisites which were not met
          */
         void prerequisiteFailed(Collection<? extends Prerequisite<?>> failed) throws InferenceException;
     }
index 1d996d97e116aeacb3fd8291214c5b4fbe7e919e..735bcb9ae002780284395adf450510f3c7dc4565 100644 (file)
@@ -73,6 +73,10 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
      *
      * @param identifier
      *            Namespace identifier.
+     * @param <K> type parameter
+     * @param <V> type parameter
+     * @param <N> type parameter
+     *
      * @return global namespace behaviour for supplied namespace type.
      */
     public static @Nonnull <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> global(
@@ -89,6 +93,10 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
      *
      * @param identifier
      *            Namespace identifier.
+     * @param <K> type parameter
+     * @param <V> type parameter
+     * @param <N> type parameter
+     *
      * @return source-local namespace behaviour for supplied namespace type.
      */
     public static <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> sourceLocal(
@@ -104,7 +112,11 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
      * supplied node.
      *
      * @param identifier
-     *            Namespace identifier.
+     *            Namespace identifier.     *
+     * @param <K> type parameter
+     * @param <V> type parameter
+     * @param <N> type parameter
+     *
      * @return tree-scoped namespace behaviour for supplied namespace type.
      */
     public static <K, V, N extends IdentifierNamespace<K, V>> NamespaceBehaviour<K, V, N> treeScoped(Class<N> identifier) {
@@ -113,16 +125,29 @@ public abstract class NamespaceBehaviour<K, V, N extends IdentifierNamespace<K,
 
     /**
      * returns value from model namespace storage according to key param class
+     *
+     * @param storage namespace storage
+     * @param key type parameter
+     *
+     * @return value from model namespace storage according to key param class
      */
     public abstract V getFrom(NamespaceStorageNode storage, K key);
 
     /**
      * returns all values of a keys of param class from model namespace storage
+     *
+     * @param storage namespace storage
+     *
+     * @return all values of keys of param class from model namespace storage
      */
     public abstract Map<K, V> getAllFrom(NamespaceStorageNode storage);
 
     /**
      * adds key and value to corresponding namespace storage according to param class
+     *
+     * @param storage namespace storage
+     * @param key type parameter
+     * @param value type parameter
      */
     public abstract void addTo(NamespaceStorageNode storage, K key, V value);
 
index 46cdb16628a66e541dae07331608aba44233bb54..ee6007ee292fb264344328c2d3e33bec471d8f9f 100644 (file)
@@ -64,6 +64,8 @@ public interface StmtContext<A, D extends DeclaredStatement<A>, E extends Effect
 
     Collection<StatementContextBase<?, ?, ?>> effectiveSubstatements();
 
+    Collection<StatementContextBase<?, ?, ?>> substatements();
+
     D buildDeclared();
 
     E buildEffective();
index b782618065b3a143e4ba9deff3780e105c55f5aa..6ff73908b9fbc1156ed37f6d63c851bcd2c15b93 100644 (file)
@@ -20,12 +20,12 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
  *
  *  To create source reference use one of this static factories:
  *  <ul>
- *  <li>{@link #atPosition(String, int, int)} - provides most specific reference of statement location,
+ *  <li>{@link #atPosition(String, String, int, int)} - provides most specific reference of statement location,
  *  this is most prefered since it provides most context to debug YANG model.
  *  </li>
- *  <li>{@link #atLine(String, int)}- provides source and line of statement location.
+ *  <li>{@link #atLine(String, String, int)}- provides source and line of statement location.
  *  </li>
- *  <li>{@link #inSource(String)} - least specific reference, should be used only if any of previous
+ *  <li>{@link #inSource(String, String)} - least specific reference, should be used only if any of previous
  *  references are unable to create / derive from source.
  *  </li>
  *  </ul>
@@ -33,14 +33,20 @@ import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
  */
 public abstract class DeclarationInTextSource implements StatementSourceReference {
 
-    private final String source;
+    private final String sourceText;
+    private final String sourceName;
 
-    DeclarationInTextSource(String source) {
-        this.source = source;
+    DeclarationInTextSource(String sourceName, String sourceText) {
+        this.sourceName = sourceName;
+        this.sourceText = sourceText;
     }
 
     public String getSourceName() {
-        return source;
+        return sourceName;
+    }
+
+    public String getSourceText() {
+        return sourceText;
     }
 
     @Override
@@ -51,22 +57,22 @@ public abstract class DeclarationInTextSource implements StatementSourceReferenc
     @Override
     public abstract String toString();
 
-    public static final DeclarationInTextSource inSource(String sourceName) {
-        return new InSource(sourceName);
+    public static final DeclarationInTextSource inSource(String sourceName, String sourceText) {
+        return new InSource(sourceName, sourceText);
     }
 
-    public static final DeclarationInTextSource atLine(String sourceName, int line) {
-        return new AtLine(sourceName,line);
+    public static final DeclarationInTextSource atLine(String sourceName, String sourceText, int line) {
+        return new AtLine(sourceName, sourceText, line);
     }
 
-    public static final DeclarationInTextSource atPosition(String sourceName, int line, int position) {
-        return new AtPosition(sourceName,line,position);
+    public static final DeclarationInTextSource atPosition(String sourceName, String sourceText, int line, int position) {
+        return new AtPosition(sourceName, sourceText, line,position);
     }
 
     private static class InSource extends DeclarationInTextSource {
 
-        public InSource(String source) {
-            super(source);
+        public InSource(String sourceName, String sourceText) {
+            super(sourceName, sourceText);
         }
 
         @Override
@@ -80,8 +86,8 @@ public abstract class DeclarationInTextSource implements StatementSourceReferenc
 
         private final int line;
 
-        public AtLine(String source,int line) {
-            super(source);
+        public AtLine(String sourceName, String sourceText, int line) {
+            super(sourceName, sourceText);
             this.line = line;
         }
 
@@ -97,8 +103,8 @@ public abstract class DeclarationInTextSource implements StatementSourceReferenc
         private int line;
         private int character;
 
-        public AtPosition(String source, int line, int character) {
-            super(source);
+        public AtPosition(String sourceName, String sourceText, int line, int character) {
+            super(sourceName, sourceText);
             this.line = line;
             this.character = character;
         }
index fc3b31222e1260c3e77e2d00d47cd1bac6a85782..3b8b11007f4d5320106f99646aca88889387c151 100644 (file)
@@ -7,8 +7,15 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 
+import java.util.Set;
+
+import java.io.FileNotFoundException;
+import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream;
+import java.util.HashMap;
+import java.util.Collections;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import java.io.File;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
-
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import java.io.InputStream;
 import java.util.List;
@@ -107,7 +114,31 @@ public class CrossSourceStatementReactor {
             return buildEffective();
         }
 
-    }
+        public Map<File, Module> buildEffectiveMappedToSource(
+                List<File> yangFiles) throws SourceException, ReactorException,
+                FileNotFoundException {
+
+            if (yangFiles == null || yangFiles.isEmpty()) {
+                return Collections.emptyMap();
+            }
+
+            Map<String, File> pathToFile = new HashMap<>();
+            Map<File, Module> sourceFileToModule = new HashMap<>();
 
+            for (File yangFile : yangFiles) {
+                addSource(new YangStatementSourceImpl(new NamedFileInputStream(
+                        yangFile, yangFile.getPath())));
+                pathToFile.put(yangFile.getPath(), yangFile);
+            }
+
+            EffectiveSchemaContext schema = buildEffective();
+            Set<Module> modules = schema.getModules();
+            for (Module module : modules) {
+                sourceFileToModule.put(
+                        pathToFile.get(module.getModuleSourcePath()), module);
+            }
 
+            return sourceFileToModule;
+        }
+    }
 }
index b05594466d5cee32e569259c837bd4a9a5a20a3d..14f3300c84d20e54c60355fb061930c8967ca104 100644 (file)
@@ -7,11 +7,16 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+
+import com.google.common.base.Optional;
+import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl;
+import java.util.Collection;
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.Multimap;
 import java.util.Iterator;
 import java.util.Map;
-
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
 
@@ -50,6 +55,26 @@ final class NamespaceBehaviourWithListeners<K,V, N extends IdentifierNamespace<K
                 listener.onValueAdded(key, value);
             }
         }
+
+        if(key instanceof ModuleIdentifier && !listeners.isEmpty()) {
+            Collection<ValueAddedListener> defaultImportListeners = getDefaultImportListeners((ModuleIdentifier) key);
+            Iterator<ValueAddedListener> defaultImportsIterator = defaultImportListeners.iterator();
+            while(defaultImportsIterator.hasNext()) {
+                ValueAddedListener listener = defaultImportsIterator.next();
+                if(listener.ctxNode == storage || hasIdentiticalValue(listener.ctxNode,key,value)) {
+                    defaultImportsIterator.remove();
+                    listener.onValueAdded(key, value);
+                }
+            }
+        }
+    }
+
+    private Collection<ValueAddedListener> getDefaultImportListeners(
+            ModuleIdentifier key) {
+        ModuleIdentifier defaultImportKey = new ModuleIdentifierImpl(
+                key.getName(), Optional.fromNullable(key.getNamespace()),
+                Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_IMP));
+        return listeners.get((K)defaultImportKey);
     }
 
     private boolean hasIdentiticalValue(NamespaceBehaviour.NamespaceStorageNode ctxNode, K key, V value) {
index 65dc89ab70807906df42b396a2d15b3b72a39056..27914951ba9472b0f554cf9ceb7f873acb3235b2 100644 (file)
@@ -7,6 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 
+import java.util.Map.Entry;
+
+import java.util.Set;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
+import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 import java.util.HashMap;
 import java.util.Map;
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
@@ -60,13 +65,38 @@ abstract class NamespaceStorageSupport implements NamespaceStorageNode {
         getBehaviourRegistry().getNamespaceBehaviour((Class)type).addTo(this, key, value);
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public <K, V, N extends IdentifierNamespace<K, V>> V getFromLocalStorage(Class<N> type, K key) {
-        @SuppressWarnings("unchecked")
         Map<K, V> localNamespace = (Map<K,V>) namespaces.get(type);
+
+        V potential = null;
         if(localNamespace != null) {
-            return localNamespace.get(key);
+            potential = localNamespace.get(key);
+        }
+
+        if(potential == null && Utils.isModuleIdentifierWithoutSpecifiedRevision(key)) {
+            potential = getRegardlessOfRevision((ModuleIdentifier)key,(Map<ModuleIdentifier,V>)localNamespace);
+        }
+
+        return potential;
+    }
+
+    private <K, V, N extends IdentifierNamespace<K, V>> V getRegardlessOfRevision(ModuleIdentifier key,
+            Map<ModuleIdentifier, V> localNamespace) {
+
+        if(localNamespace == null) {
+            return null;
         }
+
+        Set<Entry<ModuleIdentifier, V>> entrySet = localNamespace.entrySet();
+        for (Entry<ModuleIdentifier, V> entry : entrySet) {
+            ModuleIdentifier moduleIdentifierInMap = entry.getKey();
+            if(moduleIdentifierInMap.getName().equals(key.getName())) {
+                return entry.getValue();
+            }
+        }
+
         return null;
     }
 
index 8108cd810e6339ac946c7a534cc47538997dc6c6..03ce9c8c5face706af337b47d176e7bbfb95521e 100644 (file)
@@ -120,7 +120,7 @@ public class RootStatementContext<A, D extends DeclaredStatement<A>, E extends E
     /**
      * @return copy of this considering {@link TypeOfCopy} (augment, uses)
      *
-     * @throws SourceException
+     * @throws SourceException instance of SourceException
      */
     @Override
     public StatementContextBase<?, ?, ?> createCopy(StatementContextBase<?, ?, ?> newParent, TypeOfCopy typeOfCopy)
@@ -131,7 +131,7 @@ public class RootStatementContext<A, D extends DeclaredStatement<A>, E extends E
     /**
      * @return copy of this considering {@link TypeOfCopy} (augment, uses)
      *
-     * @throws SourceException
+     * @throws SourceException instance of SourceException
      */
     @Override
     public StatementContextBase<A, D, E> createCopy(QNameModule newQNameModule,
index 83356ed615814456088921510963fd803709a5c8..cd42c25b2de9dd219a720eb11beaa052466e954d 100644 (file)
@@ -234,6 +234,14 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
         return Collections.unmodifiableCollection(declared);
     }
 
+    /**
+     * @return collection of substatements
+     */
+    @Override
+    public Collection<StatementContextBase<?, ?, ?>> substatements() {
+        return Collections.unmodifiableCollection(substatements.values());
+    }
+
     /**
      * @return collection of effective substatements
      */
@@ -263,6 +271,8 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
      *             if added in declared phase
      * @throws NullPointerException
      *             if statement parameter is null
+     *
+     * @param substatement substatement
      */
     public void addEffectiveSubstatement(StatementContextBase<?, ?, ?> substatement) {
 
@@ -282,6 +292,8 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
      *             if added in effective phase
      * @throws NullPointerException
      *             if statement parameter is null
+     *
+     * @param substatement substatement
      */
     public void addDeclaredSubstatement(StatementContextBase<?, ?, ?> substatement) {
 
@@ -295,6 +307,11 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
 
     /**
      * builds new substatement from statement definition context and statement source reference
+     *
+     * @param def definition context
+     * @param ref source reference
+     *
+     * @return instance of ContextBuilder
      */
     @SuppressWarnings({ "rawtypes", "unchecked" })
     public ContextBuilder<?, ?, ?> substatementBuilder(StatementDefinitionContext<?, ?, ?> def,
@@ -451,7 +468,7 @@ public abstract class StatementContextBase<A, D extends DeclaredStatement<A>, E
     /**
      * occurs when an item is added to model namespace
      *
-     * @throws SourceException
+     * @throws SourceException instance of SourceException
      */
     @Override
     protected <K, V, N extends IdentifierNamespace<K, V>> void onNamespaceElementAdded(Class<N> type, K key, V value) {
index b79f75709eb8d4903f58e785ce3ee1e6f20c1700..9e39f9009f4657b1bb91db333d90bc3c7bd15bff 100644 (file)
@@ -87,7 +87,6 @@ public class AugmentStatementImpl extends
 
                 @Override
                 public void apply() throws InferenceException {
-
                     final StatementContextBase<?, ?, ?> augmentTargetCtx = AugmentUtils
                             .getAugmentTargetCtx(augmentNode);
 
index 5a92e31c6eb1cc645a049a9c17829d9df65342b3..9076c6873b3f07644a65a86f4c9e005679a5b891 100644 (file)
@@ -277,22 +277,19 @@ public final class AugmentUtils {
             if (substatementArgument instanceof QName) {
                 substatementQName = (QName) substatementArgument;
 
-                if (isSupportedAugmentTarget(substatement)
-                        && nextPathQName.getLocalName().equals(substatementQName.getLocalName())) {
-                    return substatement;
-                }
-            } // augment to extension
-            else if (StmtContextUtils.producesDeclared(substatement, UnknownStatementImpl.class)
-                    && substatementArgument instanceof String) {
-
-                final String nextPathName = nextPathQName.getLocalName();
-
-                if (nextPathName.equals(substatementArgument)
-                        || nextPathName.equals(substatement.getPublicDefinition().getStatementName().getLocalName())) {
-                    String message = "Module '" + substatement.getRoot().getStatementArgument()
-                            + "': augment into extension '" + substatementArgument + "'.";
-                    LOG.warn(message);
-                    return substatement;
+                if (nextPathQName.getLocalName().equals(
+                        substatementQName.getLocalName())) {
+                    if (isSupportedAugmentTarget(substatement)) {
+                        return substatement;
+                    } else if (Utils.isUnknownNode(substatement)) {
+                        // augment into unknown node
+                        String message = "Module '"
+                                + substatement.getRoot().getStatementArgument()
+                                + "': augment into unknown node '"
+                                + substatementArgument + "'.";
+                        LOG.warn(message);
+                        return substatement;
+                    }
                 }
             }
         }
index e6f496b0a46febf11d5c7e5fbc1dbec577f9321c..83a37469650deff8b982956ef3f5064000cb8729 100644 (file)
@@ -12,7 +12,6 @@ import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.RootStatementContext;
 import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace.ValidationBundleType;
 import org.opendaylight.yangtools.yang.parser.spi.validation.ValidationBundlesNamespace;
-import java.util.Iterator;
 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
 import java.util.Collection;
@@ -37,9 +36,10 @@ public final class GroupingUtils {
     }
 
     /**
-     * @param sourceGrpStmtCtx
-     * @param targetCtx
-     * @throws SourceException
+     * @param sourceGrpStmtCtx source grouping statement context
+     * @param targetCtx target context
+     * @param usesNode uses node
+     * @throws SourceException instance of SourceException
      */
     public static void copyFromSourceToTarget(
             StatementContextBase<?, ?, ?> sourceGrpStmtCtx,
@@ -69,7 +69,7 @@ public final class GroupingUtils {
                                 TypeOfCopy.ADDED_BY_USES);
                 targetCtx.addEffectiveSubstatement(copy);
                 usesNode.addAsEffectOfStatement(copy);
-            } else if (isReusedByUses(originalStmtCtx)) {
+            } else if (isReusedByUsesOnTop(originalStmtCtx)) {
                 targetCtx.addEffectiveSubstatement(originalStmtCtx);
                 usesNode.addAsEffectOfStatement(originalStmtCtx);
             }
@@ -90,7 +90,7 @@ public final class GroupingUtils {
                                 TypeOfCopy.ADDED_BY_USES);
                 targetCtx.addEffectiveSubstatement(copy);
                 usesNode.addAsEffectOfStatement(copy);
-            } else if (isReusedByUses(originalStmtCtx)) {
+            } else if (isReusedByUsesOnTop(originalStmtCtx)) {
                 targetCtx.addEffectiveSubstatement(originalStmtCtx);
                 usesNode.addAsEffectOfStatement(originalStmtCtx);
             }
@@ -120,14 +120,7 @@ public final class GroupingUtils {
                 QName targetQName = (QName) targetStmtArgument;
                 QNameModule targetQNameModule = targetQName.getModule();
 
-                QName sourceQName = (QName) sourceStmtArgument;
-                QNameModule sourceQNameModule = sourceQName.getModule();
-
-                if (targetQNameModule.equals(sourceQNameModule)) {
-                    return null;
-                } else {
-                    return targetQNameModule;
-                }
+                return targetQNameModule;
             } else {
                 return null;
             }
@@ -148,12 +141,30 @@ public final class GroupingUtils {
         noCopyDefSet.add(Rfc6020Mapping.TYPEDEF);
         noCopyDefSet.add(Rfc6020Mapping.TYPE);
 
+        final Set<StatementDefinition> noCopyFromGroupingSet = new HashSet<>();
+        noCopyFromGroupingSet.add(Rfc6020Mapping.DESCRIPTION);
+        noCopyFromGroupingSet.add(Rfc6020Mapping.REFERENCE);
+
         StatementDefinition def = stmtContext.getPublicDefinition();
-        return !noCopyDefSet.contains(def);
+        boolean dontCopyFromParentGrouping = noCopyFromGroupingSet.contains(def) && stmtContext.getParentContext()
+                .getPublicDefinition().equals(Rfc6020Mapping.GROUPING);
+
+        return !noCopyDefSet.contains(def) && !dontCopyFromParentGrouping;
     }
 
     public static boolean isReusedByUses(StmtContext<?, ?, ?> stmtContext) {
 
+        Set<StatementDefinition> reusedDefSet = new HashSet<>();
+        reusedDefSet.add(Rfc6020Mapping.TYPEDEF);
+        reusedDefSet.add(Rfc6020Mapping.TYPE);
+        reusedDefSet.add(Rfc6020Mapping.USES);
+
+        StatementDefinition def = stmtContext.getPublicDefinition();
+        return reusedDefSet.contains(def);
+    }
+
+    public static boolean isReusedByUsesOnTop(StmtContext<?, ?, ?> stmtContext) {
+
         Set<StatementDefinition> reusedDefSet = new HashSet<>();
         reusedDefSet.add(Rfc6020Mapping.TYPEDEF);
         reusedDefSet.add(Rfc6020Mapping.TYPE);
index 05b74316906d8fc4b16445eb424246d5d092a569..8d3c0cc8ac5ca07f9426107c81fbc371c7537328 100644 (file)
@@ -145,7 +145,7 @@ public class ImportStatementDefinition
         });
     }
 
-    private static ModuleIdentifier getImportedModuleIdentifier(
+    private ModuleIdentifier getImportedModuleIdentifier(
             Mutable<String, ImportStatement, ?> stmt) throws SourceException {
 
         String moduleName = stmt.getStatementArgument();
index 2dd4cb0d4035d84c9052743f41e136c641431b26..bd7175879b81ca25cd6e12677ce4ec52ace86730 100644 (file)
@@ -22,7 +22,6 @@ import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.NamespaceStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.RevisionStatement;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl;
 import org.opendaylight.yangtools.yang.parser.spi.ModuleNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.NamespaceToModule;
@@ -74,7 +73,7 @@ public class ModuleStatementSupport extends
                     + "] is missing.");
         }
 
-        Optional<Date> revisionDate = Optional.fromNullable(getLatestRevision(stmt.declaredSubstatements()));
+        Optional<Date> revisionDate = Optional.fromNullable(Utils.getLatestRevision(stmt.declaredSubstatements()));
         if (!revisionDate.isPresent()) {
             revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
         }
@@ -108,21 +107,4 @@ public class ModuleStatementSupport extends
 
         stmt.addContext(NamespaceToModule.class, qNameModule, stmt);
     }
-
-    private static Date getLatestRevision(Iterable<? extends StmtContext<?, ?, ?>> subStmts) {
-        Date revision = null;
-        for (StmtContext<?, ?, ?> subStmt : subStmts) {
-            if (subStmt.getPublicDefinition().getDeclaredRepresentationClass().isAssignableFrom(RevisionStatement
-                    .class)) {
-                if (revision == null && subStmt.getStatementArgument() != null) {
-                    revision = (Date) subStmt.getStatementArgument();
-                } else if (subStmt.getStatementArgument() != null && ((Date) subStmt.getStatementArgument()).compareTo
-                        (revision) > 0) {
-                    revision = (Date) subStmt.getStatementArgument();
-                }
-            }
-        }
-        return revision;
-    }
-
 }
\ No newline at end of file
index 9a3b1346158d3d983b751c23756072bfd3eb9205..803b5e48e0bf6f2f91e57c06c420c543b226b2a4 100644 (file)
@@ -9,6 +9,9 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.findFirstDeclaredSubstatement;
 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
+
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+
 import java.net.URI;
 import java.util.Date;
 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
@@ -16,7 +19,6 @@ 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.BelongsToStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.PrefixStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.RevisionStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.YangVersionStatement;
 import org.opendaylight.yangtools.yang.parser.builder.impl.ModuleIdentifierImpl;
@@ -67,10 +69,10 @@ public class SubmoduleStatementImpl extends
                 Mutable<String, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>> stmt)
                 throws SourceException {
 
-            Optional<Date> revisionDate = Optional
-                    .fromNullable(firstAttributeOf(
-                            stmt.declaredSubstatements(),
-                            RevisionStatement.class));
+            Optional<Date> revisionDate = Optional.fromNullable(Utils.getLatestRevision(stmt.declaredSubstatements()));
+            if (!revisionDate.isPresent()) {
+                revisionDate = Optional.of(SimpleDateFormatUtil.DEFAULT_DATE_REV);
+            }
 
             ModuleIdentifier submoduleIdentifier = new ModuleIdentifierImpl(
                     stmt.getStatementArgument(), Optional.<URI> absent(),
index f3aa9357afc5cff8200ac70ba7120b5a6eb50461..60db0b3bc06a37067bbac074b3cfe4fd0ed04340 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
+import org.opendaylight.yangtools.yang.common.QName;
+
 import javax.annotation.Nullable;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
@@ -17,40 +19,40 @@ 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.UnknownEffectiveStatementImpl;
 
-public class UnknownStatementImpl extends AbstractDeclaredStatement<String> implements UnknownStatement<String> {
+public class UnknownStatementImpl extends AbstractDeclaredStatement<QName> implements UnknownStatement<QName> {
 
-    protected UnknownStatementImpl(final StmtContext<String, ?, ?> context) {
+    protected UnknownStatementImpl(final StmtContext<QName, ?, ?> context) {
         super(context);
     }
 
     public static class Definition
             extends
-            AbstractStatementSupport<String, UnknownStatement<String>, EffectiveStatement<String, UnknownStatement<String>>> {
+            AbstractStatementSupport<QName, UnknownStatement<QName>, EffectiveStatement<QName, UnknownStatement<QName>>> {
 
         public Definition(final StatementDefinition publicDefinition) {
             super(publicDefinition);
         }
 
         @Override
-        public String parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) throws SourceException {
-            return value == null ? "" : value;
+        public QName parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) throws SourceException {
+            return Utils.qNameFromArgument(ctx, value);
         }
 
         @Override
-        public UnknownStatement<String> createDeclared(final StmtContext<String, UnknownStatement<String>, ?> ctx) {
+        public UnknownStatement<QName> createDeclared(final StmtContext<QName, UnknownStatement<QName>, ?> ctx) {
             return new UnknownStatementImpl(ctx);
         }
 
         @Override
-        public EffectiveStatement<String, UnknownStatement<String>> createEffective(
-                final StmtContext<String, UnknownStatement<String>, EffectiveStatement<String, UnknownStatement<String>>> ctx) {
+        public EffectiveStatement<QName, UnknownStatement<QName>> createEffective(
+                final StmtContext<QName, UnknownStatement<QName>, EffectiveStatement<QName, UnknownStatement<QName>>> ctx) {
             return new UnknownEffectiveStatementImpl(ctx);
         }
     }
 
     @Nullable
     @Override
-    public String getArgument() {
-        return rawArgument();
+    public QName getArgument() {
+        return argument();
     }
 }
index 2f4c55be38dea92e966be13352b23f3dc618f8f5..9d0fe3412692ee62fbe826f7022ef7fd7e2e6c84 100644 (file)
@@ -9,10 +9,14 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
 import static org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils.firstAttributeOf;
 
+import org.opendaylight.yangtools.yang.model.api.stmt.RevisionStatement;
+
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.RootStatementContext;
+import java.util.Date;
+import org.opendaylight.yangtools.yang.model.api.stmt.RefineStatement;
 import com.google.common.base.CharMatcher;
 import com.google.common.base.Splitter;
 import com.google.common.collect.Iterables;
-
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -22,19 +26,16 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
-
 import javax.annotation.Nullable;
 import javax.xml.xpath.XPath;
 import javax.xml.xpath.XPathExpressionException;
 import javax.xml.xpath.XPathFactory;
-
 import org.antlr.v4.runtime.tree.TerminalNode;
 import org.opendaylight.yangtools.antlrv4.code.gen.YangStatementParser;
 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.YangConstants;
-import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Deviation;
 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
@@ -48,7 +49,6 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Relat
 import org.opendaylight.yangtools.yang.model.api.stmt.SubmoduleStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.UsesStatement;
 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.spi.meta.StmtContextUtils;
 import org.opendaylight.yangtools.yang.parser.spi.source.BelongsToPrefixToModuleName;
 import org.opendaylight.yangtools.yang.parser.spi.source.ImpPrefixToModuleIdentifier;
@@ -69,8 +69,6 @@ public final class Utils {
     private static final CharMatcher DOUBLE_QUOTE_MATCHER = CharMatcher.is('"');
     private static final CharMatcher SINGLE_QUOTE_MATCHER = CharMatcher.is('\'');
 
-    public static final QName EMPTY_QNAME = QName.create("empty", "empty");
-
     private static final char SEPARATOR_NODENAME = '/';
 
     private static final String REGEX_PATH_ABS = "/[^/].*";
@@ -222,7 +220,7 @@ public final class Utils {
     public static QName qNameFromArgument(StmtContext<?, ?, ?> ctx, String value) {
 
         if (value == null || value.equals("")) {
-            return EMPTY_QNAME;
+            return ctx.getPublicDefinition().getStatementName();
         }
 
         String prefix;
@@ -235,7 +233,7 @@ public final class Utils {
             localName = namesParts[0];
             qNameModule = getRootModuleQName(ctx);
             break;
-        case 2:
+        default:
             prefix = namesParts[0];
             localName = namesParts[1];
             qNameModule = getModuleQNameByPrefix(ctx, prefix);
@@ -252,20 +250,11 @@ public final class Utils {
                 qNameModule = getModuleQNameByPrefix(ctx, prefix);
             }
             break;
-        default:
-            break;
         }
 
         if (qNameModule == null) {
-            if (StmtContextUtils.producesDeclared(ctx, UnknownStatementImpl.class)
-                    && StmtContextUtils.producesDeclared(ctx.getParentContext(), UnknownStatementImpl.class)) {
-
-                qNameModule = getRootModuleQName(ctx);
-                localName = value;
-            } else {
-                throw new IllegalArgumentException("Error in module '" + ctx.getRoot().rawStatementArgument()
-                        + "': can not resolve QNameModule for '" + value + "'.");
-            }
+            throw new IllegalArgumentException("Error in module '" + ctx.getRoot().rawStatementArgument()
+                    + "': can not resolve QNameModule for '" + value + "'.");
         }
 
         QNameModule resultQNameModule = qNameModule.getRevision() == null ? QNameModule.create(
@@ -298,7 +287,7 @@ public final class Utils {
         if (StmtContextUtils.producesDeclared(rootCtx, ModuleStatement.class)) {
             qNameModule = rootCtx.getFromNamespace(ModuleCtxToModuleQName.class, rootCtx);
         } else if (StmtContextUtils.producesDeclared(rootCtx, SubmoduleStatement.class)) {
-            String belongsToModuleName = firstAttributeOf(ctx.getRoot().declaredSubstatements(),
+            String belongsToModuleName = firstAttributeOf(rootCtx.substatements(),
                     BelongsToStatement.class);
             qNameModule = rootCtx.getFromNamespace(ModuleNameToModuleQName.class, belongsToModuleName);
         }
@@ -383,13 +372,17 @@ public final class Utils {
                 }
                 qNamesFromRoot.add(qname);
             } else if (nextStmtArgument instanceof String) {
-                QName qName = qNameFromArgument(ctx, ((String) nextStmtArgument));
+                StatementContextBase<?, ?, ?> originalCtx = ctx
+                        .getOriginalCtx();
+                final QName qName = (originalCtx != null) ? qNameFromArgument(
+                        originalCtx, (String) nextStmtArgument)
+                        : qNameFromArgument(ctx, (String) nextStmtArgument);
                 qNamesFromRoot.add(qName);
-            } else if (StmtContextUtils.producesDeclared(nextStmtCtx, AugmentStatement.class)
+            } else if ((StmtContextUtils.producesDeclared(nextStmtCtx, AugmentStatement.class)
+                       || StmtContextUtils.producesDeclared(nextStmtCtx, RefineStatement.class))
                     && nextStmtArgument instanceof SchemaNodeIdentifier) {
                 addQNamesFromSchemaNodeIdentifierToList(qNamesFromRoot, (SchemaNodeIdentifier) nextStmtArgument);
-            } else if (nextStmtCtx.getPublicDefinition().getDeclaredRepresentationClass()
-                    .isAssignableFrom(UnknownStatementImpl.class)) {
+            } else if (isUnknownNode(nextStmtCtx)) {
                 qNamesFromRoot.add(nextStmtCtx.getPublicDefinition().getStatementName());
             } else {
                 return SchemaPath.SAME;
@@ -400,6 +393,11 @@ public final class Utils {
         return schemaPath;
     }
 
+    public static boolean isUnknownNode(StmtContext<?, ?, ?> stmtCtx) {
+        return stmtCtx.getPublicDefinition().getDeclaredRepresentationClass()
+                .isAssignableFrom(UnknownStatementImpl.class);
+    }
+
     private static boolean isSupportedAsShorthandCase(StmtContext<?, ?, ?> statementCtx) {
 
         Collection<?> supportedCaseShorthands = statementCtx.getFromNamespace(ValidationBundlesNamespace.class,
@@ -456,4 +454,30 @@ public final class Utils {
     public static SchemaPath SchemaNodeIdentifierToSchemaPath(SchemaNodeIdentifier identifier) {
         return SchemaPath.create(identifier.getPathFromRoot(), identifier.isAbsolute());
     }
+
+    public static Date getLatestRevision(RootStatementContext<?, ?, ?> root) {
+        return getLatestRevision(root.declaredSubstatements());
+    }
+
+    public static Date getLatestRevision(Iterable<? extends StmtContext<?, ?, ?>> subStmts) {
+        Date revision = null;
+        for (StmtContext<?, ?, ?> subStmt : subStmts) {
+            if (subStmt.getPublicDefinition().getDeclaredRepresentationClass().isAssignableFrom(RevisionStatement
+                    .class)) {
+                if (revision == null && subStmt.getStatementArgument() != null) {
+                    revision = (Date) subStmt.getStatementArgument();
+                } else if (subStmt.getStatementArgument() != null && ((Date) subStmt.getStatementArgument()).compareTo
+                        (revision) > 0) {
+                    revision = (Date) subStmt.getStatementArgument();
+                }
+            }
+        }
+        return revision;
+    }
+
+    public static boolean isModuleIdentifierWithoutSpecifiedRevision(Object o) {
+        return (o instanceof ModuleIdentifier)
+                && (((ModuleIdentifier) o).getRevision() == SimpleDateFormatUtil.DEFAULT_DATE_IMP ||
+                        ((ModuleIdentifier) o).getRevision() == SimpleDateFormatUtil.DEFAULT_BELONGS_TO_DATE);
+    }
 }
index 2f885e788bd620d8d5c23d955541a39edfcb58fc..031d4cb87911c0eee8805356e7b4de65cb281db1 100644 (file)
@@ -7,8 +7,12 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective;
 
-import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
+import java.util.HashMap;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
+import com.google.common.collect.ImmutableMap;
+import java.util.LinkedHashMap;
+import org.opendaylight.yangtools.yang.parser.util.ModuleDependencySort;
 import java.util.HashSet;
 import com.google.common.collect.ImmutableList;
 import java.util.List;
@@ -60,18 +64,60 @@ public class EffectiveSchemaContext extends AbstractEffectiveSchemaContext {
                 new TreeMap<URI, Collection<Module>>(), MODULE_SET_SUPPLIER);
         final SetMultimap<String, Module> nameMap = Multimaps.newSetMultimap(
                 new TreeMap<String, Collection<Module>>(), MODULE_SET_SUPPLIER);
+        final Map<ModuleIdentifier, String> isMap = new LinkedHashMap<>();
 
         for (Module m : modulesInit) {
             nameMap.put(m.getName(), m);
             nsMap.put(m.getNamespace(), m);
+            isMap.put(m, m.getSource());
+        }
+
+        namespaceToModules = ImmutableSetMultimap.copyOf(nsMap);
+        nameToModules = ImmutableSetMultimap.copyOf(nameMap);
+        identifiersToSources = ImmutableMap.copyOf(isMap);
+
+    }
+
+    public EffectiveSchemaContext(final Set<Module> modules, final Map<ModuleIdentifier, String> identifiersToSources) {
+        this.identifiersToSources = ImmutableMap.copyOf(identifiersToSources);
+
+         /*
+         * Instead of doing this on each invocation of getModules(), pre-compute
+         * it once and keep it around -- better than the set we got in.
+         */
+        this.modules = ImmutableSet.copyOf(ModuleDependencySort.sort(modules.toArray(new Module[modules.size()])));
+
+         /*
+         * The most common lookup is from Namespace->Module.
+         *
+         * RESTCONF performs lookups based on module name only, where it wants
+         * to receive the latest revision
+         *
+         * Invest some quality time in building up lookup tables for both.
+         */
+        final SetMultimap<URI, Module> nsMap = Multimaps.newSetMultimap(
+                new TreeMap<URI, Collection<Module>>(), MODULE_SET_SUPPLIER);
+        final SetMultimap<String, Module> nameMap = Multimaps.newSetMultimap(
+                new TreeMap<String, Collection<Module>>(), MODULE_SET_SUPPLIER);
+
+        for (Module m : modules) {
+            nameMap.put(m.getName(), m);
+            nsMap.put(m.getNamespace(), m);
         }
 
         namespaceToModules = ImmutableSetMultimap.copyOf(nsMap);
         nameToModules = ImmutableSetMultimap.copyOf(nameMap);
 
-        // :TODO init identifiersToSources
-        this.identifiersToSources = null;
+        rootDeclaredStatements = null;
+        rootEffectiveStatements = null;
+    }
 
+    public static SchemaContext resolveSchemaContext(final Set<Module> modules) {
+        Map<ModuleIdentifier, String> identifiersToSources = new HashMap<>();
+        for (Module module : modules) {
+            identifiersToSources.put(module, module.getSource());
+        }
+        return new EffectiveSchemaContext(modules, identifiersToSources);
     }
 
     public ImmutableList<DeclaredStatement<?>> getRootDeclaredStatements() {
index 95f6a15c8d2a35144d533be6688694156bab2d99..ebbac6d177c55c3b7c333f2f11fef58055c19fe8 100644 (file)
@@ -118,10 +118,9 @@ public class ModuleEffectiveStatementImpl extends
             yangVersion = "1";
         }
 
-        sourcePath = ((DeclarationInTextSource) ctx
-                .getStatementSourceReference()).getSourceName();
-        // TODO source
-        // source =
+        DeclarationInTextSource sourceReference = (DeclarationInTextSource) ctx.getStatementSourceReference();
+        sourcePath = sourceReference.getSourceName();
+        source = sourceReference.getSourceText();
 
         initSubmodules(ctx);
         initSubstatementCollections(ctx);
index 220b5d830550ef97da500a3cda95163933cdab7b..f6ab150de4de5abf804285a3c5106ee5f896fc57 100644 (file)
@@ -23,7 +23,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.TypeOfCopy;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
 
-public class UnknownEffectiveStatementImpl extends EffectiveStatementBase<String, UnknownStatement<String>> implements
+public class UnknownEffectiveStatementImpl extends EffectiveStatementBase<QName, UnknownStatement<QName>> implements
         UnknownSchemaNode {
 
     private boolean augmenting;
@@ -40,33 +40,24 @@ public class UnknownEffectiveStatementImpl extends EffectiveStatementBase<String
     private QName nodeType;
     private String nodeParameter;
 
-    public UnknownEffectiveStatementImpl(final StmtContext<String, UnknownStatement<String>, ?> ctx) {
+    public UnknownEffectiveStatementImpl(final StmtContext<QName, UnknownStatement<QName>, ?> ctx) {
         super(ctx);
 
         final StmtContext<?, ExtensionStatement, EffectiveStatement<QName, ExtensionStatement>> extensionInit = ctx
                 .getAllFromNamespace(ExtensionNamespace.class).get(ctx.getPublicDefinition().getStatementName());
+
         if (extensionInit == null) {
             extension = null;
             nodeType = ctx.getPublicDefinition().getArgumentName();
-
-            if (argument() == null || argument().isEmpty()) {
-                qName = nodeType;
-            } else {
-                qName = QName.create(Utils.qNameFromArgument(ctx, ctx.getStatementArgument()).getModule(), argument());
-            }
         } else {
             extension = (ExtensionEffectiveStatementImpl) extensionInit.buildEffective();
             nodeType = extension.getQName();
-
-            if (argument() == null || argument().isEmpty()) {
-                qName = extension.getQName();
-            } else {
-                qName = QName.create(Utils.qNameFromArgument(ctx, ctx.getStatementArgument()).getModule(), argument());
-            }
         }
 
+        qName = ctx.getStatementArgument();
         path = Utils.getSchemaPath(ctx);
-        nodeParameter = argument();
+
+        nodeParameter = (ctx.rawStatementArgument() == null) ? "" : ctx.rawStatementArgument();
 
         // TODO init other fields (see Bug1412Test)
 
@@ -85,7 +76,7 @@ public class UnknownEffectiveStatementImpl extends EffectiveStatementBase<String
         initCopyType(ctx);
     }
 
-    private void initCopyType(final StmtContext<String, UnknownStatement<String>, ?> ctx) {
+    private void initCopyType(final StmtContext<QName, UnknownStatement<QName>, ?> ctx) {
 
         List<TypeOfCopy> copyTypesFromOriginal = ctx.getCopyHistory();
 
index 3f78eed6c5116bc9c3297e48246d15e0cc0074a2..ab57ab74f9b57a4ae99376eab334885a65bbae77 100644 (file)
@@ -91,6 +91,7 @@ public final class ASTSchemaSource implements SchemaSourceRepresentation {
      *
      * @param name YANG source name. Used only for error reporting.
      * @param tree ANTLR abstract syntax tree
+     * @param text YANG text source
      * @return A new representation instance.
      * @throws YangSyntaxErrorException if we fail to extract dependency information.
      *
index 03979a1a47b4f9fb0e2a8044176b33fe1ab66a16..15a0cb36d48c01982cf82972d029e94ab0ce87dc 100644 (file)
@@ -80,6 +80,7 @@ public final class ModuleDependencySort {
     /**
      * Topological sort of module builder dependency graph.
      *
+     * @param builders builders of Module object
      * @return Sorted list of Module builders. Modules can be further processed
      *         in returned order.
      */
@@ -118,6 +119,7 @@ public final class ModuleDependencySort {
     /**
      * Topological sort of module dependency graph.
      *
+     * @param modules YANG modules
      * @return Sorted list of Modules. Modules can be further processed in
      *         returned order.
      */
index 7d3ba2aee42f7ebc65deb6c2f4360b1670c7c252..e227972ee962600a430d9de7794710621f1c7f08 100644 (file)
@@ -27,6 +27,7 @@ public final class TopologicalSort {
     /**
      * Topological sort of dependent nodes in acyclic graphs.
      *
+     * @param nodes graph nodes
      * @return Sorted {@link List} of {@link Node}s. Order: Nodes with no
      *         dependencies starting.
      * @throws IllegalStateException
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/MappedEffectiveBuildTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/effective/build/test/MappedEffectiveBuildTest.java
new file mode 100644 (file)
index 0000000..ced700c
--- /dev/null
@@ -0,0 +1,42 @@
+package org.opendaylight.yangtools.yang.stmt.effective.build.test;
+
+import static org.junit.Assert.assertEquals;
+import java.io.FileNotFoundException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor.BuildAction;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import java.util.List;
+import java.util.Arrays;
+import java.net.URISyntaxException;
+import java.io.File;
+import org.junit.Test;
+
+public class MappedEffectiveBuildTest {
+
+    @Test
+    public void mappedBuildTest() throws URISyntaxException, SourceException,
+            FileNotFoundException, ReactorException {
+        File sourceDir = new File(getClass().getResource("/mapped-build/")
+                .toURI());
+        List<File> yangFiles = Arrays.asList(sourceDir.listFiles());
+
+        assertEquals(4, yangFiles.size());
+
+        BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
+        Map<File, Module> parseYangModelsMapped = reactor
+                .buildEffectiveMappedToSource(yangFiles);
+
+        assertEquals(2, parseYangModelsMapped.size());
+
+        Set<Entry<File, Module>> mapEntrySet = parseYangModelsMapped.entrySet();
+        for (Entry<File, Module> entry : mapEntrySet) {
+            assertEquals(entry.getKey().getPath(), entry.getValue()
+                    .getModuleSourcePath());
+        }
+    }
+}
index 644514beb752248df47d9edc311946c483574428..511a4be5b9a6f85e261dc583b48aa41d4aa8334e 100644 (file)
@@ -3,9 +3,10 @@
  */
 package org.opendaylight.yangtools.yang.stmt.retest;
 
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+
 import org.opendaylight.yangtools.yang.stmt.test.StmtTestUtils;
+
 import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
 import java.net.URISyntaxException;
 import java.util.Set;
@@ -33,7 +34,8 @@ public class AugmentToExtensionTest {
         modules = TestUtils.loadModules(getClass().getResource(
                 "/augment-to-extension-test/correct-path-into-unsupported-target").toURI());
         } catch (Exception e) {
-            StmtTestUtils.log(e, "     ");
+            StmtTestUtils.log(e, "    ");
+            throw e;
         }
 
         Module devicesModule = TestUtils.findModule(modules, "augment-module");
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/Bug3799Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/Bug3799Test.java
new file mode 100644 (file)
index 0000000..aa94871
--- /dev/null
@@ -0,0 +1,57 @@
+package org.opendaylight.yangtools.yang.stmt.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import java.util.Collection;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import org.junit.Test;
+
+public class Bug3799Test {
+
+    @Test
+    public void test() throws IOException, URISyntaxException, SourceException,
+            ReactorException {
+        SchemaContext schema = StmtTestUtils.parseYangSources("/bugs/bug3799");
+        assertNotNull(schema);
+
+        Set<Module> modules = schema.getModules();
+        assertNotNull(modules);
+        assertEquals(1, modules.size());
+
+        Module testModule = modules.iterator().next();
+        Set<Module> subModules = testModule.getSubmodules();
+        assertNotNull(subModules);
+        assertEquals(1, subModules.size());
+
+        Module testSubmodule = subModules.iterator().next();
+
+        Set<NotificationDefinition> notifications = testSubmodule
+                .getNotifications();
+        assertNotNull(notifications);
+        assertEquals(1, notifications.size());
+
+        NotificationDefinition bazNotification = notifications.iterator()
+                .next();
+        Collection<DataSchemaNode> childNodes = bazNotification.getChildNodes();
+        assertNotNull(childNodes);
+        assertEquals(1, childNodes.size());
+
+        DataSchemaNode child = childNodes.iterator().next();
+        assertTrue(child instanceof LeafSchemaNode);
+
+        LeafSchemaNode leafBar = (LeafSchemaNode) child;
+        String bar = leafBar.getQName().getLocalName();
+        assertEquals("bar", bar);
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ControllerStmtParserTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ControllerStmtParserTest.java
new file mode 100644 (file)
index 0000000..e9e7eb1
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * 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.stmt.test;
+
+import static org.junit.Assert.*;
+
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+
+import org.opendaylight.yangtools.yang.model.api.UsesNode;
+import java.net.URI;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
+import java.util.List;
+import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import java.text.ParseException;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import java.io.FileNotFoundException;
+import java.net.URISyntaxException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import org.junit.Test;
+
+public class ControllerStmtParserTest {
+
+    @Test
+    public void test() throws SourceException, FileNotFoundException,
+            ReactorException, URISyntaxException, ParseException {
+        SchemaContext context = StmtTestUtils
+                .parseYangSources("/sal-broker-impl");
+        assertNotNull(context);
+
+        salDomBrokerImplModuleTest(context);
+        configModuleTest(context);
+    }
+
+    private void salDomBrokerImplModuleTest(SchemaContext context)
+            throws ParseException {
+        Module module = context.findModuleByName(
+                "opendaylight-sal-dom-broker-impl", SimpleDateFormatUtil
+                        .getRevisionFormat().parse("2013-10-28"));
+        assertNotNull(module);
+
+        Set<AugmentationSchema> augmentations = module.getAugmentations();
+        boolean checked = false;
+        for (AugmentationSchema augmentationSchema : augmentations) {
+            DataSchemaNode dataNode = augmentationSchema
+                    .getDataChildByName("dom-broker-impl");
+            if (dataNode instanceof ChoiceCaseNode) {
+                ChoiceCaseNode caseNode = (ChoiceCaseNode) dataNode;
+                DataSchemaNode dataNode2 = caseNode
+                        .getDataChildByName("async-data-broker");
+                if (dataNode2 instanceof ContainerSchemaNode) {
+                    ContainerSchemaNode containerNode = (ContainerSchemaNode) dataNode2;
+                    DataSchemaNode leaf = containerNode
+                            .getDataChildByName("type");
+                    List<UnknownSchemaNode> unknownSchemaNodes = leaf
+                            .getUnknownSchemaNodes();
+                    assertEquals(1, unknownSchemaNodes.size());
+
+                    UnknownSchemaNode unknownSchemaNode = unknownSchemaNodes
+                            .get(0);
+                    assertEquals("dom-async-data-broker", unknownSchemaNode
+                            .getQName().getLocalName());
+                    assertEquals(unknownSchemaNode.getQName(),
+                            unknownSchemaNode.getPath().getLastComponent());
+
+                    checked = true;
+                }
+            }
+        }
+        assertTrue(checked);
+    }
+
+    private void configModuleTest(SchemaContext context) throws ParseException,
+            URISyntaxException {
+        Module configModule = context.findModuleByName("config",
+                SimpleDateFormatUtil.getRevisionFormat().parse("2013-04-05"));
+        assertNotNull(configModule);
+
+        DataSchemaNode dataNode = configModule.getDataChildByName("modules");
+        assertTrue(dataNode instanceof ContainerSchemaNode);
+
+        ContainerSchemaNode moduleContainer = (ContainerSchemaNode) dataNode;
+        DataSchemaNode dataChildList = moduleContainer
+                .getDataChildByName("module");
+
+        assertTrue(dataChildList instanceof ListSchemaNode);
+
+        ListSchemaNode listModule = (ListSchemaNode) dataChildList;
+        DataSchemaNode dataChildChoice = listModule
+                .getDataChildByName("configuration");
+
+        assertTrue(dataChildChoice instanceof ChoiceSchemaNode);
+
+        ChoiceSchemaNode confChoice = (ChoiceSchemaNode) dataChildChoice;
+        ChoiceCaseNode caseNodeByName = confChoice
+                .getCaseNodeByName("dom-broker-impl");
+
+        assertNotNull(caseNodeByName);
+        DataSchemaNode dataNode2 = caseNodeByName
+                .getDataChildByName("async-data-broker");
+        assertTrue(dataNode2 instanceof ContainerSchemaNode);
+
+        ContainerSchemaNode containerNode = (ContainerSchemaNode) dataNode2;
+        DataSchemaNode leaf = containerNode.getDataChildByName("type");
+        List<UnknownSchemaNode> unknownSchemaNodes = leaf
+                .getUnknownSchemaNodes();
+
+        assertEquals(1, unknownSchemaNodes.size());
+
+        UnknownSchemaNode unknownSchemaNode = unknownSchemaNodes.get(0);
+
+        assertEquals(unknownSchemaNode.getQName(), unknownSchemaNode.getPath()
+                .getLastComponent());
+        assertEquals("dom-async-data-broker", unknownSchemaNode.getQName()
+                .getLocalName());
+
+        ChoiceCaseNode domInmemoryDataBroker = confChoice
+                .getCaseNodeByName("dom-inmemory-data-broker");
+
+        assertNotNull(domInmemoryDataBroker);
+        DataSchemaNode schemaService = domInmemoryDataBroker
+                .getDataChildByName("schema-service");
+        assertTrue(schemaService instanceof ContainerSchemaNode);
+
+        ContainerSchemaNode schemaServiceContainer = (ContainerSchemaNode) schemaService;
+
+        assertEquals(1, schemaServiceContainer.getUses().size());
+        UsesNode uses = schemaServiceContainer.getUses().iterator().next();
+        QName groupingQName = QName.create("urn:opendaylight:params:xml:ns:yang:controller:config","2013-04-05","service-ref");
+        QName usesGroupingPathLastComponent = uses.getGroupingPath().getLastComponent();
+        assertEquals(groupingQName, usesGroupingPathLastComponent);
+        assertEquals(0, getChildNodeSizeWithoutUses(schemaServiceContainer));
+
+        DataSchemaNode type = schemaServiceContainer.getDataChildByName("type");
+        List<UnknownSchemaNode> typeUnknownSchemaNodes = type
+                .getUnknownSchemaNodes();
+
+        assertEquals(1, typeUnknownSchemaNodes.size());
+
+        UnknownSchemaNode typeUnknownSchemaNode = typeUnknownSchemaNodes.get(0);
+
+        QNameModule qNameModule = QNameModule
+                .create(new URI(
+                        "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl"),
+                        SimpleDateFormatUtil.getRevisionFormat().parse(
+                                "2013-10-28"));
+        QName qName = QName.create(qNameModule, "schema-service");
+
+        assertEquals(qName, typeUnknownSchemaNode.getQName());
+        assertEquals(typeUnknownSchemaNode.getQName(), typeUnknownSchemaNode
+                .getPath().getLastComponent());
+    }
+
+    private int getChildNodeSizeWithoutUses(final DataNodeContainer csn) {
+        int result = 0;
+        for (DataSchemaNode dsn : csn.getChildNodes()) {
+            if (dsn.isAddedByUses() == false) {
+                result++;
+            }
+        }
+        return result;
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ModuleSourceTest.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/test/ModuleSourceTest.java
new file mode 100644 (file)
index 0000000..b18a258
--- /dev/null
@@ -0,0 +1,57 @@
+package org.opendaylight.yangtools.yang.stmt.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+
+import java.io.FileReader;
+import java.io.BufferedReader;
+import java.io.File;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import java.net.URISyntaxException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+import org.junit.Test;
+
+public class ModuleSourceTest {
+
+    @Test
+    public void test() throws SourceException, ReactorException, URISyntaxException, IOException {
+        SchemaContext schema = StmtTestUtils.parseYangSources("/module-source");
+
+        assertNotNull(schema);
+
+        Set<Module> modules = schema.getModules();
+        assertNotNull(modules);
+        assertEquals(1,modules.size());
+
+        Module simpleModule = modules.iterator().next();
+        String source = simpleModule.getSource();
+        String moduleSourcePath = simpleModule.getModuleSourcePath();
+
+        File simpleYang = new File(getClass().getResource("/module-source/simple-module.yang").toURI());
+
+        assertEquals(simpleYang.getPath(), moduleSourcePath);
+        assertEquals(readFile(moduleSourcePath), source);
+    }
+
+    private String readFile(String fileName) throws IOException {
+        BufferedReader br = new BufferedReader(new FileReader(fileName));
+        try {
+            StringBuilder sb = new StringBuilder();
+            String line = br.readLine();
+
+            while (line != null) {
+                sb.append(line);
+                sb.append(System.lineSeparator());
+                line = br.readLine();
+            }
+            return sb.toString();
+        } finally {
+            br.close();
+        }
+    }
+}
index b46e65ebbfa790845239dac378d4264c8c936aac..0fbec5b9fc6ef2f9eb1a67ff2c380c949ef90650 100644 (file)
@@ -10,10 +10,19 @@ package org.opendaylight.yangtools.yang.stmt.test;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
+import org.opendaylight.yangtools.yang.model.api.ModuleImport;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import java.text.ParseException;
+import java.util.Date;
+import org.opendaylight.yangtools.yang.common.QName;
+import java.net.URI;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
 import java.io.FileNotFoundException;
 import java.net.URISyntaxException;
-
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import java.util.Set;
 import org.junit.Test;
@@ -125,11 +134,250 @@ public class MoreRevisionsTest {
     @Test
     public void multipleRevisionsTest() throws SourceException,
             ReactorException, FileNotFoundException, URISyntaxException {
-        for (int i = 0; i < 25; i++) {
+        for (int i = 0; i < 100; i++) {
             SchemaContext context = StmtTestUtils
                     .parseYangSources("/semantic-statement-parser/multiple-revisions");
             assertNotNull(context);
         }
     }
 
+    @Test
+    public void multipleRevisionsFullTest() throws SourceException,
+            ReactorException, FileNotFoundException, URISyntaxException,
+            ParseException {
+        for (int i = 0; i < 100; i++) {
+            SchemaContext context = StmtTestUtils
+                    .parseYangSources("/semantic-statement-parser/multiple-revisions/full");
+            assertNotNull(context);
+            assertEquals(6, context.getModules().size());
+            checkContentFullTest(context);
+        }
+    }
+
+    private void checkContentFullTest(SchemaContext context) throws ParseException,
+            URISyntaxException {
+
+        String yangTypesNSStr = "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+        URI yangTypesNS = new URI(yangTypesNSStr);
+
+        Date rev20100924 = SimpleDateFormatUtil.getRevisionFormat().parse(
+                "2010-09-24");
+        Date rev20130516 = SimpleDateFormatUtil.getRevisionFormat().parse(
+                "2013-05-16");
+        Date rev20130715 = SimpleDateFormatUtil.getRevisionFormat().parse(
+                "2013-07-15");
+
+        final QNameModule yangTypes_20100924 = QNameModule.create(yangTypesNS,
+                rev20100924);
+        final QNameModule yangTypes_20130516 = QNameModule.create(yangTypesNS,
+                rev20130516);
+        final QNameModule yangTypes_20130715 = QNameModule.create(yangTypesNS,
+                rev20130715);
+
+        final QName dateTimeTypeDef_20100924 = QName.create(yangTypes_20100924,
+                "date-and-time");
+        final QName dateTimeTypeDef_20130516 = QName.create(yangTypes_20130516,
+                "date-and-time");
+        final QName dateTimeTypeDef_20130715 = QName.create(yangTypes_20130715,
+                "date-and-time");
+
+        Module yangTypesModule_20100924 = context.findModuleByName(
+                "ietf-yang-types", rev20100924);
+        Module yangTypesModule_20130516 = context.findModuleByName(
+                "ietf-yang-types", rev20130516);
+        Module yangTypesModule_20130715 = context.findModuleByName(
+                "ietf-yang-types", rev20130715);
+
+        assertNotNull(yangTypesModule_20100924);
+        assertNotNull(yangTypesModule_20130516);
+        assertNotNull(yangTypesModule_20130715);
+
+        assertTrue(findTypeDef(yangTypesModule_20100924,
+                dateTimeTypeDef_20100924));
+        assertTrue(findTypeDef(yangTypesModule_20130516,
+                dateTimeTypeDef_20130516));
+        assertTrue(findTypeDef(yangTypesModule_20130715,
+                dateTimeTypeDef_20130715));
+
+        checkNetconfMonitoringModuleFullTest(context, rev20130715,
+                dateTimeTypeDef_20130715);
+
+        checkInterfacesModuleFullTest(context, rev20100924, dateTimeTypeDef_20100924);
+
+    }
+
+    private void checkInterfacesModuleFullTest(SchemaContext context, Date rev20100924,
+            final QName dateTimeTypeDef_20100924) throws URISyntaxException,
+            ParseException {
+        Date rev20121115 = SimpleDateFormatUtil.getRevisionFormat().parse(
+                "2012-11-15");
+
+        Module interfacesModule_20121115 = context.findModuleByName(
+                "ietf-interfaces", rev20121115);
+        assertNotNull(interfacesModule_20121115);
+
+        Set<ModuleImport> imports = interfacesModule_20121115.getImports();
+        assertEquals(1, imports.size());
+        ModuleImport interfacesImport = imports.iterator().next();
+        assertEquals("ietf-yang-types", interfacesImport.getModuleName());
+        assertEquals(rev20100924, interfacesImport.getRevision());
+    }
+
+    private void checkNetconfMonitoringModuleFullTest(SchemaContext context,
+            Date rev20130715, final QName dateTimeTypeDef_20130715)
+            throws ParseException, URISyntaxException {
+        Date rev20101004 = SimpleDateFormatUtil.getRevisionFormat().parse(
+                "2010-10-04");
+
+        Module monitoringModule_20101004 = context.findModuleByName(
+                "ietf-netconf-monitoring", rev20101004);
+        assertNotNull(monitoringModule_20101004);
+
+        Set<ModuleImport> imports = monitoringModule_20101004.getImports();
+        assertEquals(2, imports.size());
+        for (ModuleImport monitoringImport : imports) {
+            if (monitoringImport.getModuleName().equals("ietf-yang-types")) {
+                assertEquals(rev20130715, monitoringImport.getRevision());
+            }
+        }
+    }
+
+    @Test
+    public void multipleRevisionsSimpleTest() throws SourceException,
+            ReactorException, FileNotFoundException, URISyntaxException,
+            ParseException {
+        for (int i = 0; i < 1000; i++) {
+            SchemaContext context = StmtTestUtils
+                    .parseYangSources("/semantic-statement-parser/multiple-revisions/simple");
+            assertNotNull(context);
+            assertEquals(5, context.getModules().size());
+            checkContentSimpleTest(context);
+        }
+    }
+
+    private void checkContentSimpleTest(SchemaContext context)
+            throws ParseException, URISyntaxException {
+
+        String yangTypesNSStr = "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+        URI yangTypesNS = new URI(yangTypesNSStr);
+
+        Date rev20100924 = SimpleDateFormatUtil.getRevisionFormat().parse(
+                "2010-09-24");
+        Date rev20130516 = SimpleDateFormatUtil.getRevisionFormat().parse(
+                "2013-05-16");
+        Date rev20130715 = SimpleDateFormatUtil.getRevisionFormat().parse(
+                "2013-07-15");
+
+        final QNameModule yangTypes_20100924 = QNameModule.create(yangTypesNS,
+                rev20100924);
+        final QNameModule yangTypes_20130516 = QNameModule.create(yangTypesNS,
+                rev20130516);
+        final QNameModule yangTypes_20130715 = QNameModule.create(yangTypesNS,
+                rev20130715);
+
+        final QName dateTimeTypeDef_20100924 = QName.create(yangTypes_20100924,
+                "date-and-time");
+        final QName dateTimeTypeDef_20130516 = QName.create(yangTypes_20130516,
+                "date-and-time");
+        final QName dateTimeTypeDef_20130715 = QName.create(yangTypes_20130715,
+                "date-and-time");
+
+        Module yangTypesModule_20100924 = context.findModuleByName(
+                "ietf-yang-types", rev20100924);
+        Module yangTypesModule_20130516 = context.findModuleByName(
+                "ietf-yang-types", rev20130516);
+        Module yangTypesModule_20130715 = context.findModuleByName(
+                "ietf-yang-types", rev20130715);
+
+        assertNotNull(yangTypesModule_20100924);
+        assertNotNull(yangTypesModule_20130516);
+        assertNotNull(yangTypesModule_20130715);
+
+        assertTrue(findTypeDef(yangTypesModule_20100924,
+                dateTimeTypeDef_20100924));
+        assertTrue(findTypeDef(yangTypesModule_20130516,
+                dateTimeTypeDef_20130516));
+        assertTrue(findTypeDef(yangTypesModule_20130715,
+                dateTimeTypeDef_20130715));
+
+        checkNetconfMonitoringModuleSimpleTest(context, rev20130715,
+                dateTimeTypeDef_20130715);
+
+        checkInterfacesModuleSimpleTest(context, rev20100924,
+                dateTimeTypeDef_20100924);
+
+    }
+
+    private void checkInterfacesModuleSimpleTest(SchemaContext context,
+            Date rev20100924, final QName dateTimeTypeDef_20100924)
+            throws URISyntaxException, ParseException {
+        String interfacesNSStr = "urn:ietf:params:xml:ns:yang:ietf-interfaces";
+        URI interfacesNS = new URI(interfacesNSStr);
+        Date rev20121115 = SimpleDateFormatUtil.getRevisionFormat().parse(
+                "2012-11-15");
+        final QNameModule interfacesNS_20121115 = QNameModule.create(
+                interfacesNS, rev20121115);
+        QName lastChange = QName.create(interfacesNS_20121115, "last-change");
+
+        Module interfacesModule_20121115 = context.findModuleByName(
+                "ietf-interfaces", rev20121115);
+        assertNotNull(interfacesModule_20121115);
+
+        DataSchemaNode leafLastChange = interfacesModule_20121115
+                .getDataChildByName(lastChange);
+        assertNotNull(leafLastChange);
+
+        assertTrue(leafLastChange instanceof LeafSchemaNode);
+        QName lastChangeTypeQName = ((LeafSchemaNode) leafLastChange).getType()
+                .getQName();
+        assertEquals(dateTimeTypeDef_20100924, lastChangeTypeQName);
+
+        Set<ModuleImport> imports = interfacesModule_20121115.getImports();
+        assertEquals(1, imports.size());
+        ModuleImport interfacesImport = imports.iterator().next();
+        assertEquals("ietf-yang-types", interfacesImport.getModuleName());
+        assertEquals(rev20100924, interfacesImport.getRevision());
+    }
+
+    private void checkNetconfMonitoringModuleSimpleTest(SchemaContext context,
+            Date rev20130715, final QName dateTimeTypeDef_20130715)
+            throws ParseException, URISyntaxException {
+        String monitoringNSStr = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring";
+        URI monitoringNS = new URI(monitoringNSStr);
+
+        Date rev19700101 = SimpleDateFormatUtil.getRevisionFormat().parse(
+                "1970-01-01");
+        final QNameModule monitoring_19700101 = QNameModule.create(
+                monitoringNS, rev19700101);
+        QName lockedTime = QName.create(monitoring_19700101, "locked-time");
+
+        Module monitoringModule_19700101 = context.findModuleByName(
+                "ietf-netconf-monitoring", rev19700101);
+        assertNotNull(monitoringModule_19700101);
+
+        DataSchemaNode leafLockedTime = monitoringModule_19700101
+                .getDataChildByName(lockedTime);
+        assertNotNull(leafLockedTime);
+
+        assertTrue(leafLockedTime instanceof LeafSchemaNode);
+        QName lockedTimeTypeQName = ((LeafSchemaNode) leafLockedTime).getType()
+                .getQName();
+        assertEquals(dateTimeTypeDef_20130715, lockedTimeTypeQName);
+
+        Set<ModuleImport> imports = monitoringModule_19700101.getImports();
+        assertEquals(1, imports.size());
+        ModuleImport monitoringImport = imports.iterator().next();
+        assertEquals("ietf-yang-types", monitoringImport.getModuleName());
+        assertEquals(rev20130715, monitoringImport.getRevision());
+    }
+
+    private boolean findTypeDef(Module module, QName typedef) {
+        Set<TypeDefinition<?>> typeDefinitions = module.getTypeDefinitions();
+        for (TypeDefinition<?> typeDefinition : typeDefinitions) {
+            if (typeDefinition.getQName().equals(typedef)) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
index 9cbe4d4dbc89b32ec107add21d821eb6a6e436e4..e264b192082115733b9774735be8ccab3becebc0 100644 (file)
@@ -8,11 +8,12 @@
 
 package org.opendaylight.yangtools.yang.stmt.test;
 
-import java.net.URISyntaxException;
+import java.io.FileFilter;
 
+import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
@@ -33,6 +34,14 @@ import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceIm
 
 public class StmtTestUtils {
 
+    final public static FileFilter YANG_FILE_FILTER = new FileFilter() {
+        @Override
+        public boolean accept(File file) {
+            String name = file.getName().toLowerCase();
+            return name.endsWith(".yang") && file.isFile();
+        }
+    };
+
     private static final Logger LOG = LoggerFactory
             .getLogger(StmtTestUtils.class);
 
@@ -108,8 +117,7 @@ public class StmtTestUtils {
         StatementStreamSource[] sources = new StatementStreamSource[files.length];
 
         for (int i = 0; i < files.length; i++) {
-            sources[i] = new YangStatementSourceImpl(new FileInputStream(
-                    files[i]));
+            sources[i] = new YangStatementSourceImpl(new NamedFileInputStream(files[i], files[i].getPath()));
         }
 
         return parseYangSources(sources);
@@ -126,6 +134,6 @@ public class StmtTestUtils {
         URL resourceDir = StmtTestUtils.class.getResource(yangSourcesDirectoryPath);
         File testSourcesDir = new File(resourceDir.toURI());
 
-        return parseYangSources(testSourcesDir.listFiles());
+        return parseYangSources(testSourcesDir.listFiles(YANG_FILE_FILTER));
     }
 }
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug3799/test_module.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug3799/test_module.yang
new file mode 100644 (file)
index 0000000..f0b30e3
--- /dev/null
@@ -0,0 +1,25 @@
+module test_module {\r
+\r
+    namespace "http://www.example.com/test";\r
+    prefix "test";\r
+\r
+    include "test_submodule";\r
+\r
+    organization "some organisation";\r
+\r
+    description\r
+        "Testing including a submodule with a different revision number";\r
+\r
+    revision 2014-06-15 {\r
+        description "some more changes";\r
+    }\r
+    revision 2013-06-15 {\r
+        description "some changes";\r
+    }\r
+\r
+    container some_container {\r
+\r
+        description\r
+                "some container";\r
+    }\r
+}\r
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug3799/test_submodule.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug3799/test_submodule.yang
new file mode 100644 (file)
index 0000000..346f139
--- /dev/null
@@ -0,0 +1,25 @@
+submodule test_submodule {\r
+\r
+    belongs-to "test_module" {\r
+        prefix "sub";\r
+    }\r
+\r
+    organization "some organisation";\r
+\r
+    revision 2015-05-05 {\r
+        description\r
+                "submodule for testing with grouping";\r
+    }\r
+\r
+    grouping foo {\r
+        leaf bar {\r
+            description "some description";\r
+            type uint64;\r
+        }\r
+    }\r
+\r
+    notification baz {\r
+        description "container using grouping";\r
+        uses foo;\r
+    }\r
+}\r
diff --git a/yang/yang-parser-impl/src/test/resources/mapped-build/bar.yang b/yang/yang-parser-impl/src/test/resources/mapped-build/bar.yang
new file mode 100644 (file)
index 0000000..f97ebda
--- /dev/null
@@ -0,0 +1,10 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    include sub-bar { revision-date 2015-03-01; }
+    
+    revision "2015-01-01" {
+        description "Initial version";
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/mapped-build/foo.yang b/yang/yang-parser-impl/src/test/resources/mapped-build/foo.yang
new file mode 100644 (file)
index 0000000..0ce3675
--- /dev/null
@@ -0,0 +1,10 @@
+module foo {
+    namespace foo;
+    prefix foo;
+
+    include sub-foo { revision-date 2015-02-01; }
+    
+    revision "2015-01-02" {
+        description "Initial version";
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/mapped-build/sub-bar.yang b/yang/yang-parser-impl/src/test/resources/mapped-build/sub-bar.yang
new file mode 100644 (file)
index 0000000..761d30f
--- /dev/null
@@ -0,0 +1,9 @@
+submodule sub-bar {
+    belongs-to bar {
+        prefix bar-m;
+    }
+    
+    revision "2015-03-01" {
+        description "Initial version";
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/mapped-build/sub-foo.yang b/yang/yang-parser-impl/src/test/resources/mapped-build/sub-foo.yang
new file mode 100644 (file)
index 0000000..cf0d31c
--- /dev/null
@@ -0,0 +1,9 @@
+submodule sub-foo {
+    belongs-to foo {
+        prefix foo-m;
+    }
+    
+    revision "2015-02-01" {
+        description "Initial version";
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/module-source/simple-module.yang b/yang/yang-parser-impl/src/test/resources/module-source/simple-module.yang
new file mode 100644 (file)
index 0000000..6aea830
--- /dev/null
@@ -0,0 +1,4 @@
+module simple-module {
+    namespace "test";
+    prefix test;
+}
diff --git a/yang/yang-parser-impl/src/test/resources/sal-broker-impl/config.yang b/yang/yang-parser-impl/src/test/resources/sal-broker-impl/config.yang
new file mode 100644 (file)
index 0000000..c0afa1b
--- /dev/null
@@ -0,0 +1,179 @@
+module config {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:config";
+    prefix "config";
+
+    description
+        "This module contains the base YANG definitions for NS-OS configuration
+        subsystem. The system modeled revolves around two major concepts:
+        modules and services.";
+
+    revision "2013-04-05" {
+        description
+                "Reworked to give modules their own space.";
+    }
+
+    revision "2013-04-03" {
+        description
+                "Initial revision.";
+    }
+
+    extension java-class {
+        description
+                "YANG language extension carrying the fully-qualified name of
+                a Java class. Code generation tools use the provided reference
+                to tie a specific construct to its Java representation.";
+
+        argument "name";
+    }
+
+    extension required-identity {
+        description
+                "YANG language extension which indicates that a particular leafref,
+                which points to a identityref, should additionally require the
+                target node is actually set to a descendant to of a particular
+                identity. This is a workaround to two YANG deficiencies: 1) not
+                being able to leafref instances of identityref 2) not being able
+                to refine an identityref This extension takes one argument, name,
+                which MUST be the name of an identity. Furthermore, that identity
+                MUST be based, directly or indirectly, on the identity, which
+                is referenced by the leaf reference, which is annotated with this
+                extension.";
+
+        argument "name";
+    }
+
+    extension inner-state-bean {
+        description
+                "YANG language extension which indicates that a particular list
+                located under module's state should be treated as a list of child
+                state beans instead of just an ordinary list attribute";
+    }
+
+    extension provided-service {
+        description
+                "YANG language extension which indicates that a particular module
+                provides certain service. This extension can be placed on identities
+                that are based on module-type. Zero or more services can be provided.
+                This extension takes one argument - name - which MUST be the name
+                of an identity. Furthermore, this identity MUST be based on service-type.";
+
+        argument "name";
+    }
+
+    extension java-name-prefix {
+        description
+                "YANG language extension carrying java simple class name prefix
+                that will be taken into account when generating java code from
+                identities that are based on module-type.";
+        argument "java-prefix";
+    }
+
+    identity module-type {
+        description
+                "Module identity base type. All module identities must be derived
+                from this type. A module type uniquely defines a single atomic
+                component, such as an application. Each such component is assumed
+                to have its unique, stable and versioned configuration structure.";
+    }
+
+    identity service-type {
+        description
+                "Service identity base type. All service identities must be derived
+                from this type. A service type uniquely defines a single atomic
+                API contract, such as a Java interface, a set of C function declarations,
+                or similar. If the service type has a corresponding Java interface,
+                the name of that interface should be attached to the derived identity
+                MUST include a java-class keyword, whose name argument points
+                to that interface.";
+    }
+
+    typedef service-type-ref {
+        description
+                "Internal type of references to service type identity.";
+
+        type identityref {
+            base service-type;
+        }
+    }
+
+    grouping service-ref {
+        description
+                "Type of references to a particular service instance. This type
+                can be used when defining module configuration to refer to a particular
+                service instance. Containers using this grouping should not define
+                anything else. The run-time implementation is expected to inject
+                a reference to the service as the value of the container.";
+
+        leaf type {
+            description
+                        "Type of the service being referenced. Users of this grouping
+                        should refine this leaf with required-identity pointing to the
+                        actual service-type which is actually required.";
+
+            mandatory true;
+            type leafref {
+                path "/config:services/config:service/config:type";
+            }
+        }
+
+        leaf name {
+            mandatory true;
+            type leafref {
+                path "/config:services/config:service[config:type=current()/../type]/config:instance/config:name";
+            }
+        }
+    }
+
+    container modules {
+        description
+                "Top level container encapsulating configuration of all modules.";
+
+        list module {
+            key "type name";
+            leaf name {
+                description "Unique module instance name";
+                type string;
+                mandatory true;
+            }
+
+            leaf type {
+                type identityref {
+                    base module-type;
+                }
+                mandatory true;
+            }
+
+            choice configuration {
+                mandatory true;
+                config true;
+            }
+
+            choice state {
+                config false;
+            }
+        }
+    }
+
+    container services {
+        list service {
+            key "type";
+            leaf type {
+                type service-type-ref;
+            }
+            list instance {
+                key "name";
+                leaf name {
+                    type string;
+                }
+
+                leaf provider {
+                    mandatory true;
+                    type leafref {
+                        path "/modules/module/name";
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/sal-broker-impl/ietf-yang-types.yang b/yang/yang-parser-impl/src/test/resources/sal-broker-impl/ietf-yang-types.yang
new file mode 100644 (file)
index 0000000..51d9f8b
--- /dev/null
@@ -0,0 +1,396 @@
+ module ietf-yang-types {
+
+   namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+   prefix "yang";
+
+   organization
+    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+   contact
+    "WG Web:   <http://tools.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     WG Chair: David Partain
+               <mailto:david.partain@ericsson.com>
+
+     WG Chair: David Kessens
+               <mailto:david.kessens@nsn.com>
+
+     Editor:   Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>";
+
+   description
+    "This module contains a collection of generally useful derived
+     YANG data types.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or without
+     modification, is permitted pursuant to, and subject to the license
+     terms contained in, the Simplified BSD License set forth in Section
+     4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6021; see
+     the RFC itself for full legal notices.";
+
+   revision 2010-09-24 {
+     description
+      "Initial revision.";
+     reference
+      "RFC 6021: Common YANG Data Types";
+   }
+
+   /*** collection of counter and gauge types ***/
+
+   typedef counter32 {
+     type uint32;
+     description
+      "The counter32 type represents a non-negative integer
+       that monotonically increases until it reaches a
+       maximum value of 2^32-1 (4294967295 decimal), when it
+       wraps around and starts increasing again from zero.
+
+       Counters have no defined 'initial' value, and thus, a
+       single value of a counter has (in general) no information
+       content.  Discontinuities in the monotonically increasing
+       value normally occur at re-initialization of the
+       management system, and at other times as specified in the
+       description of a schema node using this type.  If such
+       other times can occur, for example, the creation of
+       a schema node of type counter32 at times other than
+       re-initialization, then a corresponding schema node
+       should be defined, with an appropriate type, to indicate
+       the last discontinuity.
+
+       The counter32 type should not be used for configuration
+       schema nodes.  A default statement SHOULD NOT be used in
+       combination with the type counter32.
+
+       In the value set and its semantics, this type is equivalent
+       to the Counter32 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef zero-based-counter32 {
+     type yang:counter32;
+     default "0";
+     description
+      "The zero-based-counter32 type represents a counter32
+       that has the defined 'initial' value zero.
+
+       A schema node of this type will be set to zero (0) on creation
+       and will thereafter increase monotonically until it reaches
+       a maximum value of 2^32-1 (4294967295 decimal), when it
+       wraps around and starts increasing again from zero.
+
+       Provided that an application discovers a new schema node
+       of this type within the minimum time to wrap, it can use the
+       'initial' value as a delta.  It is important for a management
+       station to be aware of this minimum time and the actual time
+       between polls, and to discard data if the actual time is too
+       long or there is no defined minimum time.
+
+       In the value set and its semantics, this type is equivalent
+       to the ZeroBasedCounter32 textual convention of the SMIv2.";
+     reference
+       "RFC 4502: Remote Network Monitoring Management Information
+                  Base Version 2";
+   }
+
+   typedef counter64 {
+     type uint64;
+     description
+      "The counter64 type represents a non-negative integer
+       that monotonically increases until it reaches a
+       maximum value of 2^64-1 (18446744073709551615 decimal),
+       when it wraps around and starts increasing again from zero.
+
+       Counters have no defined 'initial' value, and thus, a
+       single value of a counter has (in general) no information
+       content.  Discontinuities in the monotonically increasing
+       value normally occur at re-initialization of the
+       management system, and at other times as specified in the
+       description of a schema node using this type.  If such
+       other times can occur, for example, the creation of
+       a schema node of type counter64 at times other than
+       re-initialization, then a corresponding schema node
+       should be defined, with an appropriate type, to indicate
+       the last discontinuity.
+
+       The counter64 type should not be used for configuration
+       schema nodes.  A default statement SHOULD NOT be used in
+       combination with the type counter64.
+
+       In the value set and its semantics, this type is equivalent
+       to the Counter64 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef zero-based-counter64 {
+     type yang:counter64;
+     default "0";
+     description
+      "The zero-based-counter64 type represents a counter64 that
+       has the defined 'initial' value zero.
+
+       A schema node of this type will be set to zero (0) on creation
+       and will thereafter increase monotonically until it reaches
+       a maximum value of 2^64-1 (18446744073709551615 decimal),
+       when it wraps around and starts increasing again from zero.
+
+       Provided that an application discovers a new schema node
+       of this type within the minimum time to wrap, it can use the
+       'initial' value as a delta.  It is important for a management
+       station to be aware of this minimum time and the actual time
+       between polls, and to discard data if the actual time is too
+       long or there is no defined minimum time.
+
+       In the value set and its semantics, this type is equivalent
+       to the ZeroBasedCounter64 textual convention of the SMIv2.";
+     reference
+      "RFC 2856: Textual Conventions for Additional High Capacity
+                 Data Types";
+   }
+
+   typedef gauge32 {
+     type uint32;
+     description
+      "The gauge32 type represents a non-negative integer, which
+       may increase or decrease, but shall never exceed a maximum
+       value, nor fall below a minimum value.  The maximum value
+       cannot be greater than 2^32-1 (4294967295 decimal), and
+       the minimum value cannot be smaller than 0.  The value of
+       a gauge32 has its maximum value whenever the information
+       being modeled is greater than or equal to its maximum
+       value, and has its minimum value whenever the information
+       being modeled is smaller than or equal to its minimum value.
+       If the information being modeled subsequently decreases
+       below (increases above) the maximum (minimum) value, the
+       gauge32 also decreases (increases).
+
+       In the value set and its semantics, this type is equivalent
+       to the Gauge32 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef gauge64 {
+     type uint64;
+     description
+      "The gauge64 type represents a non-negative integer, which
+       may increase or decrease, but shall never exceed a maximum
+       value, nor fall below a minimum value.  The maximum value
+       cannot be greater than 2^64-1 (18446744073709551615), and
+       the minimum value cannot be smaller than 0.  The value of
+       a gauge64 has its maximum value whenever the information
+       being modeled is greater than or equal to its maximum
+       value, and has its minimum value whenever the information
+       being modeled is smaller than or equal to its minimum value.
+       If the information being modeled subsequently decreases
+       below (increases above) the maximum (minimum) value, the
+       gauge64 also decreases (increases).
+
+       In the value set and its semantics, this type is equivalent
+       to the CounterBasedGauge64 SMIv2 textual convention defined
+       in RFC 2856";
+     reference
+      "RFC 2856: Textual Conventions for Additional High Capacity
+                 Data Types";
+   }
+
+   /*** collection of identifier related types ***/
+
+   typedef object-identifier {
+     type string {
+       pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))'
+             + '(\.(0|([1-9]\d*)))*';
+     }
+     description
+      "The object-identifier type represents administratively
+       assigned names in a registration-hierarchical-name tree.
+
+       Values of this type are denoted as a sequence of numerical
+       non-negative sub-identifier values.  Each sub-identifier
+       value MUST NOT exceed 2^32-1 (4294967295).  Sub-identifiers
+       are separated by single dots and without any intermediate
+       whitespace.
+
+       The ASN.1 standard restricts the value space of the first
+       sub-identifier to 0, 1, or 2.  Furthermore, the value space
+       of the second sub-identifier is restricted to the range
+       0 to 39 if the first sub-identifier is 0 or 1.  Finally,
+       the ASN.1 standard requires that an object identifier
+       has always at least two sub-identifier.  The pattern
+       captures these restrictions.
+
+       Although the number of sub-identifiers is not limited,
+       module designers should realize that there may be
+       implementations that stick with the SMIv2 limit of 128
+       sub-identifiers.
+
+       This type is a superset of the SMIv2 OBJECT IDENTIFIER type
+       since it is not restricted to 128 sub-identifiers.  Hence,
+       this type SHOULD NOT be used to represent the SMIv2 OBJECT
+       IDENTIFIER type, the object-identifier-128 type SHOULD be
+       used instead.";
+     reference
+      "ISO9834-1: Information technology -- Open Systems
+       Interconnection -- Procedures for the operation of OSI
+       Registration Authorities: General procedures and top
+       arcs of the ASN.1 Object Identifier tree";
+   }
+
+
+
+
+   typedef object-identifier-128 {
+     type object-identifier {
+       pattern '\d*(\.\d*){1,127}';
+     }
+     description
+      "This type represents object-identifiers restricted to 128
+       sub-identifiers.
+
+       In the value set and its semantics, this type is equivalent
+       to the OBJECT IDENTIFIER type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   /*** collection of date and time related types ***/
+
+   typedef date-and-time {
+     type string {
+       pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+             + '(Z|[\+\-]\d{2}:\d{2})';
+     }
+     description
+      "The date-and-time type is a profile of the ISO 8601
+       standard for representation of dates and times using the
+       Gregorian calendar.  The profile is defined by the
+       date-time production in Section 5.6 of RFC 3339.
+
+       The date-and-time type is compatible with the dateTime XML
+       schema type with the following notable exceptions:
+
+       (a) The date-and-time type does not allow negative years.
+
+       (b) The date-and-time time-offset -00:00 indicates an unknown
+           time zone (see RFC 3339) while -00:00 and +00:00 and Z all
+           represent the same time zone in dateTime.
+
+       (c) The canonical format (see below) of data-and-time values
+           differs from the canonical format used by the dateTime XML
+           schema type, which requires all times to be in UTC using the
+           time-offset 'Z'.
+
+       This type is not equivalent to the DateAndTime textual
+       convention of the SMIv2 since RFC 3339 uses a different
+       separator between full-date and full-time and provides
+       higher resolution of time-secfrac.
+
+       The canonical format for date-and-time values with a known time
+       zone uses a numeric time zone offset that is calculated using
+       the device's configured known offset to UTC time.  A change of
+       the device's offset to UTC time will cause date-and-time values
+       to change accordingly.  Such changes might happen periodically
+       in case a server follows automatically daylight saving time
+       (DST) time zone offset changes.  The canonical format for
+       date-and-time values with an unknown time zone (usually referring
+       to the notion of local time) uses the time-offset -00:00.";
+     reference
+      "RFC 3339: Date and Time on the Internet: Timestamps
+       RFC 2579: Textual Conventions for SMIv2
+       XSD-TYPES: XML Schema Part 2: Datatypes Second Edition";
+   }
+
+   typedef timeticks {
+     type uint32;
+     description
+      "The timeticks type represents a non-negative integer that
+       represents the time, modulo 2^32 (4294967296 decimal), in
+       hundredths of a second between two epochs.  When a schema
+       node is defined that uses this type, the description of
+       the schema node identifies both of the reference epochs.
+
+       In the value set and its semantics, this type is equivalent
+       to the TimeTicks type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef timestamp {
+     type yang:timeticks;
+     description
+      "The timestamp type represents the value of an associated
+       timeticks schema node at which a specific occurrence happened.
+       The specific occurrence must be defined in the description
+       of any schema node defined using this type.  When the specific
+       occurrence occurred prior to the last time the associated
+       timeticks attribute was zero, then the timestamp value is
+       zero.  Note that this requires all timestamp values to be
+       reset to zero when the value of the associated timeticks
+       attribute reaches 497+ days and wraps around to zero.
+
+       The associated timeticks schema node must be specified
+       in the description of any schema node using this type.
+
+       In the value set and its semantics, this type is equivalent
+       to the TimeStamp textual convention of the SMIv2.";
+     reference
+      "RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   /*** collection of generic address types ***/
+
+   typedef phys-address {
+     type string {
+       pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+     }
+     description
+      "Represents media- or physical-level addresses represented
+       as a sequence octets, each octet represented by two hexadecimal
+       numbers.  Octets are separated by colons.  The canonical
+       representation uses lowercase characters.
+
+       In the value set and its semantics, this type is equivalent
+       to the PhysAddress textual convention of the SMIv2.";
+     reference
+      "RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   typedef mac-address {
+     type string {
+       pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}';
+     }
+     description
+      "The mac-address type represents an IEEE 802 MAC address.
+       The canonical representation uses lowercase characters.
+
+       In the value set and its semantics, this type is equivalent
+       to the MacAddress textual convention of the SMIv2.";
+     reference
+      "IEEE 802: IEEE Standard for Local and Metropolitan Area
+                 Networks: Overview and Architecture
+       RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   /*** collection of XML specific types ***/
+
+   typedef xpath1.0 {
+     type string;
+     description
+      "This type represents an XPATH 1.0 expression.
+
+       When a schema node is defined that uses this type, the
+       description of the schema node MUST specify the XPath
+       context in which the XPath expression is evaluated.";
+     reference
+      "XPATH: XML Path Language (XPath) Version 1.0";
+   }
+
+ }
diff --git a/yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-config-dom-datastore.yang b/yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-config-dom-datastore.yang
new file mode 100644 (file)
index 0000000..470d02d
--- /dev/null
@@ -0,0 +1,21 @@
+module opendaylight-config-dom-datastore {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:config-dom-store";
+    prefix "config-dom-store-spi";
+
+    import config { prefix config; revision-date 2013-04-05; }
+
+    description
+        "DOM Service Provider Interface definition for MD-SAL config store";
+
+    revision "2014-06-17" {
+        description
+                "Initial revision";
+    }
+
+    identity config-dom-datastore {
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.sal.core.spi.data.DOMStore";
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-dom-broker-impl.yang b/yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-dom-broker-impl.yang
new file mode 100644 (file)
index 0000000..944a63d
--- /dev/null
@@ -0,0 +1,218 @@
+module opendaylight-sal-dom-broker-impl {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:impl";
+    prefix "broker";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import ietf-yang-types { prefix yang; }
+    import opendaylight-md-sal-dom { prefix sal; }
+    import opendaylight-md-sal-common { prefix common; }
+    import opendaylight-config-dom-datastore { prefix config-dom-store-spi; }
+    import opendaylight-operational-dom-datastore { prefix operational-dom-store-spi; }
+    import rpc-context { prefix rpcx; revision-date 2013-06-17; }
+
+    description
+        "Service definition for Binding Aware MD-SAL. Note: The dom-inmemory-data-broker
+        utilizes configurable config-dom-datastore and operation-dom-datastore.
+        If configuration is not done for this stores then it defaults
+        to InMemoryDOMDataStore";
+
+    revision "2013-10-28" {
+        description
+                "Initial revision";
+    }
+
+    identity dom-broker-impl {
+        base config:module-type;
+        config:provided-service sal:dom-broker-osgi-registry;
+        config:java-name-prefix DomBrokerImpl;
+    }
+
+    identity dom-inmemory-data-broker {
+        base config:module-type;
+        config:provided-service sal:dom-async-data-broker;
+    }
+
+    identity schema-service-singleton {
+        base config:module-type;
+        config:provided-service sal:schema-service;
+        config:java-name-prefix SchemaServiceImplSingleton;
+    }
+
+    typedef max-queue-depth {
+        type uint32 {
+            range 1..1073741824;
+        }
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case dom-broker-impl {
+            when "/config:modules/config:module/config:type = 'dom-broker-impl'";
+
+            container async-data-broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory false;
+                        config:required-identity sal:dom-async-data-broker;
+                    }
+                }
+            }
+
+            container root-schema-service {
+                uses config:service-ref {
+                    refine type {
+                        mandatory false;
+                        config:required-identity sal:schema-service;
+                    }
+                }
+            }
+
+            leaf notification-queue-depth {
+                description "Maximum number of elements in the notification queue, must be
+                                power-of-two.";
+                type max-queue-depth;
+                default 65536;
+            }
+            leaf notification-queue-spin {
+                description "Number of milliseconds notification queue should spin for new
+                                requests before parking.";
+                type uint16;
+                units milliseconds;
+                default 1;
+            }
+            leaf notification-queue-park {
+                description "Number of milliseconds notification queue should park for new
+                                requests before blocking.";
+                type uint16;
+                units milliseconds;
+                default 30;
+            }
+        }
+    }
+
+    grouping dom-broker-config {
+        container schema-service {
+            uses config:service-ref {
+                refine type {
+                    mandatory false;
+                    config:required-identity sal:schema-service;
+                }
+            }
+        }
+
+        container config-data-store {
+            uses config:service-ref {
+                refine type {
+                    mandatory false;
+                    config:required-identity config-dom-store-spi:config-dom-datastore;
+                }
+            }
+        }
+
+        container operational-data-store {
+            uses config:service-ref {
+                refine type {
+                    mandatory false;
+                    config:required-identity operational-dom-store-spi:operational-dom-datastore;
+                }
+            }
+        }
+
+        leaf max-data-broker-future-callback-queue-size {
+            default 1000;
+            type uint16;
+            description "The maximum queue size for the data broker's commit future callback
+                        executor.";
+        }
+
+        leaf max-data-broker-future-callback-pool-size {
+            default 20;
+            type uint16;
+            description "The maximum thread pool size for the data broker's commit future
+                        callback executor.";
+        }
+
+        leaf max-data-broker-commit-queue-size {
+            default 5000;
+            type uint16;
+            description "The maximum queue size for the data broker's commit executor.";
+        }
+    }
+
+    grouping dom-broker-operational {
+        leaf total-commits {
+            type uint64;
+        }
+
+        leaf average-commit {
+            type uint64;
+            units ns;
+        }
+
+        leaf longest-commit-duration {
+            type uint64;
+            units ns;
+        }
+
+        leaf longest-commit-timestamp {
+            type yang:date-and-time;
+        }
+
+        leaf shortest-commit-duration {
+            type uint64;
+            units ns;
+        }
+
+        leaf shortest-commit-timestamp {
+            type yang:date-and-time;
+        }
+
+        rpcx:rpc-context-instance dom-broker-rpc-ctx;
+    }
+
+    identity dom-broker-rpc-ctx;
+
+    rpc reset-statistics {
+        description
+                "JMX call to clear the toasts-made counter.";
+
+        input {
+            uses rpcx:rpc-context-ref {
+                refine context-instance {
+                    rpcx:rpc-context-instance dom-broker-rpc-ctx;
+                }
+            }
+        }
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case dom-inmemory-data-broker {
+            when "/config:modules/config:module/config:type = 'dom-inmemory-data-broker'";
+
+            uses dom-broker-config;
+        }
+    }
+
+    augment "/config:modules/config:module/config:state" {
+        case dom-inmemory-data-broker {
+            when "/config:modules/config:module/config:type = 'dom-inmemory-data-broker'";
+
+            uses dom-broker-operational;
+        }
+    }
+
+    augment "/config:modules/config:module/config:state" {
+        case schema-service-singleton {
+            when "/config:modules/config:module/config:type = 'schema-service-singleton'";
+        }
+    }
+
+    augment "/config:modules/config:module/config:state" {
+        case dom-broker-impl {
+            when "/config:modules/config:module/config:type = 'dom-broker-impl'";
+            container data {
+                uses common:data-state;
+            }
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-md-sal-common.yang b/yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-md-sal-common.yang
new file mode 100644 (file)
index 0000000..bdfdb50
--- /dev/null
@@ -0,0 +1,70 @@
+module opendaylight-md-sal-common {\r
+    yang-version 1;\r
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:common";\r
+    prefix "md-sal-common";\r
+\r
+    description\r
+        "Common definition for MD-SAL.";\r
+\r
+    revision "2013-10-28" {\r
+        description\r
+                "Initial revision";\r
+    }\r
+\r
+    grouping rpc-routing-table {\r
+\r
+        leaf routing-context {\r
+            type string;\r
+        }\r
+        list routes {\r
+            leaf path {\r
+                type string;\r
+            }\r
+            leaf destination {\r
+                type string;\r
+            }\r
+        }\r
+    }\r
+\r
+    grouping rpc-router {\r
+        leaf module {\r
+            type string;\r
+        }\r
+        container routing-tables {\r
+            list routing-table {\r
+                uses rpc-routing-table;\r
+            }\r
+        }\r
+    }\r
+\r
+    grouping rpc-state {\r
+        list rpc-router {\r
+            uses rpc-router;\r
+        }\r
+    }\r
+\r
+    grouping notification-state {\r
+        container notifications {\r
+            leaf published {\r
+                type uint32;\r
+            }\r
+        }\r
+    }\r
+\r
+    grouping data-state {\r
+        container transactions {\r
+            leaf created {\r
+                type uint32;\r
+            }\r
+            leaf submitted {\r
+                type uint32;\r
+            }\r
+            leaf successful {\r
+                type uint32;\r
+            }\r
+            leaf failed {\r
+                type uint32;\r
+            }\r
+        }\r
+    }\r
+}\r
diff --git a/yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-md-sal-dom.yang b/yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-md-sal-dom.yang
new file mode 100644 (file)
index 0000000..1960c1f
--- /dev/null
@@ -0,0 +1,30 @@
+module opendaylight-md-sal-dom {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom";
+    prefix "md-sal-dom";
+
+    import config { prefix config; revision-date 2013-04-05; }
+
+    description
+        "Service definition for Binding Aware MD-SAL.";
+
+    revision "2013-10-28" {
+        description
+                "Initial revision";
+    }
+
+    identity dom-broker-osgi-registry {
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.sal.core.api.Broker";
+    }
+
+    identity dom-async-data-broker {
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.md.sal.dom.api.DOMDataBroker";
+    }
+
+    identity schema-service {
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.sal.core.api.model.SchemaService";
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-operational-dom-datastore.yang b/yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-operational-dom-datastore.yang
new file mode 100644 (file)
index 0000000..90197ea
--- /dev/null
@@ -0,0 +1,22 @@
+module opendaylight-operational-dom-datastore {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:core:spi:operational-dom-store";
+    prefix "operational-dom-store-spi";
+
+    import config { prefix config; revision-date 2013-04-05; }
+
+    description
+        "DOM Service Provider Interface definition for MD-SAL operational
+        store";
+
+    revision "2014-06-17" {
+        description
+                "Initial revision";
+    }
+
+    identity operational-dom-datastore {
+        base "config:service-type";
+        config:java-class "org.opendaylight.controller.sal.core.spi.data.DOMStore";
+    }
+
+}
diff --git a/yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-pingpong-broker.yang b/yang/yang-parser-impl/src/test/resources/sal-broker-impl/opendaylight-pingpong-broker.yang
new file mode 100644 (file)
index 0000000..0ed1bbd
--- /dev/null
@@ -0,0 +1,39 @@
+module opendaylight-pingpong-broker {
+    yang-version 1;
+    namespace "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:pingpong";
+    prefix "pingpong";
+
+    import config { prefix config; revision-date 2013-04-05; }
+    import opendaylight-md-sal-dom {prefix sal;}
+    import opendaylight-md-sal-common {prefix common;}
+    import opendaylight-config-dom-datastore {prefix config-dom-store-spi;}
+    import opendaylight-operational-dom-datastore {prefix operational-dom-store-spi;}
+
+    description
+        "Service definition for Ping-Pong DOM broker";
+
+    revision "2014-11-07" {
+        description
+            "Initial revision";
+    }
+
+    identity pingpong-data-broker {
+        base config:module-type;
+        config:provided-service sal:dom-async-data-broker;
+    }
+
+    augment "/config:modules/config:module/config:configuration" {
+        case pingpong-data-broker {
+            when "/config:modules/config:module/config:type = 'pingpong-data-broker'";
+
+            container data-broker {
+                uses config:service-ref {
+                    refine type {
+                        mandatory true;
+                        config:required-identity sal:dom-async-data-broker;
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/sal-broker-impl/rpc-context.yang b/yang/yang-parser-impl/src/test/resources/sal-broker-impl/rpc-context.yang
new file mode 100644 (file)
index 0000000..5c8b113
--- /dev/null
@@ -0,0 +1,32 @@
+module rpc-context {
+    yang-version 1;
+    namespace "urn:ietf:params:xml:ns:yang:rpc-context";
+    prefix "rpcx";
+
+    organization "TBD";
+
+    contact "TBD";
+
+    description "";
+
+    revision 2013-06-17 {
+        description "Initial mock";
+    }
+
+
+    grouping rpc-context-ref {
+        description "A reference to RPC context.";
+        leaf context-instance {
+            type instance-identifier;
+            description "Pointer to the context. ";
+        }
+    }
+
+    extension "rpc-context-instance" {
+        description
+            "Marks enclosing (parent) schema node as suitable RPC context.
+             The argument is identity which is used to identify RPC context
+             type.";
+        argument "context-type";
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-inet-types.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-inet-types.yang
new file mode 100644 (file)
index 0000000..de20feb
--- /dev/null
@@ -0,0 +1,418 @@
+ module ietf-inet-types {
+
+   namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+   prefix "inet";
+
+   organization
+    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+   contact
+    "WG Web:   <http://tools.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     WG Chair: David Partain
+               <mailto:david.partain@ericsson.com>
+
+     WG Chair: David Kessens
+               <mailto:david.kessens@nsn.com>
+
+     Editor:   Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>";
+
+   description
+    "This module contains a collection of generally useful derived
+     YANG data types for Internet addresses and related things.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or without
+     modification, is permitted pursuant to, and subject to the license
+     terms contained in, the Simplified BSD License set forth in Section
+     4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6021; see
+     the RFC itself for full legal notices.";
+
+   revision 2010-09-24 {
+     description
+      "Initial revision.";
+     reference
+      "RFC 6021: Common YANG Data Types";
+   }
+
+   /*** collection of protocol field related types ***/
+
+   typedef ip-version {
+     type enumeration {
+       enum unknown {
+         value "0";
+         description
+          "An unknown or unspecified version of the Internet protocol.";
+       }
+       enum ipv4 {
+         value "1";
+         description
+          "The IPv4 protocol as defined in RFC 791.";
+       }
+       enum ipv6 {
+         value "2";
+         description
+          "The IPv6 protocol as defined in RFC 2460.";
+       }
+     }
+     description
+      "This value represents the version of the IP protocol.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetVersion textual convention of the SMIv2.";
+     reference
+      "RFC  791: Internet Protocol
+       RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   typedef dscp {
+     type uint8 {
+       range "0..63";
+     }
+     description
+      "The dscp type represents a Differentiated Services Code-Point
+       that may be used for marking packets in a traffic stream.
+
+       In the value set and its semantics, this type is equivalent
+       to the Dscp textual convention of the SMIv2.";
+     reference
+      "RFC 3289: Management Information Base for the Differentiated
+                 Services Architecture
+       RFC 2474: Definition of the Differentiated Services Field
+                 (DS Field) in the IPv4 and IPv6 Headers
+       RFC 2780: IANA Allocation Guidelines For Values In
+                 the Internet Protocol and Related Headers";
+   }
+
+   typedef ipv6-flow-label {
+     type uint32 {
+       range "0..1048575";
+     }
+     description
+      "The flow-label type represents flow identifier or Flow Label
+       in an IPv6 packet header that may be used to discriminate
+       traffic flows.
+
+       In the value set and its semantics, this type is equivalent
+       to the IPv6FlowLabel textual convention of the SMIv2.";
+     reference
+      "RFC 3595: Textual Conventions for IPv6 Flow Label
+       RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+   }
+
+   typedef port-number {
+     type uint16 {
+       range "0..65535";
+     }
+     description
+      "The port-number type represents a 16-bit port number of an
+       Internet transport layer protocol such as UDP, TCP, DCCP, or
+       SCTP.  Port numbers are assigned by IANA.  A current list of
+       all assignments is available from <http://www.iana.org/>.
+
+       Note that the port number value zero is reserved by IANA.  In
+       situations where the value zero does not make sense, it can
+       be excluded by subtyping the port-number type.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetPortNumber textual convention of the SMIv2.";
+     reference
+      "RFC  768: User Datagram Protocol
+       RFC  793: Transmission Control Protocol
+       RFC 4960: Stream Control Transmission Protocol
+       RFC 4340: Datagram Congestion Control Protocol (DCCP)
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   /*** collection of autonomous system related types ***/
+
+   typedef as-number {
+     type uint32;
+     description
+      "The as-number type represents autonomous system numbers
+       which identify an Autonomous System (AS).  An AS is a set
+       of routers under a single technical administration, using
+       an interior gateway protocol and common metrics to route
+       packets within the AS, and using an exterior gateway
+       protocol to route packets to other ASs'.  IANA maintains
+       the AS number space and has delegated large parts to the
+       regional registries.
+
+       Autonomous system numbers were originally limited to 16
+       bits.  BGP extensions have enlarged the autonomous system
+       number space to 32 bits.  This type therefore uses an uint32
+       base type without a range restriction in order to support
+       a larger autonomous system number space.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetAutonomousSystemNumber textual convention of
+       the SMIv2.";
+     reference
+      "RFC 1930: Guidelines for creation, selection, and registration
+                 of an Autonomous System (AS)
+       RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+       RFC 4893: BGP Support for Four-octet AS Number Space
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   /*** collection of IP address and hostname related types ***/
+
+   typedef ip-address {
+     type union {
+       type inet:ipv4-address;
+       type inet:ipv6-address;
+     }
+     description
+      "The ip-address type represents an IP address and is IP
+       version neutral.  The format of the textual representations
+       implies the IP version.";
+   }
+
+   typedef ipv4-address {
+     type string {
+       pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '(%[\p{N}\p{L}]+)?';
+     }
+     description
+       "The ipv4-address type represents an IPv4 address in
+        dotted-quad notation.  The IPv4 address may include a zone
+        index, separated by a % sign.
+
+        The zone index is used to disambiguate identical address
+        values.  For link-local addresses, the zone index will
+        typically be the interface index number or the name of an
+        interface.  If the zone index is not present, the default
+        zone of the device will be used.
+
+        The canonical format for the zone index is the numerical
+        format";
+   }
+
+   typedef ipv6-address {
+     type string {
+       pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+             + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+             + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+             + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+             + '(%[\p{N}\p{L}]+)?';
+       pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+             + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+             + '(%.+)?';
+     }
+     description
+      "The ipv6-address type represents an IPv6 address in full,
+       mixed, shortened, and shortened-mixed notation.  The IPv6
+       address may include a zone index, separated by a % sign.
+
+       The zone index is used to disambiguate identical address
+       values.  For link-local addresses, the zone index will
+       typically be the interface index number or the name of an
+       interface.  If the zone index is not present, the default
+       zone of the device will be used.
+
+       The canonical format of IPv6 addresses uses the compressed
+       format described in RFC 4291, Section 2.2, item 2 with the
+       following additional rules: the :: substitution must be
+       applied to the longest sequence of all-zero 16-bit chunks
+       in an IPv6 address.  If there is a tie, the first sequence
+       of all-zero 16-bit chunks is replaced by ::.  Single
+       all-zero 16-bit chunks are not compressed.  The canonical
+       format uses lowercase characters and leading zeros are
+       not allowed.  The canonical format for the zone index is
+       the numerical format as described in RFC 4007, Section
+       11.2.";
+     reference
+      "RFC 4291: IP Version 6 Addressing Architecture
+       RFC 4007: IPv6 Scoped Address Architecture
+       RFC 5952: A Recommendation for IPv6 Address Text Representation";
+   }
+
+   typedef ip-prefix {
+     type union {
+       type inet:ipv4-prefix;
+       type inet:ipv6-prefix;
+     }
+     description
+      "The ip-prefix type represents an IP prefix and is IP
+       version neutral.  The format of the textual representations
+       implies the IP version.";
+   }
+
+   typedef ipv4-prefix {
+     type string {
+       pattern
+          '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+        +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+        + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+     }
+     description
+      "The ipv4-prefix type represents an IPv4 address prefix.
+       The prefix length is given by the number following the
+       slash character and must be less than or equal to 32.
+
+       A prefix length value of n corresponds to an IP address
+       mask that has n contiguous 1-bits from the most
+       significant bit (MSB) and all other bits set to 0.
+
+       The canonical format of an IPv4 prefix has all bits of
+       the IPv4 address set to zero that are not part of the
+       IPv4 prefix.";
+   }
+
+   typedef ipv6-prefix {
+     type string {
+       pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+             + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+             + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+             + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+             + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+       pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+             + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+             + '(/.+)';
+     }
+     description
+      "The ipv6-prefix type represents an IPv6 address prefix.
+       The prefix length is given by the number following the
+       slash character and must be less than or equal 128.
+
+       A prefix length value of n corresponds to an IP address
+       mask that has n contiguous 1-bits from the most
+       significant bit (MSB) and all other bits set to 0.
+
+       The IPv6 address should have all bits that do not belong
+       to the prefix set to zero.
+
+       The canonical format of an IPv6 prefix has all bits of
+       the IPv6 address set to zero that are not part of the
+       IPv6 prefix.  Furthermore, IPv6 address is represented
+       in the compressed format described in RFC 4291, Section
+       2.2, item 2 with the following additional rules: the ::
+       substitution must be applied to the longest sequence of
+       all-zero 16-bit chunks in an IPv6 address.  If there is
+       a tie, the first sequence of all-zero 16-bit chunks is
+       replaced by ::.  Single all-zero 16-bit chunks are not
+       compressed.  The canonical format uses lowercase
+       characters and leading zeros are not allowed.";
+     reference
+      "RFC 4291: IP Version 6 Addressing Architecture";
+   }
+
+   /*** collection of domain name and URI types ***/
+
+   typedef domain-name {
+     type string {
+       pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+            +  '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+            +  '|\.';
+       length "1..253";
+     }
+     description
+      "The domain-name type represents a DNS domain name.  The
+       name SHOULD be fully qualified whenever possible.
+
+       Internet domain names are only loosely specified.  Section
+       3.5 of RFC 1034 recommends a syntax (modified in Section
+       2.1 of RFC 1123).  The pattern above is intended to allow
+       for current practice in domain name use, and some possible
+       future expansion.  It is designed to hold various types of
+       domain names, including names used for A or AAAA records
+       (host names) and other records, such as SRV records.  Note
+       that Internet host names have a stricter syntax (described
+       in RFC 952) than the DNS recommendations in RFCs 1034 and
+       1123, and that systems that want to store host names in
+       schema nodes using the domain-name type are recommended to
+       adhere to this stricter standard to ensure interoperability.
+
+       The encoding of DNS names in the DNS protocol is limited
+       to 255 characters.  Since the encoding consists of labels
+       prefixed by a length bytes and there is a trailing NULL
+       byte, only 253 characters can appear in the textual dotted
+       notation.
+
+       The description clause of schema nodes using the domain-name
+       type MUST describe when and how these names are resolved to
+       IP addresses.  Note that the resolution of a domain-name value
+       may require to query multiple DNS records (e.g., A for IPv4
+       and AAAA for IPv6).  The order of the resolution process and
+       which DNS record takes precedence can either be defined
+       explicitely or it may depend on the configuration of the
+       resolver.
+
+       Domain-name values use the US-ASCII encoding.  Their canonical
+       format uses lowercase US-ASCII characters.  Internationalized
+       domain names MUST be encoded in punycode as described in RFC
+       3492";
+     reference
+      "RFC  952: DoD Internet Host Table Specification
+       RFC 1034: Domain Names - Concepts and Facilities
+       RFC 1123: Requirements for Internet Hosts -- Application
+                 and Support
+       RFC 2782: A DNS RR for specifying the location of services
+                 (DNS SRV)
+       RFC 3492: Punycode: A Bootstring encoding of Unicode for
+                 Internationalized Domain Names in Applications
+                 (IDNA)
+       RFC 5891: Internationalizing Domain Names in Applications
+                 (IDNA): Protocol";
+   }
+
+   typedef host {
+     type union {
+       type inet:ip-address;
+       type inet:domain-name;
+     }
+     description
+      "The host type represents either an IP address or a DNS
+       domain name.";
+   }
+
+   typedef uri {
+     type string;
+     description
+      "The uri type represents a Uniform Resource Identifier
+       (URI) as defined by STD 66.
+
+       Objects using the uri type MUST be in US-ASCII encoding,
+       and MUST be normalized as described by RFC 3986 Sections
+       6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+       percent-encoding is removed, and all case-insensitive
+       characters are set to lowercase except for hexadecimal
+       digits, which are normalized to uppercase as described in
+       Section 6.2.2.1.
+
+       The purpose of this normalization is to help provide
+       unique URIs.  Note that this normalization is not
+       sufficient to provide uniqueness.  Two URIs that are
+       textually distinct after this normalization may still be
+       equivalent.
+
+       Objects using the uri type may restrict the schemes that
+       they permit.  For example, 'data:' and 'urn:' schemes
+       might not be appropriate.
+
+       A zero-length URI is not a valid URI.  This can be used to
+       express 'URI absent' where required.
+
+       In the value set and its semantics, this type is equivalent
+       to the Uri SMIv2 textual convention defined in RFC 5017.";
+     reference
+      "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+       RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+                 Group: Uniform Resource Identifiers (URIs), URLs,
+                 and Uniform Resource Names (URNs): Clarifications
+                 and Recommendations
+       RFC 5017: MIB Textual Conventions for Uniform Resource
+                 Identifiers (URIs)";
+   }
+
+ }
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-interfaces.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-interfaces.yang
new file mode 100644 (file)
index 0000000..481a5d2
--- /dev/null
@@ -0,0 +1,469 @@
+module ietf-interfaces {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
+  prefix if;
+
+  import ietf-yang-types {
+    prefix yang;
+    revision-date 2010-09-24;
+  }
+
+  organization
+    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+  contact
+    "WG Web:   <http://tools.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     WG Chair: David Kessens
+               <mailto:david.kessens@nsn.com>
+
+     WG Chair: Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>
+
+     Editor:   Martin Bjorklund
+               <mailto:mbj@tail-f.com>";
+
+  description
+    "This module contains a collection of YANG definitions for
+     managing network interfaces.
+
+     Copyright (c) 2012 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD License
+     set forth in Section 4.c of the IETF Trust's Legal Provisions
+     Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC XXXX; see
+     the RFC itself for full legal notices.";
+
+  // RFC Ed.: replace XXXX with actual RFC number and remove this
+  // note.
+
+  // RFC Ed.: update the date below with the date of RFC publication
+  // and remove this note.
+  revision 2012-11-15 {
+    description
+      "Initial revision.";
+    reference
+      "RFC XXXX: A YANG Data Model for Interface Management";
+  }
+
+  /* Typedefs */
+
+  typedef interface-ref {
+    type leafref {
+      path "/if:interfaces/if:interface/if:name";
+    }
+    description
+      "This type is used by data models that need to reference
+       interfaces.";
+  }
+
+  /* Features */
+
+  feature arbitrary-names {
+    description
+      "This feature indicates that the server allows interfaces to
+       be named arbitrarily.";
+  }
+
+  feature if-mib {
+    description
+      "This feature indicates that the server implements IF-MIB.";
+    reference
+      "RFC 2863: The Interfaces Group MIB";
+  }
+
+  /* Data nodes */
+
+  container interfaces {
+    description
+      "Interface parameters.";
+
+    list interface {
+      key "name";
+      unique "type location";
+
+      description
+        "The list of interfaces on the device.";
+
+      leaf name {
+        type string;
+        description
+          "The name of the interface.
+
+           A device MAY restrict the allowed values for this leaf,
+           possibly depending on the type and location.
+
+           If the device allows arbitrarily named interfaces, the
+           feature 'arbitrary-names' is advertised.
+
+           This leaf MAY be mapped to ifName by an implementation.
+           Such an implementation MAY restrict the allowed values for
+           this leaf so that it matches the restrictions of ifName.
+           If a NETCONF server that implements this restriction is
+           sent a value that doesn't match the restriction, it MUST
+           reply with an rpc-error with the error-tag
+           'invalid-value'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifName";
+      }
+
+      leaf description {
+        type string;
+        description
+          "A textual description of the interface.
+
+           This leaf MAY be mapped to ifAlias by an implementation.
+           Such an implementation MAY restrict the allowed values for
+           this leaf so that it matches the restrictions of ifAlias.
+           If a NETCONF server that implements this restriction is
+           sent a value that doesn't match the restriction, it MUST
+           reply with an rpc-error with the error-tag
+           'invalid-value'.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAlias";
+      }
+
+      leaf location {
+        type string;
+        description
+          "The device-specific location of the interface of a
+           particular type.  The format of the location string
+           depends on the interface type and the device.
+
+           If the interface's type represents a physical interface,
+           this leaf MUST be set.
+
+           When an interface entry is created, a server MAY
+           initialize the location leaf with a valid value, e.g., if
+           it is possible to derive the location from the name of
+           the interface.";
+      }
+
+      leaf enabled {
+        type boolean;
+        default "true";
+        description
+          "The desired state of the interface.
+
+           This leaf contains the configured, desired state of the
+           interface.  Systems that implement the IF-MIB use the
+           value of this leaf to set IF-MIB.ifAdminStatus to 'up' or
+           'down' after an ifEntry has been initialized, as described
+           in RFC 2863.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifAdminStatus";
+      }
+
+      leaf last-change {
+        type yang:date-and-time;
+        config false;
+        description
+          "The time the interface entered its current operational
+           state.  If the current state was entered prior to the
+           last re-initialization of the local network management
+           subsystem, then this node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifLastChange";
+      }
+
+      leaf if-index {
+        if-feature if-mib;
+        type int32 {
+          range "1..2147483647";
+        }
+        config false;
+        description
+          "The ifIndex value for the ifEntry represented by this
+           interface.
+
+           Media-specific modules must specify how the type is
+           mapped to entries in the ifTable.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifIndex";
+      }
+
+      leaf phys-address {
+        type yang:phys-address;
+        config false;
+        description
+          "The interface's address at its protocol sub-layer.  For
+          example, for an 802.x interface, this object normally
+          contains a MAC address.  The interface's media-specific
+          modules must define the bit and byte ordering and the
+          format of the value of this object.  For interfaces that do
+          not have such an address (e.g., a serial line), this node
+          is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifPhysAddress";
+      }
+
+      leaf-list higher-layer-if {
+        type interface-ref;
+        config false;
+        description
+          "A list of references to interfaces layered on top of this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+
+      leaf-list lower-layer-if {
+        type interface-ref;
+        config false;
+        description
+          "A list of references to interfaces layered underneath this
+           interface.";
+        reference
+          "RFC 2863: The Interfaces Group MIB - ifStackTable";
+      }
+
+      leaf speed {
+        type yang:gauge64;
+        units "bits / second";
+        config false;
+        description
+            "An estimate of the interface's current bandwidth in bits
+             per second.  For interfaces which do not vary in
+             bandwidth or for those where no accurate estimation can
+             be made, this node should contain the nominal bandwidth.
+             For interfaces that has no concept of bandwidth, this
+             node is not present.";
+        reference
+          "RFC 2863: The Interfaces Group MIB -
+                     ifSpeed, ifHighSpeed";
+      }
+
+      container statistics {
+        config false;
+        description
+          "A collection of interface-related statistics objects.";
+
+        leaf discontinuity-time {
+          type yang:date-and-time;
+          description
+            "The time on the most recent occasion at which any one or
+             more of this interface's counters suffered a
+             discontinuity.  If no such discontinuities have occurred
+             since the last re-initialization of the local management
+             subsystem, then this node contains the time the local
+             management subsystem re-initialized itself.";
+        }
+
+        leaf in-octets {
+          type yang:counter64;
+          description
+            "The total number of octets received on the interface,
+             including framing characters.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system, and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInOctets";
+        }
+        leaf in-unicast-pkts {
+          type yang:counter64;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, which were not addressed to a
+             multicast or broadcast address at this sub-layer.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system, and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCInUcastPkts";
+        }
+        leaf in-broadcast-pkts {
+          type yang:counter64;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, which were addressed to a broadcast
+             address at this sub-layer.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system, and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInBroadcastPkts";
+        }
+        leaf in-multicast-pkts {
+          type yang:counter64;
+          description
+            "The number of packets, delivered by this sub-layer to a
+             higher (sub-)layer, which were addressed to a multicast
+             address at this sub-layer.  For a MAC layer protocol,
+             this includes both Group and Functional addresses.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system, and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCInMulticastPkts";
+        }
+        leaf in-discards {
+          type yang:counter32;
+          description
+            "The number of inbound packets which were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being deliverable to a higher-layer
+             protocol.  One possible reason for discarding such a
+             packet could be to free up buffer space.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system, and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInDiscards";
+        }
+        leaf in-errors {
+          type yang:counter32;
+          description
+            "For packet-oriented interfaces, the number of inbound
+             packets that contained errors preventing them from being
+             deliverable to a higher-layer protocol.  For character-
+             oriented or fixed-length interfaces, the number of
+             inbound transmission units that contained errors
+             preventing them from being deliverable to a higher-layer
+             protocol.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system, and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInErrors";
+        }
+        leaf in-unknown-protos {
+          type yang:counter32;
+          description
+            "For packet-oriented interfaces, the number of packets
+             received via the interface which were discarded because
+             of an unknown or unsupported protocol.  For
+             character-oriented or fixed-length interfaces that
+             support protocol multiplexing the number of transmission
+             units received via the interface which were discarded
+             because of an unknown or unsupported protocol.  For any
+             interface that does not support protocol multiplexing,
+             this counter is not present.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system, and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifInUnknownProtos";
+        }
+
+        leaf out-octets {
+          type yang:counter64;
+          description
+            "The total number of octets transmitted out of the
+             interface, including framing characters.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system, and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutOctets";
+        }
+        leaf out-unicast-pkts {
+          type yang:counter64;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted, and which were not addressed
+             to a multicast or broadcast address at this sub-layer,
+             including those that were discarded or not sent.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system, and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifHCOutUcastPkts";
+        }
+        leaf out-broadcast-pkts {
+          type yang:counter64;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted, and which were addressed to a
+             broadcast address at this sub-layer, including those
+             that were discarded or not sent.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system, and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutBroadcastPkts";
+        }
+        leaf out-multicast-pkts {
+          type yang:counter64;
+          description
+            "The total number of packets that higher-level protocols
+             requested be transmitted, and which were addressed to a
+             multicast address at this sub-layer, including those
+             that were discarded or not sent.  For a MAC layer
+             protocol, this includes both Group and Functional
+             addresses.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system, and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB -
+                       ifHCOutMulticastPkts";
+        }
+        leaf out-discards {
+          type yang:counter32;
+          description
+            "The number of outbound packets which were chosen to be
+             discarded even though no errors had been detected to
+             prevent their being transmitted.  One possible reason
+             for discarding such a packet could be to free up buffer
+             space.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system, and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutDiscards";
+        }
+        leaf out-errors {
+          type yang:counter32;
+          description
+            "For packet-oriented interfaces, the number of outbound
+             packets that could not be transmitted because of errors.
+             For character-oriented or fixed-length interfaces, the
+             number of outbound transmission units that could not be
+             transmitted because of errors.
+
+             Discontinuities in the value of this counter can occur
+             at re-initialization of the management system, and at
+             other times as indicated by the value of
+             'discontinuity-time'.";
+          reference
+            "RFC 2863: The Interfaces Group MIB - ifOutErrors";
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-netconf-monitoring.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-netconf-monitoring.yang
new file mode 100644 (file)
index 0000000..b4ad89b
--- /dev/null
@@ -0,0 +1,593 @@
+module ietf-netconf-monitoring {
+
+    yang-version 1;
+
+    namespace
+      "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring";
+
+    prefix ncm;
+
+    import ietf-yang-types {
+      prefix yang;
+    }
+    import ietf-inet-types {
+      prefix inet;
+    }
+
+    organization
+      "IETF NETCONF (Network Configuration) Working Group";
+
+    contact
+      "WG Web:   <http://tools.ietf.org/wg/netconf/>
+     WG List:  <mailto:netconf@ietf.org>
+
+     WG Chair: Mehmet Ersue
+               <mailto:mehmet.ersue@nsn.com>
+
+     WG Chair: Bert Wijnen
+               <mailto:bertietf@bwijnen.net>
+
+     Editor:   Mark Scott
+               <mailto:mark.scott@ericsson.com>
+
+     Editor:   Martin Bjorklund
+               <mailto:mbj@tail-f.com>";
+
+    description
+      "NETCONF Monitoring Module.
+     All elements in this module are read-only.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code. All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD
+     License set forth in Section 4.c of the IETF Trust's
+     Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6022; see
+     the RFC itself for full legal notices.";
+
+    revision "2010-10-04" {
+      description "Initial revision.";
+      reference
+        "RFC 6022: YANG Module for NETCONF Monitoring";
+
+    }
+
+
+    typedef netconf-datastore-type {
+      type enumeration {
+        enum "running" {
+          value 0;
+        }
+        enum "candidate" {
+          value 1;
+        }
+        enum "startup" {
+          value 2;
+        }
+      }
+      description
+        "Enumeration of possible NETCONF datastore types.";
+      reference
+        "RFC 4741: NETCONF Configuration Protocol";
+
+    }
+
+    identity transport {
+      description
+        "Base identity for NETCONF transport types.";
+    }
+
+    identity netconf-ssh {
+      base transport;
+      description
+        "NETCONF over Secure Shell (SSH).";
+      reference
+        "RFC 4742: Using the NETCONF Configuration Protocol
+              over Secure SHell (SSH)";
+
+    }
+
+    identity netconf-soap-over-beep {
+      base transport;
+      description
+        "NETCONF over Simple Object Access Protocol (SOAP) over
+       Blocks Extensible Exchange Protocol (BEEP).";
+      reference
+        "RFC 4743: Using NETCONF over the Simple Object
+              Access Protocol (SOAP)";
+
+    }
+
+    identity netconf-soap-over-https {
+      base transport;
+      description
+        "NETCONF over Simple Object Access Protocol (SOAP)
+      over Hypertext Transfer Protocol Secure (HTTPS).";
+      reference
+        "RFC 4743: Using NETCONF over the Simple Object
+              Access Protocol (SOAP)";
+
+    }
+
+    identity netconf-beep {
+      base transport;
+      description
+        "NETCONF over Blocks Extensible Exchange Protocol (BEEP).";
+      reference
+        "RFC 4744: Using the NETCONF Protocol over the
+              Blocks Extensible Exchange Protocol (BEEP)";
+
+    }
+
+    identity netconf-tls {
+      base transport;
+      description
+        "NETCONF over Transport Layer Security (TLS).";
+      reference
+        "RFC 5539: NETCONF over Transport Layer Security (TLS)";
+
+    }
+
+    identity schema-format {
+      description
+        "Base identity for data model schema languages.";
+    }
+
+    identity xsd {
+      base schema-format;
+      description
+        "W3C XML Schema Definition.";
+      reference
+        "W3C REC REC-xmlschema-1-20041028:
+          XML Schema Part 1: Structures";
+
+    }
+
+    identity yang {
+      base schema-format;
+      description
+        "The YANG data modeling language for NETCONF.";
+      reference
+        "RFC 6020:  YANG - A Data Modeling Language for the
+               Network Configuration Protocol (NETCONF)";
+
+    }
+
+    identity yin {
+      base schema-format;
+      description "The YIN syntax for YANG.";
+      reference
+        "RFC 6020:  YANG - A Data Modeling Language for the
+               Network Configuration Protocol (NETCONF)";
+
+    }
+
+    identity rng {
+      base schema-format;
+      description
+        "Regular Language for XML Next Generation (RELAX NG).";
+      reference
+        "ISO/IEC 19757-2:2008: RELAX NG";
+
+    }
+
+    identity rnc {
+      base schema-format;
+      description "Relax NG Compact Syntax";
+      reference
+        "ISO/IEC 19757-2:2008: RELAX NG";
+
+    }
+
+    grouping common-counters {
+      description
+        "Counters that exist both per session, and also globally,
+       accumulated from all sessions.";
+      leaf in-rpcs {
+        type yang:zero-based-counter32;
+        description
+          "Number of correct <rpc> messages received.";
+      }
+
+      leaf in-bad-rpcs {
+        type yang:zero-based-counter32;
+        description
+          "Number of messages received when an <rpc> message was expected,
+         that were not correct <rpc> messages.  This includes XML parse
+         errors and errors on the rpc layer.";
+      }
+
+      leaf out-rpc-errors {
+        type yang:zero-based-counter32;
+        description
+          "Number of <rpc-reply> messages sent that contained an
+         <rpc-error> element.";
+      }
+
+      leaf out-notifications {
+        type yang:zero-based-counter32;
+        description
+          "Number of <notification> messages sent.";
+      }
+    }  // grouping common-counters
+
+    container netconf-state {
+      config false;
+      description
+        "The netconf-state container is the root of the monitoring
+       data model.";
+      container capabilities {
+        description
+          "Contains the list of NETCONF capabilities supported by the
+         server.";
+        leaf-list capability {
+          type inet:uri;
+          description
+            "List of NETCONF capabilities supported by the server.";
+        }
+      }  // container capabilities
+
+      container datastores {
+        description
+          "Contains the list of NETCONF configuration datastores.";
+        list datastore {
+          key "name";
+          description
+            "List of NETCONF configuration datastores supported by
+           the NETCONF server and related information.";
+          leaf name {
+            type netconf-datastore-type;
+            description
+              "Name of the datastore associated with this list entry.";
+          }
+
+          container locks {
+            presence
+              "This container is present only if the datastore
+             is locked.";
+            description
+              "The NETCONF <lock> and <partial-lock> operations allow
+             a client to lock specific resources in a datastore.  The
+             NETCONF server will prevent changes to the locked
+             resources by all sessions except the one that acquired
+             the lock(s).
+
+             Monitoring information is provided for each datastore
+             entry including details such as the session that acquired
+             the lock, the type of lock (global or partial) and the
+             list of locked resources.  Multiple locks per datastore
+             are supported.";
+            grouping lock-info {
+              description
+                "Lock related parameters, common to both global and
+               partial locks.";
+              leaf locked-by-session {
+                type uint32;
+                mandatory true;
+                description
+                  "The session ID of the session that has locked
+                 this resource.  Both a global lock and a partial
+                 lock MUST contain the NETCONF session-id.
+
+                 If the lock is held by a session that is not managed
+                 by the NETCONF server (e.g., a CLI session), a session
+                 id of 0 (zero) is reported.";
+                reference
+                  "RFC 4741: NETCONF Configuration Protocol";
+
+              }
+
+              leaf locked-time {
+                type yang:date-and-time;
+                mandatory true;
+                description
+                  "The date and time of when the resource was
+                 locked.";
+              }
+            }  // grouping lock-info
+            choice lock-type {
+              description
+                "Indicates if a global lock or a set of partial locks
+               are set.";
+              container global-lock {
+                description
+                  "Present if the global lock is set.";
+                uses lock-info;
+              }  // container global-lock
+              list partial-lock {
+                key "lock-id";
+                description
+                  "List of partial locks.";
+                reference
+                  "RFC 5717: Partial Lock Remote Procedure Call (RPC) for
+                      NETCONF";
+
+                leaf lock-id {
+                  type uint32;
+                  description
+                    "This is the lock id returned in the <partial-lock>
+                   response.";
+                }
+
+                uses lock-info;
+
+                leaf-list select {
+                  type yang:xpath1.0;
+                  min-elements 1;
+                  description
+                    "The xpath expression that was used to request
+                   the lock.  The select expression indicates the
+                   original intended scope of the lock.";
+                }
+
+                leaf-list locked-node {
+                  type instance-identifier;
+                  description
+                    "The list of instance-identifiers (i.e., the
+                   locked nodes).
+
+                   The scope of the partial lock is defined by the list
+                   of locked nodes.";
+                }
+              }  // list partial-lock
+            }  // choice lock-type
+          }  // container locks
+        }  // list datastore
+      }  // container datastores
+
+      container schemas {
+        description
+          "Contains the list of data model schemas supported by the
+         server.";
+        list schema {
+          key "identifier version format";
+          description
+            "List of data model schemas supported by the server.";
+          leaf identifier {
+            type string;
+            description
+              "Identifier to uniquely reference the schema.  The
+             identifier is used in the <get-schema> operation and may
+             be used for other purposes such as file retrieval.
+
+             For modeling languages that support or require a data
+             model name (e.g., YANG module name) the identifier MUST
+             match that name.  For YANG data models, the identifier is
+             the name of the module or submodule.  In other cases, an
+             identifier such as a filename MAY be used instead.";
+          }
+
+          leaf version {
+            type string;
+            description
+              "Version of the schema supported.  Multiple versions MAY be
+             supported simultaneously by a NETCONF server.  Each
+             version MUST be reported individually in the schema list,
+             i.e., with same identifier, possibly different location,
+             but different version.
+
+             For YANG data models, version is the value of the most
+             recent YANG 'revision' statement in the module or
+             submodule, or the empty string if no 'revision' statement
+             is present.";
+          }
+
+          leaf format {
+            type identityref {
+              base schema-format;
+            }
+            description
+              "The data modeling language the schema is written
+             in (currently xsd, yang, yin, rng, or rnc).
+             For YANG data models, 'yang' format MUST be supported and
+             'yin' format MAY also be provided.";
+          }
+
+          leaf namespace {
+            type inet:uri;
+            mandatory true;
+            description
+              "The XML namespace defined by the data model.
+
+             For YANG data models, this is the module's namespace.
+             If the list entry describes a submodule, this field
+             contains the namespace of the module to which the
+             submodule belongs.";
+          }
+
+          leaf-list location {
+            type union {
+              type enumeration {
+                enum "NETCONF" {
+                  value 0;
+                }
+              }
+              type inet:uri;
+            }
+            description
+              "One or more locations from which the schema can be
+             retrieved.  This list SHOULD contain at least one
+             entry per schema.
+
+             A schema entry may be located on a remote file system
+             (e.g., reference to file system for ftp retrieval) or
+             retrieved directly from a server supporting the
+             <get-schema> operation (denoted by the value 'NETCONF').";
+          }
+        }  // list schema
+      }  // container schemas
+
+      container sessions {
+        description
+          "The sessions container includes session-specific data for
+         NETCONF management sessions.  The session list MUST include
+         all currently active NETCONF sessions.";
+        list session {
+          key "session-id";
+          description
+            "All NETCONF sessions managed by the NETCONF server
+           MUST be reported in this list.";
+          leaf session-id {
+            type uint32 {
+              range "1..max";
+            }
+            description
+              "Unique identifier for the session.  This value is the
+             NETCONF session identifier, as defined in RFC 4741.";
+            reference
+              "RFC 4741: NETCONF Configuration Protocol";
+
+          }
+
+          leaf transport {
+            type identityref {
+              base transport;
+            }
+            mandatory true;
+            description
+              "Identifies the transport for each session, e.g.,
+            'netconf-ssh', 'netconf-soap', etc.";
+          }
+
+          leaf username {
+            type string;
+            mandatory true;
+            description
+              "The username is the client identity that was authenticated
+            by the NETCONF transport protocol.  The algorithm used to
+            derive the username is NETCONF transport protocol specific
+            and in addition specific to the authentication mechanism
+            used by the NETCONF transport protocol.";
+          }
+
+          leaf source-host {
+            type inet:host;
+            description
+              "Host identifier of the NETCONF client.  The value
+             returned is implementation specific (e.g., hostname,
+             IPv4 address, IPv6 address)";
+          }
+
+          leaf login-time {
+            type yang:date-and-time;
+            mandatory true;
+            description
+              "Time at the server at which the session was established.";
+          }
+
+          uses common-counters {
+            description
+              "Per-session counters.  Zero based with following reset
+             behaviour:
+               - at start of a session
+               - when max value is reached";
+          }
+        }  // list session
+      }  // container sessions
+
+      container statistics {
+        description
+          "Statistical data pertaining to the NETCONF server.";
+        leaf netconf-start-time {
+          type yang:date-and-time;
+          description
+            "Date and time at which the management subsystem was
+           started.";
+        }
+
+        leaf in-bad-hellos {
+          type yang:zero-based-counter32;
+          description
+            "Number of sessions silently dropped because an
+          invalid <hello> message was received.  This includes <hello>
+          messages with a 'session-id' attribute, bad namespace, and
+          bad capability declarations.";
+        }
+
+        leaf in-sessions {
+          type yang:zero-based-counter32;
+          description
+            "Number of sessions started.  This counter is incremented
+           when a <hello> message with a <session-id> is sent.
+
+          'in-sessions' - 'in-bad-hellos' =
+              'number of correctly started netconf sessions'";
+        }
+
+        leaf dropped-sessions {
+          type yang:zero-based-counter32;
+          description
+            "Number of sessions that were abnormally terminated, e.g.,
+           due to idle timeout or transport close.  This counter is not
+           incremented when a session is properly closed by a
+           <close-session> operation, or killed by a <kill-session>
+           operation.";
+        }
+
+        uses common-counters {
+          description
+            "Global counters, accumulated from all sessions.
+           Zero based with following reset behaviour:
+             - re-initialization of NETCONF server
+             - when max value is reached";
+        }
+      }  // container statistics
+    }  // container netconf-state
+
+    rpc get-schema {
+      description
+        "This operation is used to retrieve a schema from the
+       NETCONF server.
+
+       Positive Response:
+         The NETCONF server returns the requested schema.
+
+       Negative Response:
+         If requested schema does not exist, the <error-tag> is
+         'invalid-value'.
+
+         If more than one schema matches the requested parameters, the
+         <error-tag> is 'operation-failed', and <error-app-tag> is
+         'data-not-unique'.";
+      input {
+        leaf identifier {
+          type string;
+          mandatory true;
+          description
+            "Identifier for the schema list entry.";
+        }
+
+        leaf version {
+          type string;
+          description
+            "Version of the schema requested.  If this parameter is not
+           present, and more than one version of the schema exists on
+           the server, a 'data-not-unique' error is returned, as
+           described above.";
+        }
+
+        leaf format {
+          type identityref {
+            base schema-format;
+          }
+          description
+            "The data modeling language of the schema.  If this
+            parameter is not present, and more than one formats of
+            the schema exists on the server, a 'data-not-unique' error
+            is returned, as described above.";
+        }
+      }
+
+      output {
+        anyxml data {
+          description
+            "Contains the schema content.";
+        }
+      }
+    }  // rpc get-schema
+} // module
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-yang-types.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-yang-types.yang
new file mode 100644 (file)
index 0000000..51d9f8b
--- /dev/null
@@ -0,0 +1,396 @@
+ module ietf-yang-types {
+
+   namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+   prefix "yang";
+
+   organization
+    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+   contact
+    "WG Web:   <http://tools.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     WG Chair: David Partain
+               <mailto:david.partain@ericsson.com>
+
+     WG Chair: David Kessens
+               <mailto:david.kessens@nsn.com>
+
+     Editor:   Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>";
+
+   description
+    "This module contains a collection of generally useful derived
+     YANG data types.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or without
+     modification, is permitted pursuant to, and subject to the license
+     terms contained in, the Simplified BSD License set forth in Section
+     4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6021; see
+     the RFC itself for full legal notices.";
+
+   revision 2010-09-24 {
+     description
+      "Initial revision.";
+     reference
+      "RFC 6021: Common YANG Data Types";
+   }
+
+   /*** collection of counter and gauge types ***/
+
+   typedef counter32 {
+     type uint32;
+     description
+      "The counter32 type represents a non-negative integer
+       that monotonically increases until it reaches a
+       maximum value of 2^32-1 (4294967295 decimal), when it
+       wraps around and starts increasing again from zero.
+
+       Counters have no defined 'initial' value, and thus, a
+       single value of a counter has (in general) no information
+       content.  Discontinuities in the monotonically increasing
+       value normally occur at re-initialization of the
+       management system, and at other times as specified in the
+       description of a schema node using this type.  If such
+       other times can occur, for example, the creation of
+       a schema node of type counter32 at times other than
+       re-initialization, then a corresponding schema node
+       should be defined, with an appropriate type, to indicate
+       the last discontinuity.
+
+       The counter32 type should not be used for configuration
+       schema nodes.  A default statement SHOULD NOT be used in
+       combination with the type counter32.
+
+       In the value set and its semantics, this type is equivalent
+       to the Counter32 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef zero-based-counter32 {
+     type yang:counter32;
+     default "0";
+     description
+      "The zero-based-counter32 type represents a counter32
+       that has the defined 'initial' value zero.
+
+       A schema node of this type will be set to zero (0) on creation
+       and will thereafter increase monotonically until it reaches
+       a maximum value of 2^32-1 (4294967295 decimal), when it
+       wraps around and starts increasing again from zero.
+
+       Provided that an application discovers a new schema node
+       of this type within the minimum time to wrap, it can use the
+       'initial' value as a delta.  It is important for a management
+       station to be aware of this minimum time and the actual time
+       between polls, and to discard data if the actual time is too
+       long or there is no defined minimum time.
+
+       In the value set and its semantics, this type is equivalent
+       to the ZeroBasedCounter32 textual convention of the SMIv2.";
+     reference
+       "RFC 4502: Remote Network Monitoring Management Information
+                  Base Version 2";
+   }
+
+   typedef counter64 {
+     type uint64;
+     description
+      "The counter64 type represents a non-negative integer
+       that monotonically increases until it reaches a
+       maximum value of 2^64-1 (18446744073709551615 decimal),
+       when it wraps around and starts increasing again from zero.
+
+       Counters have no defined 'initial' value, and thus, a
+       single value of a counter has (in general) no information
+       content.  Discontinuities in the monotonically increasing
+       value normally occur at re-initialization of the
+       management system, and at other times as specified in the
+       description of a schema node using this type.  If such
+       other times can occur, for example, the creation of
+       a schema node of type counter64 at times other than
+       re-initialization, then a corresponding schema node
+       should be defined, with an appropriate type, to indicate
+       the last discontinuity.
+
+       The counter64 type should not be used for configuration
+       schema nodes.  A default statement SHOULD NOT be used in
+       combination with the type counter64.
+
+       In the value set and its semantics, this type is equivalent
+       to the Counter64 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef zero-based-counter64 {
+     type yang:counter64;
+     default "0";
+     description
+      "The zero-based-counter64 type represents a counter64 that
+       has the defined 'initial' value zero.
+
+       A schema node of this type will be set to zero (0) on creation
+       and will thereafter increase monotonically until it reaches
+       a maximum value of 2^64-1 (18446744073709551615 decimal),
+       when it wraps around and starts increasing again from zero.
+
+       Provided that an application discovers a new schema node
+       of this type within the minimum time to wrap, it can use the
+       'initial' value as a delta.  It is important for a management
+       station to be aware of this minimum time and the actual time
+       between polls, and to discard data if the actual time is too
+       long or there is no defined minimum time.
+
+       In the value set and its semantics, this type is equivalent
+       to the ZeroBasedCounter64 textual convention of the SMIv2.";
+     reference
+      "RFC 2856: Textual Conventions for Additional High Capacity
+                 Data Types";
+   }
+
+   typedef gauge32 {
+     type uint32;
+     description
+      "The gauge32 type represents a non-negative integer, which
+       may increase or decrease, but shall never exceed a maximum
+       value, nor fall below a minimum value.  The maximum value
+       cannot be greater than 2^32-1 (4294967295 decimal), and
+       the minimum value cannot be smaller than 0.  The value of
+       a gauge32 has its maximum value whenever the information
+       being modeled is greater than or equal to its maximum
+       value, and has its minimum value whenever the information
+       being modeled is smaller than or equal to its minimum value.
+       If the information being modeled subsequently decreases
+       below (increases above) the maximum (minimum) value, the
+       gauge32 also decreases (increases).
+
+       In the value set and its semantics, this type is equivalent
+       to the Gauge32 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef gauge64 {
+     type uint64;
+     description
+      "The gauge64 type represents a non-negative integer, which
+       may increase or decrease, but shall never exceed a maximum
+       value, nor fall below a minimum value.  The maximum value
+       cannot be greater than 2^64-1 (18446744073709551615), and
+       the minimum value cannot be smaller than 0.  The value of
+       a gauge64 has its maximum value whenever the information
+       being modeled is greater than or equal to its maximum
+       value, and has its minimum value whenever the information
+       being modeled is smaller than or equal to its minimum value.
+       If the information being modeled subsequently decreases
+       below (increases above) the maximum (minimum) value, the
+       gauge64 also decreases (increases).
+
+       In the value set and its semantics, this type is equivalent
+       to the CounterBasedGauge64 SMIv2 textual convention defined
+       in RFC 2856";
+     reference
+      "RFC 2856: Textual Conventions for Additional High Capacity
+                 Data Types";
+   }
+
+   /*** collection of identifier related types ***/
+
+   typedef object-identifier {
+     type string {
+       pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))'
+             + '(\.(0|([1-9]\d*)))*';
+     }
+     description
+      "The object-identifier type represents administratively
+       assigned names in a registration-hierarchical-name tree.
+
+       Values of this type are denoted as a sequence of numerical
+       non-negative sub-identifier values.  Each sub-identifier
+       value MUST NOT exceed 2^32-1 (4294967295).  Sub-identifiers
+       are separated by single dots and without any intermediate
+       whitespace.
+
+       The ASN.1 standard restricts the value space of the first
+       sub-identifier to 0, 1, or 2.  Furthermore, the value space
+       of the second sub-identifier is restricted to the range
+       0 to 39 if the first sub-identifier is 0 or 1.  Finally,
+       the ASN.1 standard requires that an object identifier
+       has always at least two sub-identifier.  The pattern
+       captures these restrictions.
+
+       Although the number of sub-identifiers is not limited,
+       module designers should realize that there may be
+       implementations that stick with the SMIv2 limit of 128
+       sub-identifiers.
+
+       This type is a superset of the SMIv2 OBJECT IDENTIFIER type
+       since it is not restricted to 128 sub-identifiers.  Hence,
+       this type SHOULD NOT be used to represent the SMIv2 OBJECT
+       IDENTIFIER type, the object-identifier-128 type SHOULD be
+       used instead.";
+     reference
+      "ISO9834-1: Information technology -- Open Systems
+       Interconnection -- Procedures for the operation of OSI
+       Registration Authorities: General procedures and top
+       arcs of the ASN.1 Object Identifier tree";
+   }
+
+
+
+
+   typedef object-identifier-128 {
+     type object-identifier {
+       pattern '\d*(\.\d*){1,127}';
+     }
+     description
+      "This type represents object-identifiers restricted to 128
+       sub-identifiers.
+
+       In the value set and its semantics, this type is equivalent
+       to the OBJECT IDENTIFIER type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   /*** collection of date and time related types ***/
+
+   typedef date-and-time {
+     type string {
+       pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+             + '(Z|[\+\-]\d{2}:\d{2})';
+     }
+     description
+      "The date-and-time type is a profile of the ISO 8601
+       standard for representation of dates and times using the
+       Gregorian calendar.  The profile is defined by the
+       date-time production in Section 5.6 of RFC 3339.
+
+       The date-and-time type is compatible with the dateTime XML
+       schema type with the following notable exceptions:
+
+       (a) The date-and-time type does not allow negative years.
+
+       (b) The date-and-time time-offset -00:00 indicates an unknown
+           time zone (see RFC 3339) while -00:00 and +00:00 and Z all
+           represent the same time zone in dateTime.
+
+       (c) The canonical format (see below) of data-and-time values
+           differs from the canonical format used by the dateTime XML
+           schema type, which requires all times to be in UTC using the
+           time-offset 'Z'.
+
+       This type is not equivalent to the DateAndTime textual
+       convention of the SMIv2 since RFC 3339 uses a different
+       separator between full-date and full-time and provides
+       higher resolution of time-secfrac.
+
+       The canonical format for date-and-time values with a known time
+       zone uses a numeric time zone offset that is calculated using
+       the device's configured known offset to UTC time.  A change of
+       the device's offset to UTC time will cause date-and-time values
+       to change accordingly.  Such changes might happen periodically
+       in case a server follows automatically daylight saving time
+       (DST) time zone offset changes.  The canonical format for
+       date-and-time values with an unknown time zone (usually referring
+       to the notion of local time) uses the time-offset -00:00.";
+     reference
+      "RFC 3339: Date and Time on the Internet: Timestamps
+       RFC 2579: Textual Conventions for SMIv2
+       XSD-TYPES: XML Schema Part 2: Datatypes Second Edition";
+   }
+
+   typedef timeticks {
+     type uint32;
+     description
+      "The timeticks type represents a non-negative integer that
+       represents the time, modulo 2^32 (4294967296 decimal), in
+       hundredths of a second between two epochs.  When a schema
+       node is defined that uses this type, the description of
+       the schema node identifies both of the reference epochs.
+
+       In the value set and its semantics, this type is equivalent
+       to the TimeTicks type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef timestamp {
+     type yang:timeticks;
+     description
+      "The timestamp type represents the value of an associated
+       timeticks schema node at which a specific occurrence happened.
+       The specific occurrence must be defined in the description
+       of any schema node defined using this type.  When the specific
+       occurrence occurred prior to the last time the associated
+       timeticks attribute was zero, then the timestamp value is
+       zero.  Note that this requires all timestamp values to be
+       reset to zero when the value of the associated timeticks
+       attribute reaches 497+ days and wraps around to zero.
+
+       The associated timeticks schema node must be specified
+       in the description of any schema node using this type.
+
+       In the value set and its semantics, this type is equivalent
+       to the TimeStamp textual convention of the SMIv2.";
+     reference
+      "RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   /*** collection of generic address types ***/
+
+   typedef phys-address {
+     type string {
+       pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+     }
+     description
+      "Represents media- or physical-level addresses represented
+       as a sequence octets, each octet represented by two hexadecimal
+       numbers.  Octets are separated by colons.  The canonical
+       representation uses lowercase characters.
+
+       In the value set and its semantics, this type is equivalent
+       to the PhysAddress textual convention of the SMIv2.";
+     reference
+      "RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   typedef mac-address {
+     type string {
+       pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}';
+     }
+     description
+      "The mac-address type represents an IEEE 802 MAC address.
+       The canonical representation uses lowercase characters.
+
+       In the value set and its semantics, this type is equivalent
+       to the MacAddress textual convention of the SMIv2.";
+     reference
+      "IEEE 802: IEEE Standard for Local and Metropolitan Area
+                 Networks: Overview and Architecture
+       RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   /*** collection of XML specific types ***/
+
+   typedef xpath1.0 {
+     type string;
+     description
+      "This type represents an XPATH 1.0 expression.
+
+       When a schema node is defined that uses this type, the
+       description of the schema node MUST specify the XPath
+       context in which the XPath expression is evaluated.";
+     reference
+      "XPATH: XML Path Language (XPath) Version 1.0";
+   }
+
+ }
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-yang-types@2013-05-16.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-yang-types@2013-05-16.yang
new file mode 100644 (file)
index 0000000..6c82d9d
--- /dev/null
@@ -0,0 +1,471 @@
+module ietf-yang-types {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+  prefix "yang";
+
+  organization
+   "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+  contact
+   "WG Web:   <http://tools.ietf.org/wg/netmod/>
+    WG List:  <mailto:netmod@ietf.org>
+
+    WG Chair: David Kessens
+              <mailto:david.kessens@nsn.com>
+
+    WG Chair: Juergen Schoenwaelder
+              <mailto:j.schoenwaelder@jacobs-university.de>
+
+    Editor:   Juergen Schoenwaelder
+              <mailto:j.schoenwaelder@jacobs-university.de>";
+
+  description
+   "This module contains a collection of generally useful derived
+    YANG data types.
+
+    Copyright (c) 2013 IETF Trust and the persons identified as
+    authors of the code.  All rights reserved.
+
+    Redistribution and use in source and binary forms, with or
+    without modification, is permitted pursuant to, and subject
+    to the license terms contained in, the Simplified BSD License
+    set forth in Section 4.c of the IETF Trust's Legal Provisions
+    Relating to IETF Documents
+    (http://trustee.ietf.org/license-info).
+
+    This version of this YANG module is part of RFC XXXX; see
+    the RFC itself for full legal notices.";
+
+  revision 2013-05-16 {
+    description
+     "This revision adds the following new data types:
+      - yang-identifier
+      - hex-string
+      - uuid
+      - dotted-quad";
+    reference
+     "RFC XXXX: Common YANG Data Types";
+  }
+
+  revision 2010-09-24 {
+    description
+     "Initial revision.";
+    reference
+     "RFC 6021: Common YANG Data Types";
+  }
+
+  /*** collection of counter and gauge types ***/
+
+  typedef counter32 {
+    type uint32;
+    description
+     "The counter32 type represents a non-negative integer
+      that monotonically increases until it reaches a
+      maximum value of 2^32-1 (4294967295 decimal), when it
+      wraps around and starts increasing again from zero.
+
+      Counters have no defined 'initial' value, and thus, a
+      single value of a counter has (in general) no information
+      content.  Discontinuities in the monotonically increasing
+      value normally occur at re-initialization of the
+      management system, and at other times as specified in the
+      description of a schema node using this type.  If such
+      other times can occur, for example, the creation of
+      a schema node of type counter32 at times other than
+      re-initialization, then a corresponding schema node
+      should be defined, with an appropriate type, to indicate
+      the last discontinuity.
+
+      The counter32 type should not be used for configuration
+      schema nodes.  A default statement SHOULD NOT be used in
+      combination with the type counter32.
+
+      In the value set and its semantics, this type is equivalent
+      to the Counter32 type of the SMIv2.";
+    reference
+     "RFC 2578: Structure of Management Information Version 2
+                (SMIv2)";
+  }
+
+  typedef zero-based-counter32 {
+    type yang:counter32;
+    default "0";
+    description
+     "The zero-based-counter32 type represents a counter32
+      that has the defined 'initial' value zero.
+
+      A schema node of this type will be set to zero (0) on creation
+      and will thereafter increase monotonically until it reaches
+      a maximum value of 2^32-1 (4294967295 decimal), when it
+      wraps around and starts increasing again from zero.
+
+      Provided that an application discovers a new schema node
+      of this type within the minimum time to wrap, it can use the
+      'initial' value as a delta.  It is important for a management
+      station to be aware of this minimum time and the actual time
+      between polls, and to discard data if the actual time is too
+      long or there is no defined minimum time.
+
+      In the value set and its semantics, this type is equivalent
+      to the ZeroBasedCounter32 textual convention of the SMIv2.";
+    reference
+      "RFC 4502: Remote Network Monitoring Management Information
+                 Base Version 2";
+  }
+
+  typedef counter64 {
+    type uint64;
+    description
+     "The counter64 type represents a non-negative integer
+      that monotonically increases until it reaches a
+      maximum value of 2^64-1 (18446744073709551615 decimal),
+      when it wraps around and starts increasing again from zero.
+
+      Counters have no defined 'initial' value, and thus, a
+      single value of a counter has (in general) no information
+      content.  Discontinuities in the monotonically increasing
+      value normally occur at re-initialization of the
+      management system, and at other times as specified in the
+      description of a schema node using this type.  If such
+      other times can occur, for example, the creation of
+      a schema node of type counter64 at times other than
+      re-initialization, then a corresponding schema node
+      should be defined, with an appropriate type, to indicate
+      the last discontinuity.
+
+      The counter64 type should not be used for configuration
+      schema nodes.  A default statement SHOULD NOT be used in
+      combination with the type counter64.
+
+      In the value set and its semantics, this type is equivalent
+      to the Counter64 type of the SMIv2.";
+    reference
+     "RFC 2578: Structure of Management Information Version 2
+                (SMIv2)";
+  }
+
+  typedef zero-based-counter64 {
+    type yang:counter64;
+    default "0";
+    description
+     "The zero-based-counter64 type represents a counter64 that
+      has the defined 'initial' value zero.
+
+      A schema node of this type will be set to zero (0) on creation
+      and will thereafter increase monotonically until it reaches
+      a maximum value of 2^64-1 (18446744073709551615 decimal),
+      when it wraps around and starts increasing again from zero.
+
+      Provided that an application discovers a new schema node
+      of this type within the minimum time to wrap, it can use the
+      'initial' value as a delta.  It is important for a management
+      station to be aware of this minimum time and the actual time
+      between polls, and to discard data if the actual time is too
+      long or there is no defined minimum time.
+
+      In the value set and its semantics, this type is equivalent
+      to the ZeroBasedCounter64 textual convention of the SMIv2.";
+    reference
+     "RFC 2856: Textual Conventions for Additional High Capacity
+                Data Types";
+  }
+
+  typedef gauge32 {
+    type uint32;
+    description
+     "The gauge32 type represents a non-negative integer, which
+      may increase or decrease, but shall never exceed a maximum
+      value, nor fall below a minimum value.  The maximum value
+      cannot be greater than 2^32-1 (4294967295 decimal), and
+      the minimum value cannot be smaller than 0.  The value of
+      a gauge32 has its maximum value whenever the information
+      being modeled is greater than or equal to its maximum
+      value, and has its minimum value whenever the information
+      being modeled is smaller than or equal to its minimum value.
+      If the information being modeled subsequently decreases
+      below (increases above) the maximum (minimum) value, the
+      gauge32 also decreases (increases).
+
+      In the value set and its semantics, this type is equivalent
+      to the Gauge32 type of the SMIv2.";
+    reference
+     "RFC 2578: Structure of Management Information Version 2
+                (SMIv2)";
+  }
+
+  typedef gauge64 {
+    type uint64;
+    description
+     "The gauge64 type represents a non-negative integer, which
+      may increase or decrease, but shall never exceed a maximum
+      value, nor fall below a minimum value.  The maximum value
+      cannot be greater than 2^64-1 (18446744073709551615), and
+      the minimum value cannot be smaller than 0.  The value of
+      a gauge64 has its maximum value whenever the information
+      being modeled is greater than or equal to its maximum
+      value, and has its minimum value whenever the information
+      being modeled is smaller than or equal to its minimum value.
+      If the information being modeled subsequently decreases
+      below (increases above) the maximum (minimum) value, the
+      gauge64 also decreases (increases).
+
+      In the value set and its semantics, this type is equivalent
+      to the CounterBasedGauge64 SMIv2 textual convention defined
+      in RFC 2856";
+    reference
+     "RFC 2856: Textual Conventions for Additional High Capacity
+                Data Types";
+  }
+
+  /*** collection of identifier related types ***/
+
+  typedef object-identifier {
+    type string {
+      pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))'
+            + '(\.(0|([1-9]\d*)))*';
+    }
+    description
+     "The object-identifier type represents administratively
+      assigned names in a registration-hierarchical-name tree.
+
+      Values of this type are denoted as a sequence of numerical
+      non-negative sub-identifier values.  Each sub-identifier
+      value MUST NOT exceed 2^32-1 (4294967295).  Sub-identifiers
+      are separated by single dots and without any intermediate
+      whitespace.
+
+      The ASN.1 standard restricts the value space of the first
+      sub-identifier to 0, 1, or 2.  Furthermore, the value space
+      of the second sub-identifier is restricted to the range
+      0 to 39 if the first sub-identifier is 0 or 1.  Finally,
+      the ASN.1 standard requires that an object identifier
+      has always at least two sub-identifier.  The pattern
+      captures these restrictions.
+
+      Although the number of sub-identifiers is not limited,
+      module designers should realize that there may be
+      implementations that stick with the SMIv2 limit of 128
+      sub-identifiers.
+
+      This type is a superset of the SMIv2 OBJECT IDENTIFIER type
+      since it is not restricted to 128 sub-identifiers.  Hence,
+      this type SHOULD NOT be used to represent the SMIv2 OBJECT
+      IDENTIFIER type, the object-identifier-128 type SHOULD be
+      used instead.";
+    reference
+     "ISO9834-1: Information technology -- Open Systems
+      Interconnection -- Procedures for the operation of OSI
+      Registration Authorities: General procedures and top
+      arcs of the ASN.1 Object Identifier tree";
+  }
+
+  typedef object-identifier-128 {
+    type object-identifier {
+      pattern '\d*(\.\d*){1,127}';
+    }
+    description
+     "This type represents object-identifiers restricted to 128
+      sub-identifiers.
+
+      In the value set and its semantics, this type is equivalent
+      to the OBJECT IDENTIFIER type of the SMIv2.";
+    reference
+     "RFC 2578: Structure of Management Information Version 2
+                (SMIv2)";
+  }
+
+  typedef yang-identifier {
+    type string {
+      length "1..max";
+      pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*';
+      pattern '.|..|[^xX].*|.[^mM].*|..[^lL].*';
+    }
+    description
+      "A YANG identifier string as defined in RFC 6020, page 163.
+       An identifier must start with an alphabetic character or
+       an underscore followed by an arbitrary sequence of
+       alphabetic or numeric characters, underscores, hyphens
+       or dots.
+
+       A YANG identifier MUST NOT start with any possible
+       combination of the lower-case or upper-case character
+       sequence 'xml'.";
+    reference
+      "RFC 6020: YANG - A Data Modeling Language for the Network
+                 Configuration Protocol (NETCONF)";
+  }
+
+  /*** collection of date and time related types ***/
+
+  typedef date-and-time {
+    type string {
+      pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+            + '(Z|[\+\-]\d{2}:\d{2})';
+    }
+    description
+     "The date-and-time type is a profile of the ISO 8601
+      standard for representation of dates and times using the
+      Gregorian calendar.  The profile is defined by the
+      date-time production in Section 5.6 of RFC 3339.
+
+      The date-and-time type is compatible with the dateTime XML
+      schema type with the following notable exceptions:
+
+      (a) The date-and-time type does not allow negative years.
+
+      (b) The date-and-time time-offset -00:00 indicates an unknown
+          time zone (see RFC 3339) while -00:00 and +00:00 and Z all
+          represent the same time zone in dateTime.
+
+      (c) The canonical format (see below) of data-and-time values
+          differs from the canonical format used by the dateTime XML
+          schema type, which requires all times to be in UTC using
+          the time-offset 'Z'.
+
+      This type is not equivalent to the DateAndTime textual
+      convention of the SMIv2 since RFC 3339 uses a different
+      separator between full-date and full-time and provides
+      higher resolution of time-secfrac.
+      The canonical format for date-and-time values with a known time
+      zone uses a numeric time zone offset that is calculated using
+      the device's configured known offset to UTC time.  A change of
+      the device's offset to UTC time will cause date-and-time values
+      to change accordingly.  Such changes might happen periodically
+      in case a server follows automatically daylight saving time
+      (DST) time zone offset changes.  The canonical format for
+      date-and-time values with an unknown time zone (usually
+      referring to the notion of local time) uses the time-offset
+      -00:00.";
+    reference
+     "RFC 3339: Date and Time on the Internet: Timestamps
+      RFC 2579: Textual Conventions for SMIv2
+      XSD-TYPES: XML Schema Part 2: Datatypes Second Edition";
+  }
+
+  typedef timeticks {
+    type uint32;
+    description
+     "The timeticks type represents a non-negative integer that
+      represents the time, modulo 2^32 (4294967296 decimal), in
+      hundredths of a second between two epochs.  When a schema
+      node is defined that uses this type, the description of
+      the schema node identifies both of the reference epochs.
+
+      In the value set and its semantics, this type is equivalent
+      to the TimeTicks type of the SMIv2.";
+    reference
+     "RFC 2578: Structure of Management Information Version 2
+                (SMIv2)";
+  }
+
+  typedef timestamp {
+    type yang:timeticks;
+    description
+     "The timestamp type represents the value of an associated
+      timeticks schema node at which a specific occurrence
+      happened. The specific occurrence must be defined in the
+      description of any schema node defined using this type.  When
+      the specific occurrence occurred prior to the last time the
+      associated timeticks attribute was zero, then the timestamp
+      value is zero.  Note that this requires all timestamp values
+      to be reset to zero when the value of the associated timeticks
+      attribute reaches 497+ days and wraps around to zero.
+
+      The associated timeticks schema node must be specified
+      in the description of any schema node using this type.
+      In the value set and its semantics, this type is equivalent
+      to the TimeStamp textual convention of the SMIv2.";
+    reference
+     "RFC 2579: Textual Conventions for SMIv2";
+  }
+
+  /*** collection of generic address types ***/
+
+  typedef phys-address {
+    type string {
+      pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+    }
+    description
+     "Represents media- or physical-level addresses represented
+      as a sequence octets, each octet represented by two hexadecimal
+      numbers.  Octets are separated by colons.  The canonical
+      representation uses lowercase characters.
+
+      In the value set and its semantics, this type is equivalent
+      to the PhysAddress textual convention of the SMIv2.";
+    reference
+     "RFC 2579: Textual Conventions for SMIv2";
+  }
+
+  typedef mac-address {
+    type string {
+      pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}';
+    }
+    description
+     "The mac-address type represents an IEEE 802 MAC address.
+      The canonical representation uses lowercase characters.
+
+      In the value set and its semantics, this type is equivalent
+      to the MacAddress textual convention of the SMIv2.";
+    reference
+     "IEEE 802: IEEE Standard for Local and Metropolitan Area
+                Networks: Overview and Architecture
+      RFC 2579: Textual Conventions for SMIv2";
+  }
+
+  /*** collection of XML specific types ***/
+
+  typedef xpath1.0 {
+    type string;
+    description
+     "This type represents an XPATH 1.0 expression.
+
+      When a schema node is defined that uses this type, the
+      description of the schema node MUST specify the XPath
+      context in which the XPath expression is evaluated.";
+    reference
+     "XPATH: XML Path Language (XPath) Version 1.0";
+  }
+
+  /*** collection of string types ***/
+
+  typedef hex-string {
+    type string {
+      pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+    }
+    description
+     "A hexadecimal string with octets represented as hex digits
+      separated by colons.  The canonical representation uses
+      lowercase characters.";
+  }
+
+  typedef uuid {
+    type string {
+      pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-'
+            + '[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';
+    }
+    description
+     "A Universally Unique IDentifier in the string representation
+      defined in RFC 4122.  The canonical representation uses
+      lowercase characters.
+
+      The following is an example of a UUID in string representation:
+      f81d4fae-7dec-11d0-a765-00a0c91e6bf6
+      ";
+    reference
+     "RFC 4122: A Universally Unique IDentifier (UUID) URN
+                Namespace";
+  }
+
+  typedef dotted-quad {
+    type string {
+      pattern
+        '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+      + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
+    }
+    description
+      "An unsigned 32-bit number expressed in the dotted-quad
+       notation, i.e., four octets written as decimal numbers
+       and separated with the '.' (full stop) character.";
+  }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-yang-types@2013-07-15.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/full/ietf-yang-types@2013-07-15.yang
new file mode 100644 (file)
index 0000000..bdff18c
--- /dev/null
@@ -0,0 +1,467 @@
+module ietf-yang-types {
+
+     namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+     prefix "yang";
+
+     organization
+      "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+     contact
+      "WG Web:   <http://tools.ietf.org/wg/netmod/>
+       WG List:  <mailto:netmod@ietf.org>
+       WG Chair: David Kessens
+                 <mailto:david.kessens@nsn.com>
+
+       WG Chair: Juergen Schoenwaelder
+                 <mailto:j.schoenwaelder@jacobs-university.de>
+
+       Editor:   Juergen Schoenwaelder
+                 <mailto:j.schoenwaelder@jacobs-university.de>";
+
+     description
+      "This module contains a collection of generally useful derived
+       YANG data types.
+
+       Copyright (c) 2013 IETF Trust and the persons identified as
+       authors of the code.  All rights reserved.
+
+       Redistribution and use in source and binary forms, with or
+       without modification, is permitted pursuant to, and subject
+       to the license terms contained in, the Simplified BSD License
+       set forth in Section 4.c of the IETF Trust's Legal Provisions
+       Relating to IETF Documents
+       (http://trustee.ietf.org/license-info).
+
+       This version of this YANG module is part of RFC 6991; see
+       the RFC itself for full legal notices.";
+
+     revision 2013-07-15 {
+       description
+        "This revision adds the following new data types:
+         - yang-identifier
+         - hex-string
+         - uuid
+         - dotted-quad";
+       reference
+        "RFC 6991: Common YANG Data Types";
+     }
+
+     revision 2010-09-24 {
+       description
+        "Initial revision.";
+       reference
+        "RFC 6021: Common YANG Data Types";
+     }
+
+     /*** collection of counter and gauge types ***/
+
+     typedef counter32 {
+       type uint32;
+       description
+        "The counter32 type represents a non-negative integer
+         that monotonically increases until it reaches a
+         maximum value of 2^32-1 (4294967295 decimal), when it
+         wraps around and starts increasing again from zero.
+
+         Counters have no defined 'initial' value, and thus, a
+         single value of a counter has (in general) no information
+         content.  Discontinuities in the monotonically increasing
+         value normally occur at re-initialization of the
+         management system, and at other times as specified in the
+         description of a schema node using this type.  If such
+         other times can occur, for example, the creation of
+         a schema node of type counter32 at times other than
+         re-initialization, then a corresponding schema node
+         should be defined, with an appropriate type, to indicate
+         the last discontinuity.
+
+         The counter32 type should not be used for configuration
+         schema nodes.  A default statement SHOULD NOT be used in
+         combination with the type counter32.
+
+         In the value set and its semantics, this type is equivalent
+         to the Counter32 type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef zero-based-counter32 {
+       type yang:counter32;
+       default "0";
+       description
+        "The zero-based-counter32 type represents a counter32
+         that has the defined 'initial' value zero.
+
+         A schema node of this type will be set to zero (0) on creation
+         and will thereafter increase monotonically until it reaches
+         a maximum value of 2^32-1 (4294967295 decimal), when it
+         wraps around and starts increasing again from zero.
+
+         Provided that an application discovers a new schema node
+         of this type within the minimum time to wrap, it can use the
+         'initial' value as a delta.  It is important for a management
+         station to be aware of this minimum time and the actual time
+         between polls, and to discard data if the actual time is too
+         long or there is no defined minimum time.
+        In the value set and its semantics, this type is equivalent
+         to the ZeroBasedCounter32 textual convention of the SMIv2.";
+       reference
+         "RFC 4502: Remote Network Monitoring Management Information
+                    Base Version 2";
+     }
+
+     typedef counter64 {
+       type uint64;
+       description
+        "The counter64 type represents a non-negative integer
+         that monotonically increases until it reaches a
+         maximum value of 2^64-1 (18446744073709551615 decimal),
+         when it wraps around and starts increasing again from zero.
+
+         Counters have no defined 'initial' value, and thus, a
+         single value of a counter has (in general) no information
+         content.  Discontinuities in the monotonically increasing
+         value normally occur at re-initialization of the
+         management system, and at other times as specified in the
+         description of a schema node using this type.  If such
+         other times can occur, for example, the creation of
+         a schema node of type counter64 at times other than
+         re-initialization, then a corresponding schema node
+         should be defined, with an appropriate type, to indicate
+         the last discontinuity.
+
+         The counter64 type should not be used for configuration
+         schema nodes.  A default statement SHOULD NOT be used in
+         combination with the type counter64.
+
+         In the value set and its semantics, this type is equivalent
+         to the Counter64 type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef zero-based-counter64 {
+       type yang:counter64;
+       default "0";
+       description
+        "The zero-based-counter64 type represents a counter64 that
+         has the defined 'initial' value zero.
+         A schema node of this type will be set to zero (0) on creation
+         and will thereafter increase monotonically until it reaches
+         a maximum value of 2^64-1 (18446744073709551615 decimal),
+         when it wraps around and starts increasing again from zero.
+
+         Provided that an application discovers a new schema node
+         of this type within the minimum time to wrap, it can use the
+         'initial' value as a delta.  It is important for a management
+         station to be aware of this minimum time and the actual time
+         between polls, and to discard data if the actual time is too
+         long or there is no defined minimum time.
+
+         In the value set and its semantics, this type is equivalent
+         to the ZeroBasedCounter64 textual convention of the SMIv2.";
+       reference
+        "RFC 2856: Textual Conventions for Additional High Capacity
+                   Data Types";
+     }
+
+     typedef gauge32 {
+       type uint32;
+       description
+        "The gauge32 type represents a non-negative integer, which
+         may increase or decrease, but shall never exceed a maximum
+         value, nor fall below a minimum value.  The maximum value
+         cannot be greater than 2^32-1 (4294967295 decimal), and
+         the minimum value cannot be smaller than 0.  The value of
+         a gauge32 has its maximum value whenever the information
+         being modeled is greater than or equal to its maximum
+         value, and has its minimum value whenever the information
+         being modeled is smaller than or equal to its minimum value.
+         If the information being modeled subsequently decreases
+         below (increases above) the maximum (minimum) value, the
+         gauge32 also decreases (increases).
+
+         In the value set and its semantics, this type is equivalent
+         to the Gauge32 type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef gauge64 {
+       type uint64;
+       description
+        "The gauge64 type represents a non-negative integer, which
+         may increase or decrease, but shall never exceed a maximum
+         value, nor fall below a minimum value.  The maximum value
+         cannot be greater than 2^64-1 (18446744073709551615), and
+         the minimum value cannot be smaller than 0.  The value of
+         a gauge64 has its maximum value whenever the information
+         being modeled is greater than or equal to its maximum
+         value, and has its minimum value whenever the information
+         being modeled is smaller than or equal to its minimum value.
+         If the information being modeled subsequently decreases
+         below (increases above) the maximum (minimum) value, the
+         gauge64 also decreases (increases).
+
+         In the value set and its semantics, this type is equivalent
+         to the CounterBasedGauge64 SMIv2 textual convention defined
+         in RFC 2856";
+       reference
+        "RFC 2856: Textual Conventions for Additional High Capacity
+                   Data Types";
+     }
+
+     /*** collection of identifier-related types ***/
+
+     typedef object-identifier {
+       type string {
+         pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))'
+               + '(\.(0|([1-9]\d*)))*';
+       }
+       description
+        "The object-identifier type represents administratively
+         assigned names in a registration-hierarchical-name tree.
+
+         Values of this type are denoted as a sequence of numerical
+         non-negative sub-identifier values.  Each sub-identifier
+         value MUST NOT exceed 2^32-1 (4294967295).  Sub-identifiers
+         are separated by single dots and without any intermediate
+         whitespace.
+
+         The ASN.1 standard restricts the value space of the first
+         sub-identifier to 0, 1, or 2.  Furthermore, the value space
+         of the second sub-identifier is restricted to the range
+         0 to 39 if the first sub-identifier is 0 or 1.  Finally,
+         the ASN.1 standard requires that an object identifier
+         has always at least two sub-identifiers.  The pattern
+         captures these restrictions.
+
+         Although the number of sub-identifiers is not limited,
+         module designers should realize that there may be
+         implementations that stick with the SMIv2 limit of 128
+         sub-identifiers.
+         This type is a superset of the SMIv2 OBJECT IDENTIFIER type
+         since it is not restricted to 128 sub-identifiers.  Hence,
+         this type SHOULD NOT be used to represent the SMIv2 OBJECT
+         IDENTIFIER type; the object-identifier-128 type SHOULD be
+         used instead.";
+       reference
+        "ISO9834-1: Information technology -- Open Systems
+         Interconnection -- Procedures for the operation of OSI
+         Registration Authorities: General procedures and top
+         arcs of the ASN.1 Object Identifier tree";
+     }
+
+     typedef object-identifier-128 {
+       type object-identifier {
+         pattern '\d*(\.\d*){1,127}';
+       }
+       description
+        "This type represents object-identifiers restricted to 128
+         sub-identifiers.
+
+         In the value set and its semantics, this type is equivalent
+         to the OBJECT IDENTIFIER type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef yang-identifier {
+       type string {
+         length "1..max";
+         pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*';
+         pattern '.|..|[^xX].*|.[^mM].*|..[^lL].*';
+       }
+       description
+         "A YANG identifier string as defined by the 'identifier'
+          rule in Section 12 of RFC 6020.  An identifier must
+          start with an alphabetic character or an underscore
+          followed by an arbitrary sequence of alphabetic or
+          numeric characters, underscores, hyphens, or dots.
+
+          A YANG identifier MUST NOT start with any possible
+          combination of the lowercase or uppercase character
+          sequence 'xml'.";
+       reference
+         "RFC 6020: YANG - A Data Modeling Language for the Network
+                    Configuration Protocol (NETCONF)";
+     }
+     /*** collection of types related to date and time***/
+
+     typedef date-and-time {
+       type string {
+         pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+               + '(Z|[\+\-]\d{2}:\d{2})';
+       }
+       description
+        "The date-and-time type is a profile of the ISO 8601
+         standard for representation of dates and times using the
+         Gregorian calendar.  The profile is defined by the
+         date-time production in Section 5.6 of RFC 3339.
+
+         The date-and-time type is compatible with the dateTime XML
+         schema type with the following notable exceptions:
+
+         (a) The date-and-time type does not allow negative years.
+
+         (b) The date-and-time time-offset -00:00 indicates an unknown
+             time zone (see RFC 3339) while -00:00 and +00:00 and Z
+             all represent the same time zone in dateTime.
+
+         (c) The canonical format (see below) of data-and-time values
+             differs from the canonical format used by the dateTime XML
+             schema type, which requires all times to be in UTC using
+             the time-offset 'Z'.
+
+         This type is not equivalent to the DateAndTime textual
+         convention of the SMIv2 since RFC 3339 uses a different
+         separator between full-date and full-time and provides
+         higher resolution of time-secfrac.
+
+         The canonical format for date-and-time values with a known time
+         zone uses a numeric time zone offset that is calculated using
+         the device's configured known offset to UTC time.  A change of
+         the device's offset to UTC time will cause date-and-time values
+         to change accordingly.  Such changes might happen periodically
+         in case a server follows automatically daylight saving time
+         (DST) time zone offset changes.  The canonical format for
+         date-and-time values with an unknown time zone (usually
+         referring to the notion of local time) uses the time-offset
+         -00:00.";
+       reference
+        "RFC 3339: Date and Time on the Internet: Timestamps
+         RFC 2579: Textual Conventions for SMIv2
+         XSD-TYPES: XML Schema Part 2: Datatypes Second Edition";
+     }
+     typedef timeticks {
+       type uint32;
+       description
+        "The timeticks type represents a non-negative integer that
+         represents the time, modulo 2^32 (4294967296 decimal), in
+         hundredths of a second between two epochs.  When a schema
+         node is defined that uses this type, the description of
+         the schema node identifies both of the reference epochs.
+
+         In the value set and its semantics, this type is equivalent
+         to the TimeTicks type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef timestamp {
+       type yang:timeticks;
+       description
+        "The timestamp type represents the value of an associated
+         timeticks schema node at which a specific occurrence
+         happened.  The specific occurrence must be defined in the
+         description of any schema node defined using this type.  When
+         the specific occurrence occurred prior to the last time the
+         associated timeticks attribute was zero, then the timestamp
+         value is zero.  Note that this requires all timestamp values
+         to be reset to zero when the value of the associated timeticks
+         attribute reaches 497+ days and wraps around to zero.
+
+         The associated timeticks schema node must be specified
+         in the description of any schema node using this type.
+
+         In the value set and its semantics, this type is equivalent
+         to the TimeStamp textual convention of the SMIv2.";
+       reference
+        "RFC 2579: Textual Conventions for SMIv2";
+     }
+
+     /*** collection of generic address types ***/
+
+     typedef phys-address {
+       type string {
+         pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+       }
+       description
+        "Represents media- or physical-level addresses represented
+         as a sequence octets, each octet represented by two hexadecimal
+         numbers.  Octets are separated by colons.  The canonical
+         representation uses lowercase characters.
+
+         In the value set and its semantics, this type is equivalent
+         to the PhysAddress textual convention of the SMIv2.";
+       reference
+        "RFC 2579: Textual Conventions for SMIv2";
+     }
+
+     typedef mac-address {
+       type string {
+         pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}';
+       }
+       description
+        "The mac-address type represents an IEEE 802 MAC address.
+         The canonical representation uses lowercase characters.
+
+         In the value set and its semantics, this type is equivalent
+         to the MacAddress textual convention of the SMIv2.";
+       reference
+        "IEEE 802: IEEE Standard for Local and Metropolitan Area
+                   Networks: Overview and Architecture
+         RFC 2579: Textual Conventions for SMIv2";
+     }
+
+     /*** collection of XML-specific types ***/
+
+     typedef xpath1.0 {
+       type string;
+       description
+        "This type represents an XPATH 1.0 expression.
+
+         When a schema node is defined that uses this type, the
+         description of the schema node MUST specify the XPath
+         context in which the XPath expression is evaluated.";
+       reference
+        "XPATH: XML Path Language (XPath) Version 1.0";
+     }
+
+     /*** collection of string types ***/
+
+     typedef hex-string {
+       type string {
+         pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+       }
+       description
+        "A hexadecimal string with octets represented as hex digits
+         separated by colons.  The canonical representation uses
+         lowercase characters.";
+     }
+
+     typedef uuid {
+       type string {
+         pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-'
+               + '[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';
+       }
+       description
+        "A Universally Unique IDentifier in the string representation
+         defined in RFC 4122.  The canonical representation uses
+         lowercase characters.
+
+         The following is an example of a UUID in string representation:
+         f81d4fae-7dec-11d0-a765-00a0c91e6bf6
+         ";
+       reference
+        "RFC 4122: A Universally Unique IDentifier (UUID) URN
+                   Namespace";
+     }
+
+     typedef dotted-quad {
+       type string {
+         pattern
+           '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+         + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
+       }
+       description
+         "An unsigned 32-bit number expressed in the dotted-quad
+          notation, i.e., four octets written as decimal numbers
+          and separated with the '.' (full stop) character.";
+     }
+   }
\ No newline at end of file
index 283fd414dca216b11077107c2358a747373aca2a..1c8210e000e390f6447630f13a5afca37664f1f2 100644 (file)
@@ -8,6 +8,8 @@ module importedrevtest {
     revision 2015-05-02;
 
     typedef date-and-time {
-      type string;
+        type string {
+            pattern "[0-9]+";
+        }
     }
 }
\ No newline at end of file
index 6c025039e6643f7c440b712005bb79f1d44a87b2..b0104daaff87d8f49bf2831ca1dd45540ac7c0ce 100644 (file)
@@ -8,6 +8,8 @@ module importedrevtest {
     revision 2015-06-02;
 
     typedef date-and-time {
-      type string;
+        type string {
+            pattern "[0-9]+";
+        }
     }
 }
\ No newline at end of file
index d532636d7715c675f80f0c7b3c57f7b08a4f2055..f50d90b9898bbd1a45d9e7ba5132c5beace30d35 100644 (file)
@@ -8,6 +8,8 @@ module importedrevtest {
     revision 2015-08-02;
 
     typedef date-and-time {
-      type string;
+        type string {
+            pattern "[0-9]+";
+        }
     }
 }
\ No newline at end of file
index 5ad34ecaebc50af7695d11e65afbde5b6b6034b9..e4046a4f9b57d6e9f3a2e5089e4d67cea5fdef0e 100644 (file)
@@ -8,6 +8,8 @@ module importedrevtest {
     revision 2015-09-02;
 
     typedef date-and-time {
-      type string;
+        type string {
+            pattern "[0-9]+";
+        }
     }
 }
\ No newline at end of file
@@ -5,9 +5,11 @@ module importedrevtest {
 
     description "This is a test module";
 
-    revision 2015-07-02;
+    revision 2015-04-02;
 
     typedef date-and-time {
-      type string;
+        type string {
+            pattern "[0-9]+";
+        }
     }
-}
\ No newline at end of file
+}
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-interfaces.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-interfaces.yang
new file mode 100644 (file)
index 0000000..24afaad
--- /dev/null
@@ -0,0 +1,13 @@
+module ietf-interfaces {
+
+    namespace "urn:ietf:params:xml:ns:yang:ietf-interfaces";
+    prefix if;
+
+    import ietf-yang-types { prefix yang; revision-date 2010-09-24; }
+
+    revision 2012-11-15;
+
+    leaf last-change {
+        type yang:date-and-time;
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-netconf-monitoring.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-netconf-monitoring.yang
new file mode 100644 (file)
index 0000000..5fb888b
--- /dev/null
@@ -0,0 +1,15 @@
+module ietf-netconf-monitoring {
+
+    yang-version 1;
+
+    namespace
+        "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring";
+
+    prefix ncm;
+
+    import ietf-yang-types { prefix yang; }
+
+    leaf locked-time {
+        type yang:date-and-time;
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-yang-types.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-yang-types.yang
new file mode 100644 (file)
index 0000000..071a24f
--- /dev/null
@@ -0,0 +1,14 @@
+ module ietf-yang-types {
+
+    namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+    prefix "yang";
+
+    revision 2010-09-24;
+
+    typedef date-and-time {
+        type string {
+            pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+            + '(Z|[\+\-]\d{2}:\d{2})';
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-yang-types@2013-05-16.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-yang-types@2013-05-16.yang
new file mode 100644 (file)
index 0000000..21e9279
--- /dev/null
@@ -0,0 +1,16 @@
+module ietf-yang-types {
+
+    namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+    prefix "yang";
+
+    revision 2013-05-16;
+
+    revision 2010-09-24;
+
+    typedef date-and-time {
+        type string {
+            pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+            + '(Z|[\+\-]\d{2}:\d{2})';
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-yang-types@2013-07-15.yang b/yang/yang-parser-impl/src/test/resources/semantic-statement-parser/multiple-revisions/simple/ietf-yang-types@2013-07-15.yang
new file mode 100644 (file)
index 0000000..3ee48ab
--- /dev/null
@@ -0,0 +1,16 @@
+module ietf-yang-types {
+
+    namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+    prefix "yang";
+
+    revision 2013-07-15;
+
+    revision 2010-09-24;
+
+    typedef date-and-time {
+        type string {
+            pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+            + '(Z|[\+\-]\d{2}:\d{2})';
+        }
+    }
+}
index 2600dd472694ae330c0d91306a3c43231ce1e864..a643c1f298d195b118b4ef5eff2d5028956f78d8 100644 (file)
@@ -3,17 +3,17 @@ module testrev {
     namespace "urn:tstrev:yang";
     prefix "tstrev";
 
-    import importedrevtest {
-        prefix "imprevtst";
-    }
+    import importedrevtest { prefix "imprevtst"; }
 
     description "This is a test module";
 
-    revision 2015-07-02;
+    revision 2001-01-01 {
+        description "initial version";
+    }
 
     container mycontainer {
         leaf myleaf {
             type imprevtst:date-and-time;
         }
     }
-}
\ No newline at end of file
+}