X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-generator-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fgenerator%2Fimpl%2FModuleContext.java;h=617189b9ce9c8af3b694ad5add045c5a57050bd5;hb=9ab6fa0732bb152e682249dffe7cf940f79e66c5;hp=02ca4c493432b997dbdae0c666409b2f29b7eb54;hpb=d1081ff6798c7678eaaa5decb1a389a884389f51;p=mdsal.git diff --git a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/ModuleContext.java b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/ModuleContext.java index 02ca4c4934..617189b9ce 100644 --- a/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/ModuleContext.java +++ b/binding/mdsal-binding-generator-impl/src/main/java/org/opendaylight/mdsal/binding/generator/impl/ModuleContext.java @@ -7,6 +7,7 @@ */ package org.opendaylight.mdsal.binding.generator.impl; +import static com.google.common.base.Preconditions.checkState; import static java.util.Objects.requireNonNull; import com.google.common.collect.BiMap; @@ -22,23 +23,38 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import javax.annotation.concurrent.NotThreadSafe; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.opendaylight.mdsal.binding.model.api.GeneratedType; +import org.opendaylight.mdsal.binding.model.api.JavaTypeName; import org.opendaylight.mdsal.binding.model.api.Type; import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTOBuilder; import org.opendaylight.mdsal.binding.model.api.type.builder.GeneratedTypeBuilder; import org.opendaylight.mdsal.binding.spec.naming.BindingMapping; +import org.opendaylight.yangtools.concepts.Mutable; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.model.api.AugmentationSchemaNode; import org.opendaylight.yangtools.yang.model.api.CaseSchemaNode; +import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode; import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; import org.opendaylight.yangtools.yang.model.api.DocumentedNode.WithStatus; +import org.opendaylight.yangtools.yang.model.api.GroupingDefinition; +import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode; import org.opendaylight.yangtools.yang.model.api.Module; +import org.opendaylight.yangtools.yang.model.api.NotificationDefinition; +import org.opendaylight.yangtools.yang.model.api.OperationDefinition; import org.opendaylight.yangtools.yang.model.api.SchemaNode; import org.opendaylight.yangtools.yang.model.api.SchemaPath; import org.opendaylight.yangtools.yang.model.api.TypeDefinition; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utility class for building up Binding mapping information. This class is NOT thread-safe. + */ +public final class ModuleContext implements Mutable { + private static final Logger LOG = LoggerFactory.getLogger(ModuleContext.class); -@NotThreadSafe -public final class ModuleContext { private final BiMap typeToAugmentation = HashBiMap.create(); private final Map childNodes = new HashMap<>(); private final Map groupings = new HashMap<>(); @@ -48,12 +64,16 @@ public final class ModuleContext { private final List augmentations = new ArrayList<>(); private final Multimap choiceToCases = HashMultimap.create(); private final Set topLevelNodes = new HashSet<>(); + private final Map aliases = new HashMap<>(); private final Map typeToSchema = new HashMap<>(); private final List genTOs = new ArrayList<>(); private final Map innerTypes = new HashMap<>(); private final Map typedefs = new HashMap<>(); private final Module module; + // Conflict mapping + private final Map nameMapping = new HashMap<>(); + private GeneratedTypeBuilder moduleNode; private String modulePackageName; @@ -117,53 +137,84 @@ public final class ModuleContext { return moduleNode; } - public GeneratedTypeBuilder getChildNode(final SchemaPath p) { - return childNodes.get(p); + public GeneratedTypeBuilder getChildNode(final SchemaPath path) { + return childNodes.get(path); + } + + public GeneratedTypeBuilder getGrouping(final SchemaPath path) { + return groupings.get(path); + } + + public GeneratedTypeBuilder getCase(final SchemaPath path) { + return cases.get(path); } - public GeneratedTypeBuilder getGrouping(final SchemaPath p) { - return groupings.get(p); + public void addModuleNode(final GeneratedTypeBuilder newModuleNode) { + this.moduleNode = newModuleNode; } - public GeneratedTypeBuilder getCase(final SchemaPath p) { - return cases.get(p); + public void addGeneratedTOBuilder(final GeneratedTOBuilder builder) { + genTOs.add(builder); } - public void addModuleNode(final GeneratedTypeBuilder moduleNode) { - this.moduleNode = moduleNode; + @NonNull GeneratedType addAliasType(final ModuleContext sourceContext, final ContainerSchemaNode source, + final ContainerSchemaNode alias) { + final GeneratedTypeBuilder builder = sourceContext.getChildNode(source.getPath()); + checkState(builder != null, "Could not find builder for %s", source); + + final JavaTypeName id = builder.getIdentifier(); + final SchemaPath path = alias.getPath(); + final JavaTypeName prev = aliases.putIfAbsent(path, id); + checkState(prev == null, "Type aliasing conflict on %s: %s vs %s", path, prev, id); + + return builder.build(); } - public void addGeneratedTOBuilder(final GeneratedTOBuilder b) { - genTOs.add(b); + @Nullable JavaTypeName getAlias(final SchemaPath path) { + return aliases.get(path); } - public void addChildNodeType(final SchemaNode p, final GeneratedTypeBuilder b) { - childNodes.put(p.getPath(), b); - typeToSchema.put(b,p); + public void addChildNodeType(final SchemaNode def, final GeneratedTypeBuilder builder) { + checkNamingConflict(def, builder.getIdentifier()); + childNodes.put(def.getPath(), builder); + typeToSchema.put(builder, def); } - public void addGroupingType(final SchemaPath p, final GeneratedTypeBuilder b) { - groupings.put(p, b); + public void addGroupingType(final GroupingDefinition def, final GeneratedTypeBuilder builder) { + checkNamingConflict(def, builder.getIdentifier()); + groupings.put(def.getPath(), builder); } - public void addTypedefType(final SchemaPath p, final Type t) { - typedefs.put(p, t); + public void addTypedefType(final TypeDefinition def, final Type type) { + final JavaTypeName name = type.getIdentifier(); + final SchemaNode existingDef = nameMapping.putIfAbsent(name, def); + if (existingDef != null) { + if (!(existingDef instanceof TypeDefinition)) { + throw resolveNamingConfict(existingDef, def, name); + } + + // This seems to be fine + LOG.debug("GeneratedType conflict between {} and {} on {}", def, existingDef, name); + } + + typedefs.put(def.getPath(), type); } - public void addCaseType(final SchemaPath p, final GeneratedTypeBuilder b) { - cases.put(p, b); + public void addCaseType(final SchemaPath path, final GeneratedTypeBuilder builder) { + cases.put(path, builder); } - public void addIdentityType(final QName name,final GeneratedTypeBuilder b) { - identities.put(name, b); + public void addIdentityType(final IdentitySchemaNode def, final GeneratedTypeBuilder builder) { + checkNamingConflict(def, builder.getIdentifier()); + identities.put(def.getQName(), builder); } - public void addTopLevelNodeType(final GeneratedTypeBuilder b) { - topLevelNodes.add(b); + public void addTopLevelNodeType(final GeneratedTypeBuilder builder) { + topLevelNodes.add(builder); } - public void addAugmentType(final GeneratedTypeBuilder b) { - augmentations.add(b); + public void addAugmentType(final GeneratedTypeBuilder builder) { + augmentations.add(builder); } public Map getTypedefs() { @@ -214,9 +265,8 @@ public final class ModuleContext { } /** - * Returns mapping of type to its schema. - * - * Valid values are only instances of {@link DataSchemaNode} or {@link AugmentationSchemaNode} + * Returns mapping of type to its schema. Valid values are only instances of {@link DataSchemaNode} + * or {@link AugmentationSchemaNode}. * * @return Mapping from type to corresponding schema */ @@ -230,9 +280,6 @@ public final class ModuleContext { /** * Adds mapping between schema path and an inner type. - * - * @param path - * @param type */ void addInnerTypedefType(final SchemaPath path, final Type type) { innerTypes.put(path, type); @@ -242,4 +289,52 @@ public final class ModuleContext { return innerTypes.get(path); } + private void checkNamingConflict(final SchemaNode def, final JavaTypeName name) { + final SchemaNode existingDef = nameMapping.putIfAbsent(name, def); + if (existingDef != null) { + if (def.equals(existingDef)) { + if (LOG.isDebugEnabled()) { + // TODO: this should not really be happening + LOG.debug("Duplicate definition on {} as {}", name, def, new Throwable()); + } + } else { + throw resolveNamingConfict(existingDef, def, name); + } + } + } + + private static IllegalStateException resolveNamingConfict(final SchemaNode existing, final SchemaNode incoming, + final JavaTypeName name) { + if (existing instanceof IdentitySchemaNode) { + if (incoming instanceof GroupingDefinition || incoming instanceof TypeDefinition + || incoming instanceof DataSchemaNode || incoming instanceof NotificationDefinition + || incoming instanceof OperationDefinition) { + return new RenameMappingException(name, existing); + } + } else if (existing instanceof GroupingDefinition) { + if (incoming instanceof IdentitySchemaNode) { + return new RenameMappingException(name, incoming); + } + if (incoming instanceof TypeDefinition || incoming instanceof DataSchemaNode + || incoming instanceof NotificationDefinition || incoming instanceof OperationDefinition) { + return new RenameMappingException(name, existing); + } + } else if (existing instanceof TypeDefinition) { + if (incoming instanceof GroupingDefinition || incoming instanceof IdentitySchemaNode) { + return new RenameMappingException(name, incoming); + } + if (incoming instanceof DataSchemaNode || incoming instanceof NotificationDefinition + || incoming instanceof OperationDefinition) { + return new RenameMappingException(name, existing); + } + } else { + if (incoming instanceof GroupingDefinition || incoming instanceof IdentitySchemaNode + || incoming instanceof TypeDefinition) { + return new RenameMappingException(name, incoming); + } + } + + return new IllegalStateException(String.format("Unhandled GeneratedType conflict between %s and %s on %s", + incoming, existing, name)); + } }