From d601e4b48e111846c005b6f773634e7a5c28e89f Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 21 Dec 2021 14:22:03 +0100 Subject: [PATCH] Refactor augment generator linkage The uses/augment and module/augment cases are quite different from the perspective how we map their argument reference to generators. The uses/augment case is quite simple, as it refers to grouping's nodes, not augmentations. The only variation we need to account for is the skip back to the defining grouping. The module/augment case, on the other hand, is more complex, as it can refer to augmentations -- hence it need to account for changes namespace changes along uses/grouping as well as back from grouping child to augmentations. JIRA: MDSAL-715 Change-Id: I7425301afa6de566d985d19450ccfc64ea527119 Signed-off-by: Robert Varga --- .../reactor/AbstractCompositeGenerator.java | 70 +++++++++++++++---- .../reactor/AbstractExplicitGenerator.java | 24 ------- .../impl/reactor/GeneratorContext.java | 16 ++++- .../impl/reactor/GeneratorReactor.java | 27 ++----- .../impl/reactor/ModuleAugmentGenerator.java | 18 ++--- .../impl/reactor/UsesAugmentGenerator.java | 45 +++--------- .../binding/generator/impl/Mdsal715Test.java | 22 ++++++ .../resources/mdsal715/test-module-1.yang | 14 ++++ .../resources/mdsal715/test-module-2.yang | 14 ++++ .../resources/mdsal715/test-module-3.yang | 8 +++ .../resources/mdsal715/test-module-4.yang | 18 +++++ 11 files changed, 165 insertions(+), 111 deletions(-) create mode 100644 binding/mdsal-binding-generator/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal715Test.java create mode 100644 binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-1.yang create mode 100644 binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-2.yang create mode 100644 binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-3.yang create mode 100644 binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-4.yang diff --git a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractCompositeGenerator.java b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractCompositeGenerator.java index f75c0e6ac3..13776a5284 100644 --- a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractCompositeGenerator.java +++ b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractCompositeGenerator.java @@ -23,6 +23,7 @@ import org.opendaylight.mdsal.binding.model.api.GeneratedType; import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilder; import org.opendaylight.mdsal.binding.model.ri.BindingTypes; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.AddedByUsesAware; import org.opendaylight.yangtools.yang.model.api.CopyableNode; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; @@ -42,6 +43,7 @@ import org.opendaylight.yangtools.yang.model.api.stmt.ListEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.NotificationEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.OutputEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.UsesEffectiveStatement; @@ -140,21 +142,11 @@ abstract class AbstractCompositeGenerator> ex } final void linkUsesDependencies(final GeneratorContext context) { - // We are establishing two linkages here: - // - we are resolving 'uses' statements to their corresponding 'grouping' definitions - // - we propagate those groupings as anchors to any augment statements + // We are resolving 'uses' statements to their corresponding 'grouping' definitions final List tmp = new ArrayList<>(); for (EffectiveStatement stmt : statement().effectiveSubstatements()) { if (stmt instanceof UsesEffectiveStatement) { - final UsesEffectiveStatement uses = (UsesEffectiveStatement) stmt; - final GroupingGenerator grouping = context.resolveTreeScoped(GroupingGenerator.class, uses.argument()); - tmp.add(grouping); - - for (Generator gen : this) { - if (gen instanceof UsesAugmentGenerator) { - ((UsesAugmentGenerator) gen).linkGroupingDependency(uses, grouping); - } - } + tmp.add(context.resolveTreeScoped(GroupingGenerator.class, ((UsesEffectiveStatement) stmt).argument())); } } groupings = List.copyOf(tmp); @@ -189,7 +181,7 @@ abstract class AbstractCompositeGenerator> ex } @Override - final @Nullable AbstractExplicitGenerator findSchemaTreeGenerator(final QName qname) { + final AbstractExplicitGenerator findSchemaTreeGenerator(final QName qname) { final AbstractExplicitGenerator found = super.findSchemaTreeGenerator(qname); return found != null ? found : findInferredGenerator(qname); } @@ -213,6 +205,56 @@ abstract class AbstractCompositeGenerator> ex return null; } + final @NonNull AbstractExplicitGenerator resolveSchemaNode(final SchemaNodeIdentifier path) { + // This is not quite straightforward. 'path' works on top of schema tree, which is instantiated view. Since we + // do not generate duplicate instantiations along 'uses' path, findSchemaTreeGenerator() would satisfy our + // request by returning a child of the source 'grouping'. + // + // When that happens, our subsequent lookups need to adjust the namespace being looked up to the grouping's + // namespace... except for the case when the step is actually an augmentation, in which case we must not make + // that adjustment. + // + // Hence we deal with this lookup recursively, dropping namespace hints when we cross into groupings. + return resolveSchemaNode(path.getNodeIdentifiers().iterator(), null); + } + + private @NonNull AbstractExplicitGenerator resolveSchemaNode(final Iterator qnames, + final @Nullable QNameModule localNamespace) { + final QName qname = qnames.next(); + + // First try local augments, as those are guaranteed to match namespace exactly + for (AbstractAugmentGenerator augment : augments) { + final AbstractExplicitGenerator gen = augment.findSchemaTreeGenerator(qname); + if (gen != null) { + return resolveNext(gen, qnames, null); + } + } + + // Second try local groupings, as those perform their own adjustment + for (GroupingGenerator grouping : groupings) { + final QNameModule ns = grouping.statement().argument().getModule(); + final AbstractExplicitGenerator gen = grouping.findSchemaTreeGenerator(qname.bindTo(ns)); + if (gen != null) { + return resolveNext(gen, qnames, ns); + } + } + + // Lastly try local statements adjusted with namespace, if applicable + final QName lookup = localNamespace == null ? qname : qname.bindTo(localNamespace); + final AbstractExplicitGenerator gen = verifyNotNull(super.findSchemaTreeGenerator(lookup), + "Failed to find %s as %s in %s", qname, lookup, this); + return resolveNext(gen, qnames, localNamespace); + } + + private static @NonNull AbstractExplicitGenerator resolveNext(final @NonNull AbstractExplicitGenerator gen, + final Iterator qnames, final QNameModule localNamespace) { + if (qnames.hasNext()) { + verify(gen instanceof AbstractCompositeGenerator, "Unexpected generator %s", gen); + return ((AbstractCompositeGenerator) gen).resolveSchemaNode(qnames, localNamespace); + } + return gen; + } + /** * Update the specified builder to implement interfaces generated for the {@code grouping} statements this generator * is using. @@ -338,7 +380,7 @@ abstract class AbstractCompositeGenerator> ex final UsesEffectiveStatement uses = (UsesEffectiveStatement) stmt; for (EffectiveStatement usesSub : uses.effectiveSubstatements()) { if (usesSub instanceof AugmentEffectiveStatement) { - tmpAug.add(new UsesAugmentGenerator((AugmentEffectiveStatement) usesSub, this, uses)); + tmpAug.add(new UsesAugmentGenerator((AugmentEffectiveStatement) usesSub, this)); } } } else { diff --git a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractExplicitGenerator.java b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractExplicitGenerator.java index 9a59a88f14..3f862b2c92 100644 --- a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractExplicitGenerator.java +++ b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/AbstractExplicitGenerator.java @@ -8,7 +8,6 @@ package org.opendaylight.mdsal.binding.generator.impl.reactor; import static com.google.common.base.Verify.verify; -import static com.google.common.base.Verify.verifyNotNull; import static java.util.Objects.requireNonNull; import com.google.common.base.MoreObjects.ToStringHelper; @@ -24,12 +23,10 @@ import org.opendaylight.mdsal.binding.model.api.type.builder.MethodSignatureBuil import org.opendaylight.mdsal.binding.spec.naming.BindingMapping; import org.opendaylight.yangtools.yang.common.AbstractQName; import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.AddedByUsesAware; import org.opendaylight.yangtools.yang.model.api.CopyableNode; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionEffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -107,27 +104,6 @@ public abstract class AbstractExplicitGenerator resolveSchemaNode(final @NonNull SchemaNodeIdentifier path, - final @Nullable QNameModule targetModule) { - AbstractExplicitGenerator current = this; - QNameModule currentModule = targetModule; - - for (QName next : path.getNodeIdentifiers()) { - final QName qname = currentModule == null ? next : next.bindTo(currentModule); - current = verifyNotNull(current.findSchemaTreeGenerator(qname), - "Failed to find %s as %s in %s", next, qname, current); - - final QNameModule foundNamespace = current.getQName().getModule(); - if (!foundNamespace.equals(qname.getModule())) { - // We have located a different QName than the one we were looking for. We need to make sure we adjust - // all subsequent QNames to this new namespace - currentModule = foundNamespace; - } - } - - return current; - } - final @NonNull QName getQName() { final Object arg = statement.argument(); verify(arg instanceof QName, "Unexpected argument %s", arg); diff --git a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/GeneratorContext.java b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/GeneratorContext.java index ab0f3b2788..fb17e65bfe 100644 --- a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/GeneratorContext.java +++ b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/GeneratorContext.java @@ -10,9 +10,9 @@ package org.opendaylight.mdsal.binding.generator.impl.reactor; import edu.umd.cs.findbugs.annotations.Nullable; import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.common.QNameModule; import org.opendaylight.yangtools.yang.model.api.PathExpression; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; /** * Abstract view on generation tree as viewed by a particular {@link Generator}. @@ -43,9 +43,19 @@ abstract class GeneratorContext { abstract , G extends AbstractExplicitGenerator> @NonNull G resolveTreeScoped(@NonNull Class type, @NonNull QName argument); - abstract @NonNull AbstractExplicitGenerator resolveSchemaNode(@NonNull SchemaNodeIdentifier path); + abstract @NonNull ModuleGenerator resolveModule(@NonNull QNameModule namespace); - abstract @NonNull IdentityGenerator resolveIdentity(@NonNull QName name); + final @NonNull IdentityGenerator resolveIdentity(final @NonNull QName name) { + for (Generator gen : resolveModule(name.getModule())) { + if (gen instanceof IdentityGenerator) { + final IdentityGenerator idgen = (IdentityGenerator) gen; + if (name.equals(idgen.statement().argument())) { + return idgen; + } + } + } + throw new IllegalStateException("Failed to find identity " + name); + } final @NonNull TypedefGenerator resolveTypedef(final @NonNull QName qname) { return resolveTreeScoped(TypedefGenerator.class, qname); diff --git a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/GeneratorReactor.java b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/GeneratorReactor.java index b93cd50bd6..57d1899219 100644 --- a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/GeneratorReactor.java +++ b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/GeneratorReactor.java @@ -7,8 +7,10 @@ */ package org.opendaylight.mdsal.binding.generator.impl.reactor; +import static com.google.common.base.Preconditions.checkState; import static com.google.common.base.Verify.verify; import static com.google.common.base.Verify.verifyNotNull; +import static java.util.Objects.requireNonNull; import com.google.common.base.Stopwatch; import com.google.common.base.VerifyException; @@ -34,7 +36,6 @@ import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; import org.opendaylight.yangtools.yang.model.api.PathExpression; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; import org.opendaylight.yangtools.yang.model.ri.type.TypeBuilder; import org.opendaylight.yangtools.yang.model.spi.ModuleDependencySort; import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack; @@ -213,13 +214,6 @@ public final class GeneratorReactor extends GeneratorContext implements Mutable } } - @Override - AbstractExplicitGenerator resolveSchemaNode(final SchemaNodeIdentifier path) { - verify(path instanceof SchemaNodeIdentifier.Absolute, "Unexpected path %s", path); - return verifyNotNull(generators.get(path.firstNodeIdentifier().getModule()), "Cannot find module for %s", path) - .resolveSchemaNode(path, null); - } - @Override , G extends AbstractExplicitGenerator> G resolveTreeScoped( final Class type, final QName argument) { @@ -260,19 +254,10 @@ public final class GeneratorReactor extends GeneratorContext implements Mutable } @Override - IdentityGenerator resolveIdentity(final QName name) { - final ModuleGenerator module = generators.get(name.getModule()); - if (module != null) { - for (Generator gen : module) { - if (gen instanceof IdentityGenerator) { - final IdentityGenerator idgen = (IdentityGenerator) gen; - if (name.equals(idgen.statement().argument())) { - return idgen; - } - } - } - } - throw new IllegalStateException("Failed to find identity " + name); + ModuleGenerator resolveModule(final QNameModule namespace) { + final ModuleGenerator module = generators.get(requireNonNull(namespace)); + checkState(module != null, "Failed to find module for %s", namespace); + return module; } @Override diff --git a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/ModuleAugmentGenerator.java b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/ModuleAugmentGenerator.java index 25658cf294..f4c01a3e7e 100644 --- a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/ModuleAugmentGenerator.java +++ b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/ModuleAugmentGenerator.java @@ -8,6 +8,7 @@ package org.opendaylight.mdsal.binding.generator.impl.reactor; import org.opendaylight.yangtools.yang.model.api.stmt.AugmentEffectiveStatement; +import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; /** * Generator corresponding to a {@code augment} statement used as a child of a {@code module} statement. @@ -23,19 +24,8 @@ final class ModuleAugmentGenerator extends AbstractAugmentGenerator { } void linkAugmentationTarget(final GeneratorContext context) { - // FIXME: do we need two-step resolution here? we probably have solved this somehow, or it's part of... - // FIXME: MDSAL-696: this looks like the sort of check which should be involved in replacing getOriginal() - // - // if (targetSchemaNode instanceof DataSchemaNode && ((DataSchemaNode) targetSchemaNode).isAddedByUses()) { - // if (targetSchemaNode instanceof DerivableSchemaNode) { - // targetSchemaNode = ((DerivableSchemaNode) targetSchemaNode).getOriginal().orElse(null); - // } - // if (targetSchemaNode == null) { - // throw new IllegalStateException("Failed to find target node from grouping in augmentation " - // + augSchema + " in module " + context.module().getName()); - // } - // } - - setTargetGenerator(context.resolveSchemaNode(statement().argument())); + final SchemaNodeIdentifier path = statement().argument(); + final ModuleGenerator module = context.resolveModule(path.firstNodeIdentifier().getModule()); + setTargetGenerator(module.resolveSchemaNode(path)); } } diff --git a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/UsesAugmentGenerator.java b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/UsesAugmentGenerator.java index 919ac5fccf..f8a9eb7fb2 100644 --- a/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/UsesAugmentGenerator.java +++ b/binding/mdsal-binding-generator/src/main/java/org/opendaylight/mdsal/binding/generator/impl/reactor/UsesAugmentGenerator.java @@ -7,51 +7,26 @@ */ package org.opendaylight.mdsal.binding.generator.impl.reactor; -import static com.google.common.base.Verify.verify; -import static com.google.common.base.Verify.verifyNotNull; -import static java.util.Objects.requireNonNull; - import org.opendaylight.yangtools.yang.model.api.stmt.AugmentEffectiveStatement; -import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier; -import org.opendaylight.yangtools.yang.model.api.stmt.UsesEffectiveStatement; /** * Generator corresponding to a {@code augment} statement used as a child of a {@code uses} statement. */ final class UsesAugmentGenerator extends AbstractAugmentGenerator { - private final UsesEffectiveStatement uses; - - private GroupingGenerator grouping; - - UsesAugmentGenerator(final AugmentEffectiveStatement statement, final AbstractCompositeGenerator parent, - final UsesEffectiveStatement uses) { + UsesAugmentGenerator(final AugmentEffectiveStatement statement, final AbstractCompositeGenerator parent) { super(statement, parent); - this.uses = requireNonNull(uses); - } - - void linkGroupingDependency(final UsesEffectiveStatement checkUses, final GroupingGenerator resolvedGrouping) { - if (uses.equals(checkUses)) { - verify(grouping == null, "Attempted to relink %s from %s to %s", this, grouping, resolvedGrouping); - this.grouping = requireNonNull(resolvedGrouping); - } } @Override void loadTargetGenerator() { - final GroupingGenerator grp = verifyNotNull(grouping, "No grouping linked in %s", this); - final SchemaNodeIdentifier path = statement().argument(); - - /* - * Here we are going in the opposite direction of RFC7950, section 3.13: - * - * The effect of a "uses" reference to a grouping is that the nodes - * defined by the grouping are copied into the current schema tree and - * are then updated according to the "refine" and "augment" statements. - * - * Our argument is composed of QNames in the current schema tree's namespace, but the grouping may have been - * defined in a different module -- and therefore it knows those children under its namespace. Adjust the path - * we are searching if that happens to be the case. - */ - setTargetGenerator(grp.resolveSchemaNode(path, grp.statement().argument().getModule())); + // Here we are going in the opposite direction of RFC7950, section 7.13: + // + // The effect of a "uses" reference to a grouping is that the nodes + // defined by the grouping are copied into the current schema tree and + // are then updated according to the "refine" and "augment" statements. + // + // Our parent here is *not* the uses statement, but rather the statement which contains uses -- and its + // getSchemaTreeGenerator() is well equipped to deal with the namespace hopping needed to perform the lookups + setTargetGenerator(getParent().resolveSchemaNode(statement().argument())); } } diff --git a/binding/mdsal-binding-generator/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal715Test.java b/binding/mdsal-binding-generator/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal715Test.java new file mode 100644 index 0000000000..01a4d90eea --- /dev/null +++ b/binding/mdsal-binding-generator/src/test/java/org/opendaylight/mdsal/binding/generator/impl/Mdsal715Test.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2021 PANTHEON.tech, s.r.o. 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.mdsal.binding.generator.impl; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils; + +public class Mdsal715Test { + @Test + public void testAugmentLinking() { + final var generatedTypes = DefaultBindingGenerator.generateFor( + YangParserTestUtils.parseYangResourceDirectory("/mdsal715")); + assertEquals(12, generatedTypes.size()); + } +} diff --git a/binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-1.yang b/binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-1.yang new file mode 100644 index 0000000000..df7e57086d --- /dev/null +++ b/binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-1.yang @@ -0,0 +1,14 @@ +module test-module-1 { + namespace "test-module-1"; + prefix "tm1"; + + import test-module-2 { + prefix tm2; + } + + container test-cont { + list test-list { + uses tm2:cont-1-grouping; + } + } +} diff --git a/binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-2.yang b/binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-2.yang new file mode 100644 index 0000000000..eb14cd3b9b --- /dev/null +++ b/binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-2.yang @@ -0,0 +1,14 @@ +module test-module-2 { + namespace "test-module-2"; + prefix "tm2"; + + import test-module-3 { + prefix tm3; + } + + grouping cont-1-grouping { + container used-cont-1 { + uses tm3:cont-2-grouping; + } + } +} diff --git a/binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-3.yang b/binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-3.yang new file mode 100644 index 0000000000..40ab21e739 --- /dev/null +++ b/binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-3.yang @@ -0,0 +1,8 @@ +module test-module-3 { + namespace "test-module-3"; + prefix "tm3"; + + grouping cont-2-grouping { + container used-cont-2; + } +} diff --git a/binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-4.yang b/binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-4.yang new file mode 100644 index 0000000000..7fb3b9c920 --- /dev/null +++ b/binding/mdsal-binding-generator/src/test/resources/mdsal715/test-module-4.yang @@ -0,0 +1,18 @@ +module test-module-4 { + namespace "test-module-4"; + prefix "tm4"; + + import test-module-1 { + prefix tm1; + } + + augment "/tm1:test-cont/tm1:test-list/tm1:used-cont-1/tm1:used-cont-2" { + container augmented-cont-1 { + list augmented-list; + } + } + + augment "/tm1:test-cont/tm1:test-list/tm1:used-cont-1/tm1:used-cont-2/tm4:augmented-cont-1/tm4:augmented-list" { + container augmented-cont-2; + } +} -- 2.36.6