/**
 * Copyright (c) 2020-present, Goldman Sachs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { computed, makeObservable, observable, override } from 'mobx';
import { ApiTokenAuthenticationStrategy, DefaultH2AuthenticationStrategy, DelegatedKerberosAuthenticationStrategy, GCPApplicationDefaultCredentialsAuthenticationStrategy, OAuthAuthenticationStrategy, SnowflakePublicAuthenticationStrategy, UsernamePasswordAuthenticationStrategy, GCPWorkloadIdentityFederationAuthenticationStrategy, MiddleTierUsernamePasswordAuthenticationStrategy, TrinoDelegatedKerberosAuthenticationStrategy, } from '../../../graph/metamodel/pure/packageableElements/store/relational/connection/AuthenticationStrategy.js';
import { BigQueryDatasourceSpecification, DatabricksDatasourceSpecification, EmbeddedH2DatasourceSpecification, LocalH2DatasourceSpecification, RedshiftDatasourceSpecification, SnowflakeDatasourceSpecification, StaticDatasourceSpecification, SpannerDatasourceSpecification, TrinoDatasourceSpecification, } from '../../../graph/metamodel/pure/packageableElements/store/relational/connection/DatasourceSpecification.js';
import { SchemaNameMapper, TableNameMapper, } from '../../../graph/metamodel/pure/packageableElements/store/relational/connection/postprocessor/Mapper.js';
import { MapperPostProcessor } from '../../../graph/metamodel/pure/packageableElements/store/relational/connection/postprocessor/MapperPostProcessor.js';
import { Column } from '../../../graph/metamodel/pure/packageableElements/store/relational/model/Column.js';
import { TemporalMilestoning, } from '../../../graph/metamodel/pure/packageableElements/store/relational/model/milestoning/Milestoning.js';
import { Binary, BigInt, Bit, Char, Decimal, Double, Float, Integer, Json, Numeric, Other, Real, SemiStructured, SmallInt, Timestamp, TinyInt, VarBinary, VarChar, } from '../../../graph/metamodel/pure/packageableElements/store/relational/model/RelationalDataType.js';
import { RelationalOperationElement, DynaFunction, TableAlias, TableAliasColumn, Literal, LiteralList, RelationalOperationElementWithJoin, } from '../../../graph/metamodel/pure/packageableElements/store/relational/model/RelationalOperationElement.js';
import { TableReference, } from '../../../graph/metamodel/pure/packageableElements/store/relational/model/TableReference.js';
import { ViewReference } from '../../../graph/metamodel/pure/packageableElements/store/relational/model/ViewReference.js';
import { observe_Abstract_PackageableElement, observe_PackageableElementReference, skipObserved, skipObservedWithContext, } from './CoreObserverHelper.js';
import { observe_BindingTransformer } from './DSL_ExternalFormat_ObserverHelper.js';
import { observe_Abstract_Connection, observe_Abstract_InstanceSetImplementation, observe_Abstract_PropertyMapping, observe_PropertyMapping, observe_SetImplementation, } from './DSL_Mapping_ObserverHelper.js';
import { INTERNAL__UnknownPostProcessor } from '../../../graph/metamodel/pure/packageableElements/store/relational/connection/postprocessor/INTERNAL__UnknownPostProcessor.js';
import { INTERNAL__UnknownDatasourceSpecification } from '../../../graph/metamodel/pure/packageableElements/store/relational/connection/INTERNAL__UnknownDatasourceSpecification.js';
import { INTERNAL__UnknownAuthenticationStrategy } from '../../../graph/metamodel/pure/packageableElements/store/relational/connection/INTERNAL__UnknownAuthenticationStrategy.js';
import { GenerationFeaturesConfig, } from '../../../graph/metamodel/pure/packageableElements/store/relational/connection/RelationalQueryGenerationConfig.js';
// ------------------------------------- Operation -------------------------------------
export const observe_RelationalDataType = skipObserved((metamodel) => {
    if (metamodel instanceof BigInt ||
        metamodel instanceof SmallInt ||
        metamodel instanceof TinyInt ||
        metamodel instanceof Integer ||
        metamodel instanceof Float ||
        metamodel instanceof Double ||
        metamodel instanceof Timestamp ||
        metamodel instanceof Date ||
        metamodel instanceof Other ||
        metamodel instanceof Bit ||
        metamodel instanceof Real ||
        metamodel instanceof SemiStructured ||
        metamodel instanceof Json) {
        return makeObservable(metamodel, {
            hashCode: computed,
        });
    }
    else if (metamodel instanceof VarChar ||
        metamodel instanceof Char ||
        metamodel instanceof VarBinary ||
        metamodel instanceof Binary) {
        return makeObservable(metamodel, {
            size: observable,
            hashCode: computed,
        });
    }
    else if (metamodel instanceof Decimal || metamodel instanceof Numeric) {
        return makeObservable(metamodel, {
            precision: observable,
            scale: observable,
            hashCode: computed,
        });
    }
    return metamodel;
});
export const observe_Column = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        name: observable,
        type: observable,
        nullable: observable,
        hashCode: computed,
    });
    observe_RelationalDataType(metamodel.type);
    return metamodel;
});
export const observe_TableReference = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        value: observable,
        pointerHashCode: computed,
        selfJoinPointerHashCode: computed,
    });
    observe_PackageableElementReference(metamodel.ownerReference);
    return metamodel;
});
export const observe_ViewReference = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        value: observable,
        pointerHashCode: computed,
        selfJoinPointerHashCode: computed,
    });
    observe_PackageableElementReference(metamodel.ownerReference);
    return metamodel;
});
const observe_NamedRelationalReference = (metamodel) => {
    if (metamodel instanceof ViewReference) {
        return observe_ViewReference(metamodel);
    }
    else if (metamodel instanceof TableReference) {
        return observe_TableReference(metamodel);
    }
    return metamodel;
};
export const observe_TableAlias = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        relation: observable,
        name: observable,
        database: observable,
        isSelfJoinTarget: observable,
    });
    observe_NamedRelationalReference(metamodel.relation);
    // TODO?: database?: Database | undefined;
    return metamodel;
});
export const observe_DynaFunction = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        name: observable,
        parameters: observable,
        hashCode: computed,
    });
    metamodel.parameters.forEach(observe_RelationalOperationElement);
    return metamodel;
});
export const observe_ColumnReference = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        value: observable,
    });
    observe_PackageableElementReference(metamodel.ownerReference);
    return metamodel;
});
export const observe_TableAliasColumn = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        alias: observable,
        column: observable,
        columnName: observable,
        hashCode: computed,
    });
    observe_TableAlias(metamodel.alias);
    observe_ColumnReference(metamodel.column);
    return metamodel;
});
export const observe_JoinReference = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        value: observable,
    });
    observe_PackageableElementReference(metamodel.ownerReference);
    return metamodel;
});
export const observe_JoinTreeNode = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        alias: observable,
        children: observable,
        joinType: observable,
        hashCode: computed,
    });
    if (metamodel.alias) {
        observe_TableAlias(metamodel.alias);
    }
    metamodel.children.forEach(observe_JoinTreeNode);
    observe_JoinReference(metamodel.join);
    return metamodel;
});
export const observe_RelationalOperationElementWithJoin = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        relationalOperationElement: observable,
        joinTreeNode: observable,
        hashCode: computed,
    });
    if (metamodel.relationalOperationElement) {
        observe_RelationalOperationElement(metamodel.relationalOperationElement);
    }
    if (metamodel.joinTreeNode) {
        observe_JoinTreeNode(metamodel.joinTreeNode);
    }
    return metamodel;
});
export const observe_Literal = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        value: observable,
        hashCode: computed,
    });
    if (metamodel.value instanceof RelationalOperationElement) {
        observe_RelationalOperationElement(metamodel.value);
    }
    return metamodel;
});
export const observe_LiteralList = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        values: observable,
        hashCode: computed,
    });
    metamodel.values.forEach(observe_Literal);
    return metamodel;
});
export function observe_RelationalOperationElement(metamodel) {
    if (metamodel instanceof DynaFunction) {
        return observe_DynaFunction(metamodel);
    }
    else if (metamodel instanceof TableAlias) {
        return observe_TableAlias(metamodel);
    }
    else if (metamodel instanceof TableAliasColumn) {
        return observe_TableAliasColumn(metamodel);
    }
    else if (metamodel instanceof Column) {
        return observe_Column(metamodel);
    }
    else if (metamodel instanceof Literal) {
        return observe_Literal(metamodel);
    }
    else if (metamodel instanceof LiteralList) {
        return observe_LiteralList(metamodel);
    }
    else if (metamodel instanceof RelationalOperationElementWithJoin) {
        return observe_RelationalOperationElementWithJoin(metamodel);
    }
    return metamodel;
}
// ------------------------------------- Milestoning -------------------------------------
export const observe_TemporalMilstoning = skipObserved((metamodel) => 
// TODO
metamodel);
const observe_Milestoning = skipObservedWithContext((metamodel, context) => {
    if (metamodel instanceof TemporalMilestoning) {
        return observe_TemporalMilstoning(metamodel);
    }
    const extraMilestoningObservers = context.plugins.flatMap((plugin) => plugin.getExtraMilestoningObservers?.() ?? []);
    for (const observer of extraMilestoningObservers) {
        const observedMiletoning = observer(metamodel, context);
        if (observedMiletoning) {
            return observedMiletoning;
        }
    }
    return metamodel;
});
// ------------------------------------- Store -------------------------------------
export const observe_ColumnMapping = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        columnName: observable,
        relationalOperationElement: observable,
        hashCode: computed,
    });
    observe_RelationalOperationElement(metamodel.relationalOperationElement);
    return metamodel;
});
export const observe_FilterReference = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        value: observable,
    });
    observe_PackageableElementReference(metamodel.ownerReference);
    return metamodel;
});
export const observe_FilterMapping = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        joinTreeNode: observable,
        database: observable,
        filterName: observable,
        hashCode: computed,
    });
    if (metamodel.joinTreeNode) {
        observe_JoinTreeNode(metamodel.joinTreeNode);
    }
    observe_FilterReference(metamodel.filter);
    return metamodel;
});
export const observe_GroupByMapping = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        columns: observable,
    });
    metamodel.columns.forEach(observe_RelationalOperationElement);
    return metamodel;
});
const observe_Abstract_NamedRelation = (metamodel) => {
    makeObservable(metamodel, {
        columns: observable,
        name: observable,
    });
};
export const observe_Table = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_NamedRelation(metamodel);
    makeObservable(metamodel, {
        primaryKey: observable,
        hashCode: computed,
    });
    metamodel.primaryKey.forEach(observe_Column);
    metamodel.milestoning.forEach((m) => observe_Milestoning(m, context));
    return metamodel;
});
export const observe_View = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_NamedRelation(metamodel);
    makeObservable(metamodel, {
        primaryKey: observable,
        columnMappings: observable,
        filter: observable,
        distinct: observable,
        groupBy: observable,
        hashCode: computed,
    });
    metamodel.primaryKey.forEach(observe_Column);
    metamodel.columnMappings.forEach(observe_ColumnMapping);
    if (metamodel.filter) {
        observe_FilterMapping(metamodel.filter);
    }
    if (metamodel.groupBy) {
        observe_GroupByMapping(metamodel.groupBy);
    }
    return metamodel;
});
export const observe_Schema = skipObservedWithContext((metamodel, context) => {
    makeObservable(metamodel, {
        name: observable,
        tables: observable,
        views: observable,
        hashCode: computed,
    });
    metamodel.tables.forEach((table) => observe_Table(table, context));
    metamodel.views.forEach((view) => observe_View(view, context));
    return metamodel;
});
export const observe_Filter = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        name: observable,
        operation: observable,
        hashCode: computed,
    });
    observe_RelationalOperationElement(metamodel.operation);
    return metamodel;
});
export const observe_Join = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        name: observable,
        target: observable,
        aliases: observable,
        operation: observable,
        hashCode: computed,
    });
    if (metamodel.target) {
        observe_TableAlias(metamodel.target);
    }
    observe_RelationalOperationElement(metamodel.operation);
    // TODO?: aliases: Pair<TableAlias, TableAlias>[] = [];
    return metamodel;
});
export const observe_Database = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_PackageableElement(metamodel);
    makeObservable(metamodel, {
        schemas: observable,
        joins: observable,
        filters: observable,
        _elementHashCode: override,
    });
    metamodel.schemas.forEach((schema) => observe_Schema(schema, context));
    metamodel.joins.forEach(observe_Join);
    metamodel.filters.forEach(observe_Filter);
    return metamodel;
});
// ------------------------------------- Mapping -------------------------------------
export const observe_RelationalPropertyMapping = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_PropertyMapping(metamodel, context);
    makeObservable(metamodel, {
        transformer: observable,
        relationalOperation: observable.ref, // only observe the reference, the object itself is not observed
        bindingTransformer: observable,
        hashCode: computed,
    });
    // TODO transformer?: EnumerationMapping | undefined;
    if (metamodel.bindingTransformer) {
        observe_BindingTransformer(metamodel.bindingTransformer);
    }
    return metamodel;
});
export const observe_Abstract_EmbeddedRelationalInstanceSetImplementation = (metamodel, context) => {
    observe_Abstract_InstanceSetImplementation(metamodel, context);
    observe_Abstract_PropertyMapping(metamodel, context);
    makeObservable(metamodel, {
        id: observable,
        rootInstanceSetImplementation: observable,
        primaryKey: observable,
    });
    metamodel.primaryKey.forEach(observe_RelationalOperationElement);
    return metamodel;
};
export const observe_EmbeddedRelationalInstanceSetImplementation = skipObservedWithContext(observe_Abstract_EmbeddedRelationalInstanceSetImplementation);
export const observe_InlineEmbeddedRelationalInstanceSetImplementation = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_EmbeddedRelationalInstanceSetImplementation(metamodel, context);
    makeObservable(metamodel, {
        inlineSetImplementation: observable,
    });
    observe_SetImplementation(metamodel.inlineSetImplementation, context);
    return metamodel;
});
export const observe_OtherwiseEmbeddedRelationalInstanceSetImplementation = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_EmbeddedRelationalInstanceSetImplementation(metamodel, context);
    makeObservable(metamodel, {
        otherwisePropertyMapping: observable,
        hashCode: computed,
    });
    observe_PropertyMapping(metamodel.otherwisePropertyMapping, context);
    return metamodel;
});
export const observe_RelationalInstanceSetImplementation = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_InstanceSetImplementation(metamodel, context);
    makeObservable(metamodel, {
        primaryKey: observable,
    });
    metamodel.primaryKey.forEach(observe_RelationalOperationElement);
    return metamodel;
});
export const observe_RootRelationalInstanceSetImplementation = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_InstanceSetImplementation(metamodel, context);
    makeObservable(metamodel, {
        columnMappings: observable,
        filter: observable,
        distinct: observable,
        groupBy: observable,
        mainTableAlias: observable,
        superSetImplementationId: observable,
        hashCode: computed,
    });
    metamodel.columnMappings.forEach(observe_ColumnMapping);
    if (metamodel.filter) {
        observe_FilterMapping(metamodel.filter);
    }
    if (metamodel.groupBy) {
        observe_GroupByMapping(metamodel.groupBy);
    }
    if (metamodel.mainTableAlias) {
        observe_TableAlias(metamodel.mainTableAlias);
    }
    return metamodel;
});
export const observe_RelationalInputData = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        data: observable,
        inputType: observable,
        hashCode: computed,
    });
    observe_PackageableElementReference(metamodel.database);
    return metamodel;
});
// ------------------------------------- Connection -------------------------------------
export const observe_StaticDatasourceSpecification = skipObserved((metamodel) => makeObservable(metamodel, {
    host: observable,
    port: observable,
    databaseName: observable,
    hashCode: computed,
}));
export const observe_DatabricksDatasourceSpecification = skipObserved((metamodel) => makeObservable(metamodel, {
    hostname: observable,
    port: observable,
    protocol: observable,
    httpPath: observable,
    hashCode: computed,
}));
export const observe_EmbeddedH2DatasourceSpecification = skipObserved((metamodel) => makeObservable(metamodel, {
    databaseName: observable,
    directory: observable,
    autoServerMode: observable,
    hashCode: computed,
}));
export const observe_LocalH2DatasourceSpecification = skipObserved((metamodel) => makeObservable(metamodel, {
    testDataSetupCsv: observable,
    testDataSetupSqls: observable,
    hashCode: computed,
}));
export const observe_SnowflakeDatasourceSpecification = skipObserved((metamodel) => makeObservable(metamodel, {
    accountName: observable,
    region: observable,
    warehouseName: observable,
    databaseName: observable,
    cloudType: observable,
    quotedIdentifiersIgnoreCase: observable,
    enableQueryTags: observable,
    proxyHost: observable,
    proxyPort: observable,
    nonProxyHosts: observable,
    organization: observable,
    accountType: observable,
    tempTableDb: observable,
    tempTableSchema: observable,
    role: observable,
    hashCode: computed,
}));
export const observe_RedshiftDatasourceSpecification = skipObserved((metamodel) => makeObservable(metamodel, {
    databaseName: observable,
    endpointURL: observable,
    port: observable,
    region: observable,
    clusterID: observable,
    host: observable,
    hashCode: computed,
}));
export const observe_BigQueryDatasourceSpecification = skipObserved((metamodel) => makeObservable(metamodel, {
    projectId: observable,
    defaultDataset: observable,
    proxyHost: observable,
    proxyPort: observable,
    hashCode: computed,
}));
export const observe_SpannerDatasourceSpecification = skipObserved((metamodel) => makeObservable(metamodel, {
    projectId: observable,
    instanceId: observable,
    databaseId: observable,
    proxyHost: observable,
    proxyPort: observable,
    hashCode: computed,
}));
export const observe_TrinoSslSpecification = skipObserved((metamodel) => makeObservable(metamodel, {
    ssl: observable,
    trustStorePathVaultReference: observable,
    trustStorePasswordVaultReference: observable,
    hashCode: computed,
}));
export const observe_TrinoDatasourceSpecification = skipObserved((metamodel) => {
    makeObservable(metamodel, {
        host: observable,
        port: observable,
        catalog: observable,
        schema: observable,
        clientTags: observable,
        hashCode: computed,
    });
    observe_TrinoSslSpecification(metamodel.sslSpecification);
    return metamodel;
});
const observe_INTERNAL__UnknownDatasourceSpecification = skipObserved((metamodel) => makeObservable(metamodel, {
    content: observable.ref,
    hashCode: computed,
}));
export const observe_DatasourceSpecification = (metamodel, context) => {
    if (metamodel instanceof INTERNAL__UnknownDatasourceSpecification) {
        return observe_INTERNAL__UnknownDatasourceSpecification(metamodel);
    }
    else if (metamodel instanceof StaticDatasourceSpecification) {
        return observe_StaticDatasourceSpecification(metamodel);
    }
    else if (metamodel instanceof DatabricksDatasourceSpecification) {
        return observe_DatabricksDatasourceSpecification(metamodel);
    }
    else if (metamodel instanceof EmbeddedH2DatasourceSpecification) {
        return observe_EmbeddedH2DatasourceSpecification(metamodel);
    }
    else if (metamodel instanceof LocalH2DatasourceSpecification) {
        return observe_LocalH2DatasourceSpecification(metamodel);
    }
    else if (metamodel instanceof SnowflakeDatasourceSpecification) {
        return observe_SnowflakeDatasourceSpecification(metamodel);
    }
    else if (metamodel instanceof RedshiftDatasourceSpecification) {
        return observe_RedshiftDatasourceSpecification(metamodel);
    }
    else if (metamodel instanceof BigQueryDatasourceSpecification) {
        return observe_BigQueryDatasourceSpecification(metamodel);
    }
    else if (metamodel instanceof SpannerDatasourceSpecification) {
        return observe_SpannerDatasourceSpecification(metamodel);
    }
    else if (metamodel instanceof TrinoDatasourceSpecification) {
        return observe_TrinoDatasourceSpecification(metamodel);
    }
    const extraObservers = context.plugins.flatMap((plugin) => plugin.getExtraDatasourceSpecificationObservers?.() ?? []);
    for (const observer of extraObservers) {
        const observedDatasourceSpec = observer(metamodel, context);
        if (observedDatasourceSpec) {
            return observedDatasourceSpec;
        }
    }
    return metamodel;
};
export const observe_DelegatedKerberosAuthenticationStrategy = skipObserved((metamodel) => makeObservable(metamodel, {
    serverPrincipal: observable,
    hashCode: computed,
}));
export const observe_DefaultH2AuthenticationStrategy = skipObserved((metamodel) => makeObservable(metamodel, {
    hashCode: computed,
}));
export const observe_ApiTokenAuthenticationStrategy = skipObserved((metamodel) => makeObservable(metamodel, {
    apiToken: observable,
    hashCode: computed,
}));
export const observe_OAuthAuthenticationStrategy = skipObserved((metamodel) => makeObservable(metamodel, {
    oauthKey: observable,
    scopeName: observable,
    hashCode: computed,
}));
export const observe_SnowflakePublicAuthenticationStrategy = skipObserved((metamodel) => makeObservable(metamodel, {
    privateKeyVaultReference: observable,
    passPhraseVaultReference: observable,
    publicUserName: observable,
    hashCode: computed,
}));
export const observe_GCPApplicationDefaultCredentialsAuthenticationStrategy = skipObserved((metamodel) => makeObservable(metamodel, {
    hashCode: computed,
}));
export const observe_UsernamePasswordAuthenticationStrategy = skipObserved((metamodel) => makeObservable(metamodel, {
    hashCode: computed,
    userNameVaultReference: observable,
    passwordVaultReference: observable,
    baseVaultReference: observable,
}));
export const observe_GCPWorkloadIdentityFederationAuthenticationStrategy = skipObserved((metamodel) => makeObservable(metamodel, {
    hashCode: computed,
    serviceAccountEmail: observable,
    additionalGcpScopes: observable,
}));
export const observe_MiddleTierUsernamePasswordAuthenticationStrategy = skipObserved((metamodel) => makeObservable(metamodel, {
    hashCode: computed,
    vaultReference: observable,
}));
export const observe_TrinoDelegatedKerberosAuthenticationStrategy = skipObserved((metamodel) => makeObservable(metamodel, {
    hashCode: computed,
    kerberosRemoteServiceName: observable,
    kerberosUseCanonicalHostname: observable,
}));
const observe_INTERNAL__UnknownAuthenticationStrategy = skipObserved((metamodel) => makeObservable(metamodel, {
    content: observable.ref,
    hashCode: computed,
}));
export const observe_AuthenticationStrategy = (metamodel, context) => {
    if (metamodel instanceof INTERNAL__UnknownAuthenticationStrategy) {
        return observe_INTERNAL__UnknownAuthenticationStrategy(metamodel);
    }
    else if (metamodel instanceof DelegatedKerberosAuthenticationStrategy) {
        return observe_DelegatedKerberosAuthenticationStrategy(metamodel);
    }
    else if (metamodel instanceof DefaultH2AuthenticationStrategy) {
        return observe_DefaultH2AuthenticationStrategy(metamodel);
    }
    else if (metamodel instanceof ApiTokenAuthenticationStrategy) {
        return observe_ApiTokenAuthenticationStrategy(metamodel);
    }
    else if (metamodel instanceof OAuthAuthenticationStrategy) {
        return observe_OAuthAuthenticationStrategy(metamodel);
    }
    else if (metamodel instanceof SnowflakePublicAuthenticationStrategy) {
        return observe_SnowflakePublicAuthenticationStrategy(metamodel);
    }
    else if (metamodel instanceof GCPApplicationDefaultCredentialsAuthenticationStrategy) {
        return observe_GCPApplicationDefaultCredentialsAuthenticationStrategy(metamodel);
    }
    else if (metamodel instanceof UsernamePasswordAuthenticationStrategy) {
        return observe_UsernamePasswordAuthenticationStrategy(metamodel);
    }
    else if (metamodel instanceof GCPWorkloadIdentityFederationAuthenticationStrategy) {
        return observe_GCPWorkloadIdentityFederationAuthenticationStrategy(metamodel);
    }
    else if (metamodel instanceof MiddleTierUsernamePasswordAuthenticationStrategy) {
        return observe_MiddleTierUsernamePasswordAuthenticationStrategy(metamodel);
    }
    else if (metamodel instanceof TrinoDelegatedKerberosAuthenticationStrategy) {
        return observe_TrinoDelegatedKerberosAuthenticationStrategy(metamodel);
    }
    const extraObservers = context.plugins.flatMap((plugin) => plugin.getExtraAuthenticationStrategyObservers?.() ?? []);
    for (const observer of extraObservers) {
        const observedAuthStrategy = observer(metamodel, context);
        if (observedAuthStrategy) {
            return observedAuthStrategy;
        }
    }
    return metamodel;
};
const observe_Abstract_Mapper = (metamodel) => {
    makeObservable(metamodel, {
        from: observable,
        to: observable,
        hashCode: computed,
    });
};
export const observe_SchemaNameMapper = skipObserved((metamodel) => {
    observe_Abstract_Mapper(metamodel);
    return metamodel;
});
export const observe_TableNameMapper = skipObserved((metamodel) => {
    observe_Abstract_Mapper(metamodel);
    makeObservable(metamodel, {
        schema: observable,
    });
    observe_SchemaNameMapper(metamodel.schema);
    return metamodel;
});
export const observe_Mapper = (metamodel) => {
    if (metamodel instanceof SchemaNameMapper) {
        return observe_SchemaNameMapper(metamodel);
    }
    else if (metamodel instanceof TableNameMapper) {
        return observe_TableNameMapper(metamodel);
    }
    return metamodel;
};
export const observe_Abstract_PostProcessor = (metamodel) => {
    makeObservable(metamodel, {
        hashCode: computed,
    });
};
export const observe_MapperPostProcessor = (metamodel) => {
    observe_Abstract_PostProcessor(metamodel);
    makeObservable(metamodel, {
        mappers: observable,
    });
    metamodel.mappers.forEach((mapper) => {
        observe_Mapper(mapper);
    });
    return metamodel;
};
const observe_INTERNAL__UnknownPostProcessor = (metamodel) => {
    observe_Abstract_PostProcessor(metamodel);
    makeObservable(metamodel, {
        content: observable.ref,
    });
    return metamodel;
};
export const observe_PostProcessor = (metamodel, context) => {
    if (metamodel instanceof INTERNAL__UnknownPostProcessor) {
        return observe_INTERNAL__UnknownPostProcessor(metamodel);
    }
    else if (metamodel instanceof MapperPostProcessor) {
        return observe_MapperPostProcessor(metamodel);
    }
    const extraObservers = context.plugins.flatMap((plugin) => plugin.getExtraPostProcessorObservers?.() ?? []);
    for (const observer of extraObservers) {
        const observedPostProcessor = observer(metamodel, context);
        if (observedPostProcessor) {
            return observedPostProcessor;
        }
    }
    return metamodel;
};
export const observe_Abstract_RelationalQueryGenerationConfig = (metamodel) => {
    makeObservable(metamodel, {
        hashCode: computed,
    });
};
export const observe_GenerationFeaturesConfig = (metamodel) => {
    observe_Abstract_RelationalQueryGenerationConfig(metamodel);
    makeObservable(metamodel, {
        enabled: observable,
        disabled: observable,
    });
    return metamodel;
};
export const observe_RelationalQueryGenerationConfig = (metamodel) => {
    if (metamodel instanceof GenerationFeaturesConfig) {
        return observe_GenerationFeaturesConfig(metamodel);
    }
    return metamodel;
};
const observe_Abstract_DatabaseConnection = (metamodel) => {
    observe_Abstract_Connection(metamodel);
    makeObservable(metamodel, {
        type: observable,
        timeZone: observable,
        quoteIdentifiers: observable,
        queryTimeOutInSeconds: observable,
        queryGenerationConfigs: observable,
    });
    metamodel.queryGenerationConfigs.forEach((config) => {
        observe_RelationalQueryGenerationConfig(config);
    });
};
export const observe_RelationalDatabaseConnection = skipObservedWithContext((metamodel, context) => {
    observe_Abstract_DatabaseConnection(metamodel);
    makeObservable(metamodel, {
        datasourceSpecification: observable,
        authenticationStrategy: observable,
        localMode: observable,
        postProcessors: observable,
        hashCode: computed,
    });
    observe_DatasourceSpecification(metamodel.datasourceSpecification, context);
    observe_AuthenticationStrategy(metamodel.authenticationStrategy, context);
    metamodel.postProcessors.forEach((postProcessor) => {
        observe_PostProcessor(postProcessor, context);
    });
    return metamodel;
});
//# sourceMappingURL=STO_Relational_ObserverHelper.js.map