/*
* Copyright (c) 2015 Cisco Systems, Inc. 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.yangtools.yang.parser.rfc7950.stmt;
import com.google.common.collect.ImmutableList;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.model.api.DocumentedNode;
import org.opendaylight.yangtools.yang.model.api.Status;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
// FIXME: 5.0.0: rename to AbstractEffectiveDocumentedNodeWithStatus
public abstract class AbstractEffectiveDocumentedNode>
extends AbstractEffectiveDocumentedNodeWithoutStatus implements DocumentedNode.WithStatus {
private static final VarHandle UNKNOWN_NODES;
static {
try {
UNKNOWN_NODES = MethodHandles.lookup().findVarHandle(AbstractEffectiveDocumentedNode.class,
"unknownNodes", ImmutableList.class);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new ExceptionInInitializerError(e);
}
}
private final @NonNull Status status;
@SuppressWarnings("unused")
private volatile ImmutableList unknownNodes;
/**
* Constructor.
*
* @param ctx
* context of statement.
*/
protected AbstractEffectiveDocumentedNode(final StmtContext ctx) {
super(ctx);
status = findFirstEffectiveSubstatementArgument(StatusEffectiveStatement.class).orElse(Status.CURRENT);
}
@Override
public final Status getStatus() {
return status;
}
@Override
public final Collection extends UnknownSchemaNode> getUnknownSchemaNodes() {
final ImmutableList existing =
(ImmutableList) UNKNOWN_NODES.getAcquire(this);
return existing != null ? existing : loadUnknownSchemaNodes();
}
@SuppressWarnings("unchecked")
private @NonNull ImmutableList loadUnknownSchemaNodes() {
final List init = new ArrayList<>();
for (EffectiveStatement, ?> stmt : effectiveSubstatements()) {
if (stmt instanceof UnknownSchemaNode) {
init.add((UnknownSchemaNode) stmt);
}
}
final ImmutableList computed = ImmutableList.copyOf(init);
final Object witness = UNKNOWN_NODES.compareAndExchangeRelease(this, null, computed);
return witness == null ? computed : (ImmutableList) witness;
}
}