import com.google.common.base.CharMatcher;
import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
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.SchemaNodeIdentifier;
-import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Relative;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Descendant;
+import org.opendaylight.yangtools.yang.model.api.stmt.UniqueEffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.stmt.UniqueStatement;
+import org.opendaylight.yangtools.yang.model.ri.stmt.DeclaredStatements;
import org.opendaylight.yangtools.yang.parser.rfc7950.stmt.ArgumentUtils;
import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
import org.opendaylight.yangtools.yang.parser.spi.meta.SubstatementValidator;
import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
-public final class UniqueStatementSupport extends AbstractStatementSupport<Set<Relative>, UniqueStatement,
- EffectiveStatement<Set<Relative>, UniqueStatement>> {
+public final class UniqueStatementSupport
+ extends AbstractStatementSupport<Set<Descendant>, UniqueStatement, UniqueEffectiveStatement> {
/**
* Support 'sep' ABNF rule in RFC7950 section 14. CRLF pattern is used to squash line-break from CRLF to LF form
* and then we use SEP_SPLITTER, which can operate on single characters.
private static final UniqueStatementSupport INSTANCE = new UniqueStatementSupport();
private UniqueStatementSupport() {
- super(YangStmtMapping.UNIQUE);
+ // FIXME: This reflects what the current implementation does. We really want to define an adaptArgumentValue(),
+ // but how that plays with the argument and expectations needs to be investigated.
+ super(YangStmtMapping.UNIQUE, StatementPolicy.contextIndependent());
}
public static UniqueStatementSupport getInstance() {
}
@Override
- public Set<Relative> parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
- final Set<Relative> uniqueConstraints = parseUniqueConstraintArgument(ctx, value);
- SourceException.throwIf(uniqueConstraints.isEmpty(), ctx.getStatementSourceReference(),
- "Invalid argument value '%s' of unique statement. The value must contains at least "
- + "one descendant schema node identifier.", value);
+ public ImmutableSet<Descendant> parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
+ final ImmutableSet<Descendant> uniqueConstraints = parseUniqueConstraintArgument(ctx, value);
+ SourceException.throwIf(uniqueConstraints.isEmpty(), ctx,
+ "Invalid argument value '%s' of unique statement. The value must contains at least one descendant schema "
+ + "node identifier.", value);
return uniqueConstraints;
}
@Override
- public UniqueStatement createDeclared(final StmtContext<Set<Relative>, UniqueStatement, ?> ctx) {
- return new UniqueStatementImpl(ctx);
+ protected SubstatementValidator getSubstatementValidator() {
+ return SUBSTATEMENT_VALIDATOR;
}
@Override
- public EffectiveStatement<Set<Relative>, UniqueStatement> createEffective(
- final StmtContext<Set<Relative>, UniqueStatement, EffectiveStatement<Set<Relative>, UniqueStatement>> ctx) {
- return new UniqueEffectiveStatementImpl(ctx);
+ protected UniqueStatement createDeclared(final StmtContext<Set<Descendant>, UniqueStatement, ?> ctx,
+ final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+ return DeclaredStatements.createUnique(ctx.getRawArgument(), ctx.getArgument(), substatements);
}
@Override
- protected SubstatementValidator getSubstatementValidator() {
- return SUBSTATEMENT_VALIDATOR;
+ protected UniqueStatement createEmptyDeclared(final StmtContext<Set<Descendant>, UniqueStatement, ?> ctx) {
+ return DeclaredStatements.createUnique(ctx.getRawArgument(), ctx.getArgument());
+ }
+
+ @Override
+ protected UniqueEffectiveStatement createEffective(final Current<Set<Descendant>, UniqueStatement> stmt,
+ final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+ return substatements.isEmpty() ? new EmptyUniqueEffectiveStatement(stmt.declared())
+ : new RegularUniqueEffectiveStatement(stmt.declared(), substatements);
+
}
- private static Set<Relative> parseUniqueConstraintArgument(final StmtContext<?, ?, ?> ctx,
+ private static ImmutableSet<Descendant> parseUniqueConstraintArgument(final StmtContext<?, ?, ?> ctx,
final String argumentValue) {
// deal with 'line-break' rule, which is either "\n" or "\r\n", but not "\r"
final String nocrlf = CRLF_PATTERN.matcher(argumentValue).replaceAll("\n");
- final Set<Relative> uniqueConstraintNodes = new HashSet<>();
+ final Set<Descendant> uniqueConstraintNodes = new HashSet<>();
for (final String uniqueArgToken : SEP_SPLITTER.split(nocrlf)) {
final SchemaNodeIdentifier nodeIdentifier = ArgumentUtils.nodeIdentifierFromPath(ctx, uniqueArgToken);
- SourceException.throwIf(nodeIdentifier.isAbsolute(), ctx.getStatementSourceReference(),
- "Unique statement argument '%s' contains schema node identifier '%s' "
- + "which is not in the descendant node identifier form.", argumentValue, uniqueArgToken);
- uniqueConstraintNodes.add((Relative) nodeIdentifier);
+ SourceException.throwIf(nodeIdentifier instanceof Absolute, ctx,
+ "Unique statement argument '%s' contains schema node identifier '%s' which is not in the descendant "
+ + "node identifier form.", argumentValue, uniqueArgToken);
+ uniqueConstraintNodes.add((Descendant) nodeIdentifier);
}
return ImmutableSet.copyOf(uniqueConstraintNodes);
}