* @param <T> BindingObject subtype
* @param <C> Root codec context type
*/
-abstract class AbstractBindingNormalizedNodeCache<T extends BindingObject, C extends NodeCodecContext>
+abstract class AbstractBindingNormalizedNodeCache<T extends BindingObject, C extends CodecContext>
extends CacheLoader<T, NormalizedNode> {
private final LoadingCache<T, NormalizedNode> cache;
private final @NonNull C rootContext;
*/
abstract class AbstractBindingNormalizedNodeCacheHolder {
@SuppressWarnings("rawtypes")
- private final LoadingCache<NodeCodecContext, AbstractBindingNormalizedNodeCache> caches =
+ private final LoadingCache<CodecContext, AbstractBindingNormalizedNodeCache> caches =
CacheBuilder.newBuilder().build(new CacheLoader<>() {
@Override
- public AbstractBindingNormalizedNodeCache load(final NodeCodecContext key) {
+ public AbstractBindingNormalizedNodeCache load(final CodecContext key) {
// FIXME: Use a switch expression once we have https://openjdk.org/jeps/441
if (key instanceof DataContainerCodecContext<?, ?> dataContainer) {
return new DataObjectNormalizedNodeCache(AbstractBindingNormalizedNodeCacheHolder.this,
}
@SuppressWarnings("unchecked")
- <T extends BindingObject, C extends NodeCodecContext & BindingObjectCodecTreeNode<?>>
+ <T extends BindingObject, C extends CodecContext & BindingObjectCodecTreeNode<?>>
AbstractBindingNormalizedNodeCache<T, C> getCachingSerializer(final C childCtx) {
return isCached(childCtx.getBindingClass()) ? caches.getUnchecked(childCtx) : null;
}
permits AugmentationNodeContext, DataObjectCodecContext {
private final ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byBindingArgClass;
private final ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byStreamClass;
- private final ImmutableMap<NodeIdentifier, NodeContextSupplier> byYang;
+ private final ImmutableMap<NodeIdentifier, CodecContextSupplier> byYang;
private final ImmutableMap<String, ValueNodeCodecContext> leafChild;
private final MethodHandle proxyConstructor;
}
@Override
- public final NodeCodecContext yangPathArgumentChild(final PathArgument arg) {
- NodeContextSupplier supplier;
+ public final CodecContext yangPathArgumentChild(final PathArgument arg) {
+ CodecContextSupplier supplier;
if (arg instanceof NodeIdentifier nodeId) {
supplier = yangChildSupplier(nodeId);
} else if (arg instanceof NodeIdentifierWithPredicates nip) {
return childNonNull(supplier, arg, "Argument %s is not valid child of %s", arg, getSchema()).get();
}
- @Nullable NodeContextSupplier yangChildSupplier(final @NonNull NodeIdentifier arg) {
+ @Nullable CodecContextSupplier yangChildSupplier(final @NonNull NodeIdentifier arg) {
return byYang.get(arg);
}
*/
@Nullable BindingDataObjectCodecTreeNode<?> getCodecContextNode(final @NonNull YangInstanceIdentifier dom,
final @Nullable Collection<InstanceIdentifier.PathArgument> bindingArguments) {
- NodeCodecContext currentNode = root;
+ CodecContext currentNode = root;
ListNodeCodecContext<?> currentList = null;
for (var domArg : dom.getPathArguments()) {
final class BindingToNormalizedStreamWriter implements AnydataBindingStreamWriter,
Delegator<NormalizedNodeStreamWriter> {
- private final Deque<NodeCodecContext> schema = new ArrayDeque<>();
+ private final Deque<CodecContext> schema = new ArrayDeque<>();
private final @NonNull NormalizedNodeStreamWriter delegate;
- private final NodeCodecContext rootContext;
+ private final CodecContext rootContext;
BindingToNormalizedStreamWriter(final DataContainerCodecContext<?, ?> rootContext,
final NormalizedNodeStreamWriter delegate) {
delegate.nextDataSchemaNode((DataSchemaNode) schemaNode);
}
- NodeCodecContext current() {
+ CodecContext current() {
return schema.peek();
}
private NodeIdentifier duplicateSchemaEnter() {
final var current = current();
- final NodeCodecContext next;
+ final CodecContext next;
if (current == null) {
// Entry of first node
next = rootContext;
@SuppressWarnings({"unchecked", "rawtypes"})
private <T extends YangInstanceIdentifier.PathArgument> T enter(final Class<?> name, final Class<T> identifier) {
final var current = current();
- final NodeCodecContext next;
+ final CodecContext next;
if (current == null) {
// Entry of first node
next = rootContext;
@Override
public void endNode() throws IOException {
- NodeCodecContext left = schema.pop();
+ CodecContext left = schema.pop();
// Due to writer does not start a new node on startCase() and on startAugmentationNode()
// node ending should not be triggered when associated endNode() is invoked.
if (!(left instanceof CaseNodeCodecContext) && !(left instanceof AugmentationNodeContext)) {
}
@Override
- public NodeCodecContext yangPathArgumentChild(final YangInstanceIdentifier.PathArgument arg) {
+ public CodecContext yangPathArgumentChild(final YangInstanceIdentifier.PathArgument arg) {
final DataContainerCodecPrototype<?> cazeProto;
if (arg instanceof NodeIdentifierWithPredicates) {
cazeProto = byYangCaseChild.get(new NodeIdentifier(arg.getNodeType()));
}
}
- interface LocalNameProvider<T> extends BridgeProvider<T> {
+ interface CodecContextSupplierProvider<T> extends BridgeProvider<T> {
- @NonNull String resolveLocalName(@NonNull String methodName);
+ @NonNull CodecContextSupplier resolveCodecContextSupplier(@NonNull String methodName);
}
- interface NodeContextSupplierProvider<T> extends BridgeProvider<T> {
+ interface LocalNameProvider<T> extends BridgeProvider<T> {
- @NonNull NodeContextSupplier resolveNodeContextSupplier(@NonNull String methodName);
+ @NonNull String resolveLocalName(@NonNull String methodName);
}
private static final ThreadLocal<BridgeProvider<?>> CURRENT_CUSTOMIZER = new ThreadLocal<>();
// Hidden on purpose
}
- public static @NonNull NodeContextSupplier resolveNodeContextSupplier(final @NonNull String methodName) {
- return current(NodeContextSupplierProvider.class).resolveNodeContextSupplier(methodName);
+ public static @NonNull CodecContextSupplier resolveCodecContextSupplier(final @NonNull String methodName) {
+ return current(CodecContextSupplierProvider.class).resolveCodecContextSupplier(methodName);
}
public static @NonNull String resolveLocalName(final @NonNull String methodName) {
* nodes contain contexts for their individual children nodes</li>
* </ul>
*/
-abstract sealed class NodeCodecContext implements BindingCodecTreeNode
+abstract sealed class CodecContext implements BindingCodecTreeNode
permits DataContainerCodecContext, ValueNodeCodecContext {
/**
* Returns {@link NodeIdentifier} of current node, if applicable.
@Beta
@FunctionalInterface
@NonNullByDefault
-public interface NodeContextSupplier {
- NodeCodecContext get();
+public interface CodecContextSupplier {
+ CodecContext get();
}
return cached != null ? unmaskNull(cached) : loadMember(handle, context.streamChild(bindingClass));
}
- protected final Object codecMember(final VarHandle handle, final NodeContextSupplier supplier) {
+ protected final Object codecMember(final VarHandle handle, final CodecContextSupplier supplier) {
final Object cached = handle.getAcquire(this);
return cached != null ? unmaskNull(cached) : loadMember(handle, supplier.get());
}
}
// Helper split out of codecMember to aid its inlining
- private Object loadMember(final VarHandle handle, final NodeCodecContext childCtx) {
+ private Object loadMember(final VarHandle handle, final CodecContext childCtx) {
final var child = data.childByArg(childCtx.getDomPathArgument());
// We do not want to use Optional.map() here because we do not want to invoke defaultObject() when we have
final @NonNull ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byStreamClass;
final @NonNull ImmutableMap<Class<?>, DataContainerCodecPrototype<?>> byBindingArgClass;
- final @NonNull ImmutableMap<NodeIdentifier, NodeContextSupplier> byYang;
+ final @NonNull ImmutableMap<NodeIdentifier, CodecContextSupplier> byYang;
final @NonNull ImmutableMap<String, ValueNodeCodecContext> leafNodes;
final @NonNull Class<? extends CodecDataObject<?>> generatedClass;
final @NonNull List<AugmentRuntimeType> possibleAugmentations;
final var clsToMethod = getChildrenClassToMethod(bindingClass);
// Indexing part: be very careful around what gets done when
- final var byYangBuilder = new HashMap<NodeIdentifier, NodeContextSupplier>();
+ final var byYangBuilder = new HashMap<NodeIdentifier, CodecContextSupplier>();
// Step 1: add leaf children
var leafBuilder = ImmutableMap.<String, ValueNodeCodecContext>builderWithExpectedSize(leafContexts.size());
import net.bytebuddy.implementation.bytecode.member.MethodVariableAccess;
import net.bytebuddy.jar.asm.Opcodes;
import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.mdsal.binding.dom.codec.impl.ClassGeneratorBridge.CodecContextSupplierProvider;
import org.opendaylight.mdsal.binding.dom.codec.impl.ClassGeneratorBridge.LocalNameProvider;
-import org.opendaylight.mdsal.binding.dom.codec.impl.ClassGeneratorBridge.NodeContextSupplierProvider;
import org.opendaylight.mdsal.binding.loader.BindingClassLoader;
import org.opendaylight.mdsal.binding.loader.BindingClassLoader.ClassGenerator;
import org.opendaylight.mdsal.binding.loader.BindingClassLoader.GeneratorResult;
* strong connection between a generated class to the extent possible. In most cases (grouping-generated types) this
* involves one level of indirection, which is a safe approach. If we are dealing with a type generated outside of a
* grouping statement, though, we are guaranteed instantiation-invariance and hence can hard-wire to a runtime-constant
- * {@link NodeContextSupplier} -- which provides significant boost to JITs ability to optimize code -- especially with
+ * {@link CodecContextSupplier} -- which provides significant boost to JITs ability to optimize code -- especially with
* inlining and constant propagation.
*
* <p>
* and class loading (in {@link BindingClassLoader}). The process is performed in four steps:
* <ul>
* <li>During code generation, the context fields are pointed towards
- * {@link ClassGeneratorBridge#resolveNodeContextSupplier(String)} and
+ * {@link ClassGeneratorBridge#resolveCodecContextSupplier(String)} and
* {@link ClassGeneratorBridge#resolveKey(String)} methods, which are public and static, hence perfectly usable
* in the context of a class initializer.</li>
* <li>During class loading of generated byte code, the original instance of the generator is called to wrap the actual
* class loading operation. At this point the generator installs itself as the current generator for this thread via
* {@link ClassGeneratorBridge#setup(CodecDataObjectGenerator)} and allows the class to be loaded.
* <li>After the class has been loaded, but before the call returns, we will force the class to initialize, at which
- * point the static invocations will be redirected to {@link #resolveNodeContextSupplier(String)} and
+ * point the static invocations will be redirected to {@link #resolveCodecContextSupplier(String)} and
* {@link #resolveKey(String)} methods, thus initializing the fields to the intended constants.</li>
* <li>Before returning from the class loading call, the generator will detach itself via
* {@link ClassGeneratorBridge#tearDown(CodecDataObjectGenerator)}.</li>
// FIXME: MDSAL-443: wire this implementation, which requires that BindingRuntimeTypes provides information about
// types being generated from within a grouping
private static final class Fixed<T extends CodecDataObject<?>> extends CodecDataObjectGenerator<T>
- implements NodeContextSupplierProvider<T> {
- private final ImmutableMap<Method, NodeContextSupplier> properties;
+ implements CodecContextSupplierProvider<T> {
+ private final ImmutableMap<Method, CodecContextSupplier> properties;
- Fixed(final TypeDescription superClass, final ImmutableMap<Method, NodeContextSupplier> properties,
+ Fixed(final TypeDescription superClass, final ImmutableMap<Method, CodecContextSupplier> properties,
final @Nullable Method keyMethod) {
super(superClass, keyMethod);
this.properties = requireNonNull(properties);
}
@Override
- public NodeContextSupplier resolveNodeContextSupplier(final String methodName) {
- final Optional<Entry<Method, NodeContextSupplier>> found = properties.entrySet().stream()
+ public CodecContextSupplier resolveCodecContextSupplier(final String methodName) {
+ final Optional<Entry<Method, CodecContextSupplier>> found = properties.entrySet().stream()
.filter(entry -> methodName.equals(entry.getKey().getName())).findAny();
verify(found.isPresent(), "Failed to find property for %s in %s", methodName, this);
return verifyNotNull(found.orElseThrow().getValue());
private static final class SupplierGetterMethodImplementation extends AbstractCachedMethodImplementation {
private static final StackManipulation CODEC_MEMBER = invokeMethod(CodecDataObject.class,
- "codecMember", VarHandle.class, NodeContextSupplier.class);
+ "codecMember", VarHandle.class, CodecContextSupplier.class);
private static final StackManipulation BRIDGE_RESOLVE = invokeMethod(ClassGeneratorBridge.class,
"resolveNodeContextSupplier", String.class);
- private static final Generic BB_NCS = TypeDefinition.Sort.describe(NodeContextSupplier.class);
+ private static final Generic BB_NCS = TypeDefinition.Sort.describe(CodecContextSupplier.class);
// getFoo$$$C
private final String contextName;
import org.slf4j.LoggerFactory;
abstract sealed class DataContainerCodecContext<D extends DataObject, T extends RuntimeTypeContainer>
- extends NodeCodecContext implements CommonDataObjectCodecTreeNode<D>
+ extends CodecContext implements CommonDataObjectCodecTreeNode<D>
permits AbstractDataObjectCodecContext, ChoiceNodeCodecContext, SchemaRootCodecContext {
private static final Logger LOG = LoggerFactory.getLogger(DataContainerCodecContext.class);
private static final VarHandle EVENT_STREAM_SERIALIZER;
* @throws IllegalArgumentException If supplied argument does not represent valid child.
*/
@Override
- public abstract NodeCodecContext yangPathArgumentChild(YangInstanceIdentifier.PathArgument arg);
+ public abstract CodecContext yangPathArgumentChild(YangInstanceIdentifier.PathArgument arg);
/**
* Returns nested node context using supplied Binding Instance Identifier
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-abstract sealed class DataContainerCodecPrototype<T extends RuntimeTypeContainer> implements NodeContextSupplier
+abstract sealed class DataContainerCodecPrototype<T extends RuntimeTypeContainer> implements CodecContextSupplier
permits AugmentationCodecPrototype, DataObjectCodecPrototype {
private static final Logger LOG = LoggerFactory.getLogger(DataContainerCodecPrototype.class);
}
@Override
- final NodeContextSupplier yangChildSupplier(final NodeIdentifier arg) {
+ final CodecContextSupplier yangChildSupplier(final NodeIdentifier arg) {
final var child = super.yangChildSupplier(arg);
if (child == null) {
final var augClass = yangToAugmentClass.get(arg);
/**
* A cache of NormalizedNodes corresponding to a particular TypeObject instantiation.
*/
-final class TypeObjectNormalizedNodeCache<C extends NodeCodecContext & BindingTypeObjectCodecTreeNode<TypeObject>>
+final class TypeObjectNormalizedNodeCache<C extends CodecContext & BindingTypeObjectCodecTreeNode<TypeObject>>
extends AbstractBindingNormalizedNodeCache<TypeObject, C> {
TypeObjectNormalizedNodeCache(final C rootContext) {
super(rootContext);
* Abstract base class for atomic nodes. These are nodes which are not decomposed in the Binding Specification, such
* as LeafNodes and LeafSetNodes.
*/
-abstract sealed class ValueNodeCodecContext extends NodeCodecContext implements NodeContextSupplier
+abstract sealed class ValueNodeCodecContext extends CodecContext implements CodecContextSupplier
permits OpaqueNodeCodecContext, ValueNodeCodecContext.WithCodec {
abstract static sealed class WithCodec extends ValueNodeCodecContext
permits LeafNodeCodecContext, LeafSetNodeCodecContext {
}
@Override
- public final NodeCodecContext get() {
+ public final CodecContext get() {
return this;
}