import static java.util.Objects.requireNonNull;
import com.google.common.annotations.Beta;
-import com.google.common.collect.Iterables;
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.Deque;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.model.api.AnydataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.AnyxmlSchemaNode;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode;
-import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
-import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ContainerLike;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaNode;
-import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.ActionEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.RpcEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
-import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema;
import org.opendaylight.yangtools.yang.model.util.LeafrefResolver;
import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack.Inference;
private NormalizedNodeStreamWriterStack(final SchemaInferenceStack dataTree) {
this.dataTree = requireNonNull(dataTree);
if (!dataTree.isEmpty()) {
- final EffectiveStatement<?, ?> current = dataTree.currentStatement();
- checkArgument(current instanceof DataNodeContainer, "Cannot instantiate on %s", current);
-
- root = (DataNodeContainer) current;
+ final var current = dataTree.currentStatement();
+ if (current instanceof DataNodeContainer container) {
+ root = container;
+ } else {
+ throw new IllegalArgumentException("Cannot instantiate on " + current);
+ }
} else {
root = dataTree.getEffectiveModelContext();
}
}
/**
- * Create a new writer with the specified context and rooted in the specified schema path.
+ * Create a new writer with the specified context and rooted in the specified {@link YangInstanceIdentifier}..
*
* @param context Associated {@link EffectiveModelContext}
- * @param path schema path
+ * @param path Normalized path
* @return A new {@link NormalizedNodeStreamWriterStack}
* @throws NullPointerException if any argument is null
* @throws IllegalArgumentException if {@code path} does not point to a valid root
*/
- @Deprecated
public static @NonNull NormalizedNodeStreamWriterStack of(final EffectiveModelContext context,
- final SchemaPath path) {
- return new NormalizedNodeStreamWriterStack(SchemaInferenceStack.ofInstantiatedPath(context, path));
+ final YangInstanceIdentifier path) {
+ return new NormalizedNodeStreamWriterStack(DataSchemaContextTree.from(context)
+ .enterPath(path)
+ .orElseThrow()
+ .stack());
}
/**
}
public Object getParent() {
- final WithStatus schema = schemaStack.peek();
+ final var schema = schemaStack.peek();
return schema == null ? root : schema;
}
verify(stmt instanceof SchemaNode, "Unexpected result %s", stmt);
final SchemaNode ret = (SchemaNode) stmt;
final Object parent = getParent();
- if (parent instanceof ChoiceSchemaNode) {
- final DataSchemaNode check = ((ChoiceSchemaNode) parent).findDataSchemaChild(qname).orElse(null);
+ if (parent instanceof ChoiceSchemaNode choice) {
+ final DataSchemaNode check = choice.findDataSchemaChild(qname).orElse(null);
verify(check == ret, "Data tree result %s does not match choice result %s", ret, check);
}
return ret;
public LeafListSchemaNode leafSetEntryNode(final QName qname) {
final Object parent = getParent();
- if (parent instanceof LeafListSchemaNode) {
- return (LeafListSchemaNode) parent;
+ if (parent instanceof LeafListSchemaNode leafList) {
+ return leafList;
}
checkArgument(parent instanceof DataNodeContainer, "Cannot lookup %s in parent %s", qname, parent);
final DataSchemaNode child = ((DataNodeContainer) parent).dataChildByName(qname);
public SchemaNode startContainerNode(final NodeIdentifier name) {
LOG.debug("Enter container {}", name);
- final SchemaNode schema = enterDataTree(name);
- checkArgument(schema instanceof ContainerLike || schema instanceof NotificationDefinition,
- "Node %s is not a container nor a notification", schema);
+
+ final SchemaNode schema;
+ if (schemaStack.isEmpty() && root instanceof NotificationDefinition notification) {
+ // Special case for stacks initialized at notification. We pretend the first container is contained within
+ // itself.
+ // FIXME: 8.0.0: factor this special case out to something more reasonable, like being initialized at the
+ // Notification's parent and knowing to enterSchemaTree() instead of enterDataTree().
+ schema = notification;
+ } else {
+ schema = enterDataTree(name);
+ checkArgument(schema instanceof ContainerLike, "Node %s is not a container", schema);
+ }
+
schemaStack.push(schema);
return schema;
}
}
return ret;
}
-
- public AugmentationSchemaNode startAugmentationNode(final AugmentationIdentifier identifier) {
- LOG.debug("Enter augmentation {}", identifier);
- Object parent = getParent();
-
- checkArgument(parent instanceof AugmentationTarget, "Augmentation not allowed under %s", parent);
- if (parent instanceof ChoiceSchemaNode) {
- final QName name = Iterables.get(identifier.getPossibleChildNames(), 0);
- parent = findCaseByChild((ChoiceSchemaNode) parent, name);
- }
- checkArgument(parent instanceof DataNodeContainer, "Augmentation allowed only in DataNodeContainer", parent);
- final AugmentationSchemaNode schema = findSchemaForAugment((AugmentationTarget) parent,
- identifier.getPossibleChildNames());
- final AugmentationSchemaNode resolvedSchema = EffectiveAugmentationSchema.create(schema,
- (DataNodeContainer) parent);
- schemaStack.push(resolvedSchema);
- return resolvedSchema;
- }
-
- // FIXME: 7.0.0: can we get rid of this?
- private static @NonNull AugmentationSchemaNode findSchemaForAugment(final AugmentationTarget schema,
- final Set<QName> qnames) {
- for (final AugmentationSchemaNode augment : schema.getAvailableAugmentations()) {
- if (qnames.equals(augment.getChildNodes().stream()
- .map(DataSchemaNode::getQName)
- .collect(Collectors.toUnmodifiableSet()))) {
- return augment;
- }
- }
-
- throw new IllegalStateException(
- "Unknown augmentation node detected, identified by: " + qnames + ", in: " + schema);
- }
-
- // FIXME: 7.0.0: can we get rid of this?
- private static SchemaNode findCaseByChild(final ChoiceSchemaNode parent, final QName qname) {
- for (final CaseSchemaNode caze : parent.getCases()) {
- final Optional<DataSchemaNode> potential = caze.findDataChildByName(qname);
- if (potential.isPresent()) {
- return caze;
- }
- }
- return null;
- }
}