Rework BindingRuntimeTypes
[mdsal.git] / binding / mdsal-binding-generator / src / main / java / org / opendaylight / mdsal / binding / generator / impl / reactor / MatchStrategy.java
1 /*
2  * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.mdsal.binding.generator.impl.reactor;
9
10 import static com.google.common.base.Verify.verify;
11
12 import com.google.common.base.MoreObjects;
13 import com.google.common.base.MoreObjects.ToStringHelper;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.eclipse.jdt.annotation.Nullable;
16 import org.opendaylight.yangtools.yang.common.QName;
17 import org.opendaylight.yangtools.yang.common.QNameModule;
18 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
19
20 /**
21  * A strategy for matching an {@link EffectiveStatement} to an {@link AbstractExplicitGenerator}.
22  */
23 abstract class MatchStrategy {
24     /**
25      * Strategy matching on exact statement identity. We use this initially as it works for non-weird cases.
26      */
27     private static final class Identity extends MatchStrategy {
28         static final @NonNull Identity INSTANCE = new Identity();
29
30         @Override
31         AbstractExplicitGenerator<?, ?> findGenerator(final EffectiveStatement<?, ?> needle,
32                 final Iterable<? extends Generator> haystack) {
33             for (Generator gen : haystack) {
34                 if (gen instanceof AbstractExplicitGenerator) {
35                     final AbstractExplicitGenerator<?, ?> ret = (AbstractExplicitGenerator<?, ?>) gen;
36                     if (needle == ret.statement()) {
37                         return ret;
38                     }
39                 }
40             }
41             return null;
42         }
43     }
44
45     /**
46      * Strategy matching on exact QName argument. Used when we are switching along the 'augments' axis.
47      */
48     private static class OnQName extends MatchStrategy {
49         static final @NonNull OnQName INSTANCE = new OnQName();
50
51         @Override
52         final AbstractExplicitGenerator<?, ?> findGenerator(final EffectiveStatement<?, ?> needle,
53                 final Iterable<? extends Generator> haystack) {
54             final Object arg = needle.argument();
55             verify(arg instanceof QName, "Unexpected argument %s in %s", arg, needle);
56             return findGenerator((QName) arg, haystack);
57         }
58
59         AbstractExplicitGenerator<?, ?> findGenerator(final QName needle,
60                 final Iterable<? extends Generator> haystack) {
61             for (Generator gen : haystack) {
62                 if (gen instanceof AbstractExplicitGenerator) {
63                     final AbstractExplicitGenerator<?, ?> ret = (AbstractExplicitGenerator<?, ?>) gen;
64                     if (needle.equals(ret.statement().argument())) {
65                         return ret;
66                     }
67                 }
68             }
69             return null;
70         }
71     }
72
73     /**
74      * Strategy matching on exact QName argument rehosted to a particular grouping. This is how we can locate a node
75      * inlined via a 'uses' of that grouping.
76      */
77     private static final class Grouping extends OnQName {
78         private final @NonNull QNameModule module;
79
80         Grouping(final GroupingGenerator grouping) {
81             module = grouping.statement().argument().getModule();
82         }
83
84         @Override
85         AbstractExplicitGenerator<?, ?> findGenerator(final QName needle,
86                 final Iterable<? extends Generator> haystack) {
87             return super.findGenerator(needle.bindTo(module), haystack);
88         }
89
90         @Override
91         ToStringHelper addToStringAttributes(final ToStringHelper helper) {
92             return super.addToStringAttributes(helper).add("module", module);
93         }
94     }
95
96     private MatchStrategy() {
97         // Hidden on purpose
98     }
99
100     static @NonNull MatchStrategy augment() {
101         return OnQName.INSTANCE;
102     }
103
104     static @NonNull MatchStrategy grouping(final GroupingGenerator grouping) {
105         return new Grouping(grouping);
106     }
107
108     static @NonNull MatchStrategy identity() {
109         return Identity.INSTANCE;
110     }
111
112     abstract @Nullable AbstractExplicitGenerator<?, ?> findGenerator(EffectiveStatement<?, ?> needle,
113             Iterable<? extends Generator> haystack);
114
115     @Override
116     public final String toString() {
117         return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
118     }
119
120     ToStringHelper addToStringAttributes(final ToStringHelper helper) {
121         return helper;
122     }
123 }