/*
* 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;
import static java.util.Objects.requireNonNull;
import com.google.common.annotations.Beta;
import com.google.common.collect.ImmutableList;
import java.util.Collection;
import org.eclipse.jdt.annotation.NonNull;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
import org.opendaylight.yangtools.yang.model.api.meta.StatementSource;
import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
/**
* An abstract base class for {@link DeclaredStatement} implementations. This is a direct competition to
* {@link org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement}, providing lower-footprint
* implementations.
*/
@Beta
public abstract class AbstractDeclaredStatement extends AbstractModelStatement implements DeclaredStatement {
protected AbstractDeclaredStatement() {
}
@Override
public final StatementSource getStatementSource() {
return StatementSource.DECLARATION;
}
@Override
public Collection extends DeclaredStatement>> declaredSubstatements() {
// Default to reduce load on subclasses and keep the number of implementations down
return ImmutableList.of();
}
/**
* Utility method for recovering singleton lists squashed by {@link #maskList(ImmutableList)}.
*
* @param masked list to unmask
* @return Unmasked list
* @throws NullPointerException if masked is null
* @throws ClassCastException if masked object does not match DeclaredStatement
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
protected static final @NonNull ImmutableList extends DeclaredStatement>> unmaskList(
final @NonNull Object masked) {
return (ImmutableList) unmaskList(masked, DeclaredStatement.class);
}
public abstract static class WithRawArgument extends AbstractDeclaredStatement {
private final String rawArgument;
protected WithRawArgument(final StmtContext context) {
rawArgument = context.rawStatementArgument();
}
@Override
public final String rawArgument() {
return rawArgument;
}
}
public abstract static class WithQNameArgument extends AbstractDeclaredStatement {
public abstract static class WithSubstatements extends WithQNameArgument {
private final @NonNull Object substatements;
protected WithSubstatements(final QName argument,
final ImmutableList extends DeclaredStatement>> substatements) {
super(argument);
this.substatements = maskList(substatements);
}
@Override
public final Collection extends DeclaredStatement>> declaredSubstatements() {
return unmaskList(substatements);
}
}
private final QName argument;
protected WithQNameArgument(final QName argument) {
this.argument = requireNonNull(argument);
}
@Override
public final @NonNull QName argument() {
return argument;
}
@Override
public final String rawArgument() {
return argument.getLocalName();
}
}
public abstract static class WithRawStringArgument extends WithRawArgument {
public abstract static class WithSubstatements extends WithRawStringArgument {
private final @NonNull Object substatements;
protected WithSubstatements(final StmtContext context,
final ImmutableList extends DeclaredStatement>> substatements) {
super(context);
this.substatements = maskList(substatements);
}
@Override
public final Collection extends DeclaredStatement>> declaredSubstatements() {
return unmaskList(substatements);
}
}
protected WithRawStringArgument(final StmtContext context) {
super(context);
}
@Override
public final String argument() {
return rawArgument();
}
}
public abstract static class WithArgument extends WithRawArgument {
public abstract static class WithSubstatements extends WithArgument {
private final @NonNull Object substatements;
protected WithSubstatements(final StmtContext context,
final ImmutableList extends DeclaredStatement>> substatements) {
super(context);
this.substatements = maskList(substatements);
}
@Override
public final Collection extends DeclaredStatement>> declaredSubstatements() {
return unmaskList(substatements);
}
}
private final A argument;
protected WithArgument(final StmtContext context) {
super(context);
argument = context.getStatementArgument();
}
@Override
public final A argument() {
return argument;
}
}
public abstract static class ArgumentToString extends AbstractDeclaredStatement {
public abstract static class WithSubstatements extends ArgumentToString {
private final @NonNull Object substatements;
protected WithSubstatements(final A argument,
final ImmutableList extends DeclaredStatement>> substatements) {
super(argument);
this.substatements = maskList(substatements);
}
@Override
public final Collection extends DeclaredStatement>> declaredSubstatements() {
return unmaskList(substatements);
}
}
private final @NonNull A argument;
protected ArgumentToString(final A argument) {
this.argument = requireNonNull(argument);
}
@Override
public final @NonNull A argument() {
return argument;
}
@Override
public final String rawArgument() {
return argument.toString();
}
}
}