*/
package org.opendaylight.yangtools.yang.model.api.stmt;
+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.StatementDefinition;
public interface TypeEffectiveStatement<T extends TypeStatement> extends EffectiveStatement<String, T>,
TypeDefinitionAware {
-
+ @Override
+ default StatementDefinition statementDefinition() {
+ return YangStmtMapping.TYPE;
+ }
}
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
@Rfc6020AbnfRule("type-stmt")
public interface TypeStatement extends DeclaredStatement<String> {
+ @Override
+ default StatementDefinition statementDefinition() {
+ return YangStmtMapping.TYPE;
+ }
+
default @NonNull String getName() {
// FIXME: YANGTOOLS-908: verifyNotNull() should not be needed here
return verifyNotNull(argument());
import com.google.common.annotations.Beta;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
+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.StatementDefinition;
/**
* Effective model statement which should be used to derive application behaviour related to typedefs.
*/
public interface TypedefEffectiveStatement extends EffectiveStatement<QName, TypedefStatement>, TypeDefinitionAware {
+ @Override
+ default StatementDefinition statementDefinition() {
+ return YangStmtMapping.TYPEDEF;
+ }
/**
* Return this type definition as an effective type statement.
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
public interface TypedefStatement extends DocumentedDeclaredStatement.WithStatus<QName>, TypeAwareDeclaredStatement,
DefaultStatementAwareDeclaredStatement {
+ @Override
+ default StatementDefinition statementDefinition() {
+ return YangStmtMapping.TYPEDEF;
+ }
+
default @NonNull QName getName() {
// FIXME: YANGTOOLS-908: verifyNotNull() should not be needed here
return verifyNotNull(argument());
import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+@Deprecated(forRemoval = true)
public abstract class AbstractEffectiveSchemaNode<D extends DeclaredStatement<QName>> extends
AbstractSchemaEffectiveDocumentedNode<QName, D> implements SchemaNode {
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
-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.TypeEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.TypeStatement;
return ImmutableList.of();
}
- @Override
- public final StatementDefinition statementDefinition() {
- return YangStmtMapping.TYPE;
- }
-
@Override
public final String argument() {
return getTypeDefinition().getQName().getLocalName();
import java.util.Collection;
import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
-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.TypeStatement;
return ImmutableList.of();
}
- @Override
- public StatementDefinition statementDefinition() {
- return YangStmtMapping.TYPE;
- }
-
@Override
public StatementSource getStatementSource() {
return StatementSource.DECLARATION;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
-import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredStatement.WithQNameArgument;
-final class TypedefStatementImpl extends AbstractDeclaredStatement<QName> implements TypedefStatement {
- TypedefStatementImpl(final StmtContext<QName, TypedefStatement, ?> context) {
- super(context);
+final class EmptyTypedefStatement extends WithQNameArgument implements TypedefStatement {
+ EmptyTypedefStatement(final QName argument) {
+ super(argument);
}
}
--- /dev/null
+/*
+ * Copyright (c) 2020 PANTHEON.tech, s.r.o. 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.typedef;
+
+import com.google.common.collect.ImmutableList;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
+import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.AbstractDeclaredStatement.WithQNameArgument.WithSubstatements;
+
+final class RegularTypedefStatement extends WithSubstatements implements TypedefStatement {
+ RegularTypedefStatement(final QName argument, final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+ super(argument, substatements);
+ }
+}
*/
package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.typedef;
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.collect.ImmutableList;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
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;
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.parser.rfc7950.stmt.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<TypedefStatement> implements
- TypedefEffectiveStatement {
+final class TypedefEffectiveStatementImpl extends Default<QName, TypedefStatement>
+ implements TypedefEffectiveStatement, SchemaNodeMixin<QName, TypedefStatement> {
private static final Logger LOG = LoggerFactory.getLogger(TypedefEffectiveStatementImpl.class);
- private final @NonNull TypeDefinition<?> typeDefinition;
+ private final @NonNull Object substatements;
+ private final @NonNull SchemaPath path;
+ private final int flags;
+ private volatile TypeDefinition<?> typeDefinition;
private volatile TypeEffectiveStatement<TypeStatement> typeStatement;
- TypedefEffectiveStatementImpl(final StmtContext<QName, TypedefStatement, ?> ctx) {
- super(ctx);
+ TypedefEffectiveStatementImpl(final TypedefStatement declared, final SchemaPath path, final int flags,
+ final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+ super(declared);
+ this.path = requireNonNull(path);
+ this.flags = flags;
+ this.substatements = maskList(substatements);
+ }
+
+ @Override
+ public int flags() {
+ return flags;
+ }
+
+ @Override
+ public SchemaPath getPath() {
+ return path;
+ }
+
+ @Override
+ public @NonNull QName argument() {
+ return getQName();
+ }
+
+ @Override
+ public ImmutableList<? extends EffectiveStatement<?, ?>> effectiveSubstatements() {
+ return unmaskList(substatements);
+ }
+
+ @Override
+ public TypeDefinition<?> getTypeDefinition() {
+ final TypeDefinition<?> existing = typeDefinition;
+ return existing != null ? existing : loadTypeDefinition();
+ }
+
+ @Override
+ public TypeEffectiveStatement<TypeStatement> asTypeEffectiveStatement() {
+ final TypeEffectiveStatement<TypeStatement> local = typeStatement;
+ return local != null ? local : loadTypeStatement();
+ }
+
+ private synchronized @NonNull TypeDefinition<?> loadTypeDefinition() {
+ final TypeDefinition<?> existing = typeDefinition;
+ if (existing != null) {
+ return existing;
+ }
+
+ final TypeEffectiveStatement<?> type = findFirstEffectiveSubstatement(TypeEffectiveStatement.class).get();
+ final DerivedTypeBuilder<?> builder = DerivedTypes.derivedTypeBuilder(type.getTypeDefinition(), path);
- 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) {
} else if (stmt instanceof UnknownSchemaNode) {
// FIXME: should not directly implement, I think
builder.addUnknownSchemaNode((UnknownSchemaNode)stmt);
- } else {
- if (!(stmt instanceof TypeEffectiveStatement)) {
- LOG.debug("Ignoring statement {}", stmt);
- }
+ } else if (!(stmt instanceof TypeEffectiveStatement)) {
+ LOG.debug("Ignoring statement {}", stmt);
}
}
- SourceException.throwIf(
- EffectiveStmtUtils.hasDefaultValueMarkedWithIfFeature(ctx.getRootVersion(), typeEffectiveStmt, dflt),
- ctx.getStatementSourceReference(),
- "Typedef '%s' has default value '%s' marked with an if-feature statement.", ctx.getStatementArgument(),
- dflt);
-
- typeDefinition = builder.build();
- }
-
- @Override
- public TypeDefinition<?> getTypeDefinition() {
- return typeDefinition;
+ final TypeDefinition<?> ret = builder.build();
+ typeDefinition = ret;
+ return ret;
}
- @Override
- public TypeEffectiveStatement<TypeStatement> asTypeEffectiveStatement() {
+ private synchronized @NonNull TypeEffectiveStatement<TypeStatement> loadTypeStatement() {
TypeEffectiveStatement<TypeStatement> ret = typeStatement;
if (ret == null) {
- synchronized (this) {
- ret = typeStatement;
- if (ret == null) {
- typeStatement = ret = new ProxyTypeEffectiveStatement();
- }
- }
+ typeStatement = ret = new ProxyTypeEffectiveStatement();
}
-
return ret;
}
return TypedefEffectiveStatementImpl.this.effectiveSubstatements();
}
- @Override
- public StatementDefinition statementDefinition() {
- return YangStmtMapping.TYPE;
- }
-
@Override
public String argument() {
return getQName().getLocalName();
*/
package org.opendaylight.yangtools.yang.parser.rfc7950.stmt.typedef;
+import com.google.common.collect.ImmutableList;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.model.api.Status;
import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
+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.DefaultEffectiveStatement;
+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.TypedefEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.TypedefStatement;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.BaseQNameStatementSupport;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStatementMixins.EffectiveStatementWithFlags.FlagsBuilder;
+import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.EffectiveStmtUtils;
import org.opendaylight.yangtools.yang.parser.spi.TypeNamespace;
-import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractQNameStatementSupport;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
public final class TypedefStatementSupport extends
- AbstractQNameStatementSupport<TypedefStatement, TypedefEffectiveStatement> {
+ BaseQNameStatementSupport<TypedefStatement, TypedefEffectiveStatement> {
private static final SubstatementValidator SUBSTATEMENT_VALIDATOR = SubstatementValidator.builder(
YangStmtMapping.TYPEDEF)
.addOptional(YangStmtMapping.DEFAULT)
return StmtContextUtils.parseIdentifier(ctx, value);
}
- @Override
- public TypedefStatement createDeclared(final StmtContext<QName, TypedefStatement, ?> ctx) {
- // Shadowing check: make sure grandparent does not see a conflicting definition. This is required to ensure
- // that a typedef in child scope does not shadow a typedef in parent scope which occurs later in the text.
- final StmtContext<?, ?, ?> parent = ctx.getParentContext();
- if (parent != null) {
- final StmtContext<?, ?, ?> grandParent = parent.getParentContext();
- if (grandParent != null) {
- checkConflict(grandParent, ctx);
- }
- }
-
- return new TypedefStatementImpl(ctx);
- }
-
- @Override
- public TypedefEffectiveStatement createEffective(
- final StmtContext<QName, TypedefStatement, TypedefEffectiveStatement> ctx) {
- return new TypedefEffectiveStatementImpl(ctx);
- }
-
@Override
public void onFullDefinitionDeclared(final Mutable<QName, TypedefStatement, TypedefEffectiveStatement> stmt) {
super.onFullDefinitionDeclared(stmt);
return SUBSTATEMENT_VALIDATOR;
}
+ @Override
+ protected TypedefStatement createDeclared(final StmtContext<QName, TypedefStatement, ?> ctx,
+ final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+ checkDeclared(ctx);
+ return new RegularTypedefStatement(ctx.coerceStatementArgument(), substatements);
+ }
+
+ @Override
+ protected TypedefStatement createEmptyDeclared(final StmtContext<QName, TypedefStatement, ?> ctx) {
+ checkDeclared(ctx);
+ return new EmptyTypedefStatement(ctx.coerceStatementArgument());
+ }
+
+ @Override
+ protected TypedefEffectiveStatement createEffective(
+ final StmtContext<QName, TypedefStatement, TypedefEffectiveStatement> ctx,
+ final TypedefStatement declared, final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+ final TypeEffectiveStatement<?> typeEffectiveStmt = findFirstStatement(substatements,
+ TypeEffectiveStatement.class);
+ final String dflt = findFirstArgument(substatements, DefaultEffectiveStatement.class, null);
+ SourceException.throwIf(
+ EffectiveStmtUtils.hasDefaultValueMarkedWithIfFeature(ctx.getRootVersion(), typeEffectiveStmt, dflt),
+ ctx.getStatementSourceReference(),
+ "Typedef '%s' has default value '%s' marked with an if-feature statement.", ctx.getStatementArgument(),
+ dflt);
+
+ return new TypedefEffectiveStatementImpl(declared, ctx.getSchemaPath().get(), computeFlags(substatements),
+ substatements);
+ }
+
+ @Override
+ protected TypedefEffectiveStatement createEmptyEffective(
+ final StmtContext<QName, TypedefStatement, TypedefEffectiveStatement> ctx,
+ final TypedefStatement declared) {
+ throw new IllegalStateException("Refusing to create empty typedef for " + declared);
+ }
+
private static void checkConflict(final StmtContext<?, ?, ?> parent, final StmtContext<QName, ?, ?> stmt) {
final QName arg = stmt.coerceStatementArgument();
final StmtContext<?, ?, ?> existing = parent.getFromNamespace(TypeNamespace.class, arg);
SourceException.throwIf(existing != null, stmt.getStatementSourceReference(), "Duplicate name for typedef %s",
arg);
}
+
+ private static void checkDeclared(final StmtContext<QName, TypedefStatement, ?> ctx) {
+ // Shadowing check: make sure grandparent does not see a conflicting definition. This is required to ensure
+ // that a typedef in child scope does not shadow a typedef in parent scope which occurs later in the text.
+ final StmtContext<?, ?, ?> parent = ctx.getParentContext();
+ if (parent != null) {
+ final StmtContext<?, ?, ?> grandParent = parent.getParentContext();
+ if (grandParent != null) {
+ checkConflict(grandParent, ctx);
+ }
+ }
+ }
+
+ private static int computeFlags(final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+ return new FlagsBuilder()
+ .setStatus(findFirstArgument(substatements, StatusEffectiveStatement.class, Status.CURRENT))
+ .toFlags();
+ }
}
\ No newline at end of file