Populate parser/ hierarchy
[yangtools.git] / parser / yang-parser-spi / src / main / java / org / opendaylight / yangtools / yang / parser / spi / meta / AbstractBooleanStatementSupport.java
diff --git a/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractBooleanStatementSupport.java b/parser/yang-parser-spi/src/main/java/org/opendaylight/yangtools/yang/parser/spi/meta/AbstractBooleanStatementSupport.java
new file mode 100644 (file)
index 0000000..7e8fd16
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * 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.spi.meta;
+
+import static java.util.Objects.requireNonNull;
+
+import com.google.common.annotations.Beta;
+import com.google.common.collect.ImmutableList;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+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.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.parser.api.YangParserConfiguration;
+import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.Current;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+
+/**
+ * Specialization of {@link AbstractStatementSupport} for statements which carry a Boolean argument and are essentially
+ * context-independent.
+ *
+ * @param <D> Declared Statement representation
+ * @param <E> Effective Statement representation
+ */
+@Beta
+public abstract class AbstractBooleanStatementSupport<D extends DeclaredStatement<Boolean>,
+        E extends EffectiveStatement<Boolean, D>> extends AbstractStatementSupport<Boolean, D, E> {
+    private final @NonNull E emptyEffectiveFalse;
+    private final @NonNull E emptyEffectiveTrue;
+    private final @NonNull D emptyDeclaredFalse;
+    private final @NonNull D emptyDeclaredTrue;
+
+    protected AbstractBooleanStatementSupport(final StatementDefinition publicDefinition,
+            final E emptyEffectiveFalse, final E emptyEffectiveTrue, final StatementPolicy<Boolean, D> policy,
+            final YangParserConfiguration config, final @Nullable SubstatementValidator validator) {
+        super(publicDefinition, policy, config, validator);
+        this.emptyEffectiveFalse = requireNonNull(emptyEffectiveFalse);
+        this.emptyEffectiveTrue = requireNonNull(emptyEffectiveTrue);
+        emptyDeclaredFalse = requireNonNull(emptyEffectiveFalse.getDeclared());
+        emptyDeclaredTrue = requireNonNull(emptyEffectiveTrue.getDeclared());
+    }
+
+    @Override
+    public final Boolean parseArgumentValue(final StmtContext<?, ?, ?> ctx, final String value) {
+        if ("true".equals(value)) {
+            return Boolean.TRUE;
+        } else if ("false".equals(value)) {
+            return Boolean.FALSE;
+        } else {
+            throw new SourceException(ctx, "Invalid '%s' statement %s '%s', it can be either 'true' or 'false'",
+                getStatementName(), getArgumentDefinition().get().getArgumentName(), value);
+        }
+    }
+
+    @Override
+    public final String internArgument(final String rawArgument) {
+        if ("true".equals(rawArgument)) {
+            return "true";
+        } else if ("false".equals(rawArgument)) {
+            return "false";
+        } else {
+            return rawArgument;
+        }
+    }
+
+    @Override
+    protected final D createDeclared(final StmtContext<Boolean, D, ?> ctx,
+            final ImmutableList<? extends DeclaredStatement<?>> substatements) {
+        final Boolean argument = ctx.getArgument();
+        if (substatements.isEmpty()) {
+            return argument ? emptyDeclaredTrue : emptyDeclaredFalse;
+        }
+        return createDeclared(argument, substatements);
+    }
+
+    protected abstract @NonNull D createDeclared(@NonNull Boolean argument,
+        @NonNull ImmutableList<? extends DeclaredStatement<?>> substatements);
+
+    @Override
+    protected final E createEffective(final Current<Boolean, D> stmt,
+            final ImmutableList<? extends EffectiveStatement<?, ?>> substatements) {
+        return substatements.isEmpty() ? createEmptyEffective(stmt) : createEffective(stmt.declared(), substatements);
+    }
+
+    protected abstract @NonNull E createEffective(@NonNull D declared,
+        ImmutableList<? extends EffectiveStatement<?, ?>> substatements);
+
+    protected abstract @NonNull E createEmptyEffective(@NonNull D declared);
+
+    private @NonNull E createEmptyEffective(final Current<Boolean, D> stmt) {
+        final D declared = stmt.declared();
+        if (emptyDeclaredTrue.equals(declared)) {
+            return emptyEffectiveTrue;
+        } else if (emptyDeclaredFalse.equals(declared)) {
+            return emptyEffectiveFalse;
+        } else {
+            return createEmptyEffective(declared);
+        }
+    }
+}