-public final class BindingRuntimeTypes implements EffectiveModelContextProvider, Immutable {
- private static final Logger LOG = LoggerFactory.getLogger(BindingRuntimeTypes.class);
- private static final VarHandle TYPE_TO_IDENTIFIER;
-
- static {
- try {
- TYPE_TO_IDENTIFIER = MethodHandles.lookup().findVarHandle(BindingRuntimeTypes.class, "typeToIdentifier",
- ImmutableMap.class);
- } catch (NoSuchFieldException | IllegalAccessException e) {
- throw new ExceptionInInitializerError(e);
- }
- }
-
- private final @NonNull EffectiveModelContext schemaContext;
- private final ImmutableMap<Type, AugmentationSchemaNode> typeToAugmentation;
- private final ImmutableMap<Type, WithStatus> typeToSchema;
- private final ImmutableMultimap<Type, Type> choiceToCases;
- private final ImmutableMap<QName, Type> identities;
- // Not Immutable as we use two different implementations
- private final Map<WithStatus, Type> schemaToType;
-
- @SuppressWarnings("unused")
- // Accessed via TYPE_TO_IDENTIFIER
- private volatile ImmutableMap<Type, Absolute> typeToIdentifier = ImmutableMap.of();
-
- public BindingRuntimeTypes(final EffectiveModelContext schemaContext,
- final Map<Type, AugmentationSchemaNode> typeToAugmentation,
- final Map<Type, WithStatus> typeToSchema, final Map<WithStatus, Type> schemaToType,
- final Multimap<Type, Type> choiceToCases, final Map<QName, Type> identities) {
- this.schemaContext = requireNonNull(schemaContext);
- this.typeToAugmentation = ImmutableMap.copyOf(typeToAugmentation);
- this.typeToSchema = ImmutableMap.copyOf(typeToSchema);
- this.choiceToCases = ImmutableMultimap.copyOf(choiceToCases);
- this.identities = ImmutableMap.copyOf(identities);
-
- // Careful to use identity for SchemaNodes, but only if needed
- // FIXME: 8.0.0: YT should be switching to identity for equals(), so this should become unnecessary
- Map<WithStatus, Type> copy;
- try {
- copy = ImmutableMap.copyOf(schemaToType);
- } catch (IllegalArgumentException e) {
- LOG.debug("Equality-duplicates found in {}", schemaToType.keySet());
- copy = new IdentityHashMap<>(schemaToType);
- }
-
- this.schemaToType = copy;
- }
-
- public BindingRuntimeTypes(final EffectiveModelContext schemaContext,
- final Map<Type, AugmentationSchemaNode> typeToAugmentation,
- final BiMap<Type, WithStatus> typeToDefiningSchema,
- final Multimap<Type, Type> choiceToCases, final Map<QName, Type> identities) {
- this(schemaContext, typeToAugmentation, typeToDefiningSchema, typeToDefiningSchema.inverse(), choiceToCases,
- identities);
- }
-
- @Override
- public EffectiveModelContext getEffectiveModelContext() {
- return schemaContext;
- }
-
- public Optional<AugmentationSchemaNode> findAugmentation(final Type type) {
- return Optional.ofNullable(typeToAugmentation.get(type));
- }
-
- public Optional<Type> findIdentity(final QName qname) {
- return Optional.ofNullable(identities.get(qname));
- }
-
- public Optional<WithStatus> findSchema(final Type type) {
- return Optional.ofNullable(typeToSchema.get(type));
- }
-
- public Optional<Absolute> findSchemaNodeIdentifier(final Type type) {
- final ImmutableMap<Type, Absolute> local = (ImmutableMap<Type, Absolute>) TYPE_TO_IDENTIFIER.getAcquire(this);
- final Absolute existing = local.get(type);
- return existing != null ? Optional.of(existing) : loadSchemaNodeIdentifier(local, type);
- }
-
- public Optional<Type> findType(final WithStatus schema) {
- return Optional.ofNullable(schemaToType.get(schema));
- }
-
- public Multimap<Type, Type> getChoiceToCases() {
- return choiceToCases;
- }
-
- public Collection<Type> findCases(final Type choiceType) {
- return choiceToCases.get(choiceType);
- }