@Nullable BindingDataObjectCodecTreeNode<?> getCodecContextNode(final @NonNull YangInstanceIdentifier dom,
final @Nullable Collection<InstanceIdentifier.PathArgument> bindingArguments) {
CodecContext currentNode = root;
- ListNodeCodecContext<?> currentList = null;
+ ListCodecContext<?> currentList = null;
for (var domArg : dom.getPathArguments()) {
checkArgument(currentNode instanceof DataContainerCodecContext,
}
currentList = null;
currentNode = nextNode;
- } else if (nextNode instanceof ListNodeCodecContext<?> listNode) {
+ } else if (nextNode instanceof ListCodecContext<?> listNode) {
// We enter list, we do not update current Node yet,
// since we need to verify
currentList = listNode;
@Override
public void startMapEntryNode(final Key<?> key, final int childSizeHint) throws IOException {
duplicateSchemaEnter();
- NodeIdentifierWithPredicates identifier = ((KeyedListNodeCodecContext<?, ?>) current()).serialize(key);
+ NodeIdentifierWithPredicates identifier = ((MapCodecContext<?, ?>) current()).serialize(key);
delegate.startMapEntryNode(identifier, childSizeHint);
}
}
@Override
- DataContainerCodecContext<?, CaseRuntimeType> createInstance() {
+ CaseNodeCodecContext<?> createInstance() {
return new CaseNodeCodecContext<>(this);
}
}
\ No newline at end of file
import org.opendaylight.yangtools.yang.binding.BindingObject;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
import org.opendaylight.yangtools.yang.binding.contract.Naming;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
implements BindingDataObjectCodecTreeNode<D> {
private static final Logger LOG = LoggerFactory.getLogger(ChoiceCodecContext.class);
- private final ImmutableMap<NodeIdentifier, DataContainerCodecPrototype<?>> byYangCaseChild;
private final ImmutableListMultimap<Class<?>, DataContainerCodecPrototype<?>> ambiguousByCaseChildClass;
private final ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byCaseChildClass;
+ private final ImmutableMap<NodeIdentifier, CaseCodecPrototype> byYangCaseChild;
private final ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byClass;
private final Set<Class<?>> ambiguousByCaseChildWarnings;
- ChoiceCodecContext(final DataContainerCodecPrototype<ChoiceRuntimeType> prototype) {
+ ChoiceCodecContext(final Class<D> cls, final ChoiceRuntimeType type, final CodecContextFactory factory) {
+ this(new ChoiceCodecPrototype(Item.of(cls), type, factory));
+ }
+
+ ChoiceCodecContext(final ChoiceCodecPrototype prototype) {
super(prototype);
- final var byYangCaseChildBuilder = new HashMap<NodeIdentifier, DataContainerCodecPrototype<?>>();
+ final var byYangCaseChildBuilder = new HashMap<NodeIdentifier, CaseCodecPrototype>();
final var byClassBuilder = new HashMap<Class<?>, DataContainerCodecPrototype<?>>();
final var childToCase = SetMultimapBuilder.hashKeys().hashSetValues()
.<Class<?>, DataContainerCodecPrototype<?>>build();
return null;
}
final var caze = byYangCaseChild.get(first.name());
- return (D) caze.getDataObject().deserialize(data);
+ return ((CaseNodeCodecContext<D>) caze.get()).deserialize(data);
}
@Override
--- /dev/null
+/*
+ * Copyright (c) 2023 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.dom.codec.impl;
+
+import org.opendaylight.mdsal.binding.runtime.api.ChoiceRuntimeType;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+
+/**
+ * A prototype for {@link ChoiceCodecContext}.
+ */
+final class ChoiceCodecPrototype extends DataObjectCodecPrototype<ChoiceRuntimeType> {
+ ChoiceCodecPrototype(final Item<?> item, final ChoiceRuntimeType type, final CodecContextFactory factory) {
+ super(item, NodeIdentifier.create(type.statement().argument()), type, factory);
+ }
+
+ @Override
+ ChoiceCodecContext<?> createInstance() {
+ return new ChoiceCodecContext<>(this);
+ }
+}
if (!(data instanceof MapEntryNode mapEntry)) {
throw new VerifyException("Unsupported value " + data);
}
- if (!(context instanceof KeyedListNodeCodecContext<?, ?> listContext)) {
+ if (!(context instanceof MapCodecContext<?, ?> listContext)) {
throw new VerifyException("Unexpected context " + context);
}
import org.opendaylight.mdsal.binding.runtime.api.AugmentableRuntimeType;
import org.opendaylight.mdsal.binding.runtime.api.ChoiceRuntimeType;
import org.opendaylight.mdsal.binding.runtime.api.CompositeRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.ContainerLikeRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.ContainerRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.ListRuntimeType;
import org.opendaylight.yangtools.yang.binding.Augmentable;
import org.opendaylight.yangtools.yang.binding.DataContainer;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.contract.Naming;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.model.api.stmt.PresenceEffectiveStatement;
/**
* Analysis of a {@link DataObject} specialization class. The primary point of this class is to separate out creation
throw DataContainerCodecContext.childNullException(factory.getRuntimeContext(), childClass,
"Node %s does not have child named %s", type, childClass);
}
-
- return DataContainerCodecPrototype.from(itemFactory.createItem(childClass, child.statement()),
- (CompositeRuntimeType) child, factory);
+ final var item = itemFactory.createItem(childClass, child.statement());
+ if (child instanceof ContainerLikeRuntimeType containerLike) {
+ if (child instanceof ContainerRuntimeType container
+ && container.statement().findFirstEffectiveSubstatement(PresenceEffectiveStatement.class).isEmpty()) {
+ return new StructuralContainerCodecPrototype(item, container, factory);
+ }
+ return new ContainerLikeCodecPrototype(item, containerLike, factory);
+ } else if (child instanceof ListRuntimeType list) {
+ return list.keyType() != null ? new MapCodecPrototype(item, list, factory)
+ : new ListCodecPrototype(item, list, factory);
+ } else if (child instanceof ChoiceRuntimeType choice) {
+ return new ChoiceCodecPrototype(item, choice, factory);
+ } else {
+ throw new UnsupportedOperationException("Unhandled type " + child);
+ }
}
import org.opendaylight.mdsal.binding.runtime.api.ContainerLikeRuntimeType;
import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
sealed class ContainerLikeCodecContext<D extends DataObject>
extends DataObjectCodecContext<D, ContainerLikeRuntimeType<?, ?>> implements RpcInputCodec<D>
permits StructuralContainerCodecContext {
- ContainerLikeCodecContext(final DataContainerCodecPrototype<ContainerLikeRuntimeType<?, ?>> prototype) {
+ ContainerLikeCodecContext(final Class<D> cls, final ContainerLikeRuntimeType<?, ?> type,
+ final CodecContextFactory factory) {
+ this(new ContainerLikeCodecPrototype(Item.of(cls), type, factory));
+ }
+
+ ContainerLikeCodecContext(final ContainerLikeCodecPrototype prototype) {
super(prototype);
}
--- /dev/null
+/*
+ * Copyright (c) 2023 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.dom.codec.impl;
+
+import org.opendaylight.mdsal.binding.runtime.api.ContainerLikeRuntimeType;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+
+/**
+ * A prototype for a {@link ContainerLikeCodecContext}.
+ */
+sealed class ContainerLikeCodecPrototype extends DataObjectCodecPrototype<ContainerLikeRuntimeType<?, ?>>
+ permits StructuralContainerCodecPrototype {
+ ContainerLikeCodecPrototype(final Item<?> item, final ContainerLikeRuntimeType<?, ?> type,
+ final CodecContextFactory factory) {
+ super(item, NodeIdentifier.create(type.statement().argument()), type, factory);
+ }
+
+ @Override
+ ContainerLikeCodecContext<?> createInstance() {
+ return new ContainerLikeCodecContext<>(this);
+ }
+}
*/
package org.opendaylight.mdsal.binding.dom.codec.impl;
-import static com.google.common.base.Verify.verify;
import static java.util.Objects.requireNonNull;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.binding.dom.codec.api.CommonDataObjectCodecTreeNode.ChildAddressabilitySummary;
-import org.opendaylight.mdsal.binding.runtime.api.CompositeRuntimeType;
import org.opendaylight.mdsal.binding.runtime.api.RuntimeType;
import org.opendaylight.mdsal.binding.runtime.api.RuntimeTypeContainer;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
-import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.QNameModule;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.model.api.AnydataSchemaNode;
return haveUnaddressable ? ChildAddressabilitySummary.MIXED : ChildAddressabilitySummary.ADDRESSABLE;
}
- static <T extends CompositeRuntimeType> DataContainerCodecPrototype<T> from(final Class<?> cls, final T type,
- final CodecContextFactory factory) {
- return new DataObjectCodecPrototype<>(cls, createIdentifier(type), type, factory);
- }
-
- static <T extends CompositeRuntimeType> DataContainerCodecPrototype<T> from(final Item<?> bindingArg, final T type,
- final CodecContextFactory factory) {
- return new DataObjectCodecPrototype<>(bindingArg, createIdentifier(type), type, factory);
- }
-
- private static @NonNull NodeIdentifier createIdentifier(final CompositeRuntimeType type) {
- final Object arg = type.statement().argument();
- verify(arg instanceof QName, "Unexpected type %s argument %s", type, arg);
- return NodeIdentifier.create((QName) arg);
- }
-
final @NonNull T getType() {
return type;
}
return existing != null ? existing : loadInstance();
}
- @SuppressWarnings("unchecked")
- final <R extends CompositeRuntimeType> DataObjectCodecContext<?, R> getDataObject() {
- final var context = get();
- verify(context instanceof DataObjectCodecContext, "Unexpected instance %s", context);
- return (DataObjectCodecContext<?, R>) context;
- }
-
private @NonNull DataContainerCodecContext<?, T> loadInstance() {
final var tmp = createInstance();
final var witness = (DataContainerCodecContext<?, T>) INSTANCE.compareAndExchangeRelease(this, null, tmp);
@Beta
public abstract sealed class DataObjectCodecContext<D extends DataObject, T extends CompositeRuntimeType>
extends AbstractDataObjectCodecContext<D, T> implements BindingDataObjectCodecTreeNode<D>
- permits CaseNodeCodecContext, ContainerLikeCodecContext, ListNodeCodecContext, NotificationCodecContext {
+ permits CaseNodeCodecContext, ContainerLikeCodecContext, ListCodecContext, NotificationCodecContext {
private static final Logger LOG = LoggerFactory.getLogger(DataObjectCodecContext.class);
private static final VarHandle MISMATCHED_AUGMENTED;
import static java.util.Objects.requireNonNull;
import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.binding.runtime.api.ChoiceRuntimeType;
-import org.opendaylight.mdsal.binding.runtime.api.ContainerLikeRuntimeType;
-import org.opendaylight.mdsal.binding.runtime.api.ContainerRuntimeType;
-import org.opendaylight.mdsal.binding.runtime.api.ListRuntimeType;
import org.opendaylight.mdsal.binding.runtime.api.RuntimeTypeContainer;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
-import org.opendaylight.yangtools.yang.binding.KeyAware;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.model.api.stmt.PresenceEffectiveStatement;
-// FIXME: abstract and sealed
-non-sealed class DataObjectCodecPrototype<T extends RuntimeTypeContainer> extends DataContainerCodecPrototype<T> {
+abstract sealed class DataObjectCodecPrototype<T extends RuntimeTypeContainer> extends DataContainerCodecPrototype<T>
+ permits CaseCodecPrototype, ChoiceCodecPrototype, ContainerLikeCodecPrototype, ListCodecPrototype,
+ NotificationCodecContext.Prototype, RootCodecContext.Prototype {
private final @NonNull NodeIdentifier yangArg;
+ // FIXME: this should not be needed
@SuppressWarnings("unchecked")
DataObjectCodecPrototype(final Class<?> cls, final NodeIdentifier yangArg, final T type,
final CodecContextFactory factory) {
final NodeIdentifier getYangArg() {
return yangArg;
}
-
- @Override
- @SuppressWarnings({ "rawtypes", "unchecked" })
- DataContainerCodecContext<?, T> createInstance() {
- final var type = getType();
- if (type instanceof ContainerLikeRuntimeType containerLike) {
- if (containerLike instanceof ContainerRuntimeType container
- && container.statement().findFirstEffectiveSubstatement(PresenceEffectiveStatement.class)
- .isEmpty()) {
- return new StructuralContainerCodecContext(this);
- }
- return new ContainerLikeCodecContext(this);
- } else if (type instanceof ListRuntimeType) {
- return KeyAware.class.isAssignableFrom(getBindingClass())
- ? KeyedListNodeCodecContext.create((DataContainerCodecPrototype<ListRuntimeType>) this)
- : new ListNodeCodecContext(this);
- } else if (type instanceof ChoiceRuntimeType) {
- return new ChoiceCodecContext(this);
- }
- throw new IllegalArgumentException("Unsupported type " + getBindingClass() + " " + type);
- }
-}
\ No newline at end of file
+}
if (codec == null) {
return null;
}
- if (codec instanceof ListNodeCodecContext && Iterables.getLast(builder) instanceof InstanceIdentifier.Item) {
+ if (codec instanceof ListCodecContext && Iterables.getLast(builder) instanceof InstanceIdentifier.Item) {
// We ended up in list, but without key, which means it represent list as a whole,
// which is not binding representable.
return null;
}
}
- private final ListNodeCodecContext<E> codec;
+ private final ListCodecContext<E> codec;
private final Object[] objects;
- private LazyBindingList(final ListNodeCodecContext<E> codec,
+ private LazyBindingList(final ListCodecContext<E> codec,
final Collection<? extends NormalizedNodeContainer<?>> entries) {
this.codec = requireNonNull(codec);
objects = entries.toArray();
}
- static <E extends DataObject> @NonNull List<E> create(final ListNodeCodecContext<E> codec, final int size,
+ static <E extends DataObject> @NonNull List<E> create(final ListCodecContext<E> codec, final int size,
final Collection<? extends DataContainerNode> entries) {
if (size == 1) {
// Do not bother with lazy instantiation in case of a singleton
return size > LAZY_CUTOFF ? new LazyBindingList<>(codec, entries) : eagerList(codec, size, entries);
}
- private static <E extends DataObject> @NonNull List<E> eagerList(final ListNodeCodecContext<E> codec,
+ private static <E extends DataObject> @NonNull List<E> eagerList(final ListCodecContext<E> codec,
final int size, final Collection<? extends DataContainerNode> entries) {
@SuppressWarnings("unchecked")
final E[] objs = (E[]) new DataObject[size];
import java.util.Optional;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.binding.dom.codec.impl.KeyedListNodeCodecContext.Unordered;
+import org.opendaylight.mdsal.binding.dom.codec.impl.MapCodecContext.Unordered;
import org.opendaylight.yangtools.concepts.Immutable;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.Key;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.binding.runtime.api.ListRuntimeType;
import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
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.UnkeyedListEntryNode;
import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-sealed class ListNodeCodecContext<D extends DataObject> extends DataObjectCodecContext<D, ListRuntimeType>
- permits KeyedListNodeCodecContext {
- ListNodeCodecContext(final DataContainerCodecPrototype<ListRuntimeType> prototype) {
+sealed class ListCodecContext<D extends DataObject> extends DataObjectCodecContext<D, ListRuntimeType>
+ permits MapCodecContext {
+ ListCodecContext(final Class<D> cls, final ListRuntimeType list, final CodecContextFactory factory) {
+ this(new ListCodecPrototype(Item.of(cls), list, factory));
+ }
+
+ ListCodecContext(final ListCodecPrototype prototype) {
super(prototype);
}
- ListNodeCodecContext(final DataContainerCodecPrototype<ListRuntimeType> prototype,
- final Method keyMethod) {
+ ListCodecContext(final ListCodecPrototype prototype, final Method keyMethod) {
super(prototype, keyMethod);
}
--- /dev/null
+/*
+ * Copyright (c) 2023 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.dom.codec.impl;
+
+import org.opendaylight.mdsal.binding.runtime.api.ListRuntimeType;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+
+/**
+ * A prototype for {@link ListCodecContext}.
+ */
+sealed class ListCodecPrototype extends DataObjectCodecPrototype<ListRuntimeType> permits MapCodecPrototype {
+ ListCodecPrototype(final Item<?> item, final ListRuntimeType type, final CodecContextFactory factory) {
+ super(item, NodeIdentifier.create(type.statement().argument()), type, factory);
+ }
+
+ @Override
+ ListCodecContext<?> createInstance() {
+ return new ListCodecContext<>(this);
+ }
+}
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
import org.opendaylight.yangtools.yang.binding.Key;
import org.opendaylight.yangtools.yang.binding.KeyAware;
import org.opendaylight.yangtools.yang.binding.contract.Naming;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
-abstract sealed class KeyedListNodeCodecContext<I extends Key<D>, D extends DataObject & KeyAware<I>>
- extends ListNodeCodecContext<D> {
+abstract sealed class MapCodecContext<I extends Key<D>, D extends DataObject & KeyAware<I>>
+ extends ListCodecContext<D> {
private static final class Ordered<I extends Key<D>, D extends DataObject & KeyAware<I>>
- extends KeyedListNodeCodecContext<I, D> {
- Ordered(final DataContainerCodecPrototype<ListRuntimeType> prototype, final Method keyMethod,
- final IdentifiableItemCodec codec) {
+ extends MapCodecContext<I, D> {
+ Ordered(final MapCodecPrototype prototype, final Method keyMethod, final IdentifiableItemCodec codec) {
super(prototype, keyMethod, codec);
}
}
static final class Unordered<I extends Key<D>, D extends DataObject & KeyAware<I>>
- extends KeyedListNodeCodecContext<I, D> {
- Unordered(final DataContainerCodecPrototype<ListRuntimeType> prototype, final Method keyMethod,
+ extends MapCodecContext<I, D> {
+ private Unordered(final MapCodecPrototype prototype, final Method keyMethod,
final IdentifiableItemCodec codec) {
super(prototype, keyMethod, codec);
}
private final IdentifiableItemCodec codec;
- KeyedListNodeCodecContext(final DataContainerCodecPrototype<ListRuntimeType> prototype,
- final Method keyMethod, final IdentifiableItemCodec codec) {
+ private MapCodecContext(final MapCodecPrototype prototype, final Method keyMethod,
+ final IdentifiableItemCodec codec) {
super(prototype, keyMethod);
this.codec = requireNonNull(codec);
}
- @SuppressWarnings("rawtypes")
- static KeyedListNodeCodecContext create(final DataContainerCodecPrototype<ListRuntimeType> prototype) {
- final Class<?> bindingClass = prototype.getBindingClass();
+ static @NonNull MapCodecContext<?, ?> of(final Class<? extends DataObject> cls,
+ final ListRuntimeType list, final CodecContextFactory factory) {
+ return of(new MapCodecPrototype(Item.of(cls), list, factory));
+ }
+
+ static @NonNull MapCodecContext<?, ?> of(final MapCodecPrototype prototype) {
+ final var bindingClass = prototype.getBindingClass();
final Method keyMethod;
try {
keyMethod = bindingClass.getMethod(Naming.KEY_AWARE_KEY_NAME);
throw new IllegalStateException("Required method not available", e);
}
- final ListRuntimeType type = prototype.getType();
- final IdentifiableItemCodec codec = prototype.getFactory().getPathArgumentCodec(bindingClass, type);
+ final var type = prototype.getType();
+ final var codec = prototype.getFactory().getPathArgumentCodec(bindingClass, type);
return type.statement().ordering() == Ordering.SYSTEM ? new Unordered<>(prototype, keyMethod, codec)
: new Ordered<>(prototype, keyMethod, codec);
}
@Override
- protected InstanceIdentifier.PathArgument getBindingPathArgument(final YangInstanceIdentifier.PathArgument domArg) {
+ protected final InstanceIdentifier.PathArgument getBindingPathArgument(
+ final YangInstanceIdentifier.PathArgument domArg) {
return domArg instanceof NodeIdentifierWithPredicates nip ? codec.domToBinding(nip)
: super.getBindingPathArgument(domArg);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
- NodeIdentifierWithPredicates serialize(final Key<?> key) {
+ final NodeIdentifierWithPredicates serialize(final Key<?> key) {
return codec.bindingToDom(IdentifiableItem.of((Class)getBindingClass(), (Key)key));
}
- @NonNull Key<?> deserialize(final @NonNull NodeIdentifierWithPredicates arg) {
+ final @NonNull Key<?> deserialize(final @NonNull NodeIdentifierWithPredicates arg) {
return codec.deserializeIdentifier(arg);
}
@Override
- public YangInstanceIdentifier.PathArgument serializePathArgument(final InstanceIdentifier.PathArgument arg) {
+ public final YangInstanceIdentifier.PathArgument serializePathArgument(final InstanceIdentifier.PathArgument arg) {
return arg instanceof IdentifiableItem<?, ?> identifiable ? codec.bindingToDom(identifiable)
: super.serializePathArgument(arg);
}
@Override
- public InstanceIdentifier.PathArgument deserializePathArgument(final YangInstanceIdentifier.PathArgument arg) {
+ public final InstanceIdentifier.PathArgument deserializePathArgument(
+ final YangInstanceIdentifier.PathArgument arg) {
return arg instanceof NodeIdentifierWithPredicates nip ? codec.domToBinding(nip)
: super.deserializePathArgument(arg);
}
--- /dev/null
+/*
+ * Copyright (c) 2023 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.dom.codec.impl;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+import org.opendaylight.mdsal.binding.runtime.api.ListRuntimeType;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
+import org.opendaylight.yangtools.yang.binding.KeyAware;
+
+/**
+ * A prototype for a {@link MapCodecContext}.
+ */
+final class MapCodecPrototype extends ListCodecPrototype {
+ MapCodecPrototype(final Item<?> item, final ListRuntimeType type, final CodecContextFactory factory) {
+ super(item, type, factory);
+ final var clazz = getBindingClass();
+ checkArgument(KeyAware.class.isAssignableFrom(clazz), "%s is not KeyAware", clazz);
+ }
+
+ @Override
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ ListCodecContext createInstance() {
+ return MapCodecContext.of(this);
+ }
+}
}
/**
- * Prototype for a {@code notiofication}. This class only exists because DataContainerCodecContext requires a
+ * Prototype for a {@code notification}. This class only exists because DataContainerCodecContext requires a
* prototype.
*/
- private static final class Prototype<D extends DataObject & BaseNotification>
+ static final class Prototype<D extends DataObject & BaseNotification>
extends DataObjectCodecPrototype<NotificationRuntimeType> {
- Prototype(final Class<?> cls, final NotificationRuntimeType type, final CodecContextFactory factory) {
+ private Prototype(final Class<?> cls, final NotificationRuntimeType type, final CodecContextFactory factory) {
super(cls, NodeIdentifier.create(type.statement().argument()), type, factory);
}
@Override
- DataContainerCodecContext<?, NotificationRuntimeType> createInstance() {
+ NotificationCodecContext<?> createInstance() {
throw new UnsupportedOperationException("Should never be invoked");
}
}
import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeContext;
import org.opendaylight.mdsal.binding.runtime.api.BindingRuntimeTypes;
import org.opendaylight.mdsal.binding.runtime.api.ChoiceRuntimeType;
-import org.opendaylight.mdsal.binding.runtime.api.CompositeRuntimeType;
import org.opendaylight.mdsal.binding.runtime.api.ContainerLikeRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.ContainerRuntimeType;
import org.opendaylight.mdsal.binding.runtime.api.DataRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.ListRuntimeType;
import org.opendaylight.mdsal.binding.runtime.api.NotificationRuntimeType;
import org.opendaylight.mdsal.binding.spec.reflect.BindingReflections;
import org.opendaylight.yangtools.util.ClassLoaderUtils;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.stmt.PresenceEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
final class RootCodecContext<D extends DataObject> extends DataContainerCodecContext<D, BindingRuntimeTypes>
* Prototype for the root of YANG modeled world. This class only exists because DataContainerCodecContext requires
* a prototype.
*/
- private static final class Prototype extends DataObjectCodecPrototype<BindingRuntimeTypes> {
+ static final class Prototype extends DataObjectCodecPrototype<BindingRuntimeTypes> {
private static final @NonNull NodeIdentifier ROOT_NODEID = NodeIdentifier.create(SchemaContext.NAME);
- Prototype(final CodecContextFactory factory) {
+ private Prototype(final CodecContextFactory factory) {
super(DataRoot.class, ROOT_NODEID, factory.getRuntimeContext().getTypes(), factory);
}
@Override
- DataContainerCodecContext<?, BindingRuntimeTypes> createInstance() {
+ RootCodecContext<?> createInstance() {
throw new UnsupportedOperationException("Should never be invoked");
}
}
final ContainerLike schema = getRpcDataSchema(potential, qname);
checkArgument(schema != null, "Schema for %s does not define input / output.", potentialQName);
- final ContainerLikeRuntimeType<?, ?> type = lookup.apply(context.getTypes(), potentialQName)
+ final var type = lookup.apply(context.getTypes(), potentialQName)
.orElseThrow(() -> new IllegalArgumentException("Cannot find runtime type for " + key));
- return (ContainerLikeCodecContext) DataContainerCodecPrototype.from(key,
- (ContainerLikeRuntimeType<?, ?>) type, factory).get();
+ // FIXME: accurate type
+ return new ContainerLikeCodecContext(key, type, factory);
}
}
DataContainerCodecContext<?, ?> createDataTreeChildContext(final Class<? extends DataObject> key) {
final var childSchema = childNonNull(type().bindingChild(JavaTypeName.create(key)), key,
"%s is not top-level item.", key);
- if (childSchema instanceof CompositeRuntimeType composite && childSchema instanceof DataRuntimeType) {
- return DataContainerCodecPrototype.from(key, composite, factory()).get();
+ if (childSchema instanceof ContainerLikeRuntimeType containerLike) {
+ if (childSchema instanceof ContainerRuntimeType container
+ && container.statement().findFirstEffectiveSubstatement(PresenceEffectiveStatement.class).isEmpty()) {
+ return new StructuralContainerCodecContext<>(key, container, factory());
+ }
+ return new ContainerLikeCodecContext<>(key, containerLike, factory());
+ } else if (childSchema instanceof ListRuntimeType list) {
+ return list.keyType() == null ? new ListCodecContext<>(key, list, factory())
+ : MapCodecContext.of(key, list, factory());
+ } else if (childSchema instanceof ChoiceRuntimeType choice) {
+ return new ChoiceCodecContext<>(key, choice, factory());
}
throw new IncorrectNestingException("%s is not a valid data tree child of %s", key, this);
}
checkArgument(args.length == expectedArgsLength, "Unexpected (%s) Action generatic arguments", args.length);
final ActionRuntimeType schema = factory().getRuntimeContext().getActionDefinition(action);
return new ActionCodecContext(
- DataContainerCodecPrototype.from(asClass(args[inputOffset], RpcInput.class), schema.input(),
- factory()).getDataObject(),
- DataContainerCodecPrototype.from(asClass(args[outputOffset], RpcOutput.class), schema.output(),
- factory()).getDataObject());
+ new ContainerLikeCodecContext(asClass(args[inputOffset], RpcInput.class), schema.input(), factory()),
+ new ContainerLikeCodecContext(asClass(args[outputOffset], RpcOutput.class), schema.output(), factory()));
}
private static <T extends DataObject> Class<? extends T> asClass(final Type type, final Class<T> target) {
throw new IllegalArgumentException(caseType + " does not refer to a choice");
}
- final var choice = DataContainerCodecPrototype.from(choiceClass, choiceType, factory()).get();
- verify(choice instanceof ChoiceCodecContext);
- return (ChoiceCodecContext<?>) choice;
+ // FIXME: accurate type!
+ return new ChoiceCodecContext(choiceClass, choiceType, factory());
}
@Override
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import org.eclipse.jdt.annotation.NonNull;
-import org.opendaylight.mdsal.binding.runtime.api.ContainerLikeRuntimeType;
+import org.opendaylight.mdsal.binding.runtime.api.ContainerRuntimeType;
import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
/**
@SuppressWarnings("unused")
private volatile D emptyObject;
- StructuralContainerCodecContext(final DataContainerCodecPrototype<ContainerLikeRuntimeType<?, ?>> prototype) {
+ StructuralContainerCodecContext(final Class<D> cls, final ContainerRuntimeType type,
+ final CodecContextFactory factory) {
+ this(new StructuralContainerCodecPrototype(Item.of(cls), type, factory));
+ }
+
+ StructuralContainerCodecContext(final StructuralContainerCodecPrototype prototype) {
super(prototype);
}
--- /dev/null
+/*
+ * Copyright (c) 2023 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.dom.codec.impl;
+
+import org.opendaylight.mdsal.binding.runtime.api.ContainerRuntimeType;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
+
+/**
+ * A prototype for a {@link StructuralContainerCodecContext}.
+ */
+final class StructuralContainerCodecPrototype extends ContainerLikeCodecPrototype {
+ StructuralContainerCodecPrototype(final Item<?> item, final ContainerRuntimeType container,
+ final CodecContextFactory factory) {
+ super(item, container, factory);
+ }
+
+ @Override
+ StructuralContainerCodecContext<?> createInstance() {
+ return new StructuralContainerCodecContext<>(this);
+ }
+}