2 * Copyright (c) 2022 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.mdsal.binding.generator.impl.reactor;
10 import static com.google.common.base.Verify.verify;
11 import static com.google.common.base.Verify.verifyNotNull;
12 import static java.util.Objects.requireNonNull;
14 import com.google.common.base.MoreObjects;
15 import com.google.common.collect.ImmutableSet;
16 import java.util.stream.Stream;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.yangtools.concepts.Immutable;
19 import org.opendaylight.yangtools.yang.common.QName;
20 import org.opendaylight.yangtools.yang.common.QNameModule;
21 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
22 import org.opendaylight.yangtools.yang.model.api.stmt.AugmentEffectiveStatement;
23 import org.opendaylight.yangtools.yang.model.api.stmt.UsesEffectiveStatement;
26 * Lookup context for dealing with namespace translation during execution of {@link AbstractCompositeGenerator}'s
27 * createInternalRuntimeType(). It tracks which namespaces should be translated on account of crossing into source
28 * {@code grouping} statement.
30 final class ChildLookup implements Immutable {
31 private final ImmutableSet<AugmentEffectiveStatement> validUsesAugments;
32 private final ImmutableSet<QNameModule> squashNamespaces;
33 private final QNameModule localNamespace;
35 private ChildLookup(final ImmutableSet<AugmentEffectiveStatement> validUsesAugments,
36 final ImmutableSet<QNameModule> squashNamespaces, final QNameModule localNamespace) {
37 this.validUsesAugments = requireNonNull(validUsesAugments);
38 this.squashNamespaces = requireNonNull(squashNamespaces);
39 this.localNamespace = localNamespace;
40 verify(localNamespace == null == squashNamespaces.isEmpty(), "Unexpected lookup state %s", this);
43 public static @NonNull ChildLookup of(final EffectiveStatement<?, ?> statement) {
44 return new ChildLookup(streamUsesAugments(statement).collect(ImmutableSet.toImmutableSet()), ImmutableSet.of(),
48 @NonNull QName adjustQName(final @NonNull QName qname) {
49 return squashNamespaces.contains(qname.getModule()) ? qname.bindTo(verifyNotNull(localNamespace)) : qname;
52 boolean contains(final AugmentEffectiveStatement augment) {
53 return validUsesAugments.contains(augment);
56 @NonNull ChildLookup inStatement(final EffectiveStatement<?, ?> statememt) {
57 return hasUsesAugments(statememt)
58 ? new ChildLookup(concatUsesAugments(statememt), squashNamespaces, localNamespace) : this;
61 @NonNull ChildLookup inGrouping(final QName qname, final GroupingGenerator grouping) {
62 final var statement = grouping.statement();
63 final var grpNamespace = statement.argument().getModule();
64 final var itemNamespace = qname.getModule();
66 final ImmutableSet<QNameModule> newSquashNamespaces;
67 if (squashNamespaces.contains(itemNamespace)) {
68 newSquashNamespaces = squashNamespaces;
70 newSquashNamespaces = ImmutableSet.<QNameModule>builderWithExpectedSize(squashNamespaces.size() + 1)
71 .addAll(squashNamespaces).add(itemNamespace).build();
74 return new ChildLookup(hasUsesAugments(statement) ? concatUsesAugments(statement) : validUsesAugments,
75 newSquashNamespaces, grpNamespace);
79 public String toString() {
80 return MoreObjects.toStringHelper(this).omitNullValues()
81 .add("augments", validUsesAugments)
82 .add("squash", squashNamespaces)
83 .add("local", localNamespace)
87 private ImmutableSet<AugmentEffectiveStatement> concatUsesAugments(final EffectiveStatement<?, ?> stmt) {
88 final var concat = ImmutableSet.<AugmentEffectiveStatement>builder().addAll(validUsesAugments);
89 streamUsesAugments(stmt).forEach(concat::add);
90 return concat.build();
93 private static boolean hasUsesAugments(final EffectiveStatement<?, ?> stmt) {
94 return streamUsesAugments(stmt).findAny().isPresent();
97 private static Stream<AugmentEffectiveStatement> streamUsesAugments(final EffectiveStatement<?, ?> stmt) {
98 return stmt.streamEffectiveSubstatements(UsesEffectiveStatement.class)
99 .flatMap(uses -> uses.streamEffectiveSubstatements(AugmentEffectiveStatement.class));