import com.google.common.base.VerifyException;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.ArrayList;
import org.eclipse.jdt.annotation.Nullable;
import org.opendaylight.mdsal.binding.api.DataObjectModification;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingAugmentationCodecTreeNode;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingChoiceCodecTreeNode;
+import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataContainerCodecTreeNode;
import org.opendaylight.mdsal.binding.dom.codec.api.BindingDataObjectCodecTreeNode;
import org.opendaylight.mdsal.binding.dom.codec.api.CommonDataObjectCodecTreeNode;
import org.opendaylight.yangtools.yang.binding.Augmentation;
import org.opendaylight.yangtools.yang.binding.ChildOf;
import org.opendaylight.yangtools.yang.binding.ChoiceIn;
import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.Identifiable;
-import org.opendaylight.yangtools.yang.binding.Identifier;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.binding.ExactDataObjectStep;
+import org.opendaylight.yangtools.yang.binding.Key;
+import org.opendaylight.yangtools.yang.binding.KeyAware;
+import org.opendaylight.yangtools.yang.binding.KeyStep;
+import org.opendaylight.yangtools.yang.binding.NodeStep;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateNode;
}
final @NonNull DataTreeCandidateNode domData;
- final @NonNull PathArgument identifier;
+ final @NonNull ExactDataObjectStep<T> step;
final @NonNull N codec;
@SuppressWarnings("unused")
+ @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "https://github.com/spotbugs/spotbugs/issues/2749")
private volatile ImmutableList<AbstractDataObjectModification<?, ?>> modifiedChildren;
@SuppressWarnings("unused")
+ @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "https://github.com/spotbugs/spotbugs/issues/2749")
private volatile ModificationType modificationType;
@SuppressWarnings("unused")
+ @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "https://github.com/spotbugs/spotbugs/issues/2749")
private volatile Object dataBefore;
@SuppressWarnings("unused")
+ @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "https://github.com/spotbugs/spotbugs/issues/2749")
private volatile Object dataAfter;
- AbstractDataObjectModification(final DataTreeCandidateNode domData, final N codec, final PathArgument identifier) {
+ AbstractDataObjectModification(final DataTreeCandidateNode domData, final N codec,
+ final ExactDataObjectStep<T> step) {
this.domData = requireNonNull(domData);
- this.identifier = requireNonNull(identifier);
+ this.step = requireNonNull(step);
this.codec = requireNonNull(codec);
}
}
@Override
- public final Class<T> getDataType() {
- return codec.getBindingClass();
+ public final ExactDataObjectStep<T> step() {
+ return step;
}
@Override
- public final PathArgument getIdentifier() {
- return identifier;
- }
-
- @Override
- public final ModificationType getModificationType() {
+ public final ModificationType modificationType() {
final var local = (ModificationType) MODIFICATION_TYPE.getAcquire(this);
return local != null ? local : loadModificationType();
}
}
@Override
- public final T getDataBefore() {
+ public final T dataBefore() {
final var local = DATA_BEFORE.getAcquire(this);
return local != null ? unmask(local) : loadDataBefore();
}
}
@Override
- public final T getDataAfter() {
+ public final T dataAfter() {
final var local = DATA_AFTER.getAcquire(this);
return local != null ? unmask(local) : loadDataAfter();
}
abstract @Nullable T deserialize(@NonNull NormalizedNode normalized);
@Override
- public final DataObjectModification<?> getModifiedChild(final PathArgument arg) {
+ public final DataObjectModification<?> getModifiedChild(final ExactDataObjectStep<?> arg) {
final var domArgumentList = new ArrayList<YangInstanceIdentifier.PathArgument>();
final var childCodec = codec.bindingPathArgumentChild(arg, domArgumentList);
final var toEnter = domArgumentList.iterator();
abstract @Nullable DataTreeCandidateNode firstModifiedChild(YangInstanceIdentifier.PathArgument arg);
@Override
- public final ImmutableList<AbstractDataObjectModification<?, ?>> getModifiedChildren() {
+ public final ImmutableList<AbstractDataObjectModification<?, ?>> modifiedChildren() {
final var local = (ImmutableList<AbstractDataObjectModification<?, ?>>) MODIFIED_CHILDREN.getAcquire(this);
return local != null ? local : loadModifiedChilden();
}
public final <H extends ChoiceIn<? super T> & DataObject, C extends ChildOf<? super H>>
List<DataObjectModification<C>> getModifiedChildren(final Class<H> caseType, final Class<C> childType) {
return streamModifiedChildren(childType)
- .filter(child -> caseType.equals(child.identifier.getCaseType().orElse(null)))
+ .filter(child -> caseType.equals(child.step.caseType()))
.collect(Collectors.toList());
}
@SuppressWarnings("unchecked")
private <C extends DataObject> Stream<LazyDataObjectModification<C>> streamModifiedChildren(
final Class<C> childType) {
- return getModifiedChildren().stream()
- .filter(child -> childType.isAssignableFrom(child.getDataType()))
+ return modifiedChildren().stream()
+ .filter(child -> childType.isAssignableFrom(child.dataType()))
.map(child -> (LazyDataObjectModification<C>) child);
}
@Override
@SuppressWarnings("unchecked")
- public final <C extends Identifiable<K> & ChildOf<? super T>, K extends Identifier<C>> DataObjectModification<C>
+ public final <C extends KeyAware<K> & ChildOf<? super T>, K extends Key<C>> DataObjectModification<C>
getModifiedChildListItem(final Class<C> listItem, final K listKey) {
- return (DataObjectModification<C>) getModifiedChild(IdentifiableItem.of(listItem, listKey));
+ return (DataObjectModification<C>) getModifiedChild(new KeyStep<>(listItem, listKey));
}
@Override
@SuppressWarnings("unchecked")
- public final <H extends ChoiceIn<? super T> & DataObject, C extends Identifiable<K> & ChildOf<? super H>,
- K extends Identifier<C>> DataObjectModification<C> getModifiedChildListItem(final Class<H> caseType,
+ public final <H extends ChoiceIn<? super T> & DataObject, C extends KeyAware<K> & ChildOf<? super H>,
+ K extends Key<C>> DataObjectModification<C> getModifiedChildListItem(final Class<H> caseType,
final Class<C> listItem, final K listKey) {
- return (DataObjectModification<C>) getModifiedChild(IdentifiableItem.of(caseType, listItem, listKey));
+ return (DataObjectModification<C>) getModifiedChild(new KeyStep<>(listItem, caseType, listKey));
}
@Override
@SuppressWarnings("unchecked")
public final <C extends ChildOf<? super T>> DataObjectModification<C> getModifiedChildContainer(
final Class<C> child) {
- return (DataObjectModification<C>) getModifiedChild(Item.of(child));
+ return (DataObjectModification<C>) getModifiedChild(new NodeStep<>(child));
}
@Override
@SuppressWarnings("unchecked")
public final <H extends ChoiceIn<? super T> & DataObject, C extends ChildOf<? super H>> DataObjectModification<C>
getModifiedChildContainer(final Class<H> caseType, final Class<C> child) {
- return (DataObjectModification<C>) getModifiedChild(Item.of(caseType, child));
+ return (DataObjectModification<C>) getModifiedChild(new NodeStep<>(caseType, child));
}
@Override
@SuppressWarnings("unchecked")
public final <C extends Augmentation<T> & DataObject> DataObjectModification<C> getModifiedAugmentation(
final Class<C> augmentation) {
- return (DataObjectModification<C>) getModifiedChild(Item.of(augmentation));
+ return (DataObjectModification<C>) getModifiedChild(new NodeStep<>(augmentation));
}
@Override
}
ToStringHelper addToStringAttributes(final ToStringHelper helper) {
- return helper.add("identifier", identifier).add("domData", domData);
+ return helper.add("step", step).add("domData", domData);
}
abstract @NonNull Collection<DataTreeCandidateNode> domChildNodes();
}
private static void populateList(final ImmutableList.Builder<AbstractDataObjectModification<?, ?>> result,
- final CommonDataObjectCodecTreeNode<?> parentCodec, final DataTreeCandidateNode parent,
+ final BindingDataContainerCodecTreeNode<?> parentCodec, final DataTreeCandidateNode parent,
final Collection<DataTreeCandidateNode> children) {
final var augmentChildren =
ArrayListMultimap.<BindingAugmentationCodecTreeNode<?>, DataTreeCandidateNode>create();
} else if (childCodec instanceof BindingAugmentationCodecTreeNode<?> childAugmentationCodec) {
// Defer creation once we have collected all modified children
augmentChildren.put(childAugmentationCodec, domChildNode);
+ } else if (childCodec instanceof BindingChoiceCodecTreeNode<?> childChoiceCodec) {
+ populateList(result, childChoiceCodec, domChildNode, domChildNode.childNodes());
} else {
throw new VerifyException("Unhandled codec %s for type %s".formatted(childCodec, type));
}