} else if (stmt instanceof TypedefEffectiveStatement) {
tmp.add(new TypedefGenerator((TypedefEffectiveStatement) stmt, this));
} else if (stmt instanceof AugmentEffectiveStatement) {
+ // FIXME: MDSAL-695: So here we are ignoring any augment which is not in a module, while the 'uses'
+ // processing takes care of the rest. There are two problems here:
+ //
+ // 1) this could be an augment introduced through uses -- in this case we are picking
+ // confusing it with this being its declaration site, we should probably be
+ // ignoring it, but then
+ //
+ // 2) we are losing track of AugmentEffectiveStatement for which we do not generate
+ // interfaces -- and recover it at runtime through explicit walk along the
+ // corresponding AugmentationSchemaNode.getOriginalDefinition() pointer
+ //
+ // So here is where we should decide how to handle this augment, and make sure we
+ // retain information about this being an alias. That will serve as the base for keys
+ // in the augment -> original map we provide to BindingRuntimeTypes.
if (this instanceof ModuleGenerator) {
tmpAug.add(new ModuleAugmentGenerator((AugmentEffectiveStatement) stmt, this));
}
public final ImmutableMap<AugmentationIdentifier, Type> getAvailableAugmentationTypes(
final DataNodeContainer container) {
if (container instanceof AugmentationTarget) {
- final Map<AugmentationIdentifier, Type> identifierToType = new HashMap<>();
- final BindingRuntimeTypes types = getTypes();
- for (final AugmentationSchemaNode augment : ((AugmentationTarget) container).getAvailableAugmentations()) {
- // Augmentation must have child nodes if is to be used with Binding classes
- AugmentationSchemaNode augOrig = augment;
- while (augOrig.getOriginalDefinition().isPresent()) {
- augOrig = augOrig.getOriginalDefinition().get();
- }
-
- if (!augment.getChildNodes().isEmpty()) {
- final Optional<Type> augType = types.findType(augOrig);
- if (augType.isPresent()) {
- identifierToType.put(getAugmentationIdentifier(augment), augType.get());
- }
+ final var augmentations = ((AugmentationTarget) container).getAvailableAugmentations();
+ if (!augmentations.isEmpty()) {
+ final var identifierToType = new HashMap<AugmentationIdentifier, Type>();
+ final var types = getTypes();
+ for (var augment : augmentations) {
+ types.findOriginalAugmentationType(augment).ifPresent(augType -> {
+ identifierToType.put(getAugmentationIdentifier(augment), augType);
+ });
}
+ return ImmutableMap.copyOf(identifierToType);
}
- return ImmutableMap.copyOf(identifierToType);
}
-
return ImmutableMap.of();
}
@NonNull Class<?> getClassForSchema(SchemaNode childSchema);
+ /**
+ * Return the mapping of a particular {@link DataNodeContainer}'s available augmentations. This method deals with
+ * resolving {@code uses foo { augment bar { ... } } } scenarios by returning the augmentation created for
+ * {@code grouping foo}'s Binding representation.
+ *
+ * @param container {@link DataNodeContainer} to examine
+ * @return a mapping from local {@link AugmentationIdentifier}s to their corresponding Binding augmentations
+ */
@NonNull ImmutableMap<AugmentationIdentifier, Type> getAvailableAugmentationTypes(DataNodeContainer container);
@NonNull Class<?> getIdentityClass(QName input);
return Optional.ofNullable(schemaToType.get(schema));
}
+ public Optional<Type> findOriginalAugmentationType(final AugmentationSchemaNode augment) {
+ // If the augment statement does not contain any child nodes, we did not generate an augmentation, as it would
+ // be plain littering.
+ // FIXME: MDSAL-695: this check is rather costly (involves filtering), can we just rely on the not being found
+ // in the end? all we are saving is essentially two map lookups after all...
+ if (augment.getChildNodes().isEmpty()) {
+ return Optional.empty();
+ }
+
+ // FIXME: MDSAL-695: We should have enough information from mdsal-binding-generator to receive a (sparse) Map
+ // for current -> original lookup. When combined with schemaToType, this amounts to the
+ // inverse view of what 'typeToSchema' holds
+ AugmentationSchemaNode current = augment;
+ while (true) {
+ // If this augmentation has been added through 'uses foo { augment bar { ... } }', we need to invert that
+ // walk and arrive at the original declaration site, as that is where we generated 'grouping foo's
+ // augmentation. That site may have a different module, hence the augment namespace may be different.
+ final Optional<AugmentationSchemaNode> original = current.getOriginalDefinition();
+ if (original.isEmpty()) {
+ return findType(current);
+ }
+ current = original.orElseThrow();
+ }
+ }
+
public Multimap<Type, Type> getChoiceToCases() {
return choiceToCases;
}