import static com.google.common.base.Verify.verify;
-import com.google.common.collect.Iterables;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import org.eclipse.jdt.annotation.NonNull;
this.factory = factory;
if (arg instanceof AugmentationIdentifier) {
- this.namespace = Iterables.getFirst(((AugmentationIdentifier) arg).getPossibleChildNames(), null)
- .getModule();
+ final var childNames = ((AugmentationIdentifier) arg).getPossibleChildNames();
+ verify(!childNames.isEmpty(), "Unexpected empty identifier for %s", type);
+ this.namespace = childNames.iterator().next().getModule();
} else {
this.namespace = arg.getNodeType().getModule();
}
final Map<PathArgument, DataContainerCodecPrototype<?>> augByYang = new HashMap<>();
final Map<Class<?>, DataContainerCodecPrototype<?>> augByStream = new HashMap<>();
for (final AugmentRuntimeType augment : possibleAugmentations) {
- final DataContainerCodecPrototype<?> augProto = getAugmentationPrototype(augment);
- final PathArgument augYangArg = augProto.getYangArg();
- if (augByYang.putIfAbsent(augYangArg, augProto) == null) {
- LOG.trace("Discovered new YANG mapping {} -> {} in {}", augYangArg, augProto, this);
- }
- final Class<?> augBindingClass = augProto.getBindingClass();
- if (augByStream.putIfAbsent(augBindingClass, augProto) == null) {
- LOG.trace("Discovered new class mapping {} -> {} in {}", augBindingClass, augProto, this);
+ final DataContainerCodecPrototype<?> augProto = loadAugmentPrototype(augment);
+ if (augProto != null) {
+ final PathArgument augYangArg = augProto.getYangArg();
+ if (augByYang.putIfAbsent(augYangArg, augProto) == null) {
+ LOG.trace("Discovered new YANG mapping {} -> {} in {}", augYangArg, augProto, this);
+ }
+ final Class<?> augBindingClass = augProto.getBindingClass();
+ if (augByStream.putIfAbsent(augBindingClass, augProto) == null) {
+ LOG.trace("Discovered new class mapping {} -> {} in {}", augBindingClass, augProto, this);
+ }
}
}
augmentationByYang = ImmutableMap.copyOf(augByYang);
return cls.equals(loaded);
}
- private @NonNull DataContainerCodecPrototype<?> getAugmentationPrototype(final AugmentRuntimeType augment) {
- final BindingRuntimeContext ctx = factory().getRuntimeContext();
+ private @Nullable DataContainerCodecPrototype<?> loadAugmentPrototype(final AugmentRuntimeType augment) {
+ // FIXME: in face of deviations this code should be looking at declared view, i.e. all possibilities at augment
+ // declaration site
+ final var possibleChildren = augment.statement()
+ .streamEffectiveSubstatements(SchemaTreeEffectiveStatement.class)
+ .map(SchemaTreeEffectiveStatement::getIdentifier)
+ .collect(ImmutableSet.toImmutableSet());
+ if (possibleChildren.isEmpty()) {
+ return null;
+ }
+ final var factory = factory();
final GeneratedType javaType = augment.javaType();
final Class<? extends Augmentation<?>> augClass;
try {
- augClass = ctx.loadClass(javaType);
+ augClass = factory.getRuntimeContext().loadClass(javaType);
} catch (final ClassNotFoundException e) {
throw new IllegalStateException(
"RuntimeContext references type " + javaType + " but failed to load its class", e);
}
- // TODO: at some point we need the effective children
- return DataContainerCodecPrototype.from(augClass, new AugmentationIdentifier(augment.statement()
- .streamEffectiveSubstatements(SchemaTreeEffectiveStatement.class)
- .map(SchemaTreeEffectiveStatement::getIdentifier)
- .collect(ImmutableSet.toImmutableSet())), augment, factory());
+ return DataContainerCodecPrototype.from(augClass, new AugmentationIdentifier(possibleChildren), augment,
+ factory);
}
@SuppressWarnings("checkstyle:illegalCatch")
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.function.Function;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.binding.generator.impl.reactor.CollisionDomain.Member;
import org.opendaylight.mdsal.binding.generator.impl.rt.DefaultAugmentRuntimeType;
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;
/**
abstract @NonNull TargetAugmentEffectiveStatement effectiveIn(SchemaTreeAwareEffectiveStatement<?, ?> target);
+ final @NonNull TargetAugmentEffectiveStatement effectiveIn(final SchemaTreeAwareEffectiveStatement<?, ?> target,
+ final Function<QName, QName> transform) {
+ 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();
+ // Note: a match in target may be missing -- for example if it was 'deviate unsupported'
+ target.get(SchemaTreeNamespace.class, transform.apply(qname)).ifPresent(builder::add);
+ } else {
+ builder.add(child);
+ }
+ }
+ return new TargetAugmentEffectiveStatement(augment, target, builder.build());
+ }
+
@Override
final void addAsGetterMethod(final GeneratedTypeBuilderBase<?> builder, final TypeBuilderFactory builderFactory) {
// Augments are never added as getters, as they are handled via Augmentable mechanics
*/
package org.opendaylight.mdsal.binding.generator.impl.reactor;
-import com.google.common.collect.ImmutableList;
+import java.util.function.Function;
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.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.
@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());
+ return effectiveIn(target, Function.identity());
}
@NonNull AugmentRequirement startLinkage(final GeneratorContext context) {
import static com.google.common.base.Verify.verifyNotNull;
import static java.util.Objects.requireNonNull;
-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.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;
import org.opendaylight.yangtools.yang.model.api.stmt.UsesEffectiveStatement;
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);
- }
- }
- return new TargetAugmentEffectiveStatement(augment, target, builder.build());
+ final var targetNamespace = ((SchemaTreeEffectiveStatement<?>) target).argument().getModule();
+ return effectiveIn(target, qname -> qname.bindTo(targetNamespace));
}
}