2 * Copyright (c) 2022 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;
14 import org.opendaylight.mdsal.binding.runtime.api.ContainerRuntimeType;
15 import org.opendaylight.yangtools.yang.binding.DataObject;
16 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item;
17 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
20 * A {@link ContainerLikeCodecContext} specialized for {@code container}s which do not have a presence statement.
22 final class StructuralContainerCodecContext<D extends DataObject> extends ContainerLikeCodecContext<D> {
23 private static final VarHandle EMPTY_OBJECT;
27 EMPTY_OBJECT = MethodHandles.lookup().findVarHandle(StructuralContainerCodecContext.class,
28 "emptyObject", DataObject.class);
29 } catch (NoSuchFieldException | IllegalAccessException e) {
30 throw new ExceptionInInitializerError(e);
34 @SuppressWarnings("unused")
35 @SuppressFBWarnings(value = "UUF_UNUSED_FIELD", justification = "https://github.com/spotbugs/spotbugs/issues/2749")
36 private volatile D emptyObject;
38 StructuralContainerCodecContext(final Class<D> cls, final ContainerRuntimeType type,
39 final CodecContextFactory factory) {
40 this(new StructuralContainerCodecPrototype(Item.of(cls), type, factory));
43 StructuralContainerCodecContext(final StructuralContainerCodecPrototype prototype) {
47 @NonNull D emptyObject() {
48 final var local = (D) EMPTY_OBJECT.getAcquire(this);
49 return local != null ? local : loadEmptyObject();
52 private @NonNull D loadEmptyObject() {
53 final var local = createBindingProxy(
54 Builders.containerBuilder().withNodeIdentifier(getDomPathArgument()).build());
55 final var witness = (D) EMPTY_OBJECT.compareAndExchangeRelease(this, null, local);
56 return witness != null ? witness : local;