import static com.google.common.base.Verify.verifyNotNull;
import static java.util.Objects.requireNonNull;
-import com.google.common.collect.ImmutableList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
-import java.util.Optional;
import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.mdsal.binding.generator.impl.reactor.CollisionDomain.Member;
import org.opendaylight.mdsal.binding.generator.impl.rt.DefaultAugmentRuntimeType;
import org.opendaylight.mdsal.binding.model.api.GeneratedType;
import org.opendaylight.yangtools.yang.model.api.stmt.AugmentEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement.SchemaTreeNamespace;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
/**
return otherIt.hasNext() ? -1 : 0;
};
- private SchemaTreeAwareEffectiveStatement<?, ?> targetStatement;
private AbstractCompositeGenerator<?, ?> targetGen;
- private Optional<AugmentRuntimeType> internalRuntimeType;
AbstractAugmentGenerator(final AugmentEffectiveStatement statement, final AbstractCompositeGenerator<?, ?> parent) {
super(statement, parent);
return builder.build();
}
- @NonNull List<CaseRuntimeType> augmentedCasesIn(final ChildLookup lookup, final ChoiceEffectiveStatement stmt) {
- final var target = verifyNotNull(targetStatement);
- if (!stmt.equals(target)) {
- return List.of();
- }
-
- final var result = createBuilder(effectiveStatement(statement(), target))
- .fillTypes(ChildLookup.of(target), this)
- .getCaseChilden();
- internalRuntimeType = Optional.empty();
- return result;
+ boolean matchesInstantiated(final AugmentEffectiveStatement statement) {
+ return statement().equals(statement);
}
- @Nullable AugmentRuntimeType runtimeTypeIn(final ChildLookup lookup, final EffectiveStatement<?, ?> stmt) {
- final var target = verifyNotNull(targetStatement);
- if (!stmt.equals(target)) {
- return null;
- }
- if (internalRuntimeType != null) {
- return internalRuntimeType.orElseThrow();
- }
-
- final var result = verifyNotNull(createInternalRuntimeType(ChildLookup.of(target),
- effectiveStatement(statement(), target)));
- internalRuntimeType = Optional.of(result);
- return result;
+ final void fillRuntimeCasesIn(final AugmentResolver resolver, final ChoiceEffectiveStatement stmt,
+ final List<CaseRuntimeType> toList) {
+ toList.addAll(createBuilder(effectiveIn(stmt)).populate(resolver, this).getCaseChilden());
}
- private static @NonNull AugmentEffectiveStatement effectiveStatement(final AugmentEffectiveStatement augment,
- final SchemaTreeAwareEffectiveStatement<?, ?> target) {
- final var stmts = augment.effectiveSubstatements();
- final var builder = ImmutableList.<EffectiveStatement<?, ?>>builderWithExpectedSize(stmts.size());
- for (var child : stmts) {
- if (child instanceof SchemaTreeEffectiveStatement) {
- final var qname = ((SchemaTreeEffectiveStatement<?>) child).getIdentifier();
- // FIXME: orElseThrow()?
- target.get(SchemaTreeNamespace.class, qname).ifPresent(builder::add);
- } else {
- builder.add(child);
- }
- }
- return new TargetAugmentEffectiveStatement(augment, target, builder.build());
+ final @NonNull AugmentRuntimeType runtimeTypeIn(final AugmentResolver resolver,
+ final EffectiveStatement<?, ?> stmt) {
+ verify(stmt instanceof SchemaTreeAwareEffectiveStatement, "Unexpected target statement %s", stmt);
+ return verifyNotNull(createInternalRuntimeType(resolver,
+ effectiveIn((SchemaTreeAwareEffectiveStatement<?, ?>) stmt)));
}
- final @Nullable AugmentRuntimeType getInternalRuntimeType() {
- return verifyNotNull(internalRuntimeType, "Internal runtime not resolved in %s", this).orElse(null);
- }
+ abstract @NonNull TargetAugmentEffectiveStatement effectiveIn(SchemaTreeAwareEffectiveStatement<?, ?> target);
@Override
final void addAsGetterMethod(final GeneratedTypeBuilderBase<?> builder, final TypeBuilderFactory builderFactory) {
final @NonNull AbstractCompositeGenerator<?, ?> targetGenerator() {
return verifyNotNull(targetGen, "No target for %s", this);
}
-
- final void setTargetStatement(final EffectiveStatement<?, ?> targetStatement) {
- verify(targetStatement instanceof SchemaTreeAwareEffectiveStatement, "Unexpected target statement %s",
- targetStatement);
- this.targetStatement = (SchemaTreeAwareEffectiveStatement<?, ?>) targetStatement;
- }
}
@Override
final R createExternalRuntimeType(final Type type) {
verify(type instanceof GeneratedType, "Unexpected type %s", type);
-
- // FIXME: we should be able to use internal cache IFF when all augments end up being local to our statement
- final var statement = statement();
- return createBuilder(statement)
- .fillTypes(ChildLookup.of(statement), this)
- .build((GeneratedType) type);
+ return createBuilder(statement()).populate(new AugmentResolver(), this).build((GeneratedType) type);
}
abstract @NonNull CompositeRuntimeTypeBuilder<S, R> createBuilder(S statement);
@Override
- final R createInternalRuntimeType(final ChildLookup lookup, final S statement, final Type type) {
+ final R createInternalRuntimeType(final AugmentResolver resolver, final S statement, final Type type) {
verify(type instanceof GeneratedType, "Unexpected type %s", type);
- return createBuilder(statement)
- .fillTypes(lookup.inStatement(statement), this)
- .build((GeneratedType) type);
+ return createBuilder(statement).populate(resolver, this).build((GeneratedType) type);
}
@Override
* @param stmt Statement for which to create the view
* @return Internally-accessible RuntimeType, or {@code null} if not applicable
*/
- final @Nullable R createInternalRuntimeType(final @NonNull ChildLookup lookup, final @NonNull S stmt) {
+ final @Nullable R createInternalRuntimeType(final @NonNull AugmentResolver resolver, final @NonNull S stmt) {
// FIXME: cache requests: if we visited this statement, we obviously know what it entails. Note that we walk
// towards the original definition. As such, the cache may have to live in the generator we look up,
// but should operate on this statement to reflect lookups. This needs a bit of figuring out.
do {
final var type = gen.runtimeJavaType();
if (type != null) {
- return createInternalRuntimeType(lookup, stmt, type);
+ return createInternalRuntimeType(resolver, stmt, type);
}
gen = gen.previous();
return null;
}
- abstract @NonNull R createInternalRuntimeType(@NonNull ChildLookup lookup, @NonNull S statement,
+ abstract @NonNull R createInternalRuntimeType(@NonNull AugmentResolver resolver, @NonNull S statement,
@NonNull Type type);
@Override
--- /dev/null
+/*
+ * Copyright (c) 2022 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.reactor;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.ArrayDeque;
+import java.util.Deque;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.concepts.Mutable;
+import org.opendaylight.yangtools.yang.model.api.stmt.AugmentEffectiveStatement;
+
+/**
+ * Utility to resolve instantiated {@code augment} statements to their {@link AbstractAugmentGenerator} counterparts.
+ * This is essentially a stack of {@link AbstractCompositeGenerator}s which should be examined.
+ */
+final class AugmentResolver implements Mutable {
+ private final Deque<AbstractCompositeGenerator<?, ?>> stack = new ArrayDeque<>();
+
+ void enter(final AbstractCompositeGenerator<?, ?> generator) {
+ stack.push(requireNonNull(generator));
+ }
+
+ void exit() {
+ stack.pop();
+ }
+
+ @NonNull AbstractAugmentGenerator getAugment(final AugmentEffectiveStatement statement) {
+ for (var generator : stack) {
+ final var found = findAugment(generator, statement);
+ if (found != null) {
+ return found;
+ }
+ }
+ throw new IllegalStateException("Failed to resolve " + statement + " in " + stack);
+ }
+
+ private @Nullable AbstractAugmentGenerator findAugment(final AbstractCompositeGenerator<?, ?> generator,
+ final AugmentEffectiveStatement statement) {
+ for (var augment : generator.augments()) {
+ if (augment.matchesInstantiated(statement)) {
+ return augment;
+ }
+ }
+ for (var grouping : generator.groupings()) {
+ final var found = findAugment(grouping, statement);
+ if (found != null) {
+ return found;
+ }
+ }
+ return null;
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2022 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.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;
-import com.google.common.collect.ImmutableSet;
-import java.util.stream.Stream;
-import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.yangtools.concepts.Immutable;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.common.QNameModule;
-import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.AugmentEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.UsesEffectiveStatement;
-
-/**
- * Lookup context for dealing with namespace translation during execution of {@link AbstractCompositeGenerator}'s
- * createInternalRuntimeType(). It tracks which namespaces should be translated on account of crossing into source
- * {@code grouping} statement.
- */
-final class ChildLookup implements Immutable {
- private final ImmutableSet<AugmentEffectiveStatement> validUsesAugments;
- private final ImmutableSet<QNameModule> squashNamespaces;
- private final QNameModule localNamespace;
-
- private ChildLookup(final ImmutableSet<AugmentEffectiveStatement> validUsesAugments,
- final ImmutableSet<QNameModule> squashNamespaces, final QNameModule localNamespace) {
- this.validUsesAugments = requireNonNull(validUsesAugments);
- this.squashNamespaces = requireNonNull(squashNamespaces);
- this.localNamespace = localNamespace;
- verify(localNamespace == null == squashNamespaces.isEmpty(), "Unexpected lookup state %s", this);
- }
-
- public static @NonNull ChildLookup of(final EffectiveStatement<?, ?> statement) {
- return new ChildLookup(streamUsesAugments(statement).collect(ImmutableSet.toImmutableSet()), ImmutableSet.of(),
- null);
- }
-
- @NonNull QName adjustQName(final @NonNull QName qname) {
- return squashNamespaces.contains(qname.getModule()) ? qname.bindTo(verifyNotNull(localNamespace)) : qname;
- }
-
- boolean contains(final AugmentEffectiveStatement augment) {
- return validUsesAugments.contains(augment);
- }
-
- @NonNull ChildLookup inStatement(final EffectiveStatement<?, ?> statememt) {
- return hasUsesAugments(statememt)
- ? new ChildLookup(concatUsesAugments(statememt), squashNamespaces, localNamespace) : this;
- }
-
- @NonNull ChildLookup inGrouping(final QName qname, final GroupingGenerator grouping) {
- final var statement = grouping.statement();
- final var grpNamespace = statement.argument().getModule();
- final var itemNamespace = qname.getModule();
-
- final ImmutableSet<QNameModule> newSquashNamespaces;
- if (squashNamespaces.contains(itemNamespace)) {
- newSquashNamespaces = squashNamespaces;
- } else {
- newSquashNamespaces = ImmutableSet.<QNameModule>builderWithExpectedSize(squashNamespaces.size() + 1)
- .addAll(squashNamespaces).add(itemNamespace).build();
- }
-
- return new ChildLookup(hasUsesAugments(statement) ? concatUsesAugments(statement) : validUsesAugments,
- newSquashNamespaces, grpNamespace);
- }
-
- @Override
- public String toString() {
- return MoreObjects.toStringHelper(this).omitNullValues()
- .add("augments", validUsesAugments)
- .add("squash", squashNamespaces)
- .add("local", localNamespace)
- .toString();
- }
-
- private ImmutableSet<AugmentEffectiveStatement> concatUsesAugments(final EffectiveStatement<?, ?> stmt) {
- final var concat = ImmutableSet.<AugmentEffectiveStatement>builder().addAll(validUsesAugments);
- streamUsesAugments(stmt).forEach(concat::add);
- return concat.build();
- }
-
- private static boolean hasUsesAugments(final EffectiveStatement<?, ?> stmt) {
- return streamUsesAugments(stmt).findAny().isPresent();
- }
-
- private static Stream<AugmentEffectiveStatement> streamUsesAugments(final EffectiveStatement<?, ?> stmt) {
- return stmt.streamEffectiveSubstatements(UsesEffectiveStatement.class)
- .flatMap(uses -> uses.streamEffectiveSubstatements(AugmentEffectiveStatement.class));
- }
-}
import static com.google.common.base.Verify.verify;
-import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
import java.util.List;
import org.opendaylight.mdsal.binding.generator.impl.rt.DefaultChoiceRuntimeType;
import org.opendaylight.mdsal.binding.model.api.GeneratedType;
*/
final class ChoiceGenerator extends CompositeSchemaTreeGenerator<ChoiceEffectiveStatement, ChoiceRuntimeType> {
static final class ChoiceBuilder extends CompositeRuntimeTypeBuilder<ChoiceEffectiveStatement, ChoiceRuntimeType> {
- private ImmutableList<CaseRuntimeType> augmentedCases;
+ private final List<CaseRuntimeType> augmentedCases = new ArrayList<>();
ChoiceBuilder(final ChoiceEffectiveStatement statement) {
super(statement);
}
@Override
- CompositeRuntimeTypeBuilder<ChoiceEffectiveStatement, ChoiceRuntimeType> fillTypes(
- final ChildLookup lookup,
- final AbstractCompositeGenerator<ChoiceEffectiveStatement, ChoiceRuntimeType> generator) {
- fillAugmentedCases(lookup, generator.augments());
- return super.fillTypes(lookup, generator);
+ void processAugment(final AugmentResolver resolver, final AbstractAugmentGenerator augment) {
+ augment.fillRuntimeCasesIn(resolver, statement(), augmentedCases);
}
@Override
- boolean isAugmentedChild(final ChildLookup lookup, final QName qname) {
+ boolean isAugmentedChild(final QName qname) {
for (var augmented : augmentedCases) {
if (qname.equals(augmented.statement().argument())) {
return true;
}
}
- return super.isAugmentedChild(lookup, qname);
+ return false;
}
@Override
children.addAll(augmentedCases);
return new DefaultChoiceRuntimeType(type, statement, children);
}
-
- private void fillAugmentedCases(final ChildLookup lookup, final List<AbstractAugmentGenerator> augments) {
- final var builder = ImmutableList.<CaseRuntimeType>builder();
- for (var augment : augments) {
- builder.addAll(augment.augmentedCasesIn(lookup, statement()));
- }
- augmentedCases = builder.build();
- }
}
ChoiceGenerator(final ChoiceEffectiveStatement statement, final AbstractCompositeGenerator<?, ?> parent) {
import java.util.List;
import java.util.stream.Collectors;
import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.mdsal.binding.model.api.GeneratedType;
import org.opendaylight.mdsal.binding.runtime.api.AugmentRuntimeType;
import org.opendaylight.mdsal.binding.runtime.api.CaseRuntimeType;
import org.opendaylight.mdsal.binding.runtime.api.RuntimeType;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.AugmentEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
abstract class CompositeRuntimeTypeBuilder<S extends EffectiveStatement<?, ?>, R extends CompositeRuntimeType> {
this.statement = requireNonNull(statement);
}
- final @NonNull S statement() {
- return statement;
+ final CompositeRuntimeTypeBuilder<S, R> populate(final AugmentResolver resolver,
+ final AbstractCompositeGenerator<S, R> generator) {
+ resolver.enter(generator);
+ try {
+ processGenerator(resolver, generator);
+ } finally {
+ resolver.exit();
+ }
+ return this;
+ }
+
+ final @NonNull R build(final @NonNull GeneratedType generatedType) {
+ return build(generatedType, statement, childTypes, augmentTypes);
}
+ abstract @NonNull R build(GeneratedType type, S statement, List<RuntimeType> children,
+ List<AugmentRuntimeType> augments);
+
final @NonNull List<CaseRuntimeType> getCaseChilden() {
return childTypes.stream()
.map(child -> {
.collect(Collectors.toUnmodifiableList());
}
- final @NonNull R build(final @NonNull GeneratedType generatedType) {
- return build(generatedType, statement, childTypes, augmentTypes);
+ final @NonNull S statement() {
+ return statement;
}
- abstract @NonNull R build(GeneratedType type, S statement, List<RuntimeType> children,
- List<AugmentRuntimeType> augments);
+ boolean isAugmentedChild(final QName qname) {
+ // Note we are dealing with two different kinds of augments and they behave differently with respect
+ // to namespaces. Top-level augments do not make an adjustment, while uses-augments do.
+ for (var augment : augmentTypes) {
+ if (augment.schemaTreeChild(qname) != null) {
+ return true;
+ }
+ }
+ return false;
+ }
- CompositeRuntimeTypeBuilder<S, R> fillTypes(final ChildLookup lookup,
- final AbstractCompositeGenerator<S, R> generator) {
+ void processAugment(final AugmentResolver resolver, final AbstractAugmentGenerator augment) {
+ augmentTypes.add(augment.runtimeTypeIn(resolver, statement));
+ }
+
+ private void processGenerator(final AugmentResolver resolver, final AbstractCompositeGenerator<S, R> generator) {
// Figure out which augments are valid in target statement and record their RuntimeTypes.
// We will pass the latter to create method. We will use the former to perform replacement lookups instead
// of 'this.augments'. That is necessary because 'this.augments' holds all augments targeting the GeneratedType,
// hence equivalent augmentations from differing places would match our lookup and the reverse search would be
// lead astray.
//
- // Augments targeting 'choice' statement are handled by a separate class and need to be skipped here
- if (!(generator instanceof ChoiceGenerator)) {
- for (var augment : generator.augments()) {
- final var augmentRuntimeType = augment.runtimeTypeIn(lookup, statement);
- if (augmentRuntimeType != null) {
- augmentTypes.add(augmentRuntimeType);
+ // Note we should not do this for 'module' and 'uses' statements, as those are not valid augment targets. Of
+ // those two we only generate things for 'module'.
+ if (!(statement instanceof ModuleEffectiveStatement)) {
+ for (var stmt : statement.effectiveSubstatements()) {
+ if (stmt instanceof AugmentEffectiveStatement) {
+ processAugment(resolver, resolver.getAugment((AugmentEffectiveStatement) stmt));
}
}
}
for (var stmt : statement.effectiveSubstatements()) {
if (stmt instanceof SchemaTreeEffectiveStatement) {
final var child = (SchemaTreeEffectiveStatement<?>) stmt;
- final var qname = child.getIdentifier();
// Try valid augments first: they should be empty most of the time and filter all the cases where we
// would not find the streamChild among our local and grouping statements. Note that unlike all others,
// such matches are not considered to be children in Binding DataObject tree, they are only considered
// such in the schema tree.
- if (isAugmentedChild(lookup, qname)) {
- continue;
- }
-
- final var childRuntimeType = findChildRuntimeType(lookup, generator, child);
- if (childRuntimeType != null) {
- childTypes.add(childRuntimeType);
- }
- }
- }
-
- return this;
- }
-
- @SuppressWarnings("unchecked")
- final <X extends SchemaTreeEffectiveStatement<?>> @Nullable RuntimeType findChildRuntimeType(
- final @NonNull ChildLookup lookup, final AbstractCompositeGenerator<?, ?> parent, final @NonNull X stmt) {
- final var qname = stmt.getIdentifier();
- // First try our local items without adjustment ...
- @SuppressWarnings("rawtypes")
- AbstractExplicitGenerator childGen = findChild(parent, qname);
- if (childGen == null) {
- // No luck, let's see if any of the groupings can find it
- for (GroupingGenerator grouping : parent.groupings()) {
- final var gen = grouping.findSchemaTreeGenerator(
- qname.bindTo(grouping.statement().argument().getModule()));
- if (gen != null) {
- return findChildRuntimeType(lookup.inGrouping(qname, grouping), grouping, stmt);
+ //
+ // That is in general -- 'choice' statements are doing their own thing separately.
+ if (!isAugmentedChild(child.getIdentifier())) {
+ final var childGen = verifyNotNull(findChildGenerator(generator, child.argument().getLocalName()),
+ "Cannot find child for %s in %s", child, generator);
+ final var childRuntimeType = childGen.createInternalRuntimeType(resolver, child);
+ if (childRuntimeType != null) {
+ childTypes.add(childRuntimeType);
+ }
}
}
-
- // Finally attempt to find adjusted QName: this has to succeed
- final var adjusted = lookup.adjustQName(qname);
- childGen = verifyNotNull(findChild(parent, adjusted),
- "Failed to find %s as %s in %s", stmt, adjusted, this);
}
-
- return childGen.createInternalRuntimeType(lookup, stmt);
}
- boolean isAugmentedChild(final ChildLookup lookup, final QName qname) {
- // Note we are dealing with two different kinds of augments and they behave differently with respect
- // to namespaces. Top-level augments do not make an adjustment, while uses-augments do.
- return augmentTypes.stream().anyMatch(augment -> augment.schemaTreeChild(qname) != null);
- }
-
- private static @Nullable AbstractExplicitGenerator<?, ?> findChild(final AbstractCompositeGenerator<?, ?> parent,
- final QName qname) {
+ // When we reach here we have dealt with all known augments in this scope, hence the only option is that the
+ // statement is either local or added via 'uses' -- in either case it has namespace equal to whatever the local
+ // namespace is and there can be no conflicts on QName.getLocalName(). That simplifies things a ton.
+ private static <S extends SchemaTreeEffectiveStatement<?>> AbstractExplicitGenerator<S, ?> findChildGenerator(
+ final AbstractCompositeGenerator<?, ?> parent, final String localName) {
+ // Search direct children first ...
for (var child : parent) {
if (child instanceof AbstractExplicitGenerator) {
- final AbstractExplicitGenerator<?, ?> gen = (AbstractExplicitGenerator<?, ?>) child;
- final EffectiveStatement<?, ?> stmt = gen.statement();
- if (stmt instanceof SchemaTreeEffectiveStatement && qname.equals(stmt.argument())) {
+ @SuppressWarnings("unchecked")
+ final AbstractExplicitGenerator<S, ?> gen = (AbstractExplicitGenerator<S, ?>) child;
+ final EffectiveStatement<?, ?> genStmt = gen.statement();
+ if (genStmt instanceof SchemaTreeEffectiveStatement
+ && localName.equals(((SchemaTreeEffectiveStatement<?>) genStmt).argument().getLocalName())) {
return gen;
}
}
}
+
+ // ... and groupings recursively last
+ for (var grouping : parent.groupings()) {
+ final AbstractExplicitGenerator<S, ?> found = findChildGenerator(grouping, localName);
+ if (found != null) {
+ return found;
+ }
+ }
+
return null;
}
}
}
@Override
- IdentityRuntimeType createInternalRuntimeType(final ChildLookup lookup, final IdentityEffectiveStatement statement,
- final Type type) {
+ IdentityRuntimeType createInternalRuntimeType(final AugmentResolver resolver,
+ final IdentityEffectiveStatement statement, final Type type) {
// 'identity' statements are not part of schema tree and hence should never an internal reference
throw new UnsupportedOperationException("Should never be called");
}
}
@Override
- KeyRuntimeType createInternalRuntimeType(final ChildLookup lookup,final KeyEffectiveStatement statement,
+ KeyRuntimeType createInternalRuntimeType(final AugmentResolver resolver, final KeyEffectiveStatement statement,
final Type type) {
// The only reference to this runtime type is from ListGenerator which is always referencing the external type
throw new UnsupportedOperationException("Should never be called");
}
@Override
- LeafRuntimeType createInternalRuntimeType(final ChildLookup lookup, final LeafEffectiveStatement statement,
+ LeafRuntimeType createInternalRuntimeType(final AugmentResolver resolver, final LeafEffectiveStatement statement,
final Type type) {
return new DefaultLeafRuntimeType(type, statement);
}
}
@Override
- LeafListRuntimeType createInternalRuntimeType(final ChildLookup lookup, final LeafListEffectiveStatement statement,
- final Type type) {
+ LeafListRuntimeType createInternalRuntimeType(final AugmentResolver resolver,
+ final LeafListEffectiveStatement statement, final Type type) {
return new DefaultLeafListRuntimeType(type, statement);
}
}
*/
package org.opendaylight.mdsal.binding.generator.impl.reactor;
+import com.google.common.collect.ImmutableList;
import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.AugmentEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement.SchemaTreeNamespace;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
/**
* Generator corresponding to a {@code augment} statement used as a child of a {@code module} statement.
super(statement, parent);
}
- @NonNull AugmentRequirement startLinkage(final GeneratorContext context) {
- setTargetStatement(SchemaInferenceStack.of(context.getEffectiveModelContext())
- .enterSchemaTree(statement().argument()));
+ @Override
+ TargetAugmentEffectiveStatement effectiveIn(final SchemaTreeAwareEffectiveStatement<?, ?> target) {
+ final var augment = statement();
+ final var stmts = augment.effectiveSubstatements();
+ final var builder = ImmutableList.<EffectiveStatement<?, ?>>builderWithExpectedSize(stmts.size());
+ for (var child : stmts) {
+ if (child instanceof SchemaTreeEffectiveStatement) {
+ final var qname = ((SchemaTreeEffectiveStatement<?>) child).getIdentifier();
+ // FIXME: orElseThrow()?
+ target.get(SchemaTreeNamespace.class, qname).ifPresent(builder::add);
+ } else {
+ builder.add(child);
+ }
+ }
+ return new TargetAugmentEffectiveStatement(augment, target, builder.build());
+ }
+ @NonNull AugmentRequirement startLinkage(final GeneratorContext context) {
return new AugmentRequirement(this,
context.resolveModule(statement().argument().firstNodeIdentifier().getModule()));
}
abstract @NonNull R createExternalRuntimeType(@NonNull GeneratedType type);
@Override
- final R createInternalRuntimeType(final ChildLookup lookup, final S statement, final Type type) {
+ final R createInternalRuntimeType(final AugmentResolver resolver, final S statement, final Type type) {
verify(type instanceof GeneratedType, "Unexpected type %s", type);
return createInternalRuntimeType(statement, (GeneratedType) type);
}
}
@Override
- TypedefRuntimeType createInternalRuntimeType(final ChildLookup lookup, final TypedefEffectiveStatement statement,
- final Type type) {
+ TypedefRuntimeType createInternalRuntimeType(final AugmentResolver resolver,
+ final TypedefEffectiveStatement statement, final Type type) {
// 'typedef' statements are not schema tree statements, they should not have internal references
throw new UnsupportedOperationException("Should never be called");
}
import static java.util.Objects.requireNonNull;
import com.google.common.collect.ImmutableList;
-import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.binding.runtime.api.AugmentRuntimeType;
-import org.opendaylight.mdsal.binding.runtime.api.CaseRuntimeType;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.AugmentEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceEffectiveStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.AugmentStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeAwareEffectiveStatement.SchemaTreeNamespace;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaTreeEffectiveStatement;
final AbstractCompositeGenerator<?, ?> parent) {
super(statement, parent);
this.uses = requireNonNull(uses);
-
- // FIXME: use SchemaTreeAwareEffectiveStatement
- var stmt = parent.statement();
- for (var qname : statement.argument().getNodeIdentifiers()) {
- final var tmp = stmt;
- stmt = stmt.streamEffectiveSubstatements(SchemaTreeEffectiveStatement.class)
- .filter(child -> qname.equals(child.argument()))
- .findFirst()
- .orElseThrow(() -> new IllegalStateException("Failed to find " + qname + " in " + tmp));
- }
- setTargetStatement(stmt);
}
void resolveGrouping(final UsesEffectiveStatement resolvedUses, final GroupingGenerator resolvedGrouping) {
}
@Override
- List<CaseRuntimeType> augmentedCasesIn(final ChildLookup lookup, final ChoiceEffectiveStatement stmt) {
- final var result = super.augmentedCasesIn(lookup, stmt);
- if (result != null) {
- return result;
- }
- final var augment = statement();
- if (!lookup.contains(augment)) {
- return List.of();
- }
-
- final var effectiveStatement = effectiveStatement(augment, stmt);
- return createBuilder(effectiveStatement)
- .fillTypes(lookup.inStatement(effectiveStatement), this)
- .getCaseChilden();
+ boolean matchesInstantiated(final AugmentEffectiveStatement statement) {
+ return super.matchesInstantiated(statement) || declared(statement()).equals(declared(statement));
}
- @Override
- AugmentRuntimeType runtimeTypeIn(final ChildLookup lookup, final EffectiveStatement<?, ?> target) {
- final var result = super.runtimeTypeIn(lookup, target);
- if (result != null) {
- return result;
- }
- final var augment = statement();
- if (!lookup.contains(augment)) {
- return null;
- }
-
- verify(target instanceof SchemaTreeAwareEffectiveStatement && target instanceof SchemaTreeEffectiveStatement,
- "Unexpected statement %s", target);
- final var effectiveStatement = effectiveStatement(augment, (SchemaTreeAwareEffectiveStatement<?, ?>) target);
- return verifyNotNull(createInternalRuntimeType(lookup.inStatement(effectiveStatement), effectiveStatement));
+ private static AugmentStatement declared(final AugmentEffectiveStatement statement) {
+ // We are generating Augmentation interfaces on declared model, hence this is accurate
+ return verifyNotNull(statement.getDeclared(), " %s does not have a declared view", statement);
}
- private static @NonNull AugmentEffectiveStatement effectiveStatement(final AugmentEffectiveStatement augment,
- final SchemaTreeAwareEffectiveStatement<?, ?> target) {
+ @Override
+ TargetAugmentEffectiveStatement effectiveIn(final SchemaTreeAwareEffectiveStatement<?, ?> target) {
verify(target instanceof SchemaTreeEffectiveStatement, "Unexpected statement %s", target);
// 'uses'/'augment': our children are binding to target's namespace
final var targetNamespace = ((SchemaTreeEffectiveStatement<?>) target).argument().getModule();
+ final var augment = statement();
final var stmts = augment.effectiveSubstatements();
final var builder = ImmutableList.<EffectiveStatement<?, ?>>builderWithExpectedSize(stmts.size());
for (var stmt : stmts) {
if (stmt instanceof SchemaTreeEffectiveStatement) {
final var qname = ((SchemaTreeEffectiveStatement<?>) stmt).getIdentifier().bindTo(targetNamespace);
+ // FIXME: orElseThrow()?
target.get(SchemaTreeNamespace.class, qname).ifPresent(builder::add);
} else {
builder.add(stmt);