Pick up byte-buddy from yangtools
[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<?, ?> ret && needle == ret.statement()) {
35                     return ret;
36                 }
37             }
38             return null;
39         }
40     }
41
42     /**
43      * Strategy matching on exact QName argument. Used when we are switching along the 'augments' axis.
44      */
45     private static class OnQName extends MatchStrategy {
46         static final @NonNull OnQName INSTANCE = new OnQName();
47
48         @Override
49         final AbstractExplicitGenerator<?, ?> findGenerator(final EffectiveStatement<?, ?> needle,
50                 final Iterable<? extends Generator> haystack) {
51             final Object arg = needle.argument();
52             verify(arg instanceof QName, "Unexpected argument %s in %s", arg, needle);
53             return findGenerator((QName) arg, haystack);
54         }
55
56         AbstractExplicitGenerator<?, ?> findGenerator(final QName needle,
57                 final Iterable<? extends Generator> haystack) {
58             for (Generator gen : haystack) {
59                 if (gen instanceof AbstractExplicitGenerator<?, ?> ret && needle.equals(ret.statement().argument())) {
60                     return ret;
61                 }
62             }
63             return null;
64         }
65     }
66
67     /**
68      * Strategy matching on exact QName argument rehosted to a particular grouping. This is how we can locate a node
69      * inlined via a 'uses' of that grouping.
70      */
71     private static final class Grouping extends OnQName {
72         private final @NonNull QNameModule module;
73
74         Grouping(final GroupingGenerator grouping) {
75             module = grouping.statement().argument().getModule();
76         }
77
78         @Override
79         AbstractExplicitGenerator<?, ?> findGenerator(final QName needle,
80                 final Iterable<? extends Generator> haystack) {
81             return super.findGenerator(needle.bindTo(module), haystack);
82         }
83
84         @Override
85         ToStringHelper addToStringAttributes(final ToStringHelper helper) {
86             return super.addToStringAttributes(helper).add("module", module);
87         }
88     }
89
90     private MatchStrategy() {
91         // Hidden on purpose
92     }
93
94     static @NonNull MatchStrategy augment() {
95         return OnQName.INSTANCE;
96     }
97
98     static @NonNull MatchStrategy grouping(final GroupingGenerator grouping) {
99         return new Grouping(grouping);
100     }
101
102     static @NonNull MatchStrategy identity() {
103         return Identity.INSTANCE;
104     }
105
106     abstract @Nullable AbstractExplicitGenerator<?, ?> findGenerator(EffectiveStatement<?, ?> needle,
107             Iterable<? extends Generator> haystack);
108
109     @Override
110     public final String toString() {
111         return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
112     }
113
114     ToStringHelper addToStringAttributes(final ToStringHelper helper) {
115         return helper;
116     }
117 }