Remove AbstractExplicitGenerator.recursiveRuntimeType()
[mdsal.git] / binding / mdsal-binding-generator / src / main / java / org / opendaylight / mdsal / binding / generator / impl / reactor / TypeBuilderFactory.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 import static java.util.Objects.requireNonNull;
12
13 import com.google.common.annotations.Beta;
14 import java.util.List;
15 import org.eclipse.jdt.annotation.NonNull;
16 import org.opendaylight.mdsal.binding.generator.BindingGeneratorUtil;
17 import org.opendaylight.mdsal.binding.model.api.GeneratedTransferObject;
18 import org.opendaylight.mdsal.binding.model.api.JavaTypeName;
19 import org.opendaylight.mdsal.binding.model.api.YangSourceDefinition;
20 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTOBuilder;
21 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilder;
22 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilderBase;
23 import org.opendaylight.mdsal.binding.model.ri.generated.type.builder.AbstractEnumerationBuilder;
24 import org.opendaylight.mdsal.binding.model.ri.generated.type.builder.CodegenEnumerationBuilder;
25 import org.opendaylight.mdsal.binding.model.ri.generated.type.builder.CodegenGeneratedTOBuilder;
26 import org.opendaylight.mdsal.binding.model.ri.generated.type.builder.CodegenGeneratedTypeBuilder;
27 import org.opendaylight.mdsal.binding.model.ri.generated.type.builder.RuntimeEnumerationBuilder;
28 import org.opendaylight.mdsal.binding.model.ri.generated.type.builder.RuntimeGeneratedTOBuilder;
29 import org.opendaylight.mdsal.binding.model.ri.generated.type.builder.RuntimeGeneratedTypeBuilder;
30 import org.opendaylight.mdsal.binding.runtime.api.RuntimeGeneratedUnion;
31 import org.opendaylight.yangtools.concepts.Immutable;
32 import org.opendaylight.yangtools.yang.model.api.DocumentedNode;
33 import org.opendaylight.yangtools.yang.model.api.Module;
34 import org.opendaylight.yangtools.yang.model.api.SchemaNode;
35 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
36 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleEffectiveStatement;
37 import org.opendaylight.yangtools.yang.model.ri.type.TypeBuilder;
38
39 /**
40  * A factory component creating {@link TypeBuilder} instances.
41  */
42 @Beta
43 public abstract class TypeBuilderFactory implements Immutable {
44     private static final class Codegen extends TypeBuilderFactory {
45         private static final @NonNull Codegen INSTANCE = new Codegen();
46
47         private Codegen() {
48             // Hidden on purpose
49         }
50
51         @Override
52         GeneratedTOBuilder newGeneratedTOBuilder(final JavaTypeName identifier) {
53             return new CodegenGeneratedTOBuilder(identifier);
54         }
55
56         @Override
57         GeneratedTypeBuilder newGeneratedTypeBuilder(final JavaTypeName identifier) {
58             return new CodegenGeneratedTypeBuilder(identifier);
59         }
60
61         @Override
62         AbstractEnumerationBuilder newEnumerationBuilder(final JavaTypeName identifier) {
63             return new CodegenEnumerationBuilder(identifier);
64         }
65
66         @Override
67         GeneratedUnionBuilder newGeneratedUnionBuilder(final JavaTypeName identifier) {
68             return new UnionBuilder(identifier);
69         }
70
71         @Override
72         void addCodegenInformation(final EffectiveStatement<?, ?> stmt,
73                 final GeneratedTypeBuilderBase<?> builder) {
74             if (stmt instanceof DocumentedNode) {
75                 addCodegenInformation((DocumentedNode) stmt, builder);
76             }
77         }
78
79         @Override
80         void addCodegenInformation(final ModuleEffectiveStatement stmt, final GeneratedTypeBuilderBase<?> builder) {
81             verify(stmt instanceof Module, "Unexpected module %s", stmt);
82             final Module module = (Module) stmt;
83
84             YangSourceDefinition.of(module).ifPresent(builder::setYangSourceDefinition);
85             TypeComments.description(module).ifPresent(builder::addComment);
86             module.getDescription().ifPresent(builder::setDescription);
87             module.getReference().ifPresent(builder::setReference);
88         }
89
90         @Override
91         void addCodegenInformation(final DocumentedNode node, final GeneratedTypeBuilderBase<?> builder) {
92             node.getDescription().map(BindingGeneratorUtil::encodeAngleBrackets).ifPresent(builder::setDescription);
93             node.getReference().ifPresent(builder::setReference);
94         }
95
96         @Override
97         void addCodegenInformation(final ModuleGenerator module, final EffectiveStatement<?, ?> stmt,
98                 final GeneratedTypeBuilderBase<?> builder) {
99             if (stmt instanceof DocumentedNode) {
100                 final DocumentedNode node = (DocumentedNode) stmt;
101                 TypeComments.description(node).ifPresent(builder::addComment);
102                 node.getDescription().ifPresent(builder::setDescription);
103                 node.getReference().ifPresent(builder::setReference);
104             }
105             if (stmt instanceof SchemaNode) {
106                 YangSourceDefinition.of(module.statement(), (SchemaNode) stmt)
107                     .ifPresent(builder::setYangSourceDefinition);
108             }
109         }
110
111         private static final class UnionBuilder extends CodegenGeneratedTOBuilder implements GeneratedUnionBuilder {
112             UnionBuilder(final JavaTypeName identifier) {
113                 super(identifier);
114                 setIsUnion(true);
115             }
116
117             @Override
118             public void setTypePropertyNames(final List<String> propertyNames) {
119                 // No-op, really
120                 requireNonNull(propertyNames);
121             }
122         }
123     }
124
125     private static final class Runtime extends TypeBuilderFactory {
126         private static final @NonNull Runtime INSTANCE = new Runtime();
127
128         private Runtime() {
129             // Hidden on purpose
130         }
131
132         @Override
133         GeneratedTOBuilder newGeneratedTOBuilder(final JavaTypeName identifier) {
134             return new RuntimeGeneratedTOBuilder(identifier);
135         }
136
137         @Override
138         GeneratedTypeBuilder newGeneratedTypeBuilder(final JavaTypeName identifier) {
139             return new RuntimeGeneratedTypeBuilder(identifier);
140         }
141
142         @Override
143         AbstractEnumerationBuilder newEnumerationBuilder(final JavaTypeName identifier) {
144             return new RuntimeEnumerationBuilder(identifier);
145         }
146
147         @Override
148         GeneratedUnionBuilder newGeneratedUnionBuilder(final JavaTypeName identifier) {
149             return new UnionBuilder(identifier);
150         }
151
152         @Override
153         void addCodegenInformation(final EffectiveStatement<?, ?> stmt, final GeneratedTypeBuilderBase<?> builder) {
154             // No-op
155         }
156
157         @Override
158         void addCodegenInformation(final ModuleEffectiveStatement stmt, final GeneratedTypeBuilderBase<?> builder) {
159             // No-op
160         }
161
162         @Override
163         void addCodegenInformation(final DocumentedNode node, final GeneratedTypeBuilderBase<?> builder) {
164             // No-op
165         }
166
167         @Override
168         void addCodegenInformation(final ModuleGenerator module, final EffectiveStatement<?, ?> stmt,
169                 final GeneratedTypeBuilderBase<?> builder) {
170             // No-op
171         }
172
173         private static final class UnionBuilder extends RuntimeGeneratedTOBuilder implements GeneratedUnionBuilder {
174             private List<String> typePropertyNames;
175
176             UnionBuilder(final JavaTypeName identifier) {
177                 super(identifier);
178                 setIsUnion(true);
179             }
180
181             @Override
182             public void setTypePropertyNames(final List<String> propertyNames) {
183                 typePropertyNames = List.copyOf(propertyNames);
184             }
185
186             @Override
187             public GeneratedTransferObject build() {
188                 return typePropertyNames == null || typePropertyNames.isEmpty()
189                     ? super.build() : new UnionGTO(this, typePropertyNames);
190             }
191
192             private static final class UnionGTO extends GTO implements RuntimeGeneratedUnion {
193                 private final @NonNull List<String> typePropertyNames;
194
195                 UnionGTO(final RuntimeGeneratedTOBuilder builder, final List<String> typePropertyNames) {
196                     super(builder);
197                     this.typePropertyNames = requireNonNull(typePropertyNames);
198                 }
199
200                 @Override
201                 public List<String> typePropertyNames() {
202                     return typePropertyNames;
203                 }
204             }
205         }
206     }
207
208     TypeBuilderFactory() {
209         // Hidden on purpose
210     }
211
212     public static @NonNull TypeBuilderFactory codegen() {
213         return Codegen.INSTANCE;
214     }
215
216     public static @NonNull TypeBuilderFactory runtime() {
217         return Runtime.INSTANCE;
218     }
219
220     abstract @NonNull AbstractEnumerationBuilder newEnumerationBuilder(JavaTypeName identifier);
221
222     abstract @NonNull GeneratedTOBuilder newGeneratedTOBuilder(JavaTypeName identifier);
223
224     abstract @NonNull GeneratedTypeBuilder newGeneratedTypeBuilder(JavaTypeName identifier);
225
226     abstract @NonNull GeneratedUnionBuilder newGeneratedUnionBuilder(JavaTypeName identifier);
227
228     abstract void addCodegenInformation(EffectiveStatement<?, ?> stmt, GeneratedTypeBuilderBase<?> builder);
229
230     abstract void addCodegenInformation(ModuleEffectiveStatement stmt, GeneratedTypeBuilderBase<?> builder);
231
232     abstract void addCodegenInformation(DocumentedNode node, GeneratedTypeBuilderBase<?> builder);
233
234     abstract void addCodegenInformation(ModuleGenerator module, EffectiveStatement<?, ?> stmt,
235         GeneratedTypeBuilderBase<?> builder);
236 }