*/
package org.opendaylight.yangtools.yang.model.ri.stmt.impl.eff;
-import static java.util.Objects.requireNonNull;
-
import com.google.common.collect.ImmutableList;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.DefaultEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.LeafEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.LeafStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.ReferenceEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.StatusEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.TypeEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.api.stmt.UnitsEffectiveStatement;
-import org.opendaylight.yangtools.yang.model.ri.type.ConcreteTypeBuilder;
import org.opendaylight.yangtools.yang.model.ri.type.ConcreteTypes;
import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement;
import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.DataSchemaNodeMixin;
extends AbstractDeclaredEffectiveStatement.Default<QName, LeafStatement>
implements LeafEffectiveStatement, LeafSchemaNode, DataSchemaNodeMixin<LeafStatement>,
MandatoryMixin<QName, LeafStatement>, MustConstraintMixin<QName, LeafStatement> {
- private final @NonNull Object substatements;
- // FIXME: YANGTOOLS-1316: this seems to imply that argument.equals(declared.argument()) and we could save a field,
- // except we need it in the constructors to materialize type. But if we turn it into a lazy
- // field, we should be okay.
- private final @NonNull QName argument;
- private final @NonNull TypeDefinition<?> type;
+ private static final VarHandle TYPE;
+
+ static {
+ try {
+ TYPE = MethodHandles.lookup().findVarHandle(AbstractLeafEffectiveStatement.class, "type",
+ TypeDefinition.class);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+ private final @NonNull Object substatements;
private final int flags;
- AbstractLeafEffectiveStatement(final LeafStatement declared, final QName argument, final int flags,
+ @SuppressWarnings("unused")
+ private volatile TypeDefinition<?> type;
+
+ AbstractLeafEffectiveStatement(final LeafStatement declared, final int flags,
final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
super(declared);
- this.argument = requireNonNull(argument);
- this.substatements = maskList(substatements);
this.flags = flags;
- type = buildType();
+ this.substatements = maskList(substatements);
}
- AbstractLeafEffectiveStatement(final AbstractLeafEffectiveStatement original, final QName argument,
- final int flags) {
+ AbstractLeafEffectiveStatement(final AbstractLeafEffectiveStatement original, final int flags) {
super(original);
- this.argument = requireNonNull(argument);
- substatements = original.substatements;
this.flags = flags;
- type = buildType();
+ substatements = original.substatements;
}
@Override
}
@Override
- public final QName argument() {
- return argument;
+ public final LeafEffectiveStatement asEffectiveStatement() {
+ return this;
}
@Override
public final TypeDefinition<?> getType() {
- return type;
+ final var local = (TypeDefinition<?>) TYPE.getAcquire(this);
+ return local != null ? local : loadType();
}
- @Override
- public final LeafEffectiveStatement asEffectiveStatement() {
- return this;
- }
-
- private TypeDefinition<?> buildType() {
- final TypeEffectiveStatement<?> typeStmt = findFirstEffectiveSubstatement(TypeEffectiveStatement.class).get();
- final ConcreteTypeBuilder<?> builder = ConcreteTypes.concreteTypeBuilder(typeStmt.getTypeDefinition(),
- getQName());
- for (final EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
- if (stmt instanceof DefaultEffectiveStatement) {
- builder.setDefaultValue(((DefaultEffectiveStatement)stmt).argument());
- } else if (stmt instanceof DescriptionEffectiveStatement) {
- builder.setDescription(((DescriptionEffectiveStatement)stmt).argument());
- } else if (stmt instanceof ReferenceEffectiveStatement) {
- builder.setReference(((ReferenceEffectiveStatement)stmt).argument());
- } else if (stmt instanceof StatusEffectiveStatement) {
- builder.setStatus(((StatusEffectiveStatement)stmt).argument());
- } else if (stmt instanceof UnitsEffectiveStatement) {
- builder.setUnits(((UnitsEffectiveStatement)stmt).argument());
- }
- }
- return builder.build();
+ private TypeDefinition<?> loadType() {
+ final var ret = ConcreteTypes.typeOf(this);
+ final var witness = (TypeDefinition<?>) TYPE.compareAndExchangeRelease(this, null, ret);
+ return witness != null ? witness : ret;
}
}