2 * Copyright (c) 2021 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.mdsal.binding.generator.impl.reactor;
10 import com.google.common.collect.Iterables;
11 import java.util.ArrayList;
12 import java.util.List;
13 import org.opendaylight.mdsal.binding.generator.impl.rt.DerivedChoiceRuntimeType;
14 import org.opendaylight.mdsal.binding.generator.impl.rt.OriginalChoiceRuntimeType;
15 import org.opendaylight.mdsal.binding.model.api.GeneratedType;
16 import org.opendaylight.mdsal.binding.model.api.Type;
17 import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilder;
18 import org.opendaylight.mdsal.binding.model.ri.BindingTypes;
19 import org.opendaylight.mdsal.binding.runtime.api.AugmentRuntimeType;
20 import org.opendaylight.mdsal.binding.runtime.api.CaseRuntimeType;
21 import org.opendaylight.mdsal.binding.runtime.api.ChoiceRuntimeType;
22 import org.opendaylight.mdsal.binding.runtime.api.RuntimeType;
23 import org.opendaylight.yangtools.yang.model.api.stmt.ChoiceEffectiveStatement;
24 import org.opendaylight.yangtools.yang.model.util.SchemaInferenceStack;
27 * Generator corresponding to a {@code choice} statement.
29 final class ChoiceGenerator extends CompositeSchemaTreeGenerator<ChoiceEffectiveStatement, ChoiceRuntimeType> {
30 ChoiceGenerator(final ChoiceEffectiveStatement statement, final AbstractCompositeGenerator<?, ?> parent) {
31 super(statement, parent);
35 void pushToInference(final SchemaInferenceStack dataTree) {
40 GeneratedType createTypeImpl(final TypeBuilderFactory builderFactory) {
41 final GeneratedTypeBuilder builder = builderFactory.newGeneratedTypeBuilder(typeName());
42 builder.addImplementsType(BindingTypes.choiceIn(Type.of(getParent().typeName())));
44 final ModuleGenerator module = currentModule();
45 module.addQNameConstant(builder, localName());
47 annotateDeprecatedIfNecessary(builder);
48 builderFactory.addCodegenInformation(module, statement(), builder);
49 // newType.setSchemaPath(schemaNode.getPath());
50 builder.setModuleName(module.statement().argument().getLocalName());
52 return builder.build();
56 ChoiceRuntimeType createRuntimeType(final GeneratedType type, final ChoiceEffectiveStatement statement,
57 final List<RuntimeType> children, final List<AugmentRuntimeType> augments) {
58 final var original = getOriginal();
59 if (!statement.equals(original.statement())) {
60 return new DerivedChoiceRuntimeType(type, statement, children, augments,
61 original.runtimeType().orElseThrow());
64 // Pick up any case statements added by augments which are not reflected in our children. This can happen when
65 // a choice is added via uses into two different places and then augmented. Since groupings are reused, validity
66 // of such use is not guarded by compile-time checks.
68 // Furthermore such case statements can be freely propagated via copy builders and thus can occur in unexpected
69 // places. If that happens, though, the two case statements can be equivalent, e.g. by having the exact same
70 // shape -- in which case Binding -> DOM translation needs to correct this mishap and play pretend the correct
72 final var augmentedCases = new ArrayList<CaseRuntimeType>();
73 for (var augment : original.augments()) {
74 for (var gen : augment) {
75 if (gen instanceof CaseGenerator) {
76 ((CaseGenerator) gen).runtimeType().ifPresent(augmented -> {
77 for (var child : Iterables.concat(children, augmentedCases)) {
78 if (child instanceof CaseRuntimeType && child.javaType().equals(augmented.javaType())) {
82 augmentedCases.add(augmented);
88 return new OriginalChoiceRuntimeType(type, statement, children, augments, augmentedCases);