Bug 7038 - Rework 'type decimal64' lookup 24/54524/7
authorPeter Kajsa <pkajsa@cisco.com>
Thu, 23 Mar 2017 16:12:33 +0000 (17:12 +0100)
committerRobert Varga <nite@hq.sk>
Fri, 14 Apr 2017 11:27:20 +0000 (11:27 +0000)
Fix of hack in SourceSpecificContext, which attempts to lookup specific
complex types by considering only a QName's localName and routes
it via BUILTIN_TYPE_SUPPORTS to specific statement support.

This solution introduces argument specific statement sub-definitions.
If a StatementSupport has some argument specific sub-supports, processing
of a statement is routed to appropriate sub-support based on given
statement argument.

Change-Id: I602c0a919107a633f594a4393299f3f6623bd1c5
Signed-off-by: Peter Kajsa <pkajsa@cisco.com>
12 files changed:
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractStatementSupport.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/StatementSupport.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/SourceSpecificContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/StatementDefinitionContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/TypeStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/TypeStatementRfc7950Support.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug7038Test.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug7038/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug7038/foo.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug7038/yang10/foo.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug7038/yang11/foo.yang [new file with mode: 0644]

index 4f5c6b3a412cf0a11b6a152f894a47d56804531a..ab535769fc76a1c0b264539fb7a87ce3fad6f262 100644 (file)
@@ -141,6 +141,20 @@ public abstract class AbstractStatementSupport<A, D extends DeclaredStatement<A>
         return getPublicView().isArgumentYinElement();
     }
 
+    @Override
+    public boolean hasArgumentSpecificSupports() {
+        // Most of statement supports don't have any argument specific
+        // supports, so return 'false'.
+        return false;
+    }
+
+    @Override
+    public StatementSupport<?, ?, ?> getSupportSpecificForArgument(final String argument) {
+        // Most of statement supports don't have any argument specific
+        // supports, so return null.
+        return null;
+    }
+
     /**
      * Returns corresponding substatement validator of a statement support
      *
index 4ccffedb2c18a1ad7c1398e98bf065fcb675d78c..9eeeefc80ce45a21415b886fd7d8c9c144e67922 100644 (file)
@@ -9,6 +9,7 @@
 package org.opendaylight.yangtools.yang.parser.spi.meta;
 
 import java.util.Optional;
+import javax.annotation.Nullable;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
@@ -161,4 +162,21 @@ public interface StatementSupport<A, D extends DeclaredStatement<A>, E extends E
      * @throws SourceException when an inconsistency is detected.
      */
     void onFullDefinitionDeclared(StmtContext.Mutable<A, D, E> stmt);
+
+    /**
+     * Returns true if this support has argument specific supports.
+     */
+    boolean hasArgumentSpecificSupports();
+
+    /**
+     * If this support has argument specific supports, the method returns
+     * support specific for given argument (e.g. type statement support need to
+     * be specialized based on its argument), otherwise returns null.
+     *
+     * @param argument
+     *            argument of statement
+     * @return statement support specific for supplied argument or null
+     */
+    @Nullable
+    StatementSupport<?, ?, ?> getSupportSpecificForArgument(String argument);
 }
\ No newline at end of file
index cfbd93377cf5e4adecc7db49bf2b040031e07b83..ee72425c428943737255952f4491ce053c896b6d 100644 (file)
@@ -11,9 +11,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.base.Verify;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableTable;
 import com.google.common.collect.Multimap;
-import com.google.common.collect.Table;
 import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -27,10 +25,8 @@ import javax.annotation.Nullable;
 import org.opendaylight.yangtools.concepts.Mutable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.common.YangConstants;
 import org.opendaylight.yangtools.yang.common.YangVersion;
 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
-import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
@@ -58,19 +54,9 @@ import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinit
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReference;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.BitsSpecificationImpl;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Decimal64SpecificationImpl;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.EnumSpecificationImpl;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.IdentityRefSpecificationImpl;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.InstanceIdentifierSpecificationImpl;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.LeafrefSpecificationImpl;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.ModelDefinedStatementDefinition;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.UnionSpecificationImpl;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.UnknownStatementImpl;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.Utils;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.IdentityrefSpecificationRfc7950Support;
-import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.LeafrefSpecificationRfc7950Support;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -83,21 +69,6 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh
     }
 
     private static final Logger LOG = LoggerFactory.getLogger(SourceSpecificContext.class);
-    private static final Table<YangVersion, String, StatementSupport<?, ?, ?>> BUILTIN_TYPE_SUPPORTS =
-            ImmutableTable.<YangVersion, String, StatementSupport<?, ?, ?>>builder()
-            .put(YangVersion.VERSION_1, TypeUtils.DECIMAL64, new Decimal64SpecificationImpl.Definition())
-            .put(YangVersion.VERSION_1, TypeUtils.UNION, new UnionSpecificationImpl.Definition())
-            .put(YangVersion.VERSION_1, TypeUtils.ENUMERATION, new EnumSpecificationImpl.Definition())
-            .put(YangVersion.VERSION_1, TypeUtils.LEAF_REF, new LeafrefSpecificationImpl.Definition())
-            .put(YangVersion.VERSION_1_1, TypeUtils.LEAF_REF, new LeafrefSpecificationRfc7950Support())
-            .put(YangVersion.VERSION_1, TypeUtils.BITS, new BitsSpecificationImpl.Definition())
-            .put(YangVersion.VERSION_1, TypeUtils.IDENTITY_REF, new IdentityRefSpecificationImpl.Definition())
-            .put(YangVersion.VERSION_1_1, TypeUtils.IDENTITY_REF, new IdentityrefSpecificationRfc7950Support())
-            .put(YangVersion.VERSION_1, TypeUtils.INSTANCE_IDENTIFIER, new InstanceIdentifierSpecificationImpl.Definition())
-                    .build();
-
-    private static final QName TYPE = YangStmtMapping.TYPE.getStatementName();
-
     private final Multimap<ModelProcessingPhase, ModifierImpl> modifiers = HashMultimap.create();
     private final QNameToStatementDefinitionMap qNameToStmtDefMap = new QNameToStatementDefinitionMap();
     private final PrefixToModuleMap prefixToModuleMap = new PrefixToModuleMap();
@@ -128,7 +99,7 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh
     }
 
     StatementContextBase<?, ?, ?> createDeclaredChild(final StatementContextBase<?, ?, ?> current, final int childId,
-            QName name, final String argument, final StatementSourceReference ref) {
+            final QName name, final String argument, final StatementSourceReference ref) {
         if (current != null) {
             // Fast path: we are entering a statement which was emitted in previous phase
             StatementContextBase<?, ?, ?> existing = current.lookupSubstatement(childId);
@@ -140,24 +111,11 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh
             }
         }
 
-        // FIXME: BUG-7038: Refactor/clean up this special case
-        if (TYPE.equals(name)) {
-            SourceException.throwIfNull(argument, ref, "Type statement requires an argument");
-            if (TypeUtils.isYangTypeBodyStmtString(argument)) {
-                name = QName.create(YangConstants.RFC6020_YIN_MODULE, argument);
-            } else {
-                name = QName.create(YangConstants.RFC6020_YIN_MODULE, TYPE.getLocalName());
-            }
-        }
-
         StatementDefinitionContext<?, ?, ?> def = currentContext.getStatementDefinition(getRootVersion(), name);
         if (def == null) {
             final StatementSupport<?, ?, ?> extension = qNameToStmtDefMap.get(name);
             if (extension != null) {
                 def = new StatementDefinitionContext<>(extension);
-            } else {
-                // type-body-stmts
-                def = resolveTypeBodyStmts(name.getLocalName(), getRootVersion());
             }
         } else if (current != null && current.definition().getRepresentingClass().equals(UnknownStatementImpl.class)) {
             /*
@@ -180,6 +138,16 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh
             SourceException.throwIf(argument != null, ref, "Statement %s does not take argument", name);
         }
 
+        /*
+         * If the current statement definition has argument specific
+         * sub-definitions, get argument specific sub-definition based on given
+         * argument (e.g. type statement need to be specialized based on its
+         * argument).
+         */
+        if (def.hasArgumentSpecificSubDefinitions()) {
+            def = def.getSubDefinitionSpecificForArgument(argument);
+        }
+
         if (current != null) {
             return current.createSubstatement(childId, def, ref, argument);
         }
@@ -411,17 +379,6 @@ public class SourceSpecificContext implements NamespaceStorageNode, NamespaceBeh
         }
     }
 
-    private static StatementDefinitionContext<?, ?, ?> resolveTypeBodyStmts(final String typeArgument,
-            final YangVersion version) {
-        StatementSupport<?, ?, ?> support = BUILTIN_TYPE_SUPPORTS.get(version, typeArgument);
-
-        if (support == null) {
-            support = BUILTIN_TYPE_SUPPORTS.get(YangVersion.VERSION_1, typeArgument);
-        }
-
-        return support == null ? null : new StatementDefinitionContext<>(support);
-    }
-
     private PrefixToModule preLinkagePrefixes() {
         final PrefixToModuleMap preLinkagePrefixes = new PrefixToModuleMap(true);
         final Map<String, URI> prefixToNamespaceMap = getAllFromLocalStorage(ImpPrefixToNamespace.class);
index c1a1d2581aab85209b5184e6c2ddf742c42c8e2b..2db65cf6cb336fd6d415d372ef90d7c5d2d5677f 100644 (file)
@@ -10,7 +10,10 @@ package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 import com.google.common.base.MoreObjects;
 import com.google.common.base.MoreObjects.ToStringHelper;
 import com.google.common.base.Preconditions;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Optional;
+import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
@@ -25,9 +28,11 @@ import org.opendaylight.yangtools.yang.parser.spi.source.StatementSourceReferenc
 
 public class StatementDefinitionContext<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> {
     private final StatementSupport<A, D, E> support;
+    private final Map<String, StatementDefinitionContext<?, ?, ?>> argumentSpecificSubDefinitions;
 
     public StatementDefinitionContext(final StatementSupport<A, D, E> support) {
         this.support = Preconditions.checkNotNull(support);
+        this.argumentSpecificSubDefinitions = support.hasArgumentSpecificSupports() ? new HashMap<>() : null;
     }
 
     public StatementFactory<A,D,E> getFactory() {
@@ -96,4 +101,25 @@ public class StatementDefinitionContext<A, D extends DeclaredStatement<A>, E ext
     protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
         return toStringHelper.add("statement", getStatementName());
     }
+
+    @Nonnull
+    public StatementDefinitionContext<?, ?, ?> getSubDefinitionSpecificForArgument(final String argument) {
+        if (!hasArgumentSpecificSubDefinitions()) {
+            return this;
+        }
+
+        StatementDefinitionContext<?, ?, ?> potential = argumentSpecificSubDefinitions.get(argument);
+        if (potential == null) {
+            final StatementSupport<?, ?, ?> argumentSpecificSupport = support.getSupportSpecificForArgument(argument);
+            potential = argumentSpecificSupport != null ? new StatementDefinitionContext<>(argumentSpecificSupport)
+                    : this;
+            argumentSpecificSubDefinitions.put(argument, potential);
+        }
+
+        return potential;
+    }
+
+    public boolean hasArgumentSpecificSubDefinitions() {
+        return support.hasArgumentSpecificSupports();
+    }
 }
index 97326b64cd0ff1dffb26c14c01adb74eb00c5780..1525a5d119802d4587cad12cae9a7f8b4b5feea2 100644 (file)
@@ -8,7 +8,9 @@
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
 import com.google.common.base.Verify;
+import com.google.common.collect.ImmutableMap;
 import java.util.Collection;
+import java.util.Map;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
@@ -40,6 +42,7 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceAction;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
 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.source.SourceException;
@@ -83,6 +86,16 @@ public class TypeStatementImpl extends AbstractDeclaredStatement<String>
             extends
             AbstractStatementSupport<String, TypeStatement, EffectiveStatement<String, TypeStatement>> {
 
+        private static final Map<String, StatementSupport<?, ?, ?>> ARGUMENT_SPECIFIC_SUPPORTS = ImmutableMap
+                .<String, StatementSupport<?, ?, ?>> builder()
+                .put(TypeUtils.DECIMAL64, new Decimal64SpecificationImpl.Definition())
+                .put(TypeUtils.UNION, new UnionSpecificationImpl.Definition())
+                .put(TypeUtils.ENUMERATION, new EnumSpecificationImpl.Definition())
+                .put(TypeUtils.LEAF_REF, new LeafrefSpecificationImpl.Definition())
+                .put(TypeUtils.BITS, new BitsSpecificationImpl.Definition())
+                .put(TypeUtils.IDENTITY_REF, new IdentityRefSpecificationImpl.Definition())
+                .put(TypeUtils.INSTANCE_IDENTIFIER, new InstanceIdentifierSpecificationImpl.Definition()).build();
+
         public Definition() {
             super(YangStmtMapping.TYPE);
         }
@@ -229,6 +242,16 @@ public class TypeStatementImpl extends AbstractDeclaredStatement<String>
         protected SubstatementValidator getSubstatementValidator() {
             return SUBSTATEMENT_VALIDATOR;
         }
+
+        @Override
+        public boolean hasArgumentSpecificSupports() {
+            return !ARGUMENT_SPECIFIC_SUPPORTS.isEmpty();
+        }
+
+        @Override
+        public StatementSupport<?, ?, ?> getSupportSpecificForArgument(final String argument) {
+            return ARGUMENT_SPECIFIC_SUPPORTS.get(argument);
+        }
     }
 
     @Nonnull
index e7c5828a3e0105763c17029d5c3b17d91be44ec6..b43e4bc8bf762647d14950e194d69715a0e51a72 100644 (file)
@@ -84,6 +84,7 @@ import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.PatternStatementRfc79
 import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.RefineStatementRfc7950Support;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.RpcStatementRfc7950Support;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.SubmoduleStatementRfc7950Support;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc7950.TypeStatementRfc7950Support;
 
 public final class YangInferencePipeline {
     public static final Set<YangVersion> SUPPORTED_VERSIONS = Sets.immutableEnumSet(VERSION_1, VERSION_1_1);
@@ -161,7 +162,8 @@ public final class YangInferencePipeline {
             .addSupport(global(IdentityNamespace.class))
             .addSupport(new DefaultStatementImpl.Definition())
             .addSupport(new StatusStatementImpl.Definition())
-            .addSupport(new TypeStatementImpl.Definition())
+            .addVersionSpecificSupport(VERSION_1, new TypeStatementImpl.Definition())
+            .addVersionSpecificSupport(VERSION_1_1, new TypeStatementRfc7950Support())
             .addSupport(new UnitsStatementImpl.Definition())
             .addSupport(new RequireInstanceStatementImpl.Definition())
             .addVersionSpecificSupport(VERSION_1, new BitStatementImpl.Definition())
diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/TypeStatementRfc7950Support.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc7950/TypeStatementRfc7950Support.java
new file mode 100644 (file)
index 0000000..25127b7
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.parser.stmt.rfc7950;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableMap;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeStatementImpl;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.TypeUtils;
+
+/**
+ * Class providing necessary support for processing YANG 1.1 Type statement.
+ */
+@Beta
+public final class TypeStatementRfc7950Support extends TypeStatementImpl.Definition {
+    private static final Map<String, StatementSupport<?, ?, ?>> ARGUMENT_SPECIFIC_SUPPORTS = ImmutableMap
+            .<String, StatementSupport<?, ?, ?>> builder()
+            .put(TypeUtils.LEAF_REF, new LeafrefSpecificationRfc7950Support())
+            .put(TypeUtils.IDENTITY_REF, new IdentityrefSpecificationRfc7950Support()).build();
+
+    @Override
+    public boolean hasArgumentSpecificSupports() {
+        return !ARGUMENT_SPECIFIC_SUPPORTS.isEmpty() || super.hasArgumentSpecificSupports();
+    }
+
+    @Override
+    public StatementSupport<?, ?, ?> getSupportSpecificForArgument(final String argument) {
+        final StatementSupport<?, ?, ?> potential = ARGUMENT_SPECIFIC_SUPPORTS.get(argument);
+        return potential != null ? potential : super.getSupportSpecificForArgument(argument);
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug7038Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug7038Test.java
new file mode 100644 (file)
index 0000000..1143db4
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
+
+public class Bug7038Test {
+    @Test
+    public void unknownNodeTest() throws Exception {
+        final SchemaContext context = StmtTestUtils.parseYangSources("/bugs/bug7038");
+        assertNotNull(context);
+        assertEquals(1, context.getUnknownSchemaNodes().size());
+    }
+
+    @Test
+    public void testYang11() throws Exception {
+        final SchemaContext context = StmtTestUtils.parseYangSources("/bugs/bug7038/yang11");
+        assertNotNull(context);
+    }
+
+    @Test
+    public void testYang10() throws Exception {
+        try {
+            StmtTestUtils.parseYangSources("/bugs/bug7038/yang10");
+        } catch (final SomeModifiersUnresolvedException e) {
+            assertTrue(e.getCause().getMessage().startsWith("REQUIRE_INSTANCE is not valid for TYPE"));
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug7038/bar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug7038/bar.yang
new file mode 100644 (file)
index 0000000..fa6f484
--- /dev/null
@@ -0,0 +1,8 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    import foo { prefix decimal64; revision-date 1970-01-01; }
+
+    decimal64:decimal64 decimal64;
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug7038/foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug7038/foo.yang
new file mode 100644 (file)
index 0000000..7ffabf5
--- /dev/null
@@ -0,0 +1,8 @@
+module foo {
+    namespace foo;
+    prefix foo;
+
+    extension decimal64 {
+        argument arg;
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug7038/yang10/foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug7038/yang10/foo.yang
new file mode 100644 (file)
index 0000000..c40e633
--- /dev/null
@@ -0,0 +1,17 @@
+module foo {
+    namespace foo;
+    prefix foo;
+    yang-version 1;
+
+    container root {
+        leaf my-leafref {
+            type leafref {
+                path "../target";
+                require-instance false;
+            }
+        }
+        leaf target {
+            type string;
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug7038/yang11/foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug7038/yang11/foo.yang
new file mode 100644 (file)
index 0000000..ee77e86
--- /dev/null
@@ -0,0 +1,17 @@
+module foo {
+    namespace foo;
+    prefix foo;
+    yang-version 1.1;
+
+    container root {
+        leaf my-leafref {
+            type leafref {
+                path "../target";
+                require-instance false;
+            }
+        }
+        leaf target {
+            type string;
+        }
+    }
+}