2 * Copyright (c) 2023 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 java.util.Objects.requireNonNull;
12 import com.google.common.base.MoreObjects;
13 import com.google.common.collect.Multimap;
14 import com.google.common.collect.Multimaps;
15 import java.util.ArrayDeque;
16 import java.util.ArrayList;
17 import java.util.HashMap;
18 import java.util.List;
20 import java.util.Map.Entry;
21 import org.eclipse.jdt.annotation.NonNull;
22 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceBehaviour;
23 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceKeyCriterion;
24 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage;
25 import org.opendaylight.yangtools.yang.parser.spi.meta.NamespaceStorage.GlobalStorage;
26 import org.opendaylight.yangtools.yang.parser.spi.meta.ParserNamespace;
29 * A {@link NamespaceAccess} backed by a {@link NamespaceBehaviour}. Also holds reference to {@link BuildGlobalContext}.
31 final class BehaviourNamespaceAccess<K, V> extends NamespaceAccess<K, V> {
32 private final @NonNull NamespaceBehaviour<K, V> behaviour;
33 private final @NonNull GlobalStorage globalStorage;
35 private Multimap<K, KeyedValueAddedListener<K, V>> keyListeners;
36 private List<PredicateValueAddedListener<K, V>> predicateListeners;
38 BehaviourNamespaceAccess(final GlobalStorage globalStorage, final NamespaceBehaviour<K, V> behaviour) {
39 this.globalStorage = requireNonNull(globalStorage);
40 this.behaviour = requireNonNull(behaviour);
44 ParserNamespace<K, V> namespace() {
45 return behaviour.namespace();
49 V valueFrom(final NamespaceStorage storage, final K key) {
50 return behaviour.getFrom(globalStorage, storage, key);
54 void valueTo(final NamespaceStorage storage, final K key, final V value) {
55 behaviour.addTo(globalStorage, storage, key, value);
57 if (keyListeners != null) {
58 final var listeners = keyListeners.get(key);
59 if (!listeners.isEmpty()) {
60 final var toNotify = new ArrayList<KeyedValueAddedListener<K, V>>();
61 final var it = listeners.iterator();
62 while (it.hasNext()) {
63 final var listener = it.next();
64 if (listener.isRequestedValue(this, storage, key, value)) {
66 toNotify.add(listener);
69 for (var listener : toNotify) {
70 listener.onValueAdded(key, value);
73 if (keyListeners.isEmpty()) {
79 if (predicateListeners != null) {
80 final var it = predicateListeners.iterator();
81 while (it.hasNext()) {
82 if (it.next().onValueAdded(key, value)) {
86 if (predicateListeners != null && predicateListeners.isEmpty()) {
87 predicateListeners = null;
93 Map<K, V> allFrom(final NamespaceStorage storage) {
94 return behaviour.getAllFrom(globalStorage, storage);
98 Entry<K, V> entryFrom(final NamespaceStorage storage, final NamespaceKeyCriterion<K> criterion) {
99 return behaviour.getFrom(globalStorage, storage, criterion);
103 void addListener(final K key, final KeyedValueAddedListener<K, V> listener) {
104 final var k = requireNonNull(key);
105 final var l = requireNonNull(listener);
106 if (keyListeners == null) {
107 keyListeners = Multimaps.newMultimap(new HashMap<>(), ArrayDeque::new);
109 keyListeners.put(k, l);
113 void addListener(final PredicateValueAddedListener<K, V> listener) {
114 if (predicateListeners == null) {
115 predicateListeners = new ArrayList<>();
117 predicateListeners.add(listener);
121 public String toString() {
122 return MoreObjects.toStringHelper(this).add("behaviour", behaviour).toString();