final DataContainerAnalysis<AugmentRuntimeType> analysis) {
super(prototype, analysis);
- final var bindingClass = CodecDataObjectGenerator.generate(prototype.getFactory().getLoader(),
- prototype.getBindingClass(), analysis.leafContexts, analysis.daoProperties, null);
+ final var bindingClass = CodecDataObjectGenerator.generate(prototype.contextFactory().getLoader(),
+ prototype.javaClass(), analysis.leafContexts, analysis.daoProperties, null);
final MethodHandle ctor;
try {
final class CaseCodecContext<D extends DataObject> extends DataObjectCodecContext<D, CaseRuntimeType> {
CaseCodecContext(final CaseCodecPrototype prototype) {
- super(prototype, CodecItemFactory.of(prototype.getBindingClass()));
+ super(prototype, CodecItemFactory.of(prototype.javaClass()));
}
@Override
.<Class<?>, CommonDataObjectCodecPrototype<?>>build();
// Load case statements valid in this choice and keep track of their names
- final var choiceType = prototype.getType();
- final var factory = prototype.getFactory();
+ final var choiceType = prototype.runtimeType();
+ final var factory = prototype.contextFactory();
final var localCases = new HashSet<JavaTypeName>();
for (var caseType : choiceType.validCaseChildren()) {
@SuppressWarnings("unchecked")
if (cases.size() != 1) {
// Sort all possibilities by their FQCN to retain semi-predictable results
final var list = new ArrayList<>(entry.getValue());
- list.sort(Comparator.comparing(proto -> proto.getBindingClass().getCanonicalName()));
+ list.sort(Comparator.comparing(proto -> proto.javaClass().getCanonicalName()));
ambiguousByCaseBuilder.putAll(entry.getKey(), list);
} else {
unambiguousByCaseBuilder.put(entry.getKey(), cases.iterator().next());
Ambiguous reference {} to child of {} resolved to {}, the first case in {} This mapping is \
not guaranteed to be stable and is subject to variations based on runtime circumstances. \
Please see the stack trace for hints about the source of ambiguity.""",
- type, bindingArg(), result.getBindingClass(),
- Lists.transform(inexact, CommonDataObjectCodecPrototype::getBindingClass), new Throwable());
+ type, bindingArg(), result.javaClass(),
+ Lists.transform(inexact, CommonDataObjectCodecPrototype::javaClass), new Throwable());
}
}
}
final @NonNull CommonDataObjectCodecPrototype<T> prototype;
CommonDataObjectCodecContext(final CommonDataObjectCodecPrototype<T> prototype) {
- super(prototype.getType());
+ super(prototype.runtimeType());
this.prototype = requireNonNull(prototype);
}
@SuppressWarnings("unchecked")
@Override
public final Class<D> getBindingClass() {
- return Class.class.cast(prototype.getBindingClass());
+ return Class.class.cast(prototype.javaClass());
}
@Override
protected final CodecContextFactory factory() {
- return prototype.getFactory();
+ return prototype.contextFactory();
}
@Override
protected final T type() {
- return prototype.getType();
+ return prototype.runtimeType();
}
@Override
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.mdsal.binding.runtime.api.CompositeRuntimeType;
+import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-abstract sealed class CommonDataObjectCodecPrototype<T extends CompositeRuntimeType>
- extends LazyCodecContextSupplier<CommonDataObjectCodecContext<?, T>>
+/**
+ * Common superclass for {@link DataObjectCodecPrototype} and {@link AugmentationCodecPrototype}.
+ *
+ * @param <R> {@link CompositeRuntimeType} type
+ */
+abstract sealed class CommonDataObjectCodecPrototype<R extends CompositeRuntimeType>
+ extends DataContainerPrototype<CommonDataObjectCodecContext<?, R>, R>
permits AugmentationCodecPrototype, DataObjectCodecPrototype {
- private final @NonNull T type;
- private final @NonNull CodecContextFactory factory;
private final @NonNull Item<?> bindingArg;
- CommonDataObjectCodecPrototype(final Item<?> bindingArg, final T type, final CodecContextFactory factory) {
+ CommonDataObjectCodecPrototype(final Item<?> bindingArg, final R runtimeType, final CodecContextFactory factory) {
+ super(factory, runtimeType);
this.bindingArg = requireNonNull(bindingArg);
- this.type = requireNonNull(type);
- this.factory = requireNonNull(factory);
- }
-
- final @NonNull T getType() {
- return type;
- }
-
- final @NonNull CodecContextFactory getFactory() {
- return factory;
}
- final @NonNull Class<?> getBindingClass() {
+ @Override
+ final Class<? extends DataObject> javaClass() {
return bindingArg.getType();
}
final @NonNull ImmutableMap<Class<?>, PropertyInfo> daoProperties;
DataContainerAnalysis(final CommonDataObjectCodecPrototype<R> prototype, final CodecItemFactory itemFactory) {
- this(prototype.getBindingClass(), prototype.getType(), prototype.getFactory(), itemFactory);
+ this(prototype.javaClass(), prototype.runtimeType(), prototype.contextFactory(), itemFactory);
}
DataContainerAnalysis(final Class<?> bindingClass, final R runtimeType, final CodecContextFactory factory,
daoPropertiesBuilder.put(retClass, new PropertyInfo.Getter(method));
final var childProto = getChildPrototype(runtimeType, factory, itemFactory, retClass);
- byStreamClassBuilder.put(childProto.getBindingClass(), childProto);
+ byStreamClassBuilder.put(childProto.javaClass(), childProto);
byYangBuilder.put(childProto.getYangArg(), childProto);
// FIXME: It really feels like we should be specializing DataContainerCodecPrototype so as to ditch
// createInstance() and then we could do an instanceof check instead.
- if (childProto.getType() instanceof ChoiceRuntimeType) {
+ if (childProto.runtimeType() instanceof ChoiceRuntimeType) {
final var choice = (ChoiceCodecContext<?>) childProto.getCodecContext();
for (var cazeChild : choice.getCaseChildrenClasses()) {
byBindingArgClassBuilder.put(cazeChild, childProto);
--- /dev/null
+/*
+ * Copyright (c) 2024 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 java.util.Objects.requireNonNull;
+
+import org.eclipse.jdt.annotation.NonNull;
+import org.opendaylight.mdsal.binding.runtime.api.CompositeRuntimeType;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+/**
+ * A prototype for codecs dealing with {@link DataContainer}s.
+ *
+ * @param <C> {@link CodecContext} type
+ * @param <R> {@link CompositeRuntimeType} type
+ */
+abstract sealed class DataContainerPrototype<C extends CodecContext, R extends CompositeRuntimeType>
+ extends LazyCodecContextSupplier<C> permits CommonDataObjectCodecPrototype {
+ private final @NonNull CodecContextFactory contextFactory;
+ private final @NonNull R runtimeType;
+
+ DataContainerPrototype(final CodecContextFactory contextFactory, final R runtimeType) {
+ this.contextFactory = requireNonNull(contextFactory);
+ this.runtimeType = requireNonNull(runtimeType);
+ }
+
+ /**
+ * Return the {@link CodecContextFactory} associated with this prototype.
+ *
+ * @return the context factory associated with this prototype
+ */
+ final @NonNull CodecContextFactory contextFactory() {
+ return contextFactory;
+ }
+
+ /**
+ * Return associated run-time type.
+ *
+ * @return associated run-time type
+ */
+ final @NonNull R runtimeType() {
+ return runtimeType;
+ }
+
+ /**
+ * Return the generated binding class this prototype corresponds to.
+ *
+ * @return the generated binding class this prototype corresponds to
+ */
+ abstract @NonNull Class<? extends DataContainer> javaClass();
+}
final List<AugmentRuntimeType> possibleAugmentations;
if (Augmentable.class.isAssignableFrom(bindingClass)) {
// Verify we have the appropriate backing runtimeType
- final var runtimeType = prototype.getType();
+ final var runtimeType = prototype.runtimeType();
if (!(runtimeType instanceof AugmentableRuntimeType augmentableRuntimeType)) {
throw new VerifyException(
"Unexpected type %s backing augmenable %s".formatted(runtimeType, bindingClass));
for (var augment : possibleAugmentations) {
final var augProto = loadAugmentPrototype(augment);
if (augProto != null) {
- final var augBindingClass = augProto.getBindingClass();
+ final var augBindingClass = augProto.javaClass();
for (var childPath : augProto.getChildArgs()) {
augPathToBinding.putIfAbsent(childPath, augBindingClass);
}
// context would load.
if (getBindingClass().equals(augTarget) && belongsToRuntimeContext(childClass)) {
for (var realChild : augmentToPrototype.values()) {
- if (Augmentation.class.isAssignableFrom(realChild.getBindingClass())
- && isSubstitutionFor(childClass, realChild.getBindingClass())) {
+ final var realClass = realChild.javaClass();
+ if (Augmentation.class.isAssignableFrom(realClass) && isSubstitutionFor(childClass, realClass)) {
return cacheMismatched(oldMismatched, childClass, realChild);
}
}
*
* @param <C> {@link CodecContext} type
*/
-public abstract sealed class LazyCodecContextSupplier<C extends CodecContext> implements CodecContextSupplier
- permits CommonDataObjectCodecPrototype {
+abstract sealed class LazyCodecContextSupplier<C extends CodecContext> implements CodecContextSupplier
+ // Note: while we could merge this class into DataContainerCodecPrototype, we want to keep the lazy-loading part
+ // separate in case we need to non-DataContainer contexts.
+ permits DataContainerPrototype {
private static final VarHandle INSTANCE;
static {
}
static @NonNull MapCodecContext<?, ?> of(final MapCodecPrototype prototype) {
- final var bindingClass = prototype.getBindingClass();
+ final var bindingClass = prototype.javaClass();
final Method keyMethod;
try {
keyMethod = bindingClass.getMethod(Naming.KEY_AWARE_KEY_NAME);
throw new IllegalStateException("Required method not available", e);
}
- final var type = prototype.getType();
- final var codec = prototype.getFactory().getPathArgumentCodec(bindingClass, type);
+ final var type = prototype.runtimeType();
+ final var codec = prototype.contextFactory().getPathArgumentCodec(bindingClass, type);
return type.statement().ordering() == Ordering.SYSTEM ? new Unordered<>(prototype, keyMethod, codec)
: new Ordered<>(prototype, keyMethod, codec);
final class MapCodecPrototype extends ListCodecPrototype {
MapCodecPrototype(final Item<?> item, final ListRuntimeType type, final CodecContextFactory factory) {
super(item, type, factory);
- final var clazz = getBindingClass();
+ final var clazz = javaClass();
checkArgument(KeyAware.class.isAssignableFrom(clazz), "%s is not KeyAware", clazz);
}