2 * Copyright (c) 2024 PANTHEON.tech, s.r.o. 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 edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
11 import java.lang.invoke.MethodHandles;
12 import java.lang.invoke.VarHandle;
13 import org.eclipse.jdt.annotation.NonNull;
16 * Abstract base class for lazily-instantiated {@link CodecContextSupplier} instances.
18 * @param <C> {@link CodecContext} type
20 public abstract sealed class LazyCodecContextSupplier<C extends CodecContext> implements CodecContextSupplier
21 permits CommonDataObjectCodecPrototype {
22 private static final VarHandle INSTANCE;
26 INSTANCE = MethodHandles.lookup().findVarHandle(LazyCodecContextSupplier.class, "instance",
28 } catch (NoSuchFieldException | IllegalAccessException e) {
29 throw new ExceptionInInitializerError(e);
33 // Accessed via INSTANCE
34 @SuppressWarnings("unused")
35 @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "https://github.com/spotbugs/spotbugs/issues/2749")
36 private volatile C instance;
39 public final C getCodecContext() {
40 final var existing = (C) INSTANCE.getAcquire(this);
41 return existing != null ? existing : loadInstance();
44 private @NonNull C loadInstance() {
45 final var tmp = createInstance();
46 final var witness = (C) INSTANCE.compareAndExchangeRelease(this, null, tmp);
47 return witness == null ? tmp : witness;
50 // This method must allow concurrent loading, i.e. nothing in it may have effects outside of the loaded object
51 abstract @NonNull C createInstance();