2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.mdsal.binding.dom.codec.impl;
10 import static java.util.Objects.requireNonNull;
12 import java.lang.invoke.MethodHandles;
13 import java.lang.invoke.VarHandle;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.opendaylight.mdsal.binding.runtime.api.RuntimeTypeContainer;
16 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
17 import org.opendaylight.yangtools.yang.common.QNameModule;
18 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
20 abstract sealed class CommonDataObjectCodecPrototype<T extends RuntimeTypeContainer> implements CodecContextSupplier
21 permits AugmentationCodecPrototype, DataObjectCodecPrototype {
22 private static final VarHandle INSTANCE;
26 INSTANCE = MethodHandles.lookup().findVarHandle(CommonDataObjectCodecPrototype.class,
27 "instance", CommonDataObjectCodecContext.class);
28 } catch (NoSuchFieldException | IllegalAccessException e) {
29 throw new ExceptionInInitializerError(e);
33 private final @NonNull T type;
34 private final @NonNull QNameModule namespace;
35 private final @NonNull CodecContextFactory factory;
36 private final @NonNull Item<?> bindingArg;
38 // multiple paths represent augmentation wrapper
39 // FIXME: this means it is either this or 'childArgs'
41 // Accessed via INSTANCE
42 @SuppressWarnings("unused")
43 private volatile CommonDataObjectCodecContext<?, T> instance;
45 CommonDataObjectCodecPrototype(final Item<?> bindingArg, final QNameModule namespace, final T type,
46 final CodecContextFactory factory) {
47 this.bindingArg = requireNonNull(bindingArg);
48 this.namespace = requireNonNull(namespace);
49 this.type = requireNonNull(type);
50 this.factory = requireNonNull(factory);
53 final @NonNull T getType() {
57 final @NonNull QNameModule getNamespace() {
61 final @NonNull CodecContextFactory getFactory() {
65 final @NonNull Class<?> getBindingClass() {
66 return bindingArg.getType();
69 final @NonNull Item<?> getBindingArg() {
73 abstract @NonNull NodeIdentifier getYangArg();
76 public final CommonDataObjectCodecContext<?, T> get() {
77 final var existing = (CommonDataObjectCodecContext<?, T>) INSTANCE.getAcquire(this);
78 return existing != null ? existing : loadInstance();
81 private @NonNull CommonDataObjectCodecContext<?, T> loadInstance() {
82 final var tmp = createInstance();
83 final var witness = (CommonDataObjectCodecContext<?, T>) INSTANCE.compareAndExchangeRelease(this, null, tmp);
84 return witness == null ? tmp : witness;
87 // This method must allow concurrent loading, i.e. nothing in it may have effects outside of the loaded object
88 abstract @NonNull CommonDataObjectCodecContext<?, T> createInstance();