2 * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
10 import static com.google.common.base.Verify.verify;
11 import static java.util.Objects.requireNonNull;
13 import com.google.common.collect.ImmutableList;
14 import java.util.Collection;
15 import java.util.stream.Stream;
16 import org.eclipse.jdt.annotation.NonNull;
17 import org.eclipse.jdt.annotation.Nullable;
18 import org.opendaylight.yangtools.yang.model.api.meta.DeclaredStatement;
19 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
20 import org.opendaylight.yangtools.yang.parser.spi.meta.CopyType;
21 import org.opendaylight.yangtools.yang.parser.spi.meta.EffectiveStmtCtx.UndeclaredCurrent;
22 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementFactory;
23 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
24 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
25 import org.opendaylight.yangtools.yang.parser.spi.meta.UndeclaredStatementFactory;
26 import org.opendaylight.yangtools.yang.parser.spi.source.ImplicitSubstatement;
29 * A statement which has not been declared, but exists in the statement hierarchy through some inference.
31 * @param <A> Argument type
32 * @param <D> Declared Statement representation
33 * @param <E> Effective Statement representation
35 class UndeclaredStmtCtx<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
36 extends OriginalStmtCtx<A, D, E> implements UndeclaredCurrent<A, D> {
37 private final StatementContextBase<?, ?, ?> parent;
38 private final A argument;
40 private UndeclaredStmtCtx(final UndeclaredStmtCtx<A, D, E> original, final StatementContextBase<?, ?, ?> parent) {
42 this.parent = requireNonNull(parent);
43 argument = original.argument;
46 UndeclaredStmtCtx(final StatementContextBase<?, ?, ?> parent, final StatementSupport<A, D, E> support,
47 final @Nullable A argument) {
48 super(new StatementDefinitionContext<>(support), ImplicitSubstatement.of(parent.sourceReference()));
49 this.parent = requireNonNull(parent);
50 this.argument = argument != null ? argument : definition().parseArgumentValue(this, null);
53 // Exposed for StatementContextBase.wrapWithImplicit()
54 UndeclaredStmtCtx(final StatementContextBase<?, ?, ?> original, final StatementSupport<A, D, E> support) {
55 super(new StatementDefinitionContext<>(verifySupport(support)), original.sourceReference(),
56 original.getLastOperation());
57 parent = original.getParentContext();
58 argument = castArgument(original);
61 // Exposed for implicit substatement wrapping in StatementContextBase.childCopyOf()
62 UndeclaredStmtCtx(final StatementContextBase<?, ?, ?> parent, final StatementSupport<A, D, E> support,
63 final StatementContextBase<?, ?, ?> original, final CopyType type) {
64 super(new StatementDefinitionContext<>(verifySupport(support)), original.sourceReference(), type);
65 this.parent = requireNonNull(parent);
66 argument = castArgument(original);
69 // Exposed for ImplicitStmtCtx
70 UndeclaredStmtCtx(final StatementContextBase<?, ?, ?> parent, final StatementSupport<A, D, E> support,
71 final String rawArgument) {
72 super(new StatementDefinitionContext<>(support), ImplicitSubstatement.of(parent.sourceReference()));
73 this.parent = requireNonNull(parent);
74 argument = definition().parseArgumentValue(this, rawArgument);
77 // FIXME: this assumes original's argument type matches this type... which is true for the only case we
78 // currently care about (implicit case in choice, which is always triggered by a SchemaTree original),
79 // but this will need re-visiting
80 @SuppressWarnings("unchecked")
81 private static <A> @NonNull A castArgument(final StatementContextBase<?, ?, ?> original) {
82 return (A) original.getArgument();
85 private static <T> T verifySupport(final T support) {
86 verify(support instanceof UndeclaredStatementFactory, "Unexpected statement support %s", support);
91 public Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements() {
92 return ImmutableList.of();
96 Stream<? extends @NonNull ReactorStmtCtx<?, ?, ?>> streamDeclared() {
97 return Stream.empty();
101 void dropDeclaredSubstatements() {
106 UndeclaredStmtCtx<A, D, E> reparent(final StatementContextBase<?, ?, ?> newParent) {
107 return new UndeclaredStmtCtx<>(this, newParent);
111 E createEffective(final StatementFactory<A, D, E> factory) {
112 return createEffective(factory, this, streamEffective());
115 @SuppressWarnings("unchecked")
116 private static <A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> @NonNull E createEffective(
117 final @NonNull StatementFactory<A, D, E> factory, final @NonNull UndeclaredCurrent<A, D> ctx,
118 final @NonNull Stream<? extends StmtContext<?, ?, ?>> substatements) {
119 verify(factory instanceof UndeclaredStatementFactory, "Unexpected factory %s", factory);
120 return ((UndeclaredStatementFactory<A, D, E>) factory).createUndeclaredEffective(ctx, substatements);
124 E createInferredEffective(final StatementFactory<A, D, E> factory, final InferredStatementContext<A, D, E> ctx,
125 final Stream<? extends ReactorStmtCtx<?, ?, ?>> declared,
126 final Stream<? extends ReactorStmtCtx<?, ?, ?>> effective) {
127 final long declaredCount = declared.count();
128 verify(declaredCount == 0, "Unexpected non-empty declared statements in %s", ctx);
129 return createEffective(factory, new ForwardingUndeclaredCurrent<>(ctx), effective);
133 * KEEP THINGS ORGANIZED!
135 * below methods exist in the same form in InferredStatementContext. If any adjustment is made here, make sure it is
136 * properly updated there.
139 public A argument() {
144 public StatementContextBase<?, ?, ?> getParentContext() {
149 public StatementContextBase<?, ?, ?> getParentStorage() {
154 public RootStatementContext<?, ?, ?> getRoot() {
155 return parent.getRoot();
159 public EffectiveConfig effectiveConfig() {
160 return effectiveConfig(parent);
164 protected boolean isIgnoringIfFeatures() {
165 return isIgnoringIfFeatures(parent);
169 protected boolean isIgnoringConfig() {
170 return isIgnoringConfig(parent);
174 protected boolean isParentSupportedByFeatures() {
175 return parent.isSupportedByFeatures();