X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=yang%2Fyang-parser-rfc7950%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fparser%2Frfc7950%2Fstmt%2Ftypedef%2FTypedefEffectiveStatementImpl.java;h=c243097be60d870117ca76d1ff1bf9da4f8b5382;hb=7fd1abd03d792989653a05052e723b1516a9e554;hp=8ab0ae3ad4149d707671d758273e186c35706c0e;hpb=19efe56f8f20f5692a100e765a581fbc8f0b4aca;p=yangtools.git diff --git a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefEffectiveStatementImpl.java b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefEffectiveStatementImpl.java index 8ab0ae3ad4..c243097be6 100644 --- a/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefEffectiveStatementImpl.java +++ b/yang/yang-parser-rfc7950/src/main/java/org/opendaylight/yangtools/yang/parser/rfc7950/stmt/typedef/TypedefEffectiveStatementImpl.java @@ -7,17 +7,22 @@ */ package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.typedef; +import static java.util.Objects.requireNonNull; + +import com.google.common.collect.ImmutableList; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; +import java.lang.invoke.VarHandle; import java.util.Collection; import java.util.Map; import java.util.Optional; import org.eclipse.jdt.annotation.NonNull; +import org.opendaylight.yangtools.concepts.Immutable; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode; -import org.opendaylight.yangtools.yang.model.api.YangStmtMapping; import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement; import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace; -import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition; import org.opendaylight.yangtools.yang.model.api.meta.StatementSource; import org.opendaylight.yangtools.yang.model.api.stmt.DefaultEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.DescriptionEffectiveStatement; @@ -28,34 +33,90 @@ import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypedefEffectiveStatement; import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement; import org.opendaylight.yangtools.yang.model.api.stmt.UnitsEffectiveStatement; -import org.opendaylight.yangtools.yang.model.util.type.DerivedTypeBuilder; -import org.opendaylight.yangtools.yang.model.util.type.DerivedTypes; -import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractEffectiveSchemaNode; -import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStmtUtils; -import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext; -import org.opendaylight.yangtools.yang.parser.spi.source.SourceException; +import org.opendaylight.yangtools.yang.model.ri.type.DerivedTypeBuilder; +import org.opendaylight.yangtools.yang.model.ri.type.DerivedTypes; +import org.opendaylight.yangtools.yang.model.spi.meta.AbstractDeclaredEffectiveStatement.Default; +import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.SchemaNodeMixin; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -final class TypedefEffectiveStatementImpl extends AbstractEffectiveSchemaNode implements - TypedefEffectiveStatement { +final class TypedefEffectiveStatementImpl extends Default + implements TypedefEffectiveStatement, SchemaNodeMixin { private static final Logger LOG = LoggerFactory.getLogger(TypedefEffectiveStatementImpl.class); - private final @NonNull TypeDefinition typeDefinition; + private static final VarHandle TYPE_DEFINITION; + private static final VarHandle TYPE_STATEMENT; + + static { + final Lookup lookup = MethodHandles.lookup(); + try { + TYPE_DEFINITION = lookup.findVarHandle(TypedefEffectiveStatementImpl.class, "typeDefinition", + TypeDefinition.class); + TYPE_STATEMENT = lookup.findVarHandle(TypedefEffectiveStatementImpl.class, "typeStatement", + ProxyTypeEffectiveStatement.class); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new ExceptionInInitializerError(e); + } + } + + private final @NonNull Object substatements; + private final @NonNull Immutable path; + private final int flags; + + // Accessed via TYPE_DEFINITION + @SuppressWarnings("unused") + private volatile TypeDefinition typeDefinition; + // Accessed via TYPE_STATEMENT + @SuppressWarnings("unused") + private volatile ProxyTypeEffectiveStatement typeStatement; + + TypedefEffectiveStatementImpl(final TypedefStatement declared, final Immutable path, final int flags, + final ImmutableList> substatements) { + super(declared); + this.path = requireNonNull(path); + this.flags = flags; + this.substatements = maskList(substatements); + } + + @Override + public int flags() { + return flags; + } - private volatile TypeEffectiveStatement typeStatement; + @Override + public Immutable pathObject() { + return path; + } - TypedefEffectiveStatementImpl(final StmtContext ctx) { - super(ctx); + @Override + public @NonNull QName argument() { + return getQName(); + } + + @Override + public ImmutableList> effectiveSubstatements() { + return unmaskList(substatements); + } + + @Override + public TypeDefinition getTypeDefinition() { + final TypeDefinition existing = (TypeDefinition) TYPE_DEFINITION.getAcquire(this); + return existing != null ? existing : loadTypeDefinition(); + } + + @Override + public TypeEffectiveStatement asTypeEffectiveStatement() { + final ProxyTypeEffectiveStatement local = (ProxyTypeEffectiveStatement) TYPE_STATEMENT.getAcquire(this); + return local != null ? local : loadTypeStatement(); + } + + private @NonNull TypeDefinition loadTypeDefinition() { + final TypeEffectiveStatement type = findFirstEffectiveSubstatement(TypeEffectiveStatement.class).get(); + final DerivedTypeBuilder builder = DerivedTypes.derivedTypeBuilder(type.getTypeDefinition(), getQName()); - final TypeEffectiveStatement typeEffectiveStmt = firstSubstatementOfType(TypeEffectiveStatement.class); - final DerivedTypeBuilder builder = DerivedTypes.derivedTypeBuilder(typeEffectiveStmt.getTypeDefinition(), - ctx.getSchemaPath().get()); - String dflt = null; for (final EffectiveStatement stmt : effectiveSubstatements()) { if (stmt instanceof DefaultEffectiveStatement) { - dflt = ((DefaultEffectiveStatement) stmt).argument(); - builder.setDefaultValue(dflt); + builder.setDefaultValue(((DefaultEffectiveStatement) stmt).argument()); } else if (stmt instanceof DescriptionEffectiveStatement) { builder.setDescription(((DescriptionEffectiveStatement)stmt).argument()); } else if (stmt instanceof ReferenceEffectiveStatement) { @@ -67,40 +128,20 @@ final class TypedefEffectiveStatementImpl extends AbstractEffectiveSchemaNode getTypeDefinition() { - return typeDefinition; + final TypeDefinition created = builder.build(); + final Object witness = TYPE_DEFINITION.compareAndExchangeRelease(this, null, created); + return witness == null ? created : (TypeDefinition) witness; } - @Override - public TypeEffectiveStatement asTypeEffectiveStatement() { - TypeEffectiveStatement ret = typeStatement; - if (ret == null) { - synchronized (this) { - ret = typeStatement; - if (ret == null) { - typeStatement = ret = new ProxyTypeEffectiveStatement(); - } - } - } - - return ret; + private @NonNull ProxyTypeEffectiveStatement loadTypeStatement() { + final ProxyTypeEffectiveStatement created = new ProxyTypeEffectiveStatement(); + final Object witness = TYPE_STATEMENT.compareAndExchangeRelease(this, null, created); + return witness == null ? created : (ProxyTypeEffectiveStatement) witness; } private final class ProxyTypeEffectiveStatement implements TypeEffectiveStatement { @@ -125,11 +166,6 @@ final class TypedefEffectiveStatementImpl extends AbstractEffectiveSchemaNode