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.NamespaceBehaviour.StorageNodeType;
23 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementFactory;
24 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
25 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
26 import org.opendaylight.yangtools.yang.parser.spi.meta.UndeclaredStatementFactory;
27 import org.opendaylight.yangtools.yang.parser.spi.source.ImplicitSubstatement;
30 * A statement which has not been declared, but exists in the statement hierarchy through some inference.
32 * @param <A> Argument type
33 * @param <D> Declared Statement representation
34 * @param <E> Effective Statement representation
36 class UndeclaredStmtCtx<A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>>
37 extends OriginalStmtCtx<A, D, E> implements UndeclaredCurrent<A, D> {
38 private final StatementContextBase<?, ?, ?> parent;
39 private final A argument;
41 private UndeclaredStmtCtx(final UndeclaredStmtCtx<A, D, E> original, final StatementContextBase<?, ?, ?> parent) {
43 this.parent = requireNonNull(parent);
44 this.argument = original.argument;
47 UndeclaredStmtCtx(final StatementContextBase<?, ?, ?> parent, final StatementSupport<A, D, E> support,
48 final @Nullable A argument) {
49 super(new StatementDefinitionContext<>(support), ImplicitSubstatement.of(parent.sourceReference()));
50 this.parent = requireNonNull(parent);
51 this.argument = argument != null ? argument : definition().parseArgumentValue(this, null);
54 // Exposed for StatementContextBase.wrapWithImplicit()
55 UndeclaredStmtCtx(final StatementContextBase<?, ?, ?> original, final StatementSupport<A, D, E> support) {
56 super(new StatementDefinitionContext<>(verifySupport(support)), original.sourceReference(),
57 original.getLastOperation());
58 this.parent = original.getParentContext();
59 this.argument = castArgument(original);
62 // Exposed for implicit substatement wrapping in StatementContextBase.childCopyOf()
63 UndeclaredStmtCtx(final StatementContextBase<?, ?, ?> parent, final StatementSupport<A, D, E> support,
64 final StatementContextBase<?, ?, ?> original, final CopyType type) {
65 super(new StatementDefinitionContext<>(verifySupport(support)), original.sourceReference(), type);
66 this.parent = requireNonNull(parent);
67 this.argument = castArgument(original);
70 // Exposed for ImplicitStmtCtx
71 UndeclaredStmtCtx(final StatementContextBase<?, ?, ?> parent, final StatementSupport<A, D, E> support,
72 final String rawArgument) {
73 super(new StatementDefinitionContext<>(support), ImplicitSubstatement.of(parent.sourceReference()));
74 this.parent = requireNonNull(parent);
75 this.argument = definition().parseArgumentValue(this, rawArgument);
78 // FIXME: this assumes original's argument type matches this type... which is true for the only case we
79 // currently care about (implicit case in choice, which is always triggered by a SchemaTree original),
80 // but this will need re-visiting
81 @SuppressWarnings("unchecked")
82 private static <A> @NonNull A castArgument(final StatementContextBase<?, ?, ?> original) {
83 return (A) original.getArgument();
86 private static <T> T verifySupport(final T support) {
87 verify(support instanceof UndeclaredStatementFactory, "Unexpected statement support %s", support);
92 public Collection<? extends StatementContextBase<?, ?, ?>> mutableDeclaredSubstatements() {
93 return ImmutableList.of();
97 Stream<? extends @NonNull ReactorStmtCtx<?, ?, ?>> streamDeclared() {
98 return Stream.empty();
102 void dropDeclaredSubstatements() {
107 UndeclaredStmtCtx<A, D, E> reparent(final StatementContextBase<?, ?, ?> newParent) {
108 return new UndeclaredStmtCtx<>(this, newParent);
112 E createEffective(final StatementFactory<A, D, E> factory) {
113 return createEffective(factory, this, streamEffective());
116 @SuppressWarnings("unchecked")
117 private static <A, D extends DeclaredStatement<A>, E extends EffectiveStatement<A, D>> @NonNull E createEffective(
118 final @NonNull StatementFactory<A, D, E> factory, final @NonNull UndeclaredCurrent<A, D> ctx,
119 final @NonNull Stream<? extends StmtContext<?, ?, ?>> substatements) {
120 verify(factory instanceof UndeclaredStatementFactory, "Unexpected factory %s", factory);
121 return ((UndeclaredStatementFactory<A, D, E>) factory).createUndeclaredEffective(ctx, substatements);
125 E createInferredEffective(final StatementFactory<A, D, E> factory, final InferredStatementContext<A, D, E> ctx,
126 final Stream<? extends ReactorStmtCtx<?, ?, ?>> declared,
127 final Stream<? extends ReactorStmtCtx<?, ?, ?>> effective) {
128 final long declaredCount = declared.count();
129 verify(declaredCount == 0, "Unexpected non-empty declared statements in %s", ctx);
130 return createEffective(factory, new ForwardingUndeclaredCurrent<>(ctx), effective);
134 * KEEP THINGS ORGANIZED!
136 * below methods exist in the same form in InferredStatementContext. If any adjustment is made here, make sure it is
137 * properly updated there.
140 public A argument() {
145 public StatementContextBase<?, ?, ?> getParentContext() {
150 public StorageNodeType getStorageNodeType() {
151 return StorageNodeType.STATEMENT_LOCAL;
155 public StatementContextBase<?, ?, ?> getParentNamespaceStorage() {
160 public RootStatementContext<?, ?, ?> getRoot() {
161 return parent.getRoot();
165 public EffectiveConfig effectiveConfig() {
166 return effectiveConfig(parent);
170 protected boolean isIgnoringIfFeatures() {
171 return isIgnoringIfFeatures(parent);
175 protected boolean isIgnoringConfig() {
176 return isIgnoringConfig(parent);
180 protected boolean isParentSupportedByFeatures() {
181 return parent.isSupportedByFeatures();