import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
import org.opendaylight.yangtools.yang.data.api.codec.InstanceIdentifierCodec;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.PathMixin;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.util.LeafrefResolver;
checkArgument(current != null, "Invalid input %s: schema for argument %s (after %s) not found", data, arg,
sb);
- if (current.isMixin()) {
+ if (current instanceof PathMixin) {
/*
- * XML/YANG instance identifier does not have concept
- * of augmentation identifier, or list as whole which
- * identifies a mixin (same as the parent element),
- * so we can safely ignore it if it is part of path
+ * XML/YANG instance identifier does not have concept of augmentation identifier, or list as whole which
+ * identifies a mixin (same as the parent element), so we can safely ignore it if it is part of path
* (since child node) is identified in same fashion.
*/
continue;
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+import org.opendaylight.yangtools.yang.data.util.impl.legacy.AbstractMixinContextNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
* {@link org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode} and serialization format defined in RFC6020,
* since the mapping is not one-to-one.
*/
-// FIXME: YANGTOOLS-1413: this really should be an interface, as there is a ton of non-trivial composition going on:
-// - getDataSchemaNode() cannot return AugmentationSchemaNode, which is guarded by isMixinNode() and users should
-// not be touching mixin details anyway
public interface DataSchemaContextNode {
+ /**
+ * This node is a {@link NormalizedNode} intermediate, not represented in RFC7950 XML encoding. This is typically
+ * one of
+ * <ul>
+ * <li>{@link ChoiceNode} backed by a {@link ChoiceSchemaNode}, or</li>
+ * <li>{@link LeafSetNode} backed by a {@link LeafListSchemaNode}, or</li>
+ * <li>{@link MapNode} backed by a {@link ListSchemaNode} with a non-empty
+ * {@link ListSchemaNode#getKeyDefinition()}, or</li>
+ * <li>{@link UnkeyedListNode} backed by a {@link ListSchemaNode} with an empty
+ * {@link ListSchemaNode#getKeyDefinition()}</li>
+ * </ul>
+ *
+ * <p>
+ * This trait is important for XML codec, but also for JSON encoding of {@link YangInstanceIdentifier}.
+ */
+ sealed interface PathMixin extends DataSchemaContextNode permits AbstractMixinContextNode {
+ /**
+ * The mixed-in {@link PathArgument}.
+ *
+ * @return Mixed-in PathArgument
+ */
+ @NonNull PathArgument mixinPathArgument();
+ }
@NonNull DataSchemaNode getDataSchemaNode();
// because those identifiers need a value.
@NonNull PathArgument pathArgument();
- /**
- * This node is a {@link NormalizedNode} intermediate, not represented in RFC7950 XML encoding. This is typically
- * one of
- * <ul>
- * <li>{@link ChoiceNode} backed by a {@link ChoiceSchemaNode}, or</li>
- * <li>{@link LeafSetNode} backed by a {@link LeafListSchemaNode}, or</li>
- * <li>{@link MapNode} backed by a {@link ListSchemaNode} with a non-empty
- * {@link ListSchemaNode#getKeyDefinition()}, or</li>
- * <li>{@link UnkeyedListNode} backed by a {@link ListSchemaNode} with an empty
- * {@link ListSchemaNode#getKeyDefinition()}</li>
- * </ul>
- *
- * @return {@code} false if this node corresponds to an XML element, or {@code true} if it is an encapsulation node.
- */
- boolean isMixin();
-
// FIXME: YANGTOOLS-1413: document this method and (most likely) split it out to a separate interface
boolean isKeyedEntry();
/**
* Find a child node identifier by its {code data tree} {@link QName}. This method returns intermediate nodes
* significant from {@link YangInstanceIdentifier} hierarchy of {@link PathArgument}s. If the returned node
- * indicates {@code true} via {@link #isMixin()}, it represents a {@link NormalizedNode} encapsulation which is
- * not visible in RFC7950 XML encoding, and a further call to this method with the same {@code child} argument will
- * provide the next step.
+ * indicates is also a {@link PathMixin}, it represents a {@link NormalizedNode} encapsulation which is not visible
+ * in RFC7950 XML encoding, and a further call to this method with the same {@code child} argument will provide the
+ * next step.
*
* @param child Child data tree QName
* @return A child node, or null if not found
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.PathMixin;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
private DataSchemaContextNode nextContextNode(final QName name) {
current = current.getChild(name);
checkValid(current != null, "%s is not correct schema node identifier.", name);
- while (current.isMixin()) {
- product.add(current.pathArgument());
+ while (current instanceof PathMixin mixin) {
+ product.add(mixin.mixinPathArgument());
current = current.getChild(name);
}
stack.enterDataTree(name);
return pathArgument;
}
- @Override
- public boolean isMixin() {
- return false;
- }
-
@Override
public boolean isKeyedEntry() {
return false;
* representation of these nodes is similar to JSON encoding and therefore we have two {@link DataSchemaContextNode}
* levels backed by a single {@link DataSchemaNode}.
*/
-abstract class AbstractListLikeContextNode extends AbstractMixinContextNode {
- AbstractListLikeContextNode(final PathArgument pathArgument, final DataSchemaNode schema) {
- super(pathArgument, schema);
+abstract sealed class AbstractListLikeContextNode extends AbstractMixinContextNode
+ permits UnkeyedListMixinContextNode, UnorderedLeafListMixinContextNode, UnorderedMapMixinContextNode {
+ AbstractListLikeContextNode(final DataSchemaNode schema) {
+ super(schema);
}
@Override
*/
package org.opendaylight.yangtools.yang.data.util.impl.legacy;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode.PathMixin;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
-abstract class AbstractMixinContextNode extends AbstractInteriorContextNode {
- AbstractMixinContextNode(final PathArgument pathArgument, final DataSchemaNode schema) {
- super(pathArgument, schema);
+public abstract sealed class AbstractMixinContextNode extends AbstractInteriorContextNode implements PathMixin
+ permits AbstractListLikeContextNode, ChoiceNodeContextNode {
+ AbstractMixinContextNode(final DataSchemaNode schema) {
+ super(NodeIdentifier.create(schema.getQName()), schema);
}
@Override
- public final boolean isMixin() {
- return true;
+ public PathArgument mixinPathArgument() {
+ return pathArgument();
}
}
\ No newline at end of file
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
private final ImmutableMap<DataSchemaContextNode, QName> childToCase;
ChoiceNodeContextNode(final ChoiceSchemaNode schema) {
- super(NodeIdentifier.create(schema.getQName()), schema);
+ super(schema);
final var childToCaseBuilder = ImmutableMap.<DataSchemaContextNode, QName>builder();
final var byQNameBuilder = ImmutableMap.<QName, AbstractDataSchemaContextNode>builder();
final var byArgBuilder = ImmutableMap.<PathArgument, AbstractDataSchemaContextNode>builder();
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
private final UnkeyedListItemContextNode innerNode;
UnkeyedListMixinContextNode(final ListSchemaNode list) {
- super(NodeIdentifier.create(list.getQName()), list);
+ super(list);
innerNode = new UnkeyedListItemContextNode(list);
}
package org.opendaylight.yangtools.yang.data.util.impl.legacy;
import org.opendaylight.yangtools.yang.common.QName;
-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.data.util.DataSchemaContextNode;
import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
-class UnorderedLeafListMixinContextNode extends AbstractListLikeContextNode {
+sealed class UnorderedLeafListMixinContextNode extends AbstractListLikeContextNode
+ permits OrderedLeafListMixinContextNode {
private final LeafListEntryContextNode innerOp;
UnorderedLeafListMixinContextNode(final LeafListSchemaNode schema) {
- super(NodeIdentifier.create(schema.getQName()), schema);
+ super(schema);
innerOp = new LeafListEntryContextNode(schema);
}
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.data.util.DataSchemaContextNode;
import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
-class UnorderedMapMixinContextNode extends AbstractListLikeContextNode {
+sealed class UnorderedMapMixinContextNode extends AbstractListLikeContextNode permits OrderedMapMixinContextNode {
private final ListItemContextNode innerNode;
UnorderedMapMixinContextNode(final ListSchemaNode list) {
- super(NodeIdentifier.create(list.getQName()), list);
+ super(list);
innerNode = new ListItemContextNode(list);
}