*/
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.LeafListSchemaNode;
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.DescriptionEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.LeafListEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.LeafListStatement;
-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;
import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.MustConstraintMixin;
-import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.UserOrderedMixin;
+import org.opendaylight.yangtools.yang.model.spi.meta.EffectiveStatementMixins.UserOrderedAwareMixin;
abstract class AbstractLeafListEffectiveStatement
extends AbstractDeclaredEffectiveStatement.Default<QName, LeafListStatement>
- implements LeafListEffectiveStatement, LeafListSchemaNode, UserOrderedMixin<QName, LeafListStatement>,
+ implements LeafListEffectiveStatement, LeafListSchemaNode,
+ UserOrderedAwareMixin<QName, LeafListStatement, LeafListEffectiveStatement>,
DataSchemaNodeMixin<LeafListStatement>, MustConstraintMixin<QName, LeafListStatement> {
+ private static final VarHandle TYPE;
+
+ static {
+ try {
+ TYPE = MethodHandles.lookup().findVarHandle(AbstractLeafListEffectiveStatement.class, "type",
+ TypeDefinition.class);
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new ExceptionInInitializerError(e);
+ }
+ }
+
private final @NonNull Object substatements;
- private final @NonNull QName argument;
- private final @NonNull TypeDefinition<?> type;
private final int flags;
- AbstractLeafListEffectiveStatement(final LeafListStatement declared, final QName argument, final int flags,
+ @SuppressWarnings("unused")
+ private volatile TypeDefinition<?> type;
+
+ AbstractLeafListEffectiveStatement(final LeafListStatement declared, final int flags,
final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
super(declared);
- this.argument = requireNonNull(argument);
this.substatements = maskList(substatements);
this.flags = flags;
- // TODO: lazy instantiation?
- this.type = buildType();
}
- AbstractLeafListEffectiveStatement(final AbstractLeafListEffectiveStatement original, final QName argument,
- final int flags) {
+ AbstractLeafListEffectiveStatement(final AbstractLeafListEffectiveStatement original, final int flags) {
super(original);
- this.argument = requireNonNull(argument);
- this.substatements = original.substatements;
+ substatements = original.substatements;
this.flags = flags;
- // TODO: lazy instantiation?
- this.type = buildType();
}
@Override
return flags;
}
- @Override
- public final QName argument() {
- return argument;
- }
-
- @Override
- public final TypeDefinition<?> getType() {
- return type;
- }
-
- @Override
- public final boolean isUserOrdered() {
- return userOrdered();
- }
-
@Override
public final LeafListEffectiveStatement asEffectiveStatement() {
return this;
}
@Override
- public final String toString() {
- return getClass().getSimpleName() + "[" + argument + "]";
+ public final TypeDefinition<?> getType() {
+ final var local = (TypeDefinition<?>) TYPE.getAcquire(this);
+ return local != null ? local : loadType();
}
- private TypeDefinition<?> buildType() {
- final TypeEffectiveStatement<?> typeStmt = findFirstEffectiveSubstatement(TypeEffectiveStatement.class).get();
- final ConcreteTypeBuilder<?> builder = ConcreteTypes.concreteTypeBuilder(typeStmt.getTypeDefinition(),
- getQName());
- for (final EffectiveStatement<?, ?> stmt : effectiveSubstatements()) {
- // NOTE: 'default' is omitted here on purpose
- 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;
}
}