3b15fed218d45d3d376303e6e88951fec28c3405
[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, final Iterable<? extends Generator> haystack) {
60             for (Generator gen : haystack) {
61                 if (gen instanceof AbstractExplicitGenerator) {
62                     final AbstractExplicitGenerator<?> ret = (AbstractExplicitGenerator<?>) gen;
63                     if (needle.equals(ret.statement().argument())) {
64                         return ret;
65                     }
66                 }
67             }
68             return null;
69         }
70     }
71
72     /**
73      * Strategy matching on exact QName argument rehosted to a particular grouping. This is how we can locate a node
74      * inlined via a 'uses' of that grouping.
75      */
76     private static final class Grouping extends OnQName {
77         private final @NonNull QNameModule module;
78
79         Grouping(final GroupingGenerator grouping) {
80             module = grouping.statement().argument().getModule();
81         }
82
83         @Override
84         AbstractExplicitGenerator<?> findGenerator(final QName needle, final Iterable<? extends Generator> haystack) {
85             return super.findGenerator(needle.bindTo(module), haystack);
86         }
87
88         @Override
89         ToStringHelper addToStringAttributes(final ToStringHelper helper) {
90             return super.addToStringAttributes(helper).add("module", module);
91         }
92     }
93
94     private MatchStrategy() {
95         // Hidden on purpose
96     }
97
98     static @NonNull MatchStrategy augment() {
99         return OnQName.INSTANCE;
100     }
101
102     static @NonNull MatchStrategy grouping(final GroupingGenerator grouping) {
103         return new Grouping(grouping);
104     }
105
106     static @NonNull MatchStrategy identity() {
107         return Identity.INSTANCE;
108     }
109
110     abstract @Nullable AbstractExplicitGenerator<?> findGenerator(EffectiveStatement<?, ?> needle,
111             Iterable<? extends Generator> haystack);
112
113     @Override
114     public final String toString() {
115         return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
116     }
117
118     ToStringHelper addToStringAttributes(final ToStringHelper helper) {
119         return helper;
120     }
121 }