import { createTypeSpecLibrary, paramMessage, SyntaxKind, isTemplateDeclaration, getNamespaceFullName, createRule, getService, isTemplateInstance, ignoreDiagnostics, isTemplateDeclarationOrInstance, getDiscriminator, getTypeName, getEncode, isErrorModel, isNeverType, getEffectiveModelType, createDiagnosticCollector, isErrorType, isType, compilerAssert, setTypeSpecNamespace, isStringType, getKnownValues, walkPropertiesInherited, isVoidType, isKey, typespecTypeToJson, isNullType, getSourceLocation, getPositionBeforeTrivia, isUnknownType, getDiscriminatedTypes, getDoc, getVisibility, defineLinter } from '@typespec/compiler';
import { getAuthentication, getHttpOperation, isStatusCode, isHeader, getHeaderFieldName, getOperationVerb, isBody, isBodyRoot, isMetadata, getResponsesForOperation, getOperationParameters, getRoutePath, isPathParam, getHeaderFieldOptions, getQueryParamOptions, createMetadataInfo, Visibility, isQueryParam } from '@typespec/http';
import { getActionDetails, getResourceLocationType, getResourceOperation, getResourceTypeKey, getSegment, isAutoRoute, isListOperation } from '@typespec/rest';

const $lib = createTypeSpecLibrary({
    name: "@azure-tools/typespec-azure-core",
    diagnostics: {
        "lro-status-union-non-string": {
            severity: "error",
            messages: {
                default: paramMessage `Union contains non-string value type ${"type"}.`,
            },
        },
        "lro-status-property-invalid-type": {
            severity: "error",
            messages: {
                default: "Property type must be a union of strings or an enum.",
            },
        },
        "lro-status-missing": {
            severity: "error",
            messages: {
                default: paramMessage `Terminal long-running operation states are missing: ${"states"}.`,
            },
        },
        "lro-status-monitor-invalid-result-property": {
            severity: "warning",
            messages: {
                default: paramMessage `StatusMonitor has more than one ${"resultType"} property marked with '${"decorator"}'.  Ensure that only one property in the model is marked with this decorator.`,
            },
        },
        "invalid-final-state": {
            severity: "warning",
            messages: {
                badValue: paramMessage `Specified final state value '${"finalStateValue"}' is not valid. It must be one of ("operation-location", "original-uri", "location", "azure-async-operation")`,
                notPut: "The final state value 'original-uri' can only be used in http PUT operations",
                noHeader: paramMessage `There was no header corresponding to the desired final-state-via value '${"finalStateValue"}'.`,
            },
        },
        "bad-record-type": {
            severity: "warning",
            messages: {
                extendUnknown: paramMessage `${"name"} should not use '${"keyword"} Record<${"typeName"}>'. Use '${"keyword"} Record<string>' instead.`,
                recordWithProperties: paramMessage `${"name"} that uses '${"keyword"} Record<${"typeName"}>' should not have properties.`,
            },
        },
        "request-parameter-invalid": {
            severity: "error",
            messages: {
                default: paramMessage `Request parameter '${"name"}' not found on request body model.`,
            },
        },
        "response-property-invalid": {
            severity: "error",
            messages: {
                default: paramMessage `Response property '${"name"}' not found on success response model.`,
            },
        },
        "operation-link-parameter-invalid": {
            severity: "error",
            messages: {
                default: "Parameters must be of template type RequestParameter<T> or ResponseProperty<T>.",
            },
        },
        "operation-link-parameter-invalid-target": {
            severity: "error",
            messages: {
                default: paramMessage `Request parameter '${"name"}' not found in linked operation.`,
            },
        },
        "invalid-resource-type": {
            severity: "error",
            messages: {
                missingKey: paramMessage `Model type '${"name"}' is not a valid resource type.  It must contain a property decorated with '@key'.`,
                missingSegment: paramMessage `Model type '${"name"}' is not a valid resource type.  It must be decorated with the '@resource' decorator.`,
            },
        },
        "polling-operation-return-model": {
            severity: "error",
            messages: {
                default: "An operation annotated with @pollingOperation must return a model or union of model.",
            },
        },
        "polling-operation-no-status-monitor": {
            severity: "warning",
            messages: {
                default: "The operation linked in  @pollingOperation must return a valid status monitor.  The status monitor model must contain a 'status' property, or a property decorated with  '@lroStatus'.  The status field must be of Enum or Union type and contain terminal status values for success and failure.",
            },
        },
        "polling-operation-no-lro-success": {
            severity: "warning",
            messages: {
                default: "The status monitor returned from the polling operation must have a status property, with a known status value the indicates successful completion. This known value may be named 'Succeeded' or marked with the '@lroSucceeded' decorator.",
            },
        },
        "polling-operation-no-lro-failure": {
            severity: "warning",
            messages: {
                default: "The status monitor returned from the polling operation must have a status property, with a known status value the indicates failure. This known value may be named 'Failed' or marked with the '@lroFailed' decorator.",
            },
        },
        "polling-operation-no-ref-or-link": {
            severity: "warning",
            messages: {
                default: "An operation decorated with '@pollingOperation' must either return a response with an 'Operation-Location' header that will contain a runtime link to the polling operation, or specify parameters and return type properties to map into the polling operation parameters.  A map into polling operation parameters can be created using the '@pollingOperationParameter' decorator",
            },
        },
        "invalid-final-operation": {
            severity: "warning",
            messages: {
                default: "The operation linked in the '@finalOperation' decorator must have a 200 response that includes a model.",
            },
        },
        "invalid-trait-property-count": {
            severity: "error",
            messages: {
                default: paramMessage `Trait type '${"modelName"}' is not a valid trait type.  It must contain exactly one property that maps to a model type.`,
            },
        },
        "invalid-trait-property-type": {
            severity: "error",
            messages: {
                default: paramMessage `Trait type '${"modelName"}' has an invalid envelope property type.  The property '${"propertyName"}' must be a model type.`,
            },
        },
        "invalid-trait-context": {
            severity: "error",
            messages: {
                default: "The trait context can only be an enum member, union of enum members, or `unknown`.",
            },
        },
        "trait-property-without-location": {
            severity: "error",
            messages: {
                default: paramMessage `Trait type '${"modelName"}' contains property '${"propertyName"}' which does not have a @traitLocation decorator.`,
            },
        },
        "expected-trait-missing": {
            severity: "error",
            messages: {
                default: paramMessage `Expected trait '${"trait"}' is missing. ${"message"}`,
            },
        },
        "client-request-id-trait-missing": {
            severity: "warning",
            messages: {
                default: paramMessage `The ClientRequestId trait is required for the ResourceOperations interface.  Include either SupportsClientRequestId or NoClientRequestId in the traits model for your interface declaration.`,
            },
        },
        "repeatable-requests-trait-missing": {
            severity: "warning",
            messages: {
                default: paramMessage `The RepeatableRequests trait is required for the ResourceOperations interface.  Include either SupportsRepeatableRequests or NoRepeatableRequests in the traits model for your interface declaration.`,
            },
        },
        "conditional-requests-trait-missing": {
            severity: "warning",
            messages: {
                default: paramMessage `The ConditionalRequests trait is required for the ResourceOperations interface.  Include either SupportsConditionalRequests or NoConditionalRequests in the traits model for your interface declaration.`,
            },
        },
        "expected-trait-diagnostic-missing": {
            severity: "error",
            messages: {
                default: `Expected trait entries must have a "diagnostic" field with a valid diagnostic code for the missing trait.`,
            },
        },
        "invalid-parameter": {
            severity: "error",
            messages: {
                default: paramMessage `Expected property '${"propertyName"}' to be a ${"kind"} parameter.`,
            },
        },
        "expected-success-response": {
            severity: "error",
            messages: {
                default: "The operation must have a success response",
            },
        },
        "lro-polling-data-missing-from-operation-response": {
            severity: "error",
            messages: {
                default: "At least one operation response must contain a field marked with `@lroStatus`",
            },
        },
        "no-object": {
            severity: "warning",
            messages: {
                default: "Don't use 'object'.\n - If you want an object with any properties, use `Record<unknown>`\n - If you meant anything, use `unknown`.",
            },
        },
        "verb-conflict": {
            severity: "warning",
            messages: {
                default: paramMessage `Operation template '${"templateName"}' requires HTTP verb '${"requiredVerb"}' but found '${"verb"}'.`,
            },
        },
        "rpc-operation-needs-route": {
            severity: "warning",
            messages: {
                default: "The operation needs a @route",
            },
        },
        "union-enums-multiple-kind": {
            severity: "warning",
            messages: {
                default: paramMessage `Couldn't resolve the kind of the union as it has multiple types: ${"kinds"}`,
            },
        },
        "union-enums-invalid-kind": {
            severity: "warning",
            messages: {
                default: paramMessage `Kind ${"kind"} prevents this union from being resolved as an enum.`,
            },
        },
        "union-enums-circular": {
            severity: "warning",
            messages: {
                default: `Union is referencing itself and cannot be resolved as an enum.`,
            },
        },
    },
});
const { reportDiagnostic: reportDiagnostic$1, createDiagnostic, createStateSymbol: createStateSymbol$1 } = $lib;

const { reportDiagnostic, createStateSymbol, stateKeys: VersioningStateKeys, } = createTypeSpecLibrary({
    name: "@typespec/versioning",
    diagnostics: {
        "versioned-dependency-tuple": {
            severity: "error",
            messages: {
                default: `Versioned dependency mapping must be a tuple [SourceVersion, TargetVersion].`,
            },
        },
        "versioned-dependency-tuple-enum-member": {
            severity: "error",
            messages: {
                default: `Versioned dependency mapping must be between enum members.`,
            },
        },
        "versioned-dependency-same-namespace": {
            severity: "error",
            messages: {
                default: `Versioned dependency mapping must all point to the same namespace but 2 versions have different namespaces '${"namespace1"}' and '${"namespace2"}'.`,
            },
        },
        "versioned-dependency-record-not-mapping": {
            severity: "error",
            messages: {
                default: paramMessage `The versionedDependency decorator must provide a model mapping local versions to dependency '${"dependency"}' versions`,
            },
        },
        "versioned-dependency-not-picked": {
            severity: "error",
            messages: {
                default: paramMessage `The versionedDependency decorator must provide a version of the dependency '${"dependency"}'.`,
            },
        },
        "version-not-found": {
            severity: "error",
            messages: {
                default: paramMessage `The provided version '${"version"}' from '${"enumName"}' is not declared as a version enum. Use '@versioned(${"enumName"})' on the containing namespace.`,
            },
        },
        "version-duplicate": {
            severity: "error",
            messages: {
                default: paramMessage `Multiple versions from '${"name"}' resolve to the same value. Version enums must resolve to unique values.`,
            },
        },
        "using-versioned-library": {
            severity: "error",
            messages: {
                default: paramMessage `Namespace '${"sourceNs"}' is referencing types from versioned namespace '${"targetNs"}' but didn't specify which versions with @useDependency.`,
            },
        },
        "invalid-renamed-from-value": {
            severity: "error",
            messages: {
                default: "@renamedFrom.oldName cannot be empty string.",
            },
        },
        "no-service-fixed-version": {
            severity: "error",
            messages: {
                default: paramMessage `Namespace '${"name"}' cannot specify a fixed service version with @service({version: ${"version"}}) while using @versioned. Remove the version argument from @service.`,
            },
        },
        "incompatible-versioned-reference": {
            severity: "error",
            messages: {
                default: paramMessage `'${"sourceName"}' is referencing versioned type '${"targetName"}' but is not versioned itself.`,
                addedAfter: paramMessage `'${"sourceName"}' was added in version '${"sourceAddedOn"}' but referencing type '${"targetName"}' added in version '${"targetAddedOn"}'.`,
                dependentAddedAfter: paramMessage `'${"sourceName"}' was added in version '${"sourceAddedOn"}' but contains type '${"targetName"}' added in version '${"targetAddedOn"}'.`,
                removedBefore: paramMessage `'${"sourceName"}' was removed in version '${"sourceRemovedOn"}' but referencing type '${"targetName"}' removed in version '${"targetRemovedOn"}'.`,
                dependentRemovedBefore: paramMessage `'${"sourceName"}' was removed in version '${"sourceRemovedOn"}' but contains type '${"targetName"}' removed in version '${"targetRemovedOn"}'.`,
                versionedDependencyAddedAfter: paramMessage `'${"sourceName"}' is referencing type '${"targetName"}' added in version '${"targetAddedOn"}' but version used is ${"dependencyVersion"}.`,
                versionedDependencyRemovedBefore: paramMessage `'${"sourceName"}' is referencing type '${"targetName"}' removed in version '${"targetAddedOn"}' but version used is ${"dependencyVersion"}.`,
                doesNotExist: paramMessage `'${"sourceName"}' is referencing type '${"targetName"}' which does not exist in version '${"version"}'.`,
            },
        },
        "incompatible-versioned-namespace-use-dependency": {
            severity: "error",
            messages: {
                default: "The useDependency decorator can only be used on a Namespace if the namespace is unversioned. For versioned namespaces, put the useDependency decorator on the version enum members.",
            },
        },
        "made-optional-not-optional": {
            severity: "error",
            messages: {
                default: paramMessage `Property '${"name"}' marked with @madeOptional but is required. Should be '${"name"}?'`,
            },
        },
        "made-required-optional": {
            severity: "error",
            messages: {
                default: paramMessage `Property '${"name"}?' marked with @madeRequired but is optional. Should be '${"name"}'`,
            },
        },
        "renamed-duplicate-property": {
            severity: "error",
            messages: {
                default: paramMessage `Property '${"name"}' marked with '@renamedFrom' conflicts with existing property in version ${"version"}.`,
            },
        },
    },
    state: {
        versionIndex: { description: "Version index" },
        addedOn: { description: "State for @addedOn decorator" },
        removedOn: { description: "State for @removedOn decorator" },
        versions: { description: "State for @versioned decorator" },
        useDependencyNamespace: { description: "State for @useDependency decorator on Namespaces" },
        useDependencyEnum: { description: "State for @useDependency decorator on Enums" },
        renamedFrom: { description: "State for @renamedFrom decorator" },
        madeOptional: { description: "State for @madeOptional decorator" },
        madeRequired: { description: "State for @madeRequired decorator" },
        typeChangedFrom: { description: "State for @typeChangedFrom decorator" },
        returnTypeChangedFrom: { description: "State for @returnTypeChangedFrom decorator" },
    },
});

function getVersionsForEnum(program, en) {
    const namespace = en.namespace;
    if (namespace === undefined) {
        return [];
    }
    const nsVersion = getVersion(program, namespace);
    if (nsVersion === undefined) {
        return [];
    }
    return [namespace, nsVersion];
}
var Availability;
(function (Availability) {
    Availability["Unavailable"] = "Unavailable";
    Availability["Added"] = "Added";
    Availability["Available"] = "Available";
    Availability["Removed"] = "Removed";
})(Availability || (Availability = {}));
function getVersionForEnumMember(program, member) {
    // Always lookup for the original type. This ensure reference equality when comparing versions.
    member = member.projectionBase ?? member;
    const parentEnum = member.enum;
    const [, versions] = getVersionsForEnum(program, parentEnum);
    return versions?.getVersionForEnumMember(member);
}

function checkIsVersion(program, enumMember, diagnosticTarget) {
    const version = getVersionForEnumMember(program, enumMember);
    if (!version) {
        reportDiagnostic(program, {
            code: "version-not-found",
            target: diagnosticTarget,
            format: { version: enumMember.name, enumName: enumMember.enum.name },
        });
    }
    return version;
}
const $added = (context, t, v) => {
    const { program } = context;
    const version = checkIsVersion(context.program, v, context.getArgumentTarget(0));
    if (!version) {
        return;
    }
    // retrieve statemap to update or create a new one
    const record = program.stateMap(VersioningStateKeys.addedOn).get(t) ?? new Array();
    record.push(version);
    // ensure that records are stored in ascending order
    record.sort((a, b) => a.index - b.index);
    program.stateMap(VersioningStateKeys.addedOn).set(t, record);
};
/**
 * @returns the array of RenamedFrom metadata if applicable.
 */
function getRenamedFrom(p, t) {
    return p.stateMap(VersioningStateKeys.renamedFrom).get(t);
}
/**
 * @returns the list of versions for which this decorator has been applied
 */
function getRenamedFromVersions(p, t) {
    return getRenamedFrom(p, t)?.map((x) => x.version);
}
function getAddedOnVersions(p, t) {
    return p.stateMap(VersioningStateKeys.addedOn).get(t);
}
function getRemovedOnVersions(p, t) {
    return p.stateMap(VersioningStateKeys.removedOn).get(t);
}
/**
 * @returns version when the given type was made optional if applicable.
 */
function getMadeOptionalOn(p, t) {
    return p.stateMap(VersioningStateKeys.madeOptional).get(t);
}
/**
 * Get the version map of the namespace.
 */
function getVersion(program, namespace) {
    return program.stateMap(VersioningStateKeys.versions).get(namespace);
}

/**
 * Returns the full namespace name for the given type, if available.
 * @param program the TypeSpec program
 * @param type the type to query
 * @returns The name of the namespace the type belongs in.
 */
function getNamespaceName(program, type) {
    if (type === undefined)
        return "";
    if (type.kind === "ModelProperty")
        return type.model ? getNamespaceName(program, type.model) : "";
    if (type.kind === "EnumMember")
        return type.enum ? getNamespaceName(program, type.enum) : "";
    if (type.kind === "UnionVariant")
        return type.union ? getNamespaceName(program, type.union) : "";
    if (type.kind !== "Namespace")
        type = type.namespace;
    if (type === undefined) {
        return "";
    }
    return getNamespaceFullName(type);
}
/**
 * Returns true if the type is defined in a namespace that is excluded from linting.
 * @param program the TypeSpec program
 * @param type the type to query
 * @returns true if the type is defined in a namespace that is excluded from linting.
 */
function isExcludedCoreType(program, type) {
    // Don't enforce documentation on core libraries. They contain
    // developer-facing building blocks that do not need API-consumer-oriented
    // documentation using `@doc`.
    //
    // This is a stop-gap and we probably need a more general mechanism to
    // prevent linters from reporting issues on imported library code outside
    // the linter-user's control.
    //
    // https://github.com/Azure/typespec-azure/issues/801#issuecomment-1194454247
    //
    const nsName = getNamespaceName(program, type);
    const allowedNamespaces = ["TypeSpec", "Azure.Core", "Azure.ResourceManager", "OpenAPI"];
    return allowedNamespaces.find((allowed) => nsName.startsWith(allowed)) !== undefined;
}
function isAzureSubNamespace(program, ns) {
    if (!ns)
        return false;
    const nsName = getNamespaceName(program, ns);
    return nsName.startsWith("Azure.");
}
/**
 * Returns true if the model type is inline (has no name).
 * @param target the target model
 * @returns true if the model type is inline (has no name).
 */
function isInlineModel(target) {
    return !target.name;
}
/**
 * Returns true if the model type is a model with template declaration.
 * @param target the target model
 * @returns true if the model type is a model with template declaration.
 */
function isTemplateDeclarationType(target) {
    return target.node?.kind === SyntaxKind.ModelStatement && target.node.templateParameters.length;
}
/**
 * Returns true if the operation is defined on a templated interface which hasn't had args filled in
 * @param target the target operation
 * @returns true if the operation is defined on a templated interface which hasn't had args filled in
 */
function isTemplatedInterfaceOperation(target) {
    return (target.node?.kind === SyntaxKind.OperationStatement &&
        target.interface &&
        isTemplateDeclaration(target.interface));
}
/**
 * Returns true if the operation is an uninstantiated signature template
 * @param target the target operation
 * @returns true if the operation is an uninstantiated signature template
 */
function isTemplatedOperationSignature(target) {
    return target.node?.kind === SyntaxKind.OperationStatement && isTemplateDeclaration(target);
}
/**
 * Checks whether a given name is in PascalCase
 * @param name the name to check
 * @returns true if the name is in PascalCase
 */
function isPascalCaseNoAcronyms(name) {
    if (name === undefined || name === null || name === "")
        return true;
    return /^([A-Z][a-z0-9]+)*[A-Z]?$/.test(name);
}
/**
 * Checks whether a given name is in camelCase
 * @param name the name to check
 * @returns true if the name is in camelCase
 */
function isCamelCaseNoAcronyms(name) {
    if (name === undefined || name === null || name === "")
        return true;
    return /^[^a-zA-Z0-9]?[a-z][a-z0-9]*([A-Z][a-z0-9]+)*[A-Z]?$/.test(name);
}

function isApiVersionParam(prop) {
    return prop.name === "apiVersion" && prop.type.kind === "Scalar" && prop.type.name === "string";
}
// TODO: Remove this function once we have a mechanism for overriding or disabling linter rules
// See: https://github.com/microsoft/typespec/issues/1785
function isArmProviderNamespace$1(ns) {
    for (const dec of ns.decorators) {
        if (dec.decorator.name === "$armProviderNamespace") {
            return true;
        }
    }
    return false;
}
const apiVersionRule = createRule({
    name: "operation-missing-api-version",
    description: "Operations need an api version parameter.",
    severity: "warning",
    messages: {
        default: `Operation is missing an api version parameter.`,
    },
    create(context) {
        return {
            operation: (op) => {
                if (isExcludedCoreType(context.program, op))
                    return;
                if (!op.namespace)
                    return;
                // ignore ARM namespaces. They have their own rule
                if (isArmProviderNamespace$1(op.namespace))
                    return;
                const versionMap = getVersion(context.program, op.namespace);
                // rule only applies to versioned Azure operations
                if (!versionMap)
                    return;
                for (const param of op.parameters.properties.values()) {
                    if (isApiVersionParam(param))
                        return;
                }
                context.reportDiagnostic({
                    target: op,
                });
            },
        };
    },
});

const authRequiredRule = createRule({
    name: "auth-required",
    description: "Enforce service authentication.",
    severity: "warning",
    messages: {
        default: "Provide an authentication scheme using the `@useAuth` decorator. See: https://azure.github.io/typespec-azure/docs/reference/azure-style-guide#security-definitions",
    },
    create(context) {
        return {
            namespace: (namespace) => {
                if (isExcludedCoreType(context.program, namespace))
                    return;
                if (!isAzureSubNamespace(context.program, namespace))
                    return;
                const service = getService(context.program, namespace);
                if (!service)
                    return;
                const auth = getAuthentication(context.program, namespace);
                if (!auth) {
                    context.reportDiagnostic({
                        target: namespace,
                    });
                }
            },
        };
    },
});

const binaryContentTypes = new Set(["application/octet-stream", "multipart/form-data"]);
const byosRule = createRule({
    name: "byos",
    description: "Use the BYOS pattern recommended for Azure Services.",
    severity: "warning",
    messages: {
        default: paramMessage `The content type "${"contentType"}" indicates this operation is storing or retrieving binary data. It is recommended to use the BYOS pattern for Azure Services. https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md#bring-your-own-storage-byos`,
    },
    create(context) {
        return {
            operation: (operation) => {
                if (isTemplateInstance(operation)) {
                    // Operation template instance are just referenced in `op is`. Main operation will be validated.
                    return;
                }
                const httpOperation = ignoreDiagnostics(getHttpOperation(context.program, operation));
                if (httpOperation.parameters.body !== undefined) {
                    for (const contentType of httpOperation.parameters.body.contentTypes) {
                        if (binaryContentTypes.has(contentType)) {
                            context.reportDiagnostic({
                                format: { contentType },
                                target: operation,
                            });
                        }
                    }
                }
            },
        };
    },
});

const casingRule = createRule({
    name: "casing-style",
    description: "Ensure proper casing style.",
    severity: "warning",
    messages: {
        default: paramMessage `The names of ${"type"} types must use ${"casing"}`,
    },
    create(context) {
        return {
            model: (model) => {
                if (isExcludedCoreType(context.program, model))
                    return;
                if (!isPascalCaseNoAcronyms(model.name)) {
                    context.reportDiagnostic({
                        format: { type: "Model", casing: "PascalCase" },
                        target: model,
                    });
                }
            },
            modelProperty: (property) => {
                if (property.name === "_")
                    return;
                if (isExcludedCoreType(context.program, property))
                    return;
                if (!isCamelCaseNoAcronyms(property.name)) {
                    context.reportDiagnostic({
                        format: { type: "Property", casing: "camelCase" },
                        target: property,
                    });
                }
            },
            operation: (operation) => {
                if (isExcludedCoreType(context.program, operation))
                    return;
                if (isTemplateDeclarationOrInstance(operation)) {
                    if (!isPascalCaseNoAcronyms(operation.name)) {
                        context.reportDiagnostic({
                            format: { type: "Operation Template", casing: "PascalCase" },
                            target: operation,
                        });
                    }
                }
                else if (!isCamelCaseNoAcronyms(operation.name)) {
                    context.reportDiagnostic({
                        format: { type: "Operation", casing: "camelCase" },
                        target: operation,
                    });
                }
            },
            interface: (operationGroup) => {
                if (isExcludedCoreType(context.program, operationGroup))
                    return;
                if (!isPascalCaseNoAcronyms(operationGroup.name)) {
                    context.reportDiagnostic({
                        format: { type: "Interface", casing: "PascalCase" },
                        target: operationGroup,
                    });
                }
            },
            namespace: (namespace) => {
                if (isExcludedCoreType(context.program, namespace))
                    return;
                if (!isPascalCaseNoAcronyms(namespace.name)) {
                    context.reportDiagnostic({
                        format: { type: "Namespace", casing: "PascalCase" },
                        target: namespace,
                    });
                }
            },
        };
    },
});

const compositionOverInheritanceRule = createRule({
    name: "composition-over-inheritance",
    description: "Check that if a model is used in an operation and has derived models that it has a discriminator or recommend to use composition via spread or `is`.",
    severity: "warning",
    messages: {
        default: paramMessage `Model '${"name"}' is extending '${"baseModel"}' that doesn't define a discriminator. If '${"baseModel"}' is meant to be used:
 - For composition consider using spread \`...\` or \`model is\` instead.
 - As a polymorphic relation, add the \`@discriminator\` decorator on the base model.`,
        instance: paramMessage `Model '${"name"}' is extending a template '${"baseModel"}'. Consider using composition with spread \`...\` or \`model is\` instead.`,
    },
    create(context) {
        return {
            model: (model) => {
                if (model.baseModel &&
                    model.node?.kind === SyntaxKind.ModelStatement &&
                    model.node.extends &&
                    getDiscriminator(context.program, model.baseModel) === undefined) {
                    context.reportDiagnostic({
                        messageId: isTemplateInstance(model.baseModel) ? "instance" : "default",
                        format: {
                            name: model.name,
                            baseModel: getTypeName(model.baseModel),
                        },
                        target: model.node.extends,
                    });
                }
            },
        };
    },
});

const friendlyNameRule = createRule({
    name: "friendly-name",
    description: "Ensures that @friendlyName is used as intended.",
    severity: "warning",
    messages: {
        scope: paramMessage `@friendlyName should not decorate ${"kind"}.`,
        template: paramMessage `@friendlyName should decorate template and use template parameter's properties in friendly name.`,
    },
    create(context) {
        return {
            model: (entity) => {
                checkFriendlyName(context, entity);
            },
            modelProperty: (entity) => {
                checkFriendlyName(context, entity);
            },
            scalar: (entity) => {
                checkFriendlyName(context, entity);
            },
            interface: (entity) => {
                checkFriendlyName(context, entity);
            },
            enum: (entity) => {
                checkFriendlyName(context, entity);
            },
            enumMember: (entity) => {
                checkFriendlyName(context, entity);
            },
            namespace: (entity) => {
                checkFriendlyName(context, entity);
            },
            operation: (entity) => {
                checkFriendlyName(context, entity);
            },
            union: (entity) => {
                checkFriendlyName(context, entity);
            },
            unionVariant: (entity) => {
                checkFriendlyName(context, entity);
            },
        };
    },
});
function checkFriendlyName(context, type) {
    const decorator = getFriendlyNameDecoratorOnType(type);
    if (decorator) {
        if (["Model", "Operation", "Interface", "Union"].includes(type.kind)) {
            // @friendlyName should decorate template and use template parameter's properties in friendly name.
            if (!isTemplateInstance(type) || decorator.args.length !== 2) {
                context.reportDiagnostic({
                    messageId: "template",
                    target: type,
                    format: {},
                });
            }
        }
        else {
            context.reportDiagnostic({
                messageId: "scope",
                target: type,
                format: { kind: type.kind },
            });
        }
    }
}
function getFriendlyNameDecoratorOnType(type) {
    const decorators = type.decorators.filter((x) => x.decorator.name === "$friendlyName" &&
        x.node?.kind === SyntaxKind.DecoratorExpression &&
        x.node?.parent === type.node);
    return decorators[0];
}

const knownEncodings = new Set([
    // utcDateTime and offsetDateTime
    "rfc3339",
    "rfc7231",
    "unixTimestamp",
    // duration
    "ISO8601",
    "seconds",
    // bytes
    "base64",
    "base64url",
]);
const knownEncodingRule = createRule({
    name: "known-encoding",
    description: "Check for supported encodings.",
    severity: "warning",
    messages: {
        default: paramMessage `Encoding "${"encoding"}" is not supported for Azure Services. Known encodings are: ${"knownEncodings"}`,
    },
    create(context) {
        function checkEncoding(type) {
            const encode = getEncode(context.program, type);
            if (encode) {
                if (!knownEncodings.has(encode.encoding)) {
                    context.reportDiagnostic({
                        format: {
                            encoding: encode.encoding,
                            knownEncodings: [...knownEncodings].join(","),
                        },
                        target: type,
                    });
                }
            }
        }
        return {
            modelProperty: (property) => checkEncoding(property),
            scalar: (scalar) => checkEncoding(scalar),
        };
    },
});

/**
 * Filter the model properties of a model, using the given predicate
 * @param model The model to filter
 * @parm predicate The predicate function used to filter model properties
 * @returns a list of filtered properties, it will have length 0 if no properties
 * match the filter.
 */
function filterModelProperties(model, predicate) {
    return [...getAllProperties(model).values()].filter(predicate);
}
/**
 * Filter operation responses using a predicate
 * @param operation The operation containign the response models to filter
 * @param predicate A predicate function to apply to each response model
 * @returns A list of models matching the predicate, or undefined if there are none
 */
function filterResponseModels(operation, predicate) {
    const models = [];
    for (const response of operation.responses) {
        switch (response.type.kind) {
            case "Model":
                if (predicate(response.type))
                    models.push(response.type);
                break;
            case "Union":
                for (const variant of response.type.variants.values()) {
                    if (variant.type.kind === "Model" && predicate(variant.type))
                        models.push(variant.type);
                }
                break;
            case "Tuple":
                for (const type of response.type.values) {
                    if (type.kind === "Model" && predicate(type))
                        models.push(type);
                }
        }
    }
    return models.length > 0 ? models : undefined;
}
/**
 * Get the Http metadata for this operation
 * @param program The program being processed
 * @param operation The operation to get http metadata for
 * @returns An HttpOperation with http metadata.  May emit error diagnostics.
 */
function getHttpMetadata(program, operation) {
    const [httpOperation, diagnostics] = getHttpOperation(program, operation);
    if (diagnostics && diagnostics.length > 0) {
        program.reportDiagnostics(diagnostics);
    }
    return httpOperation;
}
/**
 * Get the main success response from an operation
 * @param program Get success responses for an operation
 * @param operation The operation to process
 * @returns A model, if there is a 2xx response, or nothing otherwise
 */
function getOperationResponse(program, operation) {
    const response = getSuccessResponse(program, getHttpMetadata(program, operation));
    if (response === undefined) {
        reportDiagnostic$1(program, { code: "expected-success-response", target: operation });
    }
    return response;
}
/**
 * Return the first response model that has any properties matching the given model property predicate
 * @param program The program being processed
 * @param operation The operation to retrieve matching response from
 * @param predicate The predicate function to apply to each model property of the responses
 * @returns The model and matching model property, or nothing if no matching models are found
 */
function getResultModelWithProperty(program, operation, predicate) {
    const httpOperation = getHttpMetadata(program, operation);
    const models = filterResponseModels(httpOperation, (model) => filterModelProperties(model, predicate).length > 0);
    if (models === undefined || models.length < 1)
        return undefined;
    const properties = [...models[0].properties.values()].filter(predicate);
    if (properties.length < 1)
        return undefined;
    return [models[0], properties[0]];
}
/**
 * Get the first success response of an operation
 * @param program The program being processed
 * @param operation The operation to process
 * @returns The first success response, or nothing, if no matching models are found
 */
function getSuccessResponse(program, operation) {
    const candidates = filterResponseModels(operation, (response) => !isErrorModel(program, response))?.filter((m) => {
        const prop = getStatusCodeProperty(program, m);
        return (prop === undefined ||
            (prop.type?.kind === "String" && prop.type.value?.startsWith("2")) ||
            (prop.type?.kind === "Number" && prop.type.value >= 200 && prop.type.value < 300));
    });
    if (candidates === undefined || candidates.length < 1)
        return undefined;
    return candidates[0];
}
/**
 *
 * @param program The probgram being processed
 * @param model The model to check for status code properties
 * @returns The property that represents an http status code, or nothing if there is none.
 */
function getStatusCodeProperty(program, model) {
    const properties = filterModelProperties(model, (prop) => isStatusCode(program, prop));
    return properties.length > 0 ? properties[0] : undefined;
}
/**
 *
 * @param model The model to process
 * @param collection The set of ModelProperties found so far
 * @returns The full set of model properties found in a model and all ancestors
 */
function getAllProperties(model, collection) {
    const outCollection = collection ?? new Map();
    for (const [name, value] of model.properties.entries()) {
        outCollection.set(name, value);
    }
    if (model.baseModel)
        return getAllProperties(model.baseModel, outCollection);
    return outCollection;
}

/**
 * Azure SDK polling information: provides data contained in the
 * long-running-operation-options.final-state-via field
 */
var FinalStateValue;
(function (FinalStateValue) {
    /** Poll the Azure-AsyncOperation header */
    FinalStateValue["azureAsyncOperation"] = "azure-async-operation";
    /** Poll the location header */
    FinalStateValue["location"] = "location";
    /** poll the Operation-Location header */
    FinalStateValue["operationLocation"] = "operation-location";
    /** poll (GET) the same uri as the original operation */
    FinalStateValue["originalUri"] = "original-uri";
    /** Poll on a header or field other than those above */
    FinalStateValue["customLink"] = "custom-link";
    /** Call a polling operation using the data in LroMetadata */
    FinalStateValue["customOperationReference"] = "custom-operation-reference";
})(FinalStateValue || (FinalStateValue = {}));
/**
 *
 * @param program The program being processed
 * @param operation The operation to get Lwo Metadata for
 * @returns LroMetadata for the operation is it is long-running,
 * or nothing if the operation is synchronous, or lro information
 * cannot be processed.
 */
function getLroMetadata(program, operation) {
    const context = ensureContext(program, operation);
    if (context === undefined)
        return undefined;
    processFinalReference(program, operation, context);
    processFinalLink(program, operation, context);
    const nextReference = processStatusMonitorReference(program, operation, context);
    if (nextReference !== undefined && nextReference.responseModel.kind === "Model") {
        context.statusMonitorStep = nextReference;
        processFinalReference(program, nextReference.target.operation, context);
        processFinalLink(program, nextReference.target.operation, context);
        context.pollingStep = getPollingStep(program, nextReference.responseModel, context);
        return createLroMetadata(program, operation, context);
    }
    if (processStatusMonitorLink(program, operation, context)) {
        return createLroMetadata(program, operation, context);
    }
    const originalStep = getPollingStep(program, operation, context);
    if (originalStep !== undefined) {
        context.pollingStep = originalStep;
        return createLroMetadata(program, operation, context);
    }
    return undefined;
}
function createFinalOperationLink(program, model, property) {
    let resourceType;
    // if finalOperationLink is a ResourceLocation, then the responseModel is the resource type
    if (property.type.kind === "Scalar" && property.type.name === "ResourceLocation") {
        resourceType = property.type.templateMapper?.args[0];
    }
    // override this value if specified by the `@finalLocation` decorator
    const override = getFinalLocationValue(program, property);
    return {
        kind: "finalOperationLink",
        responseModel: override ?? resourceType ?? model,
        target: {
            kind: "link",
            location: isHeader(program, property) ? "ResponseHeader" : "ResponseBody",
            property: property,
        },
    };
}
function createLroMetadata(program, operation, context) {
    const [finalState, model] = getFinalStateVia(program, operation, context);
    if (finalState === undefined || model === undefined || context.pollingStep === undefined)
        return undefined;
    const logicalPathName = context.finalStep?.kind === "pollingSuccessProperty"
        ? context.finalStep.target.name
        : undefined;
    let finalResult = model.kind === "Model" ? model : "void";
    let finalEnvelopeResult = model.kind === "Model" ? model : "void";
    if (context.finalStep && context.finalStep.kind === "pollingSuccessProperty") {
        finalEnvelopeResult = context.pollingStep.responseModel;
    }
    else if (context.finalStep && context.finalStep.kind === "noPollingResult") {
        finalResult = "void";
        finalEnvelopeResult = "void";
    }
    return {
        operation: operation,
        logicalResult: model.kind === "Intrinsic" ? context.pollingStep.responseModel : model,
        finalStateVia: finalState,
        statusMonitorStep: context.statusMonitorStep,
        pollingInfo: context.pollingStep,
        finalStep: context.finalStep,
        envelopeResult: context.pollingStep.responseModel,
        logicalPath: logicalPathName,
        finalResult: finalResult,
        finalEnvelopeResult: finalEnvelopeResult,
        finalResultPath: logicalPathName,
    };
}
function createOperationLink(program, modelProperty) {
    let location = "ResponseBody";
    if (isHeader(program, modelProperty))
        location = "ResponseHeader";
    if (isBody(program, modelProperty) || isBodyRoot(program, modelProperty))
        location = "Self";
    return {
        kind: "link",
        location: location,
        property: modelProperty,
    };
}
function createOperationReference(metadata) {
    if (!metadata.parameterMap)
        return undefined;
    const map = new Map();
    if (metadata.parameterMap) {
        for (const [name, parameters] of metadata.parameterMap) {
            switch (parameters.sourceKind) {
                case "RequestBody":
                    map.set(name, { location: "RequestBody", parameter: parameters.source.name });
                    break;
                case "RequestParameter":
                    map.set(name, { location: "OperationParameters", parameter: parameters.source.name });
                    break;
                case "ResponseBody":
                    map.set(name, { location: "Response", parameter: parameters.source.name });
                    break;
            }
        }
        return {
            kind: "reference",
            operation: metadata.linkedOperation,
            parameterMap: map,
            parameters: metadata.parameterMap,
        };
    }
    return undefined;
}
function createPollingStep(pollingData) {
    return {
        kind: "pollingOperationStep",
        responseModel: pollingData.monitorType,
        resultProperty: pollingData.successProperty,
        errorProperty: pollingData.errorProperty,
        terminationStatus: {
            kind: "model-property",
            canceledState: pollingData.lroStates.canceledState,
            failedState: pollingData.lroStates.failedState,
            succeededState: pollingData.lroStates.succeededState,
            property: pollingData.statusProperty,
        },
    };
}
function ensureContext(program, operation, context) {
    const [httpOperation, diagnostics] = getHttpOperation(program, operation);
    if (diagnostics !== undefined && diagnostics.length > 0) {
        program.reportDiagnostics(diagnostics);
    }
    const candidate = getSuccessResponse(program, httpOperation);
    if (candidate === undefined)
        return undefined;
    return {
        visitedModels: new Set(),
        visitedOperations: new Set(),
        httpOperation: httpOperation,
        originalModel: candidate,
    };
}
function getBodyType(program, model) {
    const bodyProps = filterModelProperties(model, (p) => isBody(program, p) || isBodyRoot(program, p));
    if (bodyProps.length === 1 && bodyProps[0].type.kind === "Model")
        return bodyProps[0].type;
    return undefined;
}
function getLogicalResourceOperation(program, operation, model) {
    const resOp = getResourceOperation(program, operation);
    if (resOp !== undefined)
        return resOp;
    if (model === undefined)
        return undefined;
    const bodyModel = getBodyType(program, model);
    if (bodyModel !== undefined)
        model = bodyModel;
    model = getEffectiveModelType(program, model);
    let resultOp;
    const verb = getOperationVerb(program, operation);
    switch (verb) {
        case "delete":
            resultOp = "delete";
            break;
        case "put":
            resultOp = "createOrReplace";
            break;
        default:
            return undefined;
    }
    return { operation: resultOp, resourceType: model };
}
function getFinalStateVia(program, operation, context) {
    const operationAction = getActionDetails(program, operation);
    let model = context.originalModel?.name !== undefined ? context.originalModel : undefined;
    let finalState = FinalStateValue.originalUri;
    const finalStateOverride = getFinalStateOverride(program, operation);
    const resOp = getLogicalResourceOperation(program, operation, model);
    if (operationAction !== undefined || resOp?.operation === "delete") {
        finalState = FinalStateValue.operationLocation;
        model = context.pollingStep?.responseModel ?? context.originalModel;
    }
    if (context.finalStep &&
        context.finalStep.kind !== "noPollingResult" &&
        (context.finalStep.kind !== "pollingSuccessProperty" ||
            resOp?.operation === undefined ||
            resOp.operation !== "createOrReplace")) {
        model = context.finalStep.responseModel;
        if (context.finalStep.kind === "pollingSuccessProperty" &&
            context.statusMonitorStep !== undefined) {
            switch (context.statusMonitorStep.kind) {
                case "nextOperationLink":
                    finalState = getLroStatusFromHeaderProperty(program, context.statusMonitorStep.target.property);
                    break;
                case "nextOperationReference":
                    finalState = FinalStateValue.customOperationReference;
            }
        }
        else {
            finalState = getStatusFromLinkOrReference(program, operation, context.finalStep.target);
        }
        return [finalStateOverride || finalState, model];
    }
    if (resOp !== undefined &&
        resOp.operation !== undefined &&
        resOp.operation === "createOrReplace" &&
        resOp.resourceType !== undefined) {
        model = resOp.resourceType;
        return [finalStateOverride || FinalStateValue.originalUri, model];
    }
    // handle actions and delete operations
    if ((operationAction !== undefined &&
        operationAction !== null &&
        context.statusMonitorStep !== undefined) ||
        (resOp?.operation === "delete" &&
            context.pollingStep !== undefined &&
            context.statusMonitorStep !== undefined) ||
        (operationAction === undefined &&
            resOp === undefined &&
            context.pollingStep !== undefined &&
            context.statusMonitorStep !== undefined)) {
        const info = getStatusMonitorInfo(program, context.statusMonitorStep.responseModel);
        if (info !== undefined) {
            model = info.successType ?? program.checker.voidType;
            finalState = getStatusFromLinkOrReference(program, operation, context.statusMonitorStep?.target);
            if (context.finalStep === undefined && info.successProperty === undefined) {
                context.finalStep = { kind: "noPollingResult", responseModel: program.checker.voidType };
            }
        }
    }
    return [finalStateOverride || finalState, model];
}
function getLroStatusFromHeaderProperty(program, property) {
    let finalState;
    if (property === undefined || !isHeader(program, property))
        return FinalStateValue.customLink;
    const name = getHeaderFieldName(program, property);
    if (name === undefined)
        return FinalStateValue.customLink;
    switch (name.toLowerCase()) {
        case "operation-location":
            finalState = FinalStateValue.operationLocation;
            break;
        case "azure-asyncoperation":
        case "azureasyncoperation":
            finalState = FinalStateValue.azureAsyncOperation;
            break;
        case "location":
            finalState = FinalStateValue.location;
            break;
        default:
            finalState = FinalStateValue.customLink;
    }
    return finalState;
}
function getLroStatusProperty$1(program, model) {
    const properties = filterModelProperties(model, (prop) => ignoreDiagnostics(extractLroStates(program, prop)) !== undefined);
    return properties.length > 0 ? properties[0] : undefined;
}
function getPollingStep(program, modelOrOperation, context) {
    function getModel(property) {
        return property?.type.kind === "Model" ? property.type : undefined;
    }
    let info;
    if (!context.pollingOperationLink) {
        context.pollingOperationLink = getOperationLink(program, context.httpOperation.operation, PollingOperationKey);
    }
    if (context.pollingOperationLink?.parameterMap === undefined)
        return undefined;
    const statusMonitorOverride = context.pollingOperationLink?.result?.statusMonitor;
    if (statusMonitorOverride !== undefined && statusMonitorOverride.monitorType !== undefined) {
        info = {
            lroStates: statusMonitorOverride.lroStates,
            monitorType: statusMonitorOverride.monitorType,
            statusProperty: statusMonitorOverride.statusProperty,
            errorProperty: statusMonitorOverride.errorProperty,
            errorType: getModel(statusMonitorOverride.errorProperty),
            successProperty: statusMonitorOverride.successProperty,
            successType: getModel(statusMonitorOverride.successProperty),
        };
        return createPollingStep(info);
    }
    switch (modelOrOperation.kind) {
        case "Operation":
            const httpOperation = getHttpMetadata(program, modelOrOperation);
            info = GetStatusMonitorInfoFromOperation(program, httpOperation);
            break;
        case "Model":
            info = getStatusMonitorInfo(program, modelOrOperation);
            break;
    }
    if (info === undefined)
        return undefined;
    return createPollingStep(info);
}
function getStatusFromLinkOrReference(program, sourceOperation, target) {
    let finalState = FinalStateValue.originalUri;
    switch (target.kind) {
        case "link":
            {
                switch (target.location) {
                    case "ResponseBody":
                        finalState = FinalStateValue.customLink;
                        break;
                    case "ResponseHeader":
                        finalState = getLroStatusFromHeaderProperty(program, target.property);
                        break;
                }
            }
            break;
        case "reference":
            {
                finalState = FinalStateValue.customOperationReference;
                if (isMatchingGetOperation(program, sourceOperation, target.operation)) {
                    finalState = FinalStateValue.originalUri;
                }
            }
            break;
    }
    return finalState;
}
/**
 * Extracts status monitor information from a pollingLink
 * @param program The program being processed
 * @param link The link to the status monitor
 */
function getStatusMonitorInfo(program, modelOrLink, pollingOverride) {
    if (pollingOverride?.kind === pollingOptionsKind.StatusMonitor) {
        return {
            ...pollingOverride.info,
        };
    }
    if (modelOrLink.kind === "link") {
        if (modelOrLink.property === undefined)
            return undefined;
        const statusMonitorType = resolveOperationLocation(program, modelOrLink.property);
        if (statusMonitorType === undefined || statusMonitorType.kind === "Intrinsic")
            return undefined;
        modelOrLink = statusMonitorType;
    }
    const statusProperty = getLroStatusProperty$1(program, modelOrLink);
    if (statusProperty === undefined)
        return undefined;
    const successInfo = getTargetModelInformation(program, modelOrLink);
    const lroStates = ignoreDiagnostics(extractLroStates(program, statusProperty));
    if (lroStates === undefined)
        return undefined;
    return {
        monitorType: modelOrLink,
        successType: successInfo !== undefined ? successInfo[0] : undefined,
        successProperty: successInfo !== undefined ? successInfo[1] : undefined,
        statusProperty: statusProperty,
        lroStates: lroStates,
    };
}
function GetStatusMonitorInfoFromOperation(program, operation) {
    const models = filterResponseModels(operation, (model) => filterModelProperties(model, (prop) => ignoreDiagnostics(extractLroStates(program, prop)) !== undefined).length > 0);
    if (models === undefined || models.length < 1)
        return undefined;
    return getStatusMonitorInfo(program, models[0]);
}
function getStatusMonitorLinks(program, operation) {
    const models = filterResponseModels(operation, (model) => filterModelProperties(model, (prop) => isPollingLocation(program, prop) || isFinalLocation(program, prop)).length > 0);
    if (models === undefined || models.length < 1)
        return undefined;
    return getStatusMonitorLinksFromModel(program, models[0]);
}
function getStatusMonitorLinksFromModel(program, model) {
    let pollingData = undefined;
    let pollingLinks = filterModelProperties(model, (prop) => isPollingLocation(program, prop));
    if (pollingLinks === undefined)
        return undefined;
    // favor status monitor links over stepwise polling
    if (pollingLinks.length > 1) {
        pollingLinks = pollingLinks.filter((p) => !isBody(program, p) && !isBodyRoot(program, p));
    }
    const pollingProperty = pollingLinks[0];
    pollingData = getPollingLocationInfo(program, pollingProperty);
    const pollingLink = createOperationLink(program, pollingProperty);
    const monitorInfo = getStatusMonitorInfo(program, pollingLink, pollingData);
    if (monitorInfo === undefined)
        return undefined;
    let finalLinks = filterModelProperties(model, (prop) => isFinalLocation(program, prop));
    if ((finalLinks === undefined || finalLinks.length !== 1) && monitorInfo.monitorType) {
        finalLinks = filterModelProperties(monitorInfo.monitorType, (prop) => isFinalLocation(program, prop));
    }
    const finalLink = finalLinks === undefined || finalLinks.length !== 1
        ? undefined
        : createOperationLink(program, finalLinks[0]);
    let finalTarget;
    if (finalLink !== undefined && finalLink.property !== undefined) {
        finalTarget = resolveOperationLocation(program, finalLink.property);
    }
    return {
        model: monitorInfo.monitorType,
        statusMonitor: pollingLink,
        pollingData: monitorInfo,
        final: finalLink,
        finalModel: finalTarget,
    };
}
/**
 * Gets the target model, as defined in the status monitor, either through result property
 * or `@finalLocation` links
 * @param program The program being processed
 * @param link The link pointing to the monitor
 */
function getTargetModelInformation(program, modelOrLink) {
    if (modelOrLink.kind === "Intrinsic")
        return undefined;
    if (modelOrLink.kind === "link") {
        if (modelOrLink.property === undefined)
            return undefined;
        const linkModel = resolveOperationLocation(program, modelOrLink.property);
        if (linkModel === undefined || linkModel.kind === "Intrinsic")
            return undefined;
        modelOrLink = linkModel;
    }
    const finalLinkProps = filterModelProperties(modelOrLink, (prop) => isFinalLocation(program, prop));
    const resultProps = filterModelProperties(modelOrLink, (prop) => isResultProperty(program, prop));
    if (finalLinkProps.length === 1) {
        const result = resolveOperationLocation(program, finalLinkProps[0]);
        if (result !== undefined)
            return [result, finalLinkProps[0]];
    }
    if (resultProps.length === 1 &&
        !isNeverType(resultProps[0].type) &&
        resultProps[0].type.kind === "Model") {
        return [resultProps[0].type, resultProps[0]];
    }
    return undefined;
}
function isMatchingGetOperation(program, sourceOperation, targetOperation) {
    const sourceHttp = getHttpMetadata(program, sourceOperation);
    const targetHttp = getHttpMetadata(program, targetOperation);
    return sourceHttp.path === targetHttp.path && targetHttp.verb === "get";
}
function isResultProperty(program, property) {
    if (property.model !== undefined) {
        const [lroResult, _] = getLroResult(program, property.model);
        if (lroResult !== undefined) {
            return lroResult.name === property.name;
        }
    }
    return property.name === "result";
}
function processFinalLink(program, modelOrOperation, context) {
    // Allow @finalOperation to override link types
    const overrideModel = context.finalOperationLink?.result?.type;
    if (context.finalStep !== undefined)
        return;
    switch (modelOrOperation.kind) {
        case "Operation":
            {
                const result = getResultModelWithProperty(program, modelOrOperation, (prop) => isFinalLocation(program, prop));
                if (result === undefined)
                    return;
                const [model, property] = result;
                context.finalStep = createFinalOperationLink(program, overrideModel ?? model, property);
            }
            break;
        case "Model":
            {
                const outProperties = filterModelProperties(modelOrOperation, (prop) => isFinalLocation(program, prop));
                if (outProperties === undefined || outProperties.length !== 1)
                    return;
                context.finalStep = createFinalOperationLink(program, overrideModel ?? modelOrOperation, outProperties[0]);
            }
            break;
    }
}
function processFinalReference(program, operation, context) {
    if (context.finalStep !== undefined)
        return;
    // looks for operation marked with @finalOperation
    const link = getOperationLink(program, operation, "final");
    if (link === undefined || link.parameterMap === undefined || link.result?.type === undefined)
        return;
    context.finalOperationLink = link;
    const reference = createOperationReference(link);
    if (reference === undefined)
        return;
    context.finalStep = {
        kind: "finalOperationReference",
        responseModel: link.result?.type,
        target: reference,
    };
}
function createStatusMonitorPollingData(data) {
    function getModel(property) {
        return property?.type.kind === "Model" ? property.type : undefined;
    }
    return {
        lroStates: data.lroStates,
        monitorType: data.monitorType,
        statusProperty: data.statusProperty,
        errorProperty: data.errorProperty,
        errorType: getModel(data.errorProperty),
        successProperty: data.successProperty,
        successType: getModel(data.successProperty),
    };
}
function processStatusMonitorLink(program, modelOrOperation, context) {
    let lroData;
    if (context.pollingOperationLink?.result?.statusMonitor && context.pollingOperationLink?.link) {
        const polling = createStatusMonitorPollingData(context.pollingOperationLink.result.statusMonitor);
        lroData = {
            model: context.pollingOperationLink.result.statusMonitor.monitorType,
            pollingData: polling,
            statusMonitor: context.pollingOperationLink.link,
        };
    }
    else {
        switch (modelOrOperation.kind) {
            case "Operation":
                lroData = getStatusMonitorLinks(program, context.httpOperation);
                break;
            case "Model":
                lroData = getStatusMonitorLinksFromModel(program, modelOrOperation);
                break;
        }
    }
    if (lroData === undefined || lroData.statusMonitor === undefined) {
        return false;
    }
    context.pollingStep = createPollingStep(lroData.pollingData);
    if (context.finalStep === undefined) {
        if (lroData.final !== undefined && lroData.finalModel !== undefined) {
            context.finalStep = {
                kind: "finalOperationLink",
                responseModel: lroData.finalModel,
                target: lroData.final,
            };
        }
        else if (lroData.pollingData.successProperty !== undefined &&
            lroData.pollingData.successType !== undefined &&
            lroData.pollingData.successType.kind !== "Intrinsic") {
            const final = {
                kind: "pollingSuccessProperty",
                target: lroData.pollingData.successProperty,
                responseModel: lroData.pollingData.successType,
                sourceProperty: lroData.statusMonitor.property,
            };
            context.finalStep = final;
        }
    }
    context.statusMonitorStep = {
        kind: "nextOperationLink",
        responseModel: lroData.model,
        target: lroData.statusMonitor,
    };
    return true;
}
function processStatusMonitorReference(program, referencedOperation, context) {
    const references = getOperationLinks(program, referencedOperation);
    if (references === undefined)
        return undefined;
    const pollingData = references.get(PollingOperationKey);
    if (pollingData === undefined)
        return undefined;
    context.pollingOperationLink = pollingData;
    const pollingReference = createOperationReference(pollingData);
    if (pollingReference === undefined)
        return undefined;
    context.statusMonitorInfo = pollingData.result?.statusMonitor;
    const finalData = references.get(FinalOperationKey);
    if (context.finalStep === undefined && finalData !== undefined) {
        const finalReference = createOperationReference(finalData);
        const finalModel = finalData?.result?.type;
        if (finalReference !== undefined && finalModel !== undefined) {
            context.finalStep = {
                kind: "finalOperationReference",
                responseModel: finalModel,
                target: finalReference,
            };
        }
    }
    if (context.finalStep === undefined &&
        pollingData.result?.statusMonitor?.successProperty !== undefined &&
        pollingData.result.statusMonitor.successProperty.type.kind === "Model") {
        context.finalStep = {
            kind: "pollingSuccessProperty",
            target: pollingData.result.statusMonitor.successProperty,
            responseModel: pollingData.result.statusMonitor.successProperty.type,
            sourceProperty: pollingData.result.statusMonitor.successProperty,
        };
    }
    const responseModel = pollingData.result?.type;
    if (responseModel === undefined)
        return undefined;
    return {
        kind: "nextOperationReference",
        responseModel: responseModel,
        target: pollingReference,
    };
}
function resolveOperationLocation(program, property) {
    const override = getFinalLocationValue(program, property);
    if (override)
        return override;
    const resolvedScalar = resolveToScalarType(program, property.type);
    if (resolvedScalar === undefined)
        return undefined;
    return getResourceLocationType(program, resolvedScalar);
}
function resolveToScalarType(program, type) {
    switch (type.kind) {
        case "Scalar":
            return type;
    }
    return undefined;
}

function extractStatusMonitorInfo(program, model, statusProperty) {
    const diagnosticsToToss = createDiagnosticCollector();
    const diagnosticsToKeep = createDiagnosticCollector();
    const lroResult = diagnosticsToKeep.pipe(getLroResult(program, model, true));
    const successProperty = lroResult?.kind === "ModelProperty" ? lroResult : undefined;
    const errorProperty = diagnosticsToKeep.pipe(getLroErrorResult(program, model, true));
    const states = getLongRunningStates(program, statusProperty) ??
        diagnosticsToToss.pipe(extractLroStates(program, statusProperty));
    if (!states || !statusProperty)
        return diagnosticsToKeep.wrap(undefined);
    return diagnosticsToKeep.wrap({
        monitorType: getEffectiveModelType(program, model, (p) => !isMetadata(program, p)) ?? model,
        successProperty: successProperty,
        errorProperty: errorProperty,
        statusProperty: statusProperty,
        lroStates: states,
        errorType: errorProperty?.type.kind === "Model" ? errorProperty.type : undefined,
        successType: successProperty?.type?.kind === "Intrinsic" || successProperty?.type?.kind === "Model"
            ? successProperty.type
            : program.checker.voidType,
        terminationInfo: {
            kind: "model-property",
            property: statusProperty,
            canceledState: states.canceledState,
            failedState: states.failedState,
            succeededState: states.succeededState,
        },
    });
}
function getLroOperationInfo(program, sourceOperation, targetOperation, parameters) {
    const diagnostics = createDiagnosticCollector();
    const targetResponses = diagnostics.pipe(getResponsesForOperation(program, targetOperation));
    const targetParameters = diagnostics.pipe(getOperationParameters(program, targetOperation));
    const targetProperties = new Map();
    const parameterMap = new Map();
    const unmatchedParameters = new Set(targetParameters.parameters.flatMap((p) => p.name));
    for (const parameter of targetParameters.parameters) {
        targetProperties.set(parameter.name, parameter.param);
    }
    if (targetParameters.body) {
        const body = targetParameters.body;
        if (body.bodyKind === "single" && body.property) {
            targetProperties.set(body.property.name, body.property);
        }
        else if (body.type.kind === "Model") {
            for (const [name, param] of getAllProperties(body.type)) {
                targetProperties.set(name, param);
            }
        }
    }
    const sourceResponses = diagnostics.pipe(getResponsesForOperation(program, sourceOperation));
    const sourceParameters = diagnostics.pipe(getOperationParameters(program, sourceOperation));
    const sourceBodyProperties = new Map();
    if (sourceParameters.body && sourceParameters.body.type.kind === "Model") {
        for (const [sourceName, sourceProp] of getAllProperties(sourceParameters.body.type)) {
            sourceBodyProperties.set(sourceName, sourceProp);
            handleExplicitParameterMap(sourceProp, "RequestBody");
        }
    }
    const sourceParamProperties = new Map();
    for (const parameter of sourceParameters.parameters) {
        sourceParamProperties.set(parameter.name, parameter.param);
        handleExplicitParameterMap(parameter.param, "RequestParameter");
    }
    const sourceResponseProperties = new Map();
    let pollingLink = undefined;
    let resultModel;
    for (const response of targetResponses) {
        visitResponse(program, response, (model) => {
            if (!isErrorType(model) && resultModel === undefined) {
                resultModel = model;
            }
        });
    }
    let statusMonitor = undefined;
    for (const response of sourceResponses) {
        visitResponse(program, response, undefined, (name, prop) => {
            sourceResponseProperties.set(name, prop);
            handleExplicitParameterMap(prop, "ResponseBody");
            const link = extractPollinglink(prop);
            if (link && !pollingLink) {
                pollingLink = link;
            }
        });
    }
    gatherLroParameters();
    diagnostics.pipe(getStatusMonitorInfo());
    function gatherLroParameters() {
        if (unmatchedParameters.size > 0) {
            for (const [targetName, targetProperty] of targetProperties) {
                getLroParameterFromProperty(targetName, targetProperty, sourceParamProperties, "RequestParameter");
                sourceBodyProperties.size > 0 &&
                    getLroParameterFromProperty(targetName, targetProperty, sourceBodyProperties, "RequestBody");
                sourceResponseProperties.size > 0 &&
                    getLroParameterFromProperty(targetName, targetProperty, sourceResponseProperties, "ResponseBody");
            }
        }
        if (parameters === undefined)
            return;
        for (const [_, parameter] of getAllProperties(parameters)) {
            processModelPropertyFromParameterMap(parameter);
        }
    }
    function getStatusMonitorInfo() {
        let result = undefined;
        const diagnostics = createDiagnosticCollector();
        for (const response of targetResponses) {
            visitResponse(program, response, (m) => {
                const status = getLroStatusProperty(program, m);
                if (status !== undefined) {
                    result = diagnostics.pipe(extractStatusMonitorInfo(program, m, status));
                }
            });
            if (result) {
                break;
            }
        }
        statusMonitor = result;
        return diagnostics.wrap(result);
    }
    function handleExplicitParameterMap(source, kind) {
        const directMapping = getPollingOperationParameter(program, source);
        if (directMapping === undefined)
            return;
        let targetName = directMapping;
        let targetProperty = directMapping;
        if (targetName.length > 0 && targetProperties.has(targetName)) {
            targetProperty = targetProperties.get(targetName);
        }
        targetName = targetProperty.name;
        parameterMap.set(targetName, { source: source, target: targetProperty, sourceKind: kind });
        unmatchedParameters.delete(targetName);
    }
    function getLroParameterFromProperty(targetName, targetProperty, sourceProperties, sourceKind) {
        const sourceProperty = sourceProperties.get(targetName);
        if (sourceProperty !== undefined) {
            parameterMap.set(targetName, {
                sourceKind: sourceKind,
                source: sourceProperty,
                target: targetProperty,
            });
            unmatchedParameters.delete(targetName);
        }
    }
    function visitResponse(program, response, modelAction, modelPropertyAction) {
        function visitModel(model) {
            modelAction && modelAction(model);
            if (modelPropertyAction) {
                for (const [name, prop] of getAllProperties(model)) {
                    modelPropertyAction(name, prop);
                }
            }
        }
        function visitUnion(union) {
            for (const [_, prop] of union.variants) {
                visitVariant(prop);
            }
        }
        function visitVariant(variant) {
            switch (variant.type.kind) {
                case "Model":
                    visitModel(variant.type);
                    break;
                case "Union":
                    visitUnion(variant.type);
                    break;
            }
        }
        if (isErrorType(response.type))
            return;
        switch (response.type.kind) {
            case "Model":
                visitModel(response.type);
                break;
            case "Union":
                visitUnion(response.type);
                break;
            // throw diagnostic
        }
    }
    function processModelPropertyFromParameterMap(property) {
        if (property.type.kind !== "Model") {
            diagnostics.add(createDiagnostic({
                code: "operation-link-parameter-invalid",
                target: sourceOperation,
                format: {},
            }));
            return;
        }
        const propMap = property.type;
        const typeName = propMap.name;
        const namespace = propMap.namespace?.name;
        if (namespace !== "Core" ||
            (typeName !== "RequestParameter" && typeName !== "ResponseProperty")) {
            diagnostics.add(createDiagnostic({
                code: "operation-link-parameter-invalid",
                target: sourceOperation,
                format: {},
            }));
            return;
        }
        const targetProperty = targetProperties.get(property.name);
        if (targetProperty === undefined) {
            diagnostics.add(createDiagnostic({
                code: "operation-link-parameter-invalid-target",
                target: targetOperation,
                format: { name: property.name },
            }));
            return;
        }
        let sourceProperty = propMap.templateMapper.args[0];
        if (sourceProperty.entityKind === "Indeterminate") {
            sourceProperty = sourceProperty.type;
        }
        else if (!isType(sourceProperty)) {
            compilerAssert(false, "Lro Template Arg should be a Type", propMap);
        }
        switch (sourceProperty.kind) {
            case "String":
                const sourcePropertyName = sourceProperty.value;
                if (typeName === "RequestParameter") {
                    let sourceParam = sourceParamProperties.get(sourcePropertyName);
                    if (sourceParam !== undefined) {
                        unmatchedParameters.delete(property.name);
                        parameterMap.set(property.name, {
                            sourceKind: "RequestParameter",
                            source: sourceParam,
                            target: targetProperty,
                        });
                        return;
                    }
                    sourceParam = sourceBodyProperties.get(sourcePropertyName);
                    if (sourceParam !== undefined) {
                        unmatchedParameters.delete(property.name);
                        parameterMap.set(property.name, {
                            sourceKind: "RequestBody",
                            source: sourceParam,
                            target: targetProperty,
                        });
                        return;
                    }
                    diagnostics.add(createDiagnostic({
                        code: "request-parameter-invalid",
                        target: sourceOperation,
                        format: { name: sourcePropertyName },
                    }));
                    return;
                }
                else if (typeName === "ResponseProperty") {
                    const sourceParam = sourceResponseProperties.get(sourcePropertyName);
                    if (sourceParam === undefined) {
                        diagnostics.add(createDiagnostic({
                            code: "response-property-invalid",
                            target: sourceOperation,
                            format: { name: sourcePropertyName },
                        }));
                        return;
                    }
                    unmatchedParameters.delete(property.name);
                    parameterMap.set(property.name, {
                        source: sourceParam,
                        target: targetProperty,
                        sourceKind: "ResponseBody",
                    });
                }
        }
    }
    function extractPollinglink(property) {
        let isKnownLinkHeader = false;
        if (isHeader(program, property)) {
            const headerName = getHeaderFieldName(program, property).toLowerCase();
            isKnownLinkHeader = headerName === "operation-location";
        }
        if (isPollingLocation(program, property) || isKnownLinkHeader) {
            return {
                kind: "link",
                property: property,
                location: isHeader(program, property) ? "ResponseHeader" : "ResponseBody",
            };
        }
        return undefined;
    }
    function ValidateInfo() {
        return resultModel !== undefined;
    }
    function getInvocationInfo() {
        return {
            operation: targetOperation,
            parameterMap: unmatchedParameters.size < 1 ? parameterMap : undefined,
        };
    }
    function getOperationLink() {
        return pollingLink;
    }
    function getResultInfo() {
        return {
            type: resultModel,
            statusMonitor: statusMonitor,
        };
    }
    return diagnostics.wrap(ValidateInfo() ? { getInvocationInfo, getOperationLink, getResultInfo } : undefined);
}

/*
 * Constants for polling and final operation links
 */
const PollingOperationKey = "polling";
const FinalOperationKey = "final";
// @fixed
const fixedKey = createStateSymbol$1("fixed");
function $fixed(context, target) {
    context.program.stateMap(fixedKey).set(target, true);
}
function isFixed(program, target) {
    return program.stateMap(fixedKey).get(target) !== undefined;
}
// pagedResult
const pagedResultsKey = createStateSymbol$1("pagedResult");
function $pagedResult(context, entity) {
    context.program.stateMap(pagedResultsKey).set(entity, true);
}
function findPathToProperty(program, entity, condition, current = []) {
    for (const prop of entity.properties.values()) {
        const match = condition(prop);
        if (match) {
            const segments = [...current, prop.name];
            return {
                property: prop,
                path: segments.join("."),
                segments,
            };
        }
        else {
            if (prop.type.kind === "Model") {
                const items = findPathToProperty(program, prop.type, condition, [...current, prop.name]);
                if (items !== undefined) {
                    return items;
                }
            }
        }
    }
    return undefined;
}
function _getItems(program, entity) {
    return findPathToProperty(program, entity, (prop) => getItems(program, prop) !== undefined);
}
function _getNextLink(program, entity) {
    return findPathToProperty(program, entity, (prop) => getNextLink(program, prop) !== undefined);
}
/**
 * Find all named models that could have been the source of the given
 * property. This includes the named parents of all property sources in a
 * chain.
 */
function getNamedSourceModels(property) {
    if (!property.sourceProperty) {
        return undefined;
    }
    const set = new Set();
    for (let p = property; p; p = p.sourceProperty) {
        if (p.model?.name) {
            set.add(p.model);
        }
    }
    return set;
}
/**
 * Retrieves PagedResultMetadata for a model, if available. If passed an
 * operation, this will search the operations return type for any paged
 * response and return the PagedResultMetadata for that response.
 */
function getPagedResult(program, entity) {
    let metadata = undefined;
    switch (entity.kind) {
        case "Model":
            if (program.stateMap(pagedResultsKey).get(entity)) {
                metadata = { modelType: entity };
                const items = _getItems(program, entity);
                if (items !== undefined) {
                    metadata.itemsProperty = items.property;
                    // eslint-disable-next-line deprecation/deprecation
                    metadata.itemsPath = items.path;
                    metadata.itemsSegments = items.segments;
                }
                const nextLink = _getNextLink(program, entity);
                if (nextLink !== undefined) {
                    metadata.nextLinkProperty = nextLink.property;
                    // eslint-disable-next-line deprecation/deprecation
                    metadata.nextLinkPath = nextLink.path;
                    metadata.nextLinkSegments = nextLink.segments;
                }
                return metadata;
            }
            else if (entity.templateMapper) {
                for (const arg of entity.templateMapper.args) {
                    metadata = getPagedResult(program, arg);
                    if (metadata !== undefined) {
                        break;
                    }
                }
                break;
            }
            else if (entity.name === "") {
                // for anonymous models, get the effective type of the properties to see if any are paged
                // if they are, then the anonymous model is probably paged too
                for (const property of entity.properties.values()) {
                    const sources = getNamedSourceModels(property);
                    if (sources) {
                        for (const source of sources) {
                            const sourceMetadata = getPagedResult(program, source);
                            if (sourceMetadata) {
                                return sourceMetadata;
                            }
                        }
                    }
                }
            }
            if (entity.baseModel) {
                const parentMetadata = getPagedResult(program, entity.baseModel);
                if (parentMetadata) {
                    parentMetadata.modelType = entity;
                    return parentMetadata;
                }
            }
            break;
        case "Operation":
            switch (entity.returnType.kind) {
                case "Union":
                    for (const variant of entity.returnType.variants.values()) {
                        metadata = getPagedResult(program, variant.type);
                        if (metadata !== undefined) {
                            break;
                        }
                    }
                    break;
                case "Model":
                    metadata = getPagedResult(program, entity.returnType);
                    break;
            }
            if (metadata !== undefined) {
                const nextLinkOperation = getOperationLink(program, entity, "nextPage");
                if (nextLinkOperation !== undefined) {
                    metadata.nextLinkOperation = nextLinkOperation.linkedOperation;
                }
            }
    }
    return metadata;
}
const itemsPropertyKey = createStateSymbol$1("items");
function $items(context, entity) {
    context.program.stateMap(itemsPropertyKey).set(entity, true);
}
/**
 * Returns `true` if the property is marked with `@items`.
 */
function getItems(program, entity) {
    return program.stateMap(itemsPropertyKey).get(entity);
}
const nextLinkPropertyKey = createStateSymbol$1("nextLink");
function $nextLink(context, entity) {
    context.program.stateMap(nextLinkPropertyKey).set(entity, true);
}
/**
 * Returns `true` if the property is marked with `@nextLink`.
 */
function getNextLink(program, entity) {
    return program.stateMap(nextLinkPropertyKey).get(entity);
}
const lroStatusKey = createStateSymbol$1("lroStatus");
function $lroStatus(context, entity) {
    const [states, diagnostics] = extractLroStates(context.program, entity);
    if (diagnostics.length > 0)
        context.program.reportDiagnostics(diagnostics);
    context.program.stateMap(lroStatusKey).set(entity, states);
}
function storeLroState(program, states, name, member) {
    const expectedStates = [
        ["Succeeded", isLroSucceededState, () => states.succeededState.push(name)],
        ["Failed", isLroFailedState, () => states.failedState.push(name)],
        ["Canceled", isLroCanceledState, () => states.canceledState.push(name)],
    ];
    states.states.push(name);
    for (const [knownState, stateTest, setter] of expectedStates) {
        if (name === knownState || (member && stateTest(program, member))) {
            setter();
            break;
        }
    }
}
function extractLroStatesFromUnion(program, entity, lroStateResult, diagnostics) {
    if (entity.kind === "Union") {
        for (const variant of entity.variants.values()) {
            const option = variant.type;
            if (option.kind === "Enum") {
                for (const member of option.members.values()) {
                    storeLroState(program, lroStateResult, member.name, member);
                }
            }
            else if (option.kind === "Union") {
                extractLroStatesFromUnion(program, option, lroStateResult, diagnostics);
            }
            else if (option.kind === "Scalar" && option.name === "string") {
                // Ignore string marking this union as open.
                continue;
            }
            else if (option.kind !== "String") {
                diagnostics.add(createDiagnostic({
                    code: "lro-status-union-non-string",
                    target: option,
                    format: {
                        type: option.kind,
                    },
                }));
                return diagnostics.wrap(undefined);
            }
            else {
                storeLroState(program, lroStateResult, typeof variant.name === "string" ? variant.name : option.value, variant);
            }
        }
    }
    return;
}
function extractLroStates(program, entity) {
    const result = {
        states: [],
        succeededState: [],
        failedState: [],
        canceledState: [],
    };
    const diagnostics = createDiagnosticCollector();
    if (entity.kind === "ModelProperty") {
        // Call the function recursively on the property type
        return extractLroStates(program, entity.type);
    }
    else if (entity.kind === "Enum") {
        for (const member of entity.members.values()) {
            storeLroState(program, result, member.name, member);
        }
    }
    else if (entity.kind === "Union") {
        extractLroStatesFromUnion(program, entity, result, diagnostics);
    }
    else {
        diagnostics.add(createDiagnostic({
            code: "lro-status-property-invalid-type",
            target: entity,
            format: {
                type: entity.kind,
            },
        }));
        return diagnostics.wrap(undefined);
    }
    // Make sure all terminal states have been identified
    const missingStates = [];
    if (result.succeededState.length < 1) {
        missingStates.push("Succeeded");
    }
    if (result.failedState.length < 1) {
        missingStates.push("Failed");
    }
    if (missingStates.length > 0) {
        diagnostics.add(createDiagnostic({
            code: "lro-status-missing",
            target: entity,
            format: {
                states: missingStates.join(", "),
            },
        }));
        return diagnostics.wrap(undefined);
    }
    return diagnostics.wrap(result);
}
/**
 *  Returns the `LongRunningStates` associated with `entity`.
 */
function getLongRunningStates(program, entity) {
    // Is the type a string with known values?
    if (isStringType(program, entity)) {
        // Check the known values enum for LRO states
        const knownValues = getKnownValues(program, entity);
        return knownValues ? getLongRunningStates(program, knownValues) : undefined;
    }
    // Otherwise just check the type itself
    return program.stateMap(lroStatusKey).get(entity);
}
/**
 * Return the property that contains the lro status
 * @param program The program to process
 * @param target The model to check for lro status
 */
function getLroStatusProperty(program, target) {
    function getProvisioningState(props) {
        let innerProps = undefined;
        let result = undefined;
        const innerProperty = props.get("properties");
        result = props.get("provisioningState");
        if (result === undefined &&
            innerProperty !== undefined &&
            innerProperty.type?.kind === "Model") {
            innerProps = getAllProperties(innerProperty.type);
            result = innerProps.get("provisioningState");
        }
        return result;
    }
    const props = getAllProperties(target);
    for (const [_, prop] of props.entries()) {
        let values = program.stateMap(lroStatusKey).get(prop);
        if (values !== undefined)
            return prop;
        if (prop.type.kind === "Enum" || prop.type.kind === "Union") {
            values = program.stateMap(lroStatusKey).get(prop.type);
            if (values !== undefined)
                return prop;
        }
    }
    const statusProp = props.get("status") ?? getProvisioningState(props);
    if (statusProp) {
        const [states, _] = extractLroStates(program, statusProp);
        if (states !== undefined)
            return statusProp;
    }
    return undefined;
}
//@lroResult
const lroResultKey = createStateSymbol$1("lroResult");
/**
 * Marks the property in a StatusMonitor that contains the logical result
 * of a successful operation.
 * @param context The decorator execution context.
 * @param entity The model property that contains the logical result.
 */
function $lroResult(context, entity) {
    const { program } = context;
    program.stateMap(lroResultKey).set(entity, entity);
}
/**
 * Gets the logical result property from a StatusMonitor
 * @param program The program to process.
 * @param entity The StatusMonitor model to process.
 * @param useDefault Use the default result property if no other
 * property is marked. (defaults to true)
 */
function getLroResult(program, entity, useDefault = true) {
    const diagnostics = createDiagnosticCollector();
    let count = 0;
    let resultProperty = undefined;
    let defaultProperty = undefined;
    for (const prop of walkPropertiesInherited(entity)) {
        const candidateProperty = program.stateMap(lroResultKey).get(prop);
        if (candidateProperty !== undefined) {
            resultProperty = candidateProperty;
            count++;
        }
        if (prop.name.toLowerCase() === "result")
            defaultProperty = prop;
    }
    if (count > 1) {
        diagnostics.add(createDiagnostic({
            code: "lro-status-monitor-invalid-result-property",
            target: entity,
            format: { resultType: "result", decorator: "@lroResult" },
        }));
    }
    if (resultProperty === undefined && useDefault)
        resultProperty = defaultProperty;
    if (resultProperty && isNeverType(resultProperty.type))
        resultProperty = undefined;
    return diagnostics.wrap(resultProperty);
}
//@lroErrorResult
const lroErrorResultKey = createStateSymbol$1("lroErrorResult");
/**
 * Marks the property in a StatusMonitor that contains the error result
 * of a failed operation.
 * @param context The decorator execution context.
 * @param entity The model property that contains the error result.
 */
function $lroErrorResult(context, entity) {
    const { program } = context;
    program.stateMap(lroErrorResultKey).set(entity, entity);
}
/**
 * Gets the error result property from a StatusMonitor
 * @param program The program to process.
 * @param entity The StatusMonitor model to process.
 * @param useDefault Use the default error property if no other
 * property is marked. (defaults to true)
 */
function getLroErrorResult(program, entity, useDefault = true) {
    const diagnostics = createDiagnosticCollector();
    let count = 0;
    let resultProperty = undefined;
    let defaultProperty = undefined;
    for (const prop of walkPropertiesInherited(entity)) {
        const candidateProperty = program.stateMap(lroErrorResultKey).get(prop);
        if (candidateProperty !== undefined) {
            resultProperty = candidateProperty;
            count++;
        }
        if (prop.name.toLowerCase() === "error")
            defaultProperty = prop;
    }
    if (count > 1) {
        diagnostics.add(createDiagnostic({
            code: "lro-status-monitor-invalid-result-property",
            target: entity,
            format: { resultType: "error", decorator: "@lroErrorResult" },
        }));
    }
    if (resultProperty === undefined && useDefault)
        resultProperty = defaultProperty;
    return diagnostics.wrap(resultProperty);
}
//@pollingOperationParameter
const pollingParameterKey = createStateSymbol$1("pollingOperationParameter");
function $pollingOperationParameter(context, entity, target) {
    const { program } = context;
    let storedValue;
    switch (target?.kind) {
        case "ModelProperty":
            storedValue = target;
            break;
        case "String":
            storedValue = target.value;
            break;
        default:
            storedValue = undefined;
    }
    program.stateMap(pollingParameterKey).set(entity, storedValue ?? entity.name);
}
function getPollingOperationParameter(program, entity) {
    return program.stateMap(pollingParameterKey).get(entity);
}
// @lroSucceeded
const lroSucceededKey = createStateSymbol$1("lroSucceeded");
function $lroSucceeded(context, entity) {
    context.program.stateSet(lroSucceededKey).add(entity);
}
/**
 *  Returns `true` if the enum member represents a "succeeded" state.
 */
function isLroSucceededState(program, entity) {
    return program.stateSet(lroSucceededKey).has(entity);
}
// @lroCanceled
const lroCanceledKey = createStateSymbol$1("lroCanceled");
function $lroCanceled(context, entity) {
    context.program.stateSet(lroCanceledKey).add(entity);
}
/**
 *  Returns `true` if the enum member represents a "canceled" state.
 */
function isLroCanceledState(program, entity) {
    return program.stateSet(lroCanceledKey).has(entity);
}
// @lroFailed
const lroFailedKey = createStateSymbol$1("lroFailed");
function $lroFailed(context, entity) {
    context.program.stateSet(lroFailedKey).add(entity);
}
/**
 *  Returns `true` if the enum member represents a "failed" state.
 */
function isLroFailedState(program, entity) {
    return program.stateSet(lroFailedKey).has(entity);
}
// @pollingLocation
const pollingLocationsKey = createStateSymbol$1("pollingLocations");
const pollingLocationInfoKey = createStateSymbol$1("pollingLocationInfo");
// keys of the pollingOptions type
const optionsKindKey = "kind";
const finalPropertyKey = "finalProperty";
const pollingModelKey = "pollingModel";
const finalResultKey = "finalResult";
var pollingOptionsKind;
(function (pollingOptionsKind) {
    pollingOptionsKind["StatusMonitor"] = "statusMonitor";
})(pollingOptionsKind || (pollingOptionsKind = {}));
function $pollingLocation(context, entity, options) {
    const { program } = context;
    if (options) {
        if (isNeverType(options))
            return;
        const info = extractPollingLocationInfo(program, entity, options);
        if (info) {
            program.stateMap(pollingLocationInfoKey).set(entity, info);
        }
    }
    program.stateSet(pollingLocationsKey).add(entity);
}
/**
 * Gets polling information stored with a field that contains a link to an Lro polling endpoint
 * @param program The program to check
 * @param target The ModelProperty to check for polling info
 */
function getPollingLocationInfo(program, target) {
    return program.stateMap(pollingLocationInfoKey).get(target);
}
function extractUnionVariantValue(type) {
    if (type.kind === "UnionVariant" && type.type.kind === "String")
        return type.type.value;
    return undefined;
}
function extractPollingLocationInfo(program, target, options) {
    const kind = options.properties.get(optionsKindKey);
    if (kind === undefined)
        return undefined;
    const kindValue = extractUnionVariantValue(kind.type);
    if (kindValue === undefined)
        return undefined;
    const pollingInfo = { target: target };
    const pollingModel = options.properties.get(pollingModelKey)?.type;
    if (pollingModel && pollingModel.kind === "Model")
        pollingInfo.pollingModel = pollingModel;
    if (pollingModel && isVoidType(pollingModel))
        pollingInfo.pollingModel = program.checker.voidType;
    const finalResult = options.properties.get(finalResultKey)?.type;
    if (finalResult && finalResult.kind === "Model")
        pollingInfo.finalResult = finalResult;
    if (finalResult && isVoidType(finalResult))
        pollingInfo.finalResult = program.checker.voidType;
    switch (kindValue) {
        case pollingOptionsKind.StatusMonitor:
            return extractStatusMonitorLocationInfo(program, options, pollingInfo);
        default:
            return undefined;
    }
}
function extractStatusMonitorLocationInfo(program, options, baseInfo) {
    const kind = options.properties.get(optionsKindKey);
    if (kind === undefined || extractUnionVariantValue(kind.type) !== "statusMonitor")
        return undefined;
    if (baseInfo.pollingModel === undefined || baseInfo.pollingModel.kind === "Intrinsic")
        return undefined;
    const finalProperty = options.properties.get(finalPropertyKey)?.type;
    let finalPropertyValue = undefined;
    if (finalProperty && finalProperty.kind === "ModelProperty")
        finalPropertyValue = finalProperty;
    if (finalProperty &&
        finalProperty.kind === "String" &&
        baseInfo.pollingModel.properties.has(finalProperty.value)) {
        finalPropertyValue = baseInfo.pollingModel.properties.get(finalProperty.value);
    }
    if (finalPropertyValue === undefined)
        finalPropertyValue = ignoreDiagnostics(getLroResult(program, baseInfo.pollingModel, true));
    const statusProperty = getLroStatusProperty(program, baseInfo.pollingModel);
    if (statusProperty === undefined)
        return undefined;
    const statusMonitor = ignoreDiagnostics(extractStatusMonitorInfo(program, baseInfo.pollingModel, statusProperty));
    if (statusMonitor === undefined)
        return undefined;
    statusMonitor.successProperty = finalPropertyValue;
    baseInfo.finalResult =
        finalPropertyValue?.type?.kind === "Model" ? finalPropertyValue.type : program.checker.voidType;
    return {
        kind: pollingOptionsKind.StatusMonitor,
        info: statusMonitor,
        ...baseInfo,
    };
}
/**
 *  Returns `true` if the property is marked with @pollingLocation.
 */
function isPollingLocation(program, entity) {
    return program.stateSet(pollingLocationsKey).has(entity);
}
// @finalLocation
const finalLocationsKey = createStateSymbol$1("finalLocations");
const finalLocationResultsKey = createStateSymbol$1("finalLocationResults");
function $finalLocation(context, entity, finalResult) {
    const { program } = context;
    if (finalResult !== undefined && isNeverType(finalResult))
        return;
    program.stateSet(finalLocationsKey).add(entity);
    switch (finalResult?.kind) {
        case "Model":
            program.stateMap(finalLocationResultsKey).set(entity, finalResult);
            break;
        case "Intrinsic":
            if (isVoidType(finalResult)) {
                program.stateMap(finalLocationResultsKey).set(entity, finalResult);
            }
    }
}
/**
 *  Returns `true` if the property is marked with @finalLocation.
 */
function isFinalLocation(program, entity) {
    return program.stateSet(finalLocationsKey).has(entity);
}
function getFinalLocationValue(program, entity) {
    return program.stateMap(finalLocationResultsKey).get(entity);
}
const finalStateOverrideKey = createStateSymbol$1("finalStateOverride");
/**
 * overrides the final state for an lro
 * @param context The execution context for the decorator
 * @param entity The decorated operation
 * @param finalState The desired value for final-state-via
 */
function $useFinalStateVia(context, entity, finalState) {
    const { program } = context;
    let finalStateVia;
    switch (finalState?.toLowerCase()) {
        case "original-uri":
            finalStateVia = FinalStateValue.originalUri;
            break;
        case "operation-location":
            finalStateVia = FinalStateValue.operationLocation;
            break;
        case "location":
            finalStateVia = FinalStateValue.location;
            break;
        case "azure-async-operation":
            finalStateVia = FinalStateValue.azureAsyncOperation;
            break;
        default:
            reportDiagnostic$1(program, {
                code: "invalid-final-state",
                target: entity,
                messageId: "badValue",
                format: { finalStateValue: finalState },
            });
            return;
    }
    const operation = ignoreDiagnostics(getHttpOperation(program, entity));
    const storedValue = validateFinalState(program, operation, finalStateVia);
    if (storedValue !== undefined || operation.verb === "put") {
        program.stateMap(finalStateOverrideKey).set(entity, finalStateVia);
    }
    if (storedValue === undefined &&
        [
            FinalStateValue.operationLocation,
            FinalStateValue.location,
            FinalStateValue.azureAsyncOperation,
        ].includes(finalStateVia)) {
        reportDiagnostic$1(program, {
            code: "invalid-final-state",
            target: entity,
            messageId: "noHeader",
            format: { finalStateValue: finalStateVia },
        });
    }
}
function getLroHeaderName(finalState) {
    switch (finalState) {
        case FinalStateValue.azureAsyncOperation:
            return "azure-asyncoperation";
        case FinalStateValue.location:
            return "location";
        case FinalStateValue.operationLocation:
            return "operation-location";
        default:
            return undefined;
    }
}
function getLroHeader(propertyName) {
    const name = propertyName.toLowerCase();
    switch (name) {
        case "azure-asyncoperation":
        case "location":
        case "operation-location":
            return name;
        default:
            return undefined;
    }
}
function getLroHeaders(response) {
    const result = new Set();
    for (const content of response.responses) {
        if (content.headers) {
            for (const candidate of Object.keys(content.headers)) {
                const headerName = getLroHeader(candidate);
                if (headerName !== undefined) {
                    result.add(headerName);
                }
            }
        }
    }
    return result;
}
function validateFinalState(program, operation, finalState) {
    if (finalState === FinalStateValue.originalUri) {
        if (operation.verb !== "put") {
            reportDiagnostic$1(program, {
                code: "invalid-final-state",
                target: operation.operation,
                messageId: "notPut",
            });
            return undefined;
        }
        return FinalStateValue.originalUri;
    }
    const header = getLroHeaderName(finalState);
    if (header === undefined) {
        reportDiagnostic$1(program, {
            code: "invalid-final-state",
            target: operation.operation,
            messageId: "badValue",
            format: { finalStateValue: finalState },
        });
        return undefined;
    }
    for (const response of operation.responses) {
        const lroHeaders = getLroHeaders(response);
        if (lroHeaders?.has(header)) {
            return finalState;
        }
    }
    return undefined;
}
function validateFinalStates(program, operation, finalStates) {
    const httpOp = ignoreDiagnostics(getHttpOperation(program, operation));
    for (const state of finalStates) {
        if (validateFinalState(program, httpOp, state))
            return state;
    }
    return undefined;
}
/**
 * Get the overridden final state value for this operation, if any
 * @param program The program to process
 * @param operation The operation to check for an override value
 * @returns The FInalStateValue if it exists, otherwise undefined
 */
function getFinalStateOverride(program, operation) {
    return program.stateMap(finalStateOverrideKey).get(operation);
}
function $omitKeyProperties(context, entity) {
    // Delete any key properties from the model
    for (const [key, prop] of entity.properties) {
        if (isKey(context.program, prop)) {
            entity.properties.delete(key);
        }
    }
}
const operationLinkKey = createStateSymbol$1("operationLink");
function $operationLink(context, entity, linkedOperation, linkType, parameters) {
    const { program } = context;
    const [operationInfo, diagnostics] = getLroOperationInfo(program, entity, linkedOperation, parameters);
    if (diagnostics.length > 0) {
        program.reportDiagnostics(diagnostics);
    }
    // An operation may have many operationLinks, so treat them as a collection
    let items = context.program.stateMap(operationLinkKey).get(entity);
    if (items === undefined) {
        items = new Map();
    }
    items.set(linkType, {
        parameters: parameters,
        linkedOperation: linkedOperation,
        linkType: linkType,
        link: operationInfo?.getOperationLink(),
        parameterMap: operationInfo?.getInvocationInfo()?.parameterMap,
        result: operationInfo?.getResultInfo(),
    });
    context.program.stateMap(operationLinkKey).set(entity, items);
}
/**
 * Returns the `OperationLinkMetadata` for a given operation and link type, or undefined.
 */
function getOperationLink(program, entity, linkType) {
    const items = program.stateMap(operationLinkKey).get(entity);
    if (items !== undefined) {
        return items.get(linkType);
    }
    return items;
}
/**
 * Returns the collection of `OperationLinkMetadata` for a given operation, if any, or undefined.
 */
function getOperationLinks(program, entity) {
    return program.stateMap(operationLinkKey).get(entity);
}
function $pollingOperation(context, target, linkedOperation, parameters) {
    const { program } = context;
    const isValidReturnType = target.returnType.kind === "Model" ||
        (target.returnType.kind === "Union" &&
            [...target.returnType.variants.values()].every((x) => x.type.kind === "Model"));
    if (!isValidReturnType) {
        reportDiagnostic$1(context.program, {
            code: "polling-operation-return-model",
            target: target,
        });
        return;
    }
    context.call($operationLink, target, linkedOperation, PollingOperationKey, parameters);
    const operationDetails = getOperationLink(program, target, PollingOperationKey);
    if (operationDetails === undefined || operationDetails.result === undefined) {
        reportDiagnostic$1(context.program, {
            code: "polling-operation-return-model",
            target: target,
        });
        return;
    }
    if (operationDetails.result.statusMonitor === undefined) {
        reportDiagnostic$1(context.program, {
            code: "polling-operation-no-status-monitor",
            target: linkedOperation,
        });
        return;
    }
    if (operationDetails.result.statusMonitor.terminationInfo.succeededState.length < 1) {
        reportDiagnostic$1(context.program, {
            code: "polling-operation-no-lro-success",
            target: operationDetails.result.statusMonitor.monitorType,
        });
    }
    if (operationDetails.result.statusMonitor.terminationInfo.failedState.length < 1) {
        reportDiagnostic$1(context.program, {
            code: "polling-operation-no-lro-failure",
            target: operationDetails.result.statusMonitor.monitorType,
        });
    }
    if (operationDetails.parameterMap === undefined && operationDetails.link === undefined) {
        reportDiagnostic$1(context.program, {
            code: "polling-operation-no-ref-or-link",
            target: target,
        });
    }
}
function $finalOperation(context, entity, linkedOperation, parameters) {
    const { program } = context;
    context.call($operationLink, entity, linkedOperation, FinalOperationKey, parameters);
    const operationDetails = getOperationLink(program, entity, FinalOperationKey);
    if (operationDetails === undefined || operationDetails.result === undefined) {
        reportDiagnostic$1(context.program, {
            code: "invalid-final-operation",
            target: entity,
        });
    }
}
function $nextPageOperation(context, entity, linkedOperation, parameters) {
    context.call($operationLink, entity, linkedOperation, "nextPage", parameters);
}
const requestParameterKey = createStateSymbol$1("requestParameter");
function $requestParameter(context, entity, name) {
    context.program.stateMap(requestParameterKey).set(entity, name);
}
function getRequestParameter(program, entity) {
    if (entity.type.kind !== "Model")
        return undefined;
    const parameterName = program.stateMap(requestParameterKey).get(entity.type);
    return parameterName;
}
const responsePropertyKey = createStateSymbol$1("responseParameter");
function $responseProperty(context, entity, name) {
    context.program.stateMap(responsePropertyKey).set(entity, name);
}
function getResponseProperty(program, entity) {
    if (entity.type.kind !== "Model")
        return undefined;
    const parameterName = program.stateMap(responsePropertyKey).get(entity.type);
    return parameterName;
}
function $spreadCustomParameters(context, entity, customizations) {
    const customParameters = customizations.properties.get("parameters")?.type;
    if (customParameters) {
        if (customParameters.kind !== "Model") {
            // The constraint checker will have complained about this already.
            return;
        }
        // Copy all parameters into this model type
        // TODO: This needs to use the equivalent of Checker.checkSpreadProperty
        // once a helper method is available
        for (const [key, value] of customParameters.properties) {
            entity.properties.set(key, context.program.checker.cloneType(value, {
                sourceProperty: value,
                model: entity,
            }));
        }
    }
}
function $spreadCustomResponseProperties(context, entity, customizations) {
    const customResponseProperties = customizations.properties.get("response")?.type;
    if (customResponseProperties) {
        if (customResponseProperties.kind !== "Model") {
            // The constraint checker will have complained about this already.
            return;
        }
        // Copy all parameters into this model type
        // TODO: This needs to use the equivalent of Checker.checkSpreadProperty
        // once a helper method is available
        for (const [key, value] of customResponseProperties.properties) {
            entity.properties.set(key, context.program.checker.cloneType(value, {
                sourceProperty: value,
                model: entity,
            }));
        }
    }
}
const resourceOperationKey = createStateSymbol$1("resourceOperation");
function $ensureResourceType(context, entity, resourceType) {
    if (resourceType.kind === "TemplateParameter") {
        return;
    }
    // Mark the operation as a resource operation
    context.program.stateSet(resourceOperationKey).add(entity);
    if (resourceType.kind !== "Model") {
        context.program.reportDiagnostic({
            code: "invalid-argument",
            message: `This operation expects a Model for its TResource parameter.`,
            severity: "error",
            target: entity,
        });
        return;
    }
    // If the operation is defined under Azure.Core, ignore these diagnostics.
    // We're only concerned with user-defined operations.
    if (entity.namespace && getNamespaceFullName(entity.namespace).startsWith("Azure.Core")) {
        return;
    }
    const key = getResourceTypeKey(context.program, resourceType);
    if (!key) {
        reportDiagnostic$1(context.program, {
            code: "invalid-resource-type",
            target: entity,
            messageId: "missingKey",
            format: {
                name: getTypeName(resourceType),
            },
        });
        return;
    }
    if (!getSegment(context.program, key.keyProperty)) {
        reportDiagnostic$1(context.program, {
            code: "invalid-resource-type",
            target: entity,
            messageId: "missingSegment",
            format: {
                name: getTypeName(resourceType),
            },
        });
    }
}
function isResourceOperation(program, operation) {
    return program.stateSet(resourceOperationKey).has(operation);
}
const needsRouteKey = createStateSymbol$1("needsRoute");
function $needsRoute(context, entity) {
    // If the operation is not templated, add it to the list of operations to
    // check later
    if (entity.node.templateParameters.length === 0) {
        context.program.stateSet(needsRouteKey).add(entity);
    }
}
function checkRpcRoutes(program) {
    program.stateSet(needsRouteKey).forEach((op) => {
        if (op.node.templateParameters.length === 0 &&
            !isAutoRoute(program, op) &&
            !getRoutePath(program, op)) {
            reportDiagnostic$1(program, {
                code: "rpc-operation-needs-route",
                target: op,
            });
        }
    });
}
const ensureVerbKey = createStateSymbol$1("ensureVerb");
function $ensureVerb(context, entity, templateName, verb) {
    context.program.stateMap(ensureVerbKey).set(entity, [templateName, verb]);
}
function checkEnsureVerb(program) {
    const opMap = program.stateMap(ensureVerbKey);
    for (const [operation, [templateName, requiredVerb]] of opMap.entries()) {
        if (isTemplateDeclarationOrInstance(operation))
            continue;
        const verb = getHttpOperation(program, operation)[0].verb.toString().toLowerCase();
        const reqVerb = requiredVerb.toLowerCase();
        if (verb !== reqVerb) {
            reportDiagnostic$1(program, {
                code: "verb-conflict",
                target: operation,
                format: {
                    templateName: templateName,
                    verb: verb.toUpperCase(),
                    requiredVerb: reqVerb.toUpperCase(),
                },
            });
        }
    }
}
const embeddingVectorKey = createStateSymbol$1("embeddingVector");
/** @internal */
function $embeddingVector(context, entity, elementType) {
    const metadata = {
        elementType: elementType,
    };
    context.program.stateMap(embeddingVectorKey).set(entity, metadata);
}
/**
 * If the provided model is an embedding vector, returns the appropriate metadata; otherwise,
 * returns undefined.
 * @param model the model to query
 * @returns `EmbeddingVectorMetadata`, if applicable, or undefined.
 */
function getAsEmbeddingVector(program, model) {
    return program.stateMap(embeddingVectorKey).get(model);
}
const armResourceIdentifierConfigKey = createStateSymbol$1("armResourceIdentifierConfig");
/** @internal */
function $armResourceIdentifierConfig(context, entity, config) {
    if (config.kind !== "Model")
        return;
    const prop = config.properties.get("allowedResources");
    if (prop === undefined || prop.type.kind !== "Tuple")
        return;
    const [data, diagnostics] = typespecTypeToJson(prop.type, context.getArgumentTarget(0));
    context.program.reportDiagnostics(diagnostics);
    if (data) {
        context.program
            .stateMap(armResourceIdentifierConfigKey)
            .set(entity, { allowedResources: data });
    }
}
/** Returns the config attached to an armResourceIdentifierScalar */
function getArmResourceIdentifierConfig(program, entity) {
    return program.stateMap(armResourceIdentifierConfigKey).get(entity);
}
function $defaultFinalStateVia(context, target, states) {
    const { program } = context;
    const finalStateValues = [];
    for (const finalState of states) {
        switch (finalState?.toLowerCase()) {
            case "operation-location":
                finalStateValues.push(FinalStateValue.operationLocation);
                break;
            case "location":
                finalStateValues.push(FinalStateValue.location);
                break;
            case "azure-async-operation":
                finalStateValues.push(FinalStateValue.azureAsyncOperation);
                break;
            default:
                reportDiagnostic$1(program, {
                    code: "invalid-final-state",
                    target: target,
                    messageId: "badValue",
                    format: { finalStateValue: finalState },
                });
                return;
        }
    }
    const storedValue = validateFinalStates(program, target, finalStateValues);
    if (storedValue !== undefined) {
        program.stateMap(finalStateOverrideKey).set(target, storedValue);
    }
}
setTypeSpecNamespace("Foundations", $omitKeyProperties, $requestParameter, $responseProperty);
setTypeSpecNamespace("Foundations.Private", $spreadCustomResponseProperties, $spreadCustomParameters, $ensureResourceType, $needsRoute, $ensureVerb, $embeddingVector, $armResourceIdentifierConfig, $defaultFinalStateVia);

function hasOperationLocation(program, entity) {
    if (entity.kind === "Model") {
        for (const [_, prop] of entity.properties) {
            if (isHeader(program, prop)) {
                const header = getHeaderFieldName(program, prop);
                return header.toLowerCase() === "operation-location";
            }
        }
    }
    return false;
}
const longRunningOperationsRequirePollingOperation = createRule({
    name: "long-running-polling-operation-required",
    description: "Long-running operations should have a linked polling operation.",
    severity: "warning",
    messages: {
        default: "This operation has an 'Operation-Location' header but no polling operation. Use the '@pollingOperation' decorator to link a status polling operation.",
    },
    create(context) {
        return {
            operation: (op) => {
                // Don't pay attention to operations on templated interfaces that
                // haven't been filled in with parameters yet
                if (!isTemplatedInterfaceOperation(op) &&
                    !isTemplatedOperationSignature(op) &&
                    !isExcludedCoreType(context.program, op)) {
                    // If the response has an Operation-Location header, require a polling endpoint.
                    if ((op.returnType.kind === "Union" &&
                        Array.from(op.returnType.variants.values()).find((v) => hasOperationLocation(context.program, v.type))) ||
                        hasOperationLocation(context.program, op.returnType)) {
                        // Does the operation have a polling operation registered?
                        if (!getOperationLink(context.program, op, "polling")) {
                            context.reportDiagnostic({
                                target: op,
                            });
                        }
                    }
                }
            },
        };
    },
});

/**
 * Tries to convert a union into an enum.
 * If the union only contains the same type of literal options with optionally
 * the base scalar to mark extensibility we can represent this union as an enum of that type.
 *
 * @param union Union to try to convert
 *
 * @example
 *
 * Simple closed string enum
 *
 * ```tsp
 * union PetKind { "cat", "dog" }
 * ```
 *
 * ```ts
 * const [enum, diagnostics] = getUnionAsEnum(union);
 * enum.open === false
 * enum.open.members.get("cat") // { value: "cat", variant: ... }
 * enum.open.members.get("dog") // { value: "dog", variant: ... }
 * ```
 *
 * Simple open string enum
 *
 * ```tsp
 * union PetKind { Cat: "cat", Dog: "dog", string }
 * ```
 *
 * ```ts
 * const [enum, diagnostics] = getUnionAsEnum(union);
 * enum.open === true
 * enum.open.members.get("Cat") // { value: "cat", variant: ... }
 * enum.open.members.get("Dog") // { value: "dog", variant: ... }
 * ```
 *
 * Invalid case
 *
 * ```tsp
 * union PetKind { Cat: "cat", Dog: 123, string }
 * ```
 *
 * ```ts
 * const [enum, diagnostics] = getUnionAsEnum(union);
 * enum === undefined
 * diagnostics.length === 1
 * ```
 */
function getUnionAsEnum(union) {
    return getUnionAsEnumInternal(union, new Set());
}
function getUnionAsEnumInternal(union, visited) {
    if (visited.has(union)) {
        return [undefined, [createDiagnostic({ code: "union-enums-circular", target: union })]];
    }
    visited.add(union);
    const diagnostics = createDiagnosticCollector();
    function reportInvalidKind(type) {
        diagnostics.add(createDiagnostic({
            code: "union-enums-invalid-kind",
            format: { kind: type.kind },
            target: union,
        }));
    }
    const kinds = new Set();
    const members = new Map();
    const flattenedMembers = new Map();
    let open = false;
    let nullable = false;
    for (const variant of union.variants.values()) {
        switch (variant.type.kind) {
            case "Intrinsic":
                if (isNullType(variant.type)) {
                    nullable = true;
                }
                else {
                    reportInvalidKind(variant.type);
                }
                break;
            case "String":
                kinds.add("string");
                members.set(variant.name, { value: variant.type.value, type: variant });
                break;
            case "Number":
                kinds.add("number");
                members.set(variant.name, { value: variant.type.value, type: variant });
                break;
            case "Union":
                const parentUnion = diagnostics.pipe(getUnionAsEnumInternal(variant.type, visited));
                if (parentUnion !== undefined) {
                    kinds.add(parentUnion.kind);
                    if (parentUnion.open) {
                        open = true;
                    }
                    if (parentUnion.nullable) {
                        nullable = true;
                    }
                    for (const [key, value] of parentUnion.flattenedMembers) {
                        flattenedMembers.set(key, value);
                    }
                }
                break;
            case "Enum":
                for (const member of variant.type.members.values()) {
                    kinds.add(typeof member.value === "number" ? "number" : "string");
                    flattenedMembers.set(member.name, { value: member.value ?? member.name, type: member });
                }
                break;
            case "Scalar":
                const scalar = variant.type;
                switch (scalar.name) {
                    case "string":
                        kinds.add("string");
                        open = true;
                        break;
                    case "float":
                    case "float32":
                    case "float64":
                    case "integer":
                    case "int8":
                    case "int16":
                    case "int32":
                    case "int64":
                    case "uint8":
                    case "uint16":
                    case "uint32":
                    case "uint64":
                        kinds.add("number");
                        open = true;
                        break;
                    default:
                        reportInvalidKind(variant.type);
                }
                break;
            default:
                reportInvalidKind(variant.type);
        }
    }
    for (const [key, value] of members) {
        flattenedMembers.set(key, value);
    }
    if (kinds.size > 1) {
        diagnostics.add(createDiagnostic({
            code: "union-enums-multiple-kind",
            format: { kinds: [...kinds].join(", ") },
            target: union,
        }));
    }
    if (diagnostics.diagnostics.length > 0) {
        return diagnostics.wrap(undefined);
    }
    if (flattenedMembers.size === 0) {
        return [undefined, []];
    }
    return [
        {
            kind: [...kinds][0],
            union,
            members,
            flattenedMembers,
            open,
            nullable,
        },
        [],
    ];
}

const noClosedLiteralUnionRule = createRule({
    name: "no-closed-literal-union",
    description: "Unions of literals should include the base scalar type to mark them as open enum.",
    severity: "warning",
    url: "https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-closed-literal-union",
    messages: {
        default: `Union of literals should include the base scalar as a variant to make it an open enum. (ex: \`union Choice { Yes: "yes", No: "no", string };\`).`,
    },
    create(context) {
        return {
            union: (union) => {
                const e = ignoreDiagnostics(getUnionAsEnum(union));
                if (e === undefined) {
                    return;
                }
                if (!e.open) {
                    context.reportDiagnostic({
                        target: union,
                    });
                }
            },
        };
    },
});

const noEnumRule = createRule({
    name: "no-enum",
    description: "Azure services should not use enums.",
    severity: "warning",
    url: "https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-enum",
    messages: {
        default: paramMessage `Azure services should not use the enum keyword. Extensible enums should be defined as unions with "string" as an accepted variant (ex: \`union Choice { Yes: "yes", No: "no", string };\`).`,
    },
    create(context) {
        return {
            enum: (en) => {
                const [_, versions] = getVersionsForEnum(context.program, en);
                if (versions !== undefined && versions.getVersions()[0].enumMember.enum === en) {
                    return;
                }
                context.reportDiagnostic({
                    format: { enumName: en.name },
                    target: en,
                    codefixes: [createEnumToExtensibleUnionCodeFix(en)],
                });
            },
        };
    },
});
function createEnumToExtensibleUnionCodeFix(en) {
    function convertEnumMemberToUnionVariant(node) {
        switch (node.kind) {
            case SyntaxKind.EnumSpreadMember:
                return getSourceLocation(node.target).file.text.slice(node.target.pos, node.target.end);
            case SyntaxKind.EnumMember:
                return node.value
                    ? `${node.id.sv}: ${node.value.kind === SyntaxKind.NumericLiteral
                        ? node.value.value
                        : `"${node.value.value}"`}`
                    : `${node.id.sv}: "${node.id.sv}"`;
        }
    }
    return {
        id: "enum-to-extensible-union",
        label: "Convert to extensible union",
        fix(context) {
            const type = typeof [...en.members.values()][0].value === "number" ? "number" : "string";
            const indent = getIndent(en.node);
            const script = getTypeSpecScript(en.node);
            if (script === undefined) {
                return [];
            }
            return [
                context.replaceText(getSourceLocation(en.node), [
                    getNodeAnnotations(en.node),
                    `union ${en.name} {\n`,
                    `${indent}  `,
                    `${type},\n`,
                    ...en.node.members.map((member) => {
                        return `${getNodeTrivia(script, member)}${getNodeAnnotations(member)}${convertEnumMemberToUnionVariant(member)},`;
                    }),
                    getNodeTrivia(script, en.node.end - 1),
                    "}",
                ].join("")),
            ];
        },
    };
}
function getIndent(node) {
    const source = getSourceLocation(node).file.text;
    const start = source.lastIndexOf("\n", node.pos);
    return source.slice(start + 1, node.pos);
}
function getTypeSpecScript(node) {
    let root = node;
    while (root.parent !== undefined) {
        root = root.parent;
    }
    if (root.kind !== SyntaxKind.TypeSpecScript) {
        return undefined;
    }
    return root;
}
function getNodeTrivia(root, node) {
    const end = typeof node === "number" ? node : node.pos;
    const pos = getPositionBeforeTrivia(root, end);
    return root.file.text.slice(pos, end);
}
function getNodeAnnotations(node) {
    const source = getSourceLocation(node).file.text;
    let endOfTrivia = node.pos;
    for (const directive of node.directives ?? []) {
        if (directive.end > endOfTrivia) {
            endOfTrivia = directive.end;
        }
    }
    for (const doc of node.docs ?? []) {
        if (doc.end > endOfTrivia) {
            endOfTrivia = doc.end;
        }
    }
    if ("decorators" in node) {
        for (const dec of node.decorators ?? []) {
            if (dec.end > endOfTrivia) {
                endOfTrivia = dec.end;
            }
        }
    }
    for (let i = endOfTrivia; i < node.end; i++) {
        if (source[i] === " " || source[i] === "\n") {
            endOfTrivia = i + 1;
        }
        else {
            break;
        }
    }
    return getSourceLocation(node).file.text.slice(node.pos, endOfTrivia);
}

const noErrorStatusCodesRule = createRule({
    name: "no-error-status-codes",
    description: "Recommend using the error response defined by Azure REST API guidelines.",
    severity: "warning",
    messages: {
        default: "Azure REST API guidelines recommend using 'default' error response for all error cases. Avoid defining custom 4xx or 5xx error cases.",
    },
    create(context) {
        return {
            operation: (operation) => {
                if (isExcludedCoreType(context.program, operation))
                    return;
                if (!isAzureSubNamespace(context.program, operation.namespace))
                    return;
                const httpOperation = ignoreDiagnostics(getHttpOperation(context.program, operation));
                if (httpOperation.responses !== undefined) {
                    for (const response of httpOperation.responses) {
                        const statusCode = response.statusCodes;
                        if (typeof statusCode === "number" && statusCode >= 400 && statusCode < 600) {
                            context.reportDiagnostic({
                                target: operation,
                            });
                        }
                    }
                }
            },
        };
    },
});

const noExplicitRoutesResourceOps = createRule({
    name: "no-explicit-routes-resource-ops",
    description: "The @route decorator should not be used on standard resource operation signatures.",
    severity: "warning",
    messages: {
        default: "The @route decorator should not be used on standard resource operation signatures. If you are trying to add a route prefix to an operation use the @route decorator on an interface or namespace instead.",
    },
    create(context) {
        return {
            operation: (operation) => {
                if (isExcludedCoreType(context.program, operation) ||
                    !isResourceOperation(context.program, operation)) {
                    return;
                }
                if (getRoutePath(context.program, operation)) {
                    context.reportDiagnostic({
                        target: operation,
                    });
                }
            },
        };
    },
});

const disallowList = new Set(["integer", "numeric", "float", "decimal"]);
const alternatives = new Map([
    ["integer", "int32"],
    ["numeric", "int32"],
    ["float", "float32"],
    ["decimal", "float32"],
]);
const noGenericNumericRule = createRule({
    name: "no-generic-numeric",
    description: "Don't use generic types. Use more specific types instead.",
    severity: "warning",
    url: "https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-generic-numeric",
    messages: {
        default: paramMessage `Don't use generic type '${"name"}'. Use a more specific type that specifies the bit size, such as '${"alternative"}' instead.`,
        extend: paramMessage `Don't extend generic type '${"name"}'. Use a more specific type that specifies the bit size, such as '${"alternative"}' instead.`,
    },
    create(context) {
        return {
            model: (model) => {
                for (const [_, prop] of model.properties) {
                    if (prop.type.kind === "Scalar") {
                        if (disallowList.has(prop.type.name)) {
                            context.reportDiagnostic({
                                target: prop,
                                format: {
                                    name: prop.type.name,
                                    alternative: alternatives.get(prop.type.name),
                                },
                            });
                        }
                    }
                }
            },
            scalar: (scalar) => {
                // if the scalar is the base scalar, then we don't need to check it as it will surface
                // in usage (for example: as a model property)
                if (disallowList.has(scalar.name)) {
                    return;
                }
                let baseScalar = undefined;
                while (scalar.baseScalar !== undefined) {
                    baseScalar = scalar.baseScalar;
                    break;
                }
                if (baseScalar === undefined) {
                    return;
                }
                if (disallowList.has(baseScalar.name)) {
                    context.reportDiagnostic({
                        target: scalar,
                        messageId: "extend",
                        format: {
                            name: baseScalar.name,
                            alternative: alternatives.get(baseScalar.name),
                        },
                    });
                }
            },
        };
    },
});

const noNullableRule = createRule({
    name: "no-nullable",
    description: "Use `?` for optional properties.",
    severity: "warning",
    messages: {
        default: "Don't use `| null`. If you meant to have an optional property, use `?`. (e.g. `myProp?: string`)",
    },
    create(context) {
        return {
            modelProperty: (property) => {
                if (property.type.kind !== "Union") {
                    return;
                }
                if ([...property.type.variants.values()].some((x) => isNullType(x.type))) {
                    context.reportDiagnostic({
                        target: property,
                    });
                }
            },
        };
    },
});

const noOffsetDateTimeRule = createRule({
    name: "no-offsetdatetime",
    description: "Prefer using `utcDateTime` when representing a datetime unless an offset is necessary.",
    severity: "warning",
    messages: {
        default: "Prefer using `utcDateTime` when representing a datetime unless an offset is necessary.",
    },
    create(context) {
        const [offsetDateTime] = context.program.resolveTypeReference("TypeSpec.offsetDateTime");
        const reportIfOffset = (program, type, target) => {
            if (type === offsetDateTime) {
                context.reportDiagnostic({
                    target,
                });
            }
        };
        return {
            scalar: (model) => {
                if (isExcludedCoreType(context.program, model))
                    return;
                if (model.baseScalar) {
                    reportIfOffset(context.program, model.baseScalar, model);
                }
            },
            modelProperty: (property) => {
                if (isExcludedCoreType(context.program, property))
                    return;
                reportIfOffset(context.program, property.type, property);
            },
            unionVariant: (variant) => {
                if (isExcludedCoreType(context.program, variant))
                    return;
                reportIfOffset(context.program, variant.type, variant);
            },
            operation: (operation) => {
                if (isExcludedCoreType(context.program, operation))
                    return;
                reportIfOffset(context.program, operation.returnType, operation);
            },
        };
    },
});

const operationIdRule = createRule({
    name: "no-operation-id",
    description: "Operation ID is automatically generated by the OpenAPI emitters and should not normally be specified.",
    severity: "warning",
    messages: {
        default: "Operation ID is automatically generated by the OpenAPI emitters and should not normally be specified.",
    },
    create(context) {
        return {
            operation: (operation) => {
                if (isExcludedCoreType(context.program, operation))
                    return;
                for (const dec of operation.decorators) {
                    // See issue https://github.com/microsoft/typespec/issues/1943 for more precise
                    if (dec.decorator.name === "$operationId") {
                        context.reportDiagnostic({
                            format: { operationId: operation.name },
                            target: operation,
                        });
                    }
                }
            },
        };
    },
});

const noResponseBodyRule = createRule({
    name: "no-response-body",
    description: "Ensure that the body is set correctly for the response type.",
    severity: "warning",
    messages: {
        default: `The body of non-204 responses should not be empty.`,
        response204: `The body of 204 response should be empty.`,
    },
    create(context) {
        return {
            operation: (op) => {
                if (isTemplatedInterfaceOperation(op))
                    return;
                if (!isAzureSubNamespace(context.program, op.namespace))
                    return;
                const responses = getResponsesForOperation(context.program, op)[0].find((v) => v.statusCodes !== 204);
                if (responses && !responses.responses.every((v) => v.body)) {
                    context.reportDiagnostic({
                        target: op,
                    });
                }
                const responses204 = getResponsesForOperation(context.program, op)[0].find((v) => v.statusCodes === 204);
                if (responses204 && responses204.responses.some((v) => v.body)) {
                    context.reportDiagnostic({
                        target: op,
                        messageId: "response204",
                    });
                }
            },
        };
    },
});

const noRpcPathParamsRule = createRule({
    name: "no-rpc-path-params",
    description: "Operations defined using RpcOperation should not have path parameters.",
    severity: "warning",
    messages: {
        default: "Operations defined using RpcOperation should not have path parameters. Consider using ResourceAction or ResourceCollectionAction instead.",
    },
    create(context) {
        return {
            operation: (operation) => {
                // First, let's make sure we're not already dealing with a core type or
                // a templated operation signature (whether it's an instance or not)
                if (isExcludedCoreType(context.program, operation) ||
                    operation.node.templateParameters.length !== 0) {
                    return;
                }
                // Walk up the sourceOperation chain to see if we find an RpcOperation
                // from Azure.Core
                const originalOperation = operation;
                while (operation.sourceOperation) {
                    operation = operation.sourceOperation;
                    if (operation.name.endsWith("RpcOperation") &&
                        operation.namespace?.name === "Core" &&
                        operation.namespace?.namespace?.name === "Azure") {
                        // Check the original operation to see if it contains path
                        // parameters.  We only need to check the operation parameters
                        // because the route path is validated against the op parameters
                        // separately.
                        for (const [_, param] of originalOperation.parameters.properties) {
                            if (isPathParam(context.program, param)) {
                                context.reportDiagnostic({
                                    target: originalOperation,
                                });
                                return;
                            }
                        }
                    }
                }
            },
        };
    },
});

const noStringDiscriminatorRule = createRule({
    name: "no-string-discriminator",
    description: "Azure services discriminated models should define the discriminated property as an extensible union.",
    severity: "warning",
    url: "https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/no-string-discriminator",
    messages: {
        default: `Use an extensible union instead of a plain string (ex: \`union PetKind { cat: "cat", dog: "dog", string };\`)`,
        noProp: paramMessage `Discriminated model should define an the discriminator property ${"propName"} with an extensible union as type.`,
    },
    create(context) {
        return {
            model: (model) => {
                const discriminator = getDiscriminator(context.program, model);
                if (discriminator === undefined) {
                    return;
                }
                const prop = model.properties.get(discriminator.propertyName);
                if (prop === undefined) {
                    context.reportDiagnostic({
                        format: { propName: discriminator.propertyName },
                        target: model,
                    });
                }
                else {
                    if (prop.type.kind !== "Union") {
                        context.reportDiagnostic({
                            format: { propName: discriminator.propertyName },
                            target: prop,
                        });
                    }
                }
            },
        };
    },
});

const nonBreakingVersioningRule = createRule({
    name: "non-breaking-versioning",
    description: "Check that only backward compatible versioning change are done to a service.",
    severity: "warning",
    url: "https://azure.github.io/typespec-azure/docs/libraries/azure-core/rules/non-breaking-versioning",
    messages: {
        default: paramMessage `Using ${"action"} is not backward compatible.`,
        addedRequired: "Adding required property is a breaking change.",
        optionalNoDefault: "Property made optional should have a default value.",
    },
    create(context) {
        return {
            model: checkBadVersioningPattern,
            modelProperty: checkBadVersioningPatternForProperty,
            operation: checkBadVersioningPattern,
        };
        function checkBadVersioningPattern(type) {
            if (getRemovedOnVersions(context.program, type) !== undefined) {
                reportBreakingVersioning("@removed", type);
            }
            if (getRenamedFromVersions(context.program, type) !== undefined) {
                reportBreakingVersioning("@renamedFrom", type);
            }
        }
        function checkBadVersioningPatternForProperty(modelProperty) {
            checkBadVersioningPattern(modelProperty);
            if (getAddedOnVersions(context.program, modelProperty) !== undefined &&
                !modelProperty.optional) {
                context.reportDiagnostic({
                    messageId: "addedRequired",
                    target: modelProperty,
                });
            }
            if (getMadeOptionalOn(context.program, modelProperty) !== undefined &&
                modelProperty.default === undefined) {
                context.reportDiagnostic({
                    messageId: "optionalNoDefault",
                    target: modelProperty,
                });
            }
        }
        function reportBreakingVersioning(action, target) {
            context.reportDiagnostic({
                format: { action },
                target,
            });
        }
    },
});

const preferCsvCollectionFormatRule = createRule({
    name: "prefer-csv-collection-format",
    description: `It is recommended to use "csv" for collection format of parameters.`,
    severity: "warning",
    messages: {
        default: `It is recommended to use "csv" for collection format of parameters.`,
    },
    create(context) {
        return {
            modelProperty: (property) => {
                if (isExcludedCoreType(context.program, property))
                    return;
                const headerOptions = getHeaderFieldOptions(context.program, property);
                const queryOptions = getQueryParamOptions(context.program, property);
                if ((headerOptions?.format !== undefined && headerOptions?.format !== "csv") ||
                    (queryOptions?.format !== undefined && queryOptions?.format !== "csv")) {
                    context.reportDiagnostic({
                        target: property,
                    });
                }
            },
        };
    },
});

const preventFormatUse = createRule({
    name: "no-format",
    description: "Azure services should not use the `@format` decorator.",
    severity: "warning",
    messages: {
        default: "Azure services should not use the `@format` decorator.",
    },
    create(context) {
        return {
            scalar: (scalar) => {
                if (isExcludedCoreType(context.program, scalar)) {
                    return;
                }
                for (const dec of scalar.decorators) {
                    if (dec.decorator.name === "$format") {
                        context.reportDiagnostic({
                            target: dec.node ? dec.node : scalar,
                        });
                    }
                }
            },
            modelProperty: (model) => {
                if (isExcludedCoreType(context.program, model)) {
                    return;
                }
                for (const dec of model.decorators) {
                    if (dec.decorator.name === "$format") {
                        context.reportDiagnostic({
                            target: dec.node ? dec.node : model,
                        });
                    }
                }
            },
        };
    },
});

const preventMultipleDiscriminator = createRule({
    name: "no-multiple-discriminator",
    description: "Classes should have at most one discriminator.",
    severity: "warning",
    messages: {
        default: paramMessage `Class hierarchy for '${"name"}' should only have, at most, one discriminator, but found: ${"values"}.`,
    },
    create(context) {
        return {
            model: (model) => {
                const discriminators = new Array();
                let current = model;
                while (current) {
                    const discriminator = getDiscriminator(context.program, current);
                    if (discriminator) {
                        discriminators.push(discriminator);
                    }
                    current = current.baseModel;
                }
                if (discriminators.length > 1) {
                    context.reportDiagnostic({
                        target: model,
                        format: {
                            name: model.name,
                            values: discriminators.flatMap((x) => x.propertyName).join(", "),
                        },
                    });
                }
            },
        };
    },
});

function getTypeReferenceNamespace(program, ref) {
    const baseOperation = program.checker.getTypeForNode(ref);
    return baseOperation.namespace ? getNamespaceFullName(baseOperation.namespace) : "";
}
const preventRestLibraryInterfaces = createRule({
    name: "no-rest-library-interfaces",
    description: "Resource interfaces from the TypeSpec.Rest.Resource library are incompatible with Azure.Core.",
    severity: "warning",
    messages: {
        default: `Resource interfaces from the TypeSpec.Rest.Resource library are incompatible with Azure.Core.`,
    },
    create(context) {
        return {
            interface: (interfaceContext) => {
                // If the interface itself is defined in an approved namespace, skip it
                if (isExcludedCoreType(context.program, interfaceContext)) {
                    return;
                }
                // If any interface in the `extends` list comes from `TypeSpec.Rest.Resource`, mark it
                const restInterface = interfaceContext.node.extends.find((i) => getTypeReferenceNamespace(context.program, i) === "TypeSpec.Rest.Resource");
                if (restInterface) {
                    context.reportDiagnostic({
                        target: interfaceContext,
                    });
                }
            },
        };
    },
});

const preventUnknownType = createRule({
    name: "no-unknown",
    description: "Azure services must not have properties of type `unknown`.",
    severity: "warning",
    messages: {
        default: "Azure services must not have properties of type `unknown`.",
    },
    create(context) {
        return {
            modelProperty: (modelContext) => {
                if (isUnknownType(modelContext.type)) {
                    context.reportDiagnostic({
                        target: modelContext,
                    });
                }
            },
        };
    },
});

const propertyNameRule = createRule({
    name: "property-name-conflict",
    description: "Avoid naming conflicts between a property and a model of the same name.",
    severity: "warning",
    messages: {
        default: paramMessage `Property '${"propertyName"}' having the same name as its enclosing model will cause problems with C# code generation. Consider renaming the property directly or using the @clientName("newName", "csharp") decorator to rename the property for C#.`,
    },
    create(context) {
        return {
            modelProperty: (property) => {
                if (isExcludedCoreType(context.program, property))
                    return;
                const modelName = property.model?.name.toLocaleLowerCase();
                const propertyName = property.name.toLocaleLowerCase();
                if (propertyName === modelName) {
                    context.reportDiagnostic({
                        format: { propertyName: property.name },
                        target: property,
                    });
                }
            },
        };
    },
});

function validateIsRecordType(context, type, target) {
    if (type.kind === "Intrinsic" && type.name === "unknown") {
        context.reportDiagnostic({
            messageId: "extendUnknown",
            target: target,
            format: { name: target.name, typeName: type.name, keyword: "is" },
        });
    }
    else if (type.kind === "Scalar" && target.properties.size > 0) {
        context.reportDiagnostic({
            messageId: "recordWithProperties",
            target: target,
            format: { name: target.name, typeName: type.name, keyword: "is" },
        });
    }
}
function validateExtendsRecordType(context, baseModel, target) {
    if (!baseModel.indexer) {
        return;
    }
    const indexerVal = baseModel.indexer.value;
    if (indexerVal.kind === "Intrinsic" && indexerVal.name === "unknown") {
        context.reportDiagnostic({
            messageId: "extendUnknown",
            target: target,
            format: { name: target.name, typeName: indexerVal.name, keyword: "extends" },
        });
    }
    else if (indexerVal.kind === "Scalar" && target.properties.size > 0) {
        context.reportDiagnostic({
            messageId: "recordWithProperties",
            target: target,
            format: { name: target.name, typeName: indexerVal.name, keyword: "extends" },
        });
    }
}
function validatePropertyRecordType(context, type, target) {
    if (type.kind === "Model" && type.indexer) {
        const indexerVal = type.indexer.value;
        if (indexerVal.kind === "Intrinsic" && indexerVal.name === "unknown") {
            const displayName = target.model ? `${target.model.name}.${target.name}` : target.name;
            context.reportDiagnostic({
                messageId: "extendUnknown",
                target: target,
                format: {
                    name: displayName,
                    typeName: indexerVal.name,
                    keyword: ":",
                },
            });
        }
    }
}
const recordTypeRule = createRule({
    name: "bad-record-type",
    description: "Identify bad record definitions.",
    severity: "warning",
    messages: {
        extendUnknown: paramMessage `${"name"} should not use '${"keyword"} Record<${"typeName"}>'. Use '${"keyword"} Record<string>' instead.`,
        recordWithProperties: paramMessage `${"name"} that uses '${"keyword"} Record<${"typeName"}>' should not have properties.`,
    },
    create(context) {
        return {
            model: (model) => {
                if (model.indexer && model.name !== "Record") {
                    validateIsRecordType(context, model.indexer.value, model);
                }
                else if (model.baseModel) {
                    validateExtendsRecordType(context, model.baseModel, model);
                }
            },
            modelProperty: (prop) => {
                if (prop.type.kind === "Model" && prop.type.indexer) {
                    validatePropertyRecordType(context, prop.type, prop);
                }
            },
        };
    },
});

const bodyArrayRule = createRule({
    name: "request-body-problem",
    description: "Request body should not be of raw array type.",
    severity: "warning",
    messages: {
        array: "Request body should not be of raw array type. Consider creating a container model that can add properties over time to avoid introducing breaking changes.",
    },
    create(context) {
        return {
            operation: (op) => {
                for (const prop of op.parameters.properties.values()) {
                    if ((isBody(context.program, prop) || isBodyRoot(context.program, prop)) &&
                        prop.type.kind === "Model" &&
                        prop.type.name === "Array") {
                        context.reportDiagnostic({
                            target: prop,
                            messageId: "array",
                        });
                    }
                }
            },
        };
    },
});

/** Versioning enums are self-documenting and don't need separate documentation. */
function isExcludedVersionEnum(program, enumObj) {
    const versions = getVersionsForEnum(program, enumObj);
    if (versions !== undefined && versions.length > 0) {
        return true;
    }
    return false;
}
function findDiscriminator(program, model) {
    if (!model)
        return undefined;
    const disc = getDiscriminator(program, model);
    if (disc) {
        return disc;
    }
    return findDiscriminator(program, model.baseModel);
}
/** Discriminator enums and unions are self-documenting and don't need separate documentation. */
function isExcludedDiscriminator(program, type, discTypes) {
    if (type.kind === "ModelProperty") {
        const disc = findDiscriminator(program, type.model);
        if (disc && disc.propertyName === type.name) {
            return true;
        }
    }
    else if (type.kind === "Enum" || type.kind === "Union") {
        for (const [discType, discName] of discTypes) {
            if (discType.kind === "Model") {
                const discObj = discType.properties.get(discName.propertyName);
                if (discObj?.type === type) {
                    return true;
                }
            }
        }
    }
    return false;
}
function getUnionName(union) {
    if (union.name !== undefined) {
        return union.name;
    }
    return undefined;
}
function getVariantName(variant) {
    if (variant.name !== undefined && typeof variant.name === "string") {
        return variant.name;
    }
    if (variant.type.kind === "String") {
        return variant.type.value;
    }
    return undefined;
}
const requireDocumentation = createRule({
    name: "documentation-required",
    description: "Require documentation over enums, models, and operations.",
    severity: "warning",
    messages: {
        default: paramMessage `The ${"kind"} named '${"name"}' should have a documentation or description, use doc comment /** */ to provide it.`,
    },
    create(context) {
        const discTypes = getDiscriminatedTypes(context.program);
        return {
            enum: (enumObj) => {
                // version enums and enum members are considered intrinsically self-documenting
                if (isExcludedVersionEnum(context.program, enumObj)) {
                    return;
                }
                if (isExcludedDiscriminator(context.program, enumObj, discTypes)) {
                    return;
                }
                if (!getDoc(context.program, enumObj) && !isExcludedCoreType(context.program, enumObj)) {
                    context.reportDiagnostic({
                        target: enumObj,
                        format: { kind: enumObj.kind, name: enumObj.name },
                    });
                }
                for (const member of enumObj.members.values()) {
                    if (!getDoc(context.program, member)) {
                        context.reportDiagnostic({
                            target: member,
                            format: { kind: member.kind, name: member.name },
                        });
                    }
                }
            },
            operation: (operation) => {
                // Don't pay attention to operations on templated interfaces that
                // haven't been filled in with parameters yet
                if (!isTemplatedInterfaceOperation(operation) &&
                    !isTemplatedOperationSignature(operation) &&
                    !isExcludedCoreType(context.program, operation)) {
                    if (!getDoc(context.program, operation)) {
                        context.reportDiagnostic({
                            target: operation,
                            format: { kind: operation.kind, name: operation.name },
                        });
                    }
                    for (const param of operation.parameters.properties.values()) {
                        if (!getDoc(context.program, param)) {
                            context.reportDiagnostic({
                                target: param,
                                format: { kind: param.kind, name: param.name },
                            });
                        }
                    }
                }
            },
            model: (model) => {
                // it's by design that the `getDoc` function can't get the `doc` for template declaration type.
                if (!isTemplateDeclarationType(model) &&
                    !isInlineModel(model) &&
                    !isExcludedCoreType(context.program, model) &&
                    model.name !== "object") {
                    if (!getDoc(context.program, model)) {
                        context.reportDiagnostic({
                            target: model,
                            format: { kind: model.kind, name: model.name },
                        });
                    }
                    for (const prop of model.properties.values()) {
                        // Properties that are discriminators are considered self-documenting
                        if (isExcludedDiscriminator(context.program, prop, discTypes)) {
                            return;
                        }
                        if (!getDoc(context.program, prop)) {
                            context.reportDiagnostic({
                                target: prop,
                                format: { kind: prop.kind, name: prop.name },
                            });
                        }
                    }
                }
            },
            union: (union) => {
                if (isExcludedDiscriminator(context.program, union, discTypes)) {
                    return;
                }
                if (!getDoc(context.program, union) && !isExcludedCoreType(context.program, union)) {
                    const name = getUnionName(union);
                    if (name !== undefined) {
                        context.reportDiagnostic({
                            target: union,
                            format: { kind: union.kind, name: name },
                        });
                    }
                }
                for (const variant of union.variants.values()) {
                    if (!getDoc(context.program, variant)) {
                        // symbols don't need documentation
                        const variantName = getVariantName(variant);
                        if (variantName !== undefined) {
                            context.reportDiagnostic({
                                target: variant,
                                format: { kind: variant.kind, name: variantName },
                            });
                        }
                    }
                }
            },
        };
    },
});

const requireKeyVisibility = createRule({
    name: "key-visibility-required",
    description: "Key properties need to have an explicit visibility setting.",
    severity: "warning",
    messages: {
        default: paramMessage `The key property '${"name"}' does not have an explicit visibility setting, please use the @visibility decorator to set it.`,
    },
    create(context) {
        return {
            model: (model) => {
                if (!isTemplateDeclarationType(model) &&
                    !isInlineModel(model) &&
                    !isExcludedCoreType(context.program, model) &&
                    model.name !== "object") {
                    for (const [name, prop] of model.properties) {
                        if (isKey(context.program, prop) && !getVisibility(context.program, prop)) {
                            context.reportDiagnostic({
                                target: prop,
                                format: { name },
                            });
                        }
                    }
                }
            },
        };
    },
});

const responseSchemaMultiStatusCodeRule = createRule({
    name: "response-schema-problem",
    description: "Warn about operations having multiple non-error response schemas.",
    severity: "warning",
    messages: {
        multipleSuccessSchemas: paramMessage `Operation '${"name"}' has multiple non-error response schemas. Did you forget to add '@error' to one of them?`,
    },
    create(context) {
        return {
            operation: (op) => {
                const httpOp = ignoreDiagnostics(getHttpOperation(context.program, op));
                const responses = httpOp.responses.flatMap((x) => x.responses);
                const metadataInfo = createMetadataInfo(context.program, {
                    canonicalVisibility: Visibility.Read,
                });
                let firstResponse = undefined;
                for (const resp of responses) {
                    const body = resp.body;
                    if (body === undefined)
                        continue;
                    const bodyType = body.type;
                    let currResponse = undefined;
                    switch (bodyType.kind) {
                        case "Model":
                            const effModel = metadataInfo.getEffectivePayloadType(bodyType, Visibility.Read);
                            if (isErrorModel(context.program, effModel))
                                continue;
                            currResponse = effModel;
                            break;
                        default:
                            currResponse = bodyType;
                            break;
                    }
                    if (firstResponse === undefined) {
                        firstResponse = currResponse;
                    }
                    else if (firstResponse !== currResponse) {
                        context.reportDiagnostic({
                            target: op,
                            messageId: "multipleSuccessSchemas",
                            format: {
                                name: op.name,
                            },
                        });
                        return;
                    }
                }
            },
        };
    },
});

const rpcOperationRequestBodyRule = createRule({
    name: "rpc-operation-request-body",
    description: "Warning for RPC body problems.",
    severity: "warning",
    messages: {
        default: `There is an issue with the RPCOperation request body.`,
        noBodyAllowed: paramMessage `RPCOperation with '@${"verb"}' cannot have a body.`,
    },
    create(context) {
        return {
            operation: (operation) => {
                if (isExcludedCoreType(context.program, operation))
                    return;
                if (operation.node.templateParameters.length !== 0)
                    return;
                if (!isAzureSubNamespace(context.program, operation.namespace))
                    return;
                const originalOperation = operation;
                while (operation.sourceOperation) {
                    operation = operation.sourceOperation;
                    if (operation.name === "RpcOperation" &&
                        operation.namespace?.name === "Core" &&
                        operation.namespace?.namespace?.name === "Azure") {
                        const httpOperation = getHttpOperation(context.program, originalOperation)[0];
                        const bodyParam = httpOperation.parameters.body;
                        const verb = httpOperation.verb.toLowerCase();
                        if ((verb === "get" || verb === "delete") && bodyParam !== undefined) {
                            context.reportDiagnostic({
                                target: originalOperation,
                                messageId: "noBodyAllowed",
                                format: { verb: verb },
                            });
                        }
                    }
                }
            },
        };
    },
});

const spreadDiscriminatedModelRule = createRule({
    name: "spread-discriminated-model",
    description: "Check a model with a discriminator has not been used in composition.",
    severity: "warning",
    messages: {
        default: paramMessage `Model '${"name"}' is being spread but has a discriminator. The relation between those 2 models will be lost and defeat the purpose of \`@discriminator\` Consider using \`extends\` instead.`,
    },
    create(context) {
        const visited = new Set();
        return {
            modelProperty: (property) => {
                const model = property.model;
                if (model &&
                    model.node?.kind === SyntaxKind.ModelStatement &&
                    property.sourceProperty &&
                    property.sourceProperty.model) {
                    const targetModel = property.sourceProperty.model;
                    if (visited.has(targetModel)) {
                        return;
                    }
                    visited.add(targetModel);
                    if (model.sourceModel === targetModel) {
                        return;
                    }
                    if (getDiscriminator(context.program, targetModel) !== undefined) {
                        const diagnosticTarget = model.node.properties.find((x) => x.kind === SyntaxKind.ModelSpreadProperty &&
                            context.program.checker.getTypeForNode(x.target) === targetModel) ?? model;
                        context.reportDiagnostic({
                            format: {
                                name: targetModel.name,
                            },
                            target: diagnosticTarget,
                        });
                    }
                }
            },
        };
    },
});

function isArmProviderNamespace(ns) {
    if (!ns)
        return false;
    for (const dec of ns.decorators) {
        if (dec.decorator.name === "$armProviderNamespace") {
            return true;
        }
    }
    return false;
}
function isArmResourceOperations(inter) {
    if (!inter)
        return false;
    for (const dec of inter.decorators) {
        if (dec.decorator.name === "$armResourceOperations") {
            return true;
        }
    }
    return false;
}
const useStandardNames = createRule({
    name: "use-standard-names",
    description: "Use recommended names for operations.",
    severity: "warning",
    messages: {
        get: "GET operations that return single objects should start with 'get'",
        list: "GET operations that return lists should start with 'list'",
        createOrReplace: "PUT operations that return both 201 and 200 should start with 'createOrReplace'",
        putCreate: "PUT operations that return 201 should start with 'create' or 'createOrReplace'",
        putReplace: "PUT operations that return 200 should start with 'replace' or 'createOrReplace'",
        patch: "PATCH operations that return 201 should start with 'create', 'update', or 'createOrUpdate'",
        delete: "DELETE operations should start with 'delete'",
    },
    create(context) {
        return {
            operation: (op) => {
                if (isArmProviderNamespace(op.namespace))
                    return;
                if (isArmResourceOperations(op.interface))
                    return;
                if (isTemplateDeclarationOrInstance(op))
                    return;
                if (isExcludedCoreType(context.program, op))
                    return;
                if (!isAzureSubNamespace(context.program, op.namespace))
                    return;
                const httpOp = ignoreDiagnostics(getHttpOperation(context.program, op));
                const verb = httpOp.verb;
                const name = op.name;
                const statusCodes = httpOp.responses.map((x) => x.statusCodes.toString());
                // operation is a list if it is decoratored as such (for example, through a template) or returns a paged result
                const isList = isListOperation(context.program, op) || getPagedResult(context.program, op) !== undefined;
                let errorMessage;
                switch (verb) {
                    case "get":
                        if (isList && !name.startsWith("list")) {
                            errorMessage = "list";
                        }
                        else if (!isList && !name.startsWith("get")) {
                            errorMessage = "get";
                        }
                        break;
                    case "put":
                        const is201 = statusCodes.includes("201");
                        const is200 = statusCodes.includes("200");
                        if (is201 && is200 && !name.startsWith("createOrReplace")) {
                            errorMessage = "createOrReplace";
                        }
                        else if (is201 &&
                            !is200 &&
                            !["create", "createOrReplace"].some((x) => name.startsWith(x))) {
                            errorMessage = "putCreate";
                        }
                        else if (is200 &&
                            !is201 &&
                            !["replace", "createOrReplace"].some((x) => name.startsWith(x))) {
                            errorMessage = "putReplace";
                        }
                        break;
                    case "patch":
                        const allowed = ["create", "update", "createOrUpdate".toLocaleLowerCase()];
                        if (statusCodes.includes("201") && !allowed.some((x) => name.startsWith(x))) {
                            errorMessage = "patch";
                        }
                        break;
                    case "delete":
                        if (!name.startsWith("delete")) {
                            errorMessage = "delete";
                        }
                        break;
                }
                if (errorMessage !== undefined) {
                    context.reportDiagnostic({
                        messageId: errorMessage,
                        target: op,
                    });
                }
            },
        };
    },
});

// HACK HACK HACK: This should be removed once Azure.Core-compatible
// Azure.ResourceManager operations are added
let checkStandardOperationsEnabled = true;
function __unsupported_enable_checkStandardOperations(enabled) {
    checkStandardOperationsEnabled = enabled;
}
function derivesFromAzureCoreOperation(program, operation) {
    // Check every link in the signature chain
    while (operation.node.signature.kind === SyntaxKind.OperationSignatureReference) {
        const baseOp = program.checker.getTypeForNode(operation.node.signature.baseOperation);
        if (baseOp.namespace && getNamespaceFullName(baseOp.namespace) === "Azure.Core") {
            return true;
        }
        // See if the base operation ultimately derives from an Azure.Core operation
        operation = baseOp;
    }
    return false;
}
const useStandardOperations = createRule({
    name: "use-standard-operations",
    description: "Operations should be defined using a signature from the Azure.Core namespace.",
    severity: "warning",
    messages: {
        default: paramMessage `Operation '${"name"}' should be defined using a signature from the Azure.Core namespace.`,
    },
    create(context) {
        return {
            operation: (operationContext) => {
                // HACK HACK HACK: This should be removed once Azure.Core-compatible
                // Azure.ResourceManager operations are added
                if (!checkStandardOperationsEnabled)
                    return;
                // Can we skip this operation?  Either it or the interface it's defined in
                // has to be defined in an approved namespace, or the operation itself must
                // be templated.
                if ((operationContext.interface &&
                    isExcludedCoreType(context.program, operationContext.interface)) ||
                    (!operationContext.interface && isExcludedCoreType(context.program, operationContext)) ||
                    isTemplateDeclarationOrInstance(operationContext)) {
                    return;
                }
                // If the operation comes from a TypeSpec.Rest.Resource interface, skip it
                // because another linting rule will mark the whole interface instead
                if (operationContext.interface &&
                    operationContext.namespace &&
                    getNamespaceFullName(operationContext.namespace) === "TypeSpec.Rest.Resource") {
                    return;
                }
                // Otherwise, if the operation signature is a raw declaration or does not
                // derive from an operation in Azure.Core, it violates this linting rule.
                if (operationContext.node.signature.kind === SyntaxKind.OperationSignatureDeclaration ||
                    !derivesFromAzureCoreOperation(context.program, operationContext)) {
                    context.reportDiagnostic({
                        // If the namespace where the operation's interface is defined is
                        // different than the namespace we're in, mark the operation's
                        // interface instead so that the diagnostic doesn't end up on a
                        // library operation
                        target: operationContext.interface &&
                            operationContext.interface.namespace !== operationContext.namespace
                            ? operationContext.interface
                            : operationContext,
                        format: {
                            name: operationContext.name,
                        },
                    });
                }
            },
        };
    },
});

const rules = [
    apiVersionRule,
    authRequiredRule,
    bodyArrayRule,
    byosRule,
    casingRule,
    compositionOverInheritanceRule,
    knownEncodingRule,
    longRunningOperationsRequirePollingOperation,
    noClosedLiteralUnionRule,
    noEnumRule,
    noErrorStatusCodesRule,
    noExplicitRoutesResourceOps,
    nonBreakingVersioningRule,
    noGenericNumericRule,
    noNullableRule,
    noOffsetDateTimeRule,
    noResponseBodyRule,
    noRpcPathParamsRule,
    operationIdRule,
    preferCsvCollectionFormatRule,
    preventFormatUse,
    preventMultipleDiscriminator,
    preventRestLibraryInterfaces,
    preventUnknownType,
    propertyNameRule,
    recordTypeRule,
    requireDocumentation,
    requireKeyVisibility,
    responseSchemaMultiStatusCodeRule,
    rpcOperationRequestBodyRule,
    spreadDiscriminatedModelRule,
    useStandardNames,
    useStandardOperations,
    noStringDiscriminatorRule,
    friendlyNameRule,
];
const $linter = defineLinter({
    rules,
    ruleSets: {
        "canonical-versioning": {
            enable: {
                [`@azure-tools/typespec-azure-core/${nonBreakingVersioningRule.name}`]: true,
            },
        },
    },
});

const traitSourceKey = createStateSymbol$1("traitSource");
function $traitSource(context, target, traitName) {
    // Store the source trait name on the envelope property
    context.program.stateMap(traitSourceKey).set(target, traitName);
}
/**
 * Retrieves the `traitName` stored for the given `property`, if any.
 * @param program Program object with context for the current compilation
 * @param property The model property for which the trait name should be retrieved
 */
function getSourceTraitName(program, property) {
    return program.stateMap(traitSourceKey).get(property);
}
setTypeSpecNamespace("Traits.Private", $traitSource);
const traitKey = createStateSymbol$1("trait");
function $trait(context, target, traitName) {
    if (target.properties.size !== 1) {
        reportDiagnostic$1(context.program, {
            code: "invalid-trait-property-count",
            target: target,
            format: {
                modelName: target.name,
            },
        });
        return;
    }
    // If the traitName parameter wasn't specified, use the trait type name
    traitName = traitName ?? getTypeName(target, { namespaceFilter: (ns) => false });
    // Extract the envelope property
    const [envelopeName] = target.properties.keys();
    const envelopeProperty = target.properties.get(envelopeName);
    // Ensure the envelope property is a model type
    if (envelopeProperty.type.kind !== "Model") {
        reportDiagnostic$1(context.program, {
            code: "invalid-trait-property-type",
            target: target,
            format: {
                modelName: target.name,
                propertyName: envelopeName,
            },
        });
        return;
    }
    // Ensure that all properties in the envelope property type have a location
    for (const [_, traitProperty] of envelopeProperty.type.properties) {
        if (!getTraitLocation(context.program, traitProperty)) {
            reportDiagnostic$1(context.program, {
                code: "trait-property-without-location",
                target: target,
                format: {
                    modelName: target.name,
                    propertyName: traitProperty.name,
                },
            });
        }
    }
    // Mark the property with the trait name
    context.call($traitSource, envelopeProperty, traitName);
    // Manually push the decorator onto the property so that it's copyable when
    // using model intersections and spreads
    envelopeProperty.decorators.push({
        decorator: $traitSource,
        args: [{ value: context.program.checker.createLiteralType(traitName), jsValue: traitName }],
    });
    // Mark the model as a trait type and store its name
    context.program.stateMap(traitKey).set(target, traitName);
}
setTypeSpecNamespace("Traits", $trait);
/*
 * Returns true if the `model` is marked with the `@trait` decorator.
 * @param program Program object with context for the current compilation
 * @param property The model type to consider
 */
function isTraitModel(program, model) {
    return program.stateMap(traitKey).has(model) !== undefined;
}
/*
 * Returns the trait name of the model type if it was marked with `@trait`.
 * @param program Program object with context for the current compilation
 * @param property The model type to consider
 */
function getTraitName(program, model) {
    return program.stateMap(traitKey).get(model);
}
const traitContextKey = createStateSymbol$1("traitContext");
function $traitContext(context, target, traitContext) {
    context.program
        .stateMap(traitContextKey)
        .set(target, normalizeTraitContexts(context.program, traitContext));
}
setTypeSpecNamespace("Traits", $traitContext);
function normalizeTraitContexts(program, contexts) {
    if (contexts.kind === "EnumMember") {
        return [contexts];
    }
    else if (contexts.kind === "Union") {
        const members = [];
        for (const variant of contexts.variants.values()) {
            if (variant.type.kind === "EnumMember") {
                members.push(variant.type);
            }
            else {
                reportDiagnostic$1(program, {
                    code: "invalid-trait-context",
                    target: variant,
                });
            }
        }
        return members;
    }
    else if (contexts.kind === "Intrinsic") {
        // This is a special case: treat 'unknown' as if the user never called
        // `traitContext`.  This is used when a reusable trait type needs to convey
        // that it has no context in some cases.
        if (contexts.name !== "unknown") {
            reportDiagnostic$1(program, {
                code: "invalid-trait-context",
                target: contexts,
            });
        }
    }
    return [];
}
function getTraitContextsOrUndefined(program, property) {
    // Sometimes we need to know whether a trait context was explicitly set on a
    // property without defaulting to an empty array
    return program.stateMap(traitContextKey).get(property);
}
/*
 * Retrieves the trait context stored for the given `property`, if any.  Returns
 * an empty list if no contexts are registered for the property.
 * @param program Program object with context for the current compilation
 * @param property The model property for which the trait contexts should be retrieved
 */
function getTraitContexts(program, property) {
    return program.stateMap(traitContextKey).get(property) || [];
}
const traitLocationKey = createStateSymbol$1("traitLocation");
function $traitLocation(context, target, traitLocation) {
    context.program.stateMap(traitLocationKey).set(target, traitLocation);
}
setTypeSpecNamespace("Traits", $traitLocation);
/*
 * Retrieves the trait location stored for the given `property`, if any.
 * @param program Program object with context for the current compilation
 * @param property The model property for which the trait location should be retrieved
 */
function getTraitLocation(program, property) {
    return program.stateMap(traitLocationKey).get(property);
}
const traitAddedKey = Symbol("traitLocation");
function $traitAdded(context, target, addedVersion) {
    if (addedVersion.kind !== "EnumMember") {
        // The type is probably "null" so don't do anything
        return;
    }
    if (target.kind === "Model") {
        if (target.properties.size !== 1) {
            // The @trait decorator has already raised a diagnostic so skip it.
            return;
        }
        // Invoke the decorator on the sole envelope property
        const envelopeProperty = target.properties.values().next().value;
        context.call($traitAdded, envelopeProperty, addedVersion);
        // Manually push the decorator onto the property so that it's copyable when
        // using model intersections and spreads
        envelopeProperty.decorators.push({
            decorator: $traitAdded,
            args: [{ value: addedVersion, jsValue: addedVersion }],
        });
    }
    // Save the version on the envelope property so that it can be used later when
    // we copy out trait properties
    context.program.stateMap(traitAddedKey).set(target, addedVersion);
}
function getTraitAddedVersion(program, envelopeProperty) {
    return program.stateMap(traitAddedKey).get(envelopeProperty);
}
setTypeSpecNamespace("Traits", $traitAdded);
function $addTraitProperties(context, target, traitModel, traitLocation, traitContexts) {
    // Keep track of all traits applied
    const appliedTraits = new Set();
    // Search the trait model for all trait property types that satisfy the
    // criteria for this trait location and context list
    const { program } = context;
    for (const [_, traitEnvelope] of traitModel.properties) {
        // Check whether the envelope property is marked with a traitAdded version
        const addedVersion = getTraitAddedVersion(context.program, traitEnvelope);
        // Make sure we're looking at a trait that we haven't already processed
        const traitName = getSourceTraitName(program, traitEnvelope);
        if (traitName && !appliedTraits.has(traitName)) {
            // Extract any applicable constants from the trait envelope
            const contexts = getTraitContexts(context.program, traitEnvelope);
            // Ensure that the trait envelope is actually a model
            if (traitEnvelope.type.kind !== "Model") {
                // The @trait decorator has already raised a diagnostic
                return;
            }
            // For each property in the envelope type, check if the property matches
            // the criteria of the usage site
            for (const [_, traitProperty] of traitEnvelope.type.properties) {
                // Each property inside of the trait envelope property's model can have
                // its own trait contexts which override the contexts of the trait
                // envelope.  We only apply an override if one is set, though.
                const contextsOverride = getTraitContextsOrUndefined(context.program, traitProperty);
                if (checkTraitPropertyCriteria(program, traitProperty, contextsOverride ?? contexts, traitLocation, normalizeTraitContexts(program, traitContexts))) {
                    if (traitProperty.type.kind !== "Model") {
                        // In the future, TraitType will enable passing non-model types
                        // directly to a location.  Regardless, non-model types can not be
                        // spread into a TraitProperties, so skip it.
                        return;
                    }
                    // Copy the contents of the trait property's model type into the
                    // target model
                    for (const [name, property] of traitProperty.type.properties) {
                        // TODO: This needs to use the equivalent of Checker.checkSpreadProperty
                        // once a helper method is available
                        target.properties.set(name, context.program.checker.cloneType(property, {
                            sourceProperty: property,
                            model: target,
                            decorators: [
                                ...property.decorators,
                                ...(addedVersion
                                    ? [
                                        {
                                            decorator: $added,
                                            args: [{ value: addedVersion, jsValue: addedVersion }],
                                        },
                                    ]
                                    : []),
                            ],
                        }));
                        appliedTraits.add(traitName);
                    }
                }
            }
        }
    }
}
function checkTraitPropertyCriteria(program, property, traitContexts, expectedLocation, expectedContexts) {
    const location = getTraitLocation(program, property);
    if (!location) {
        // Don't error here, the validator will take care of it
        return false;
    }
    // Traits and trait usage sites must always specify a location, so check that
    // first.  After that, check if the trait specifies any contexts.  If not, the
    // trait applies anywhere.  Otherwise, the location's contexts *must* have at
    // least one context that matches the trait's contexts.
    return (location === expectedLocation &&
        (traitContexts.length === 0 || !!traitContexts.find((c) => expectedContexts.indexOf(c) > -1)));
}
setTypeSpecNamespace("Traits.Private", $addTraitProperties);
// This variable is used globally to ensure that all overridden traits get a
// unique envelope property name.
let traitOverrideCounter = 1;
function $applyTraitOverride(context, target, traitModel) {
    if (traitModel.properties.size !== 1) {
        // The @trait decorator has already raised a diagnostic so skip it.
        return;
    }
    // If we've already populated this type then it must have been evaluated
    // previously for the trait type
    if (target.properties.size > 0) {
        return;
    }
    // Rename the sole envelope property to make it unique
    traitOverrideCounter++;
    const [envelopeName] = traitModel.properties.keys();
    const overrideName = `${envelopeName}Override${traitOverrideCounter}`;
    const envelopeProperty = traitModel.properties.get(envelopeName);
    target.properties.set(overrideName, context.program.checker.cloneType(envelopeProperty, {
        name: overrideName,
        model: target,
        sourceProperty: envelopeProperty,
    }));
}
setTypeSpecNamespace("Traits.Private", $applyTraitOverride);
function $ensureTraitsPresent(context, target, traitModel, expectedTraits) {
    // Gather all of the trait names from the envelope properties
    const traitsPresent = new Set();
    for (const [_, envelopeProperty] of traitModel.properties) {
        const traitName = getSourceTraitName(context.program, envelopeProperty);
        if (traitName) {
            traitsPresent.add(traitName);
        }
    }
    function getPropertyString(model, propertyName) {
        const val = model.properties.get(propertyName);
        return val && val.type.kind === "String" ? val.type.value : undefined;
    }
    // Check all of the expected trait types
    for (const expected of expectedTraits.values) {
        if (expected.kind === "Model") {
            // These model traits have two fields: trait and message
            const trait = getPropertyString(expected, "trait");
            if (trait && !traitsPresent.has(trait)) {
                const diagnosticName = getPropertyString(expected, "diagnostic");
                if (!diagnosticName) {
                    reportDiagnostic$1(context.program, {
                        code: "expected-trait-diagnostic-missing",
                        target: expected,
                    });
                }
                else {
                    reportDiagnostic$1(context.program, {
                        code: diagnosticName,
                        target: target,
                    });
                }
            }
        }
    }
}
setTypeSpecNamespace("Traits.Private", $ensureTraitsPresent);
function $ensureAllQueryParams(context, target, paramModel) {
    for (const [_, param] of paramModel.properties) {
        if (!isQueryParam(context.program, param)) {
            reportDiagnostic$1(context.program, {
                code: "invalid-parameter",
                target: target,
                format: {
                    propertyName: param.name,
                    kind: "query",
                },
            });
        }
    }
}
setTypeSpecNamespace("Traits.Private", $ensureAllQueryParams);
function $ensureAllHeaderParams(context, target, paramModel) {
    for (const [_, param] of paramModel.properties) {
        if (!isHeader(context.program, param)) {
            reportDiagnostic$1(context.program, {
                code: "invalid-parameter",
                target: target,
                format: {
                    propertyName: param.name,
                    kind: "header",
                },
            });
        }
    }
}
setTypeSpecNamespace("Traits.Private", $ensureAllHeaderParams);

function $onValidate(program) {
    checkRpcRoutes(program);
    checkEnsureVerb(program);
}

const namespace = "Azure.Core";

var f0 = /*#__PURE__*/Object.freeze({
    __proto__: null,
    $addTraitProperties: $addTraitProperties,
    $applyTraitOverride: $applyTraitOverride,
    $armResourceIdentifierConfig: $armResourceIdentifierConfig,
    $defaultFinalStateVia: $defaultFinalStateVia,
    $embeddingVector: $embeddingVector,
    $ensureAllHeaderParams: $ensureAllHeaderParams,
    $ensureAllQueryParams: $ensureAllQueryParams,
    $ensureResourceType: $ensureResourceType,
    $ensureTraitsPresent: $ensureTraitsPresent,
    $ensureVerb: $ensureVerb,
    $finalLocation: $finalLocation,
    $finalOperation: $finalOperation,
    $fixed: $fixed,
    $items: $items,
    $lib: $lib,
    $linter: $linter,
    $lroCanceled: $lroCanceled,
    $lroErrorResult: $lroErrorResult,
    $lroFailed: $lroFailed,
    $lroResult: $lroResult,
    $lroStatus: $lroStatus,
    $lroSucceeded: $lroSucceeded,
    $needsRoute: $needsRoute,
    $nextLink: $nextLink,
    $nextPageOperation: $nextPageOperation,
    $omitKeyProperties: $omitKeyProperties,
    $onValidate: $onValidate,
    $operationLink: $operationLink,
    $pagedResult: $pagedResult,
    $pollingLocation: $pollingLocation,
    $pollingOperation: $pollingOperation,
    $pollingOperationParameter: $pollingOperationParameter,
    $requestParameter: $requestParameter,
    $responseProperty: $responseProperty,
    $spreadCustomParameters: $spreadCustomParameters,
    $spreadCustomResponseProperties: $spreadCustomResponseProperties,
    $trait: $trait,
    $traitAdded: $traitAdded,
    $traitContext: $traitContext,
    $traitLocation: $traitLocation,
    $traitSource: $traitSource,
    $useFinalStateVia: $useFinalStateVia,
    FinalOperationKey: FinalOperationKey,
    get FinalStateValue () { return FinalStateValue; },
    PollingOperationKey: PollingOperationKey,
    __unsupported_enable_checkStandardOperations: __unsupported_enable_checkStandardOperations,
    checkEnsureVerb: checkEnsureVerb,
    checkRpcRoutes: checkRpcRoutes,
    extractLroStates: extractLroStates,
    filterModelProperties: filterModelProperties,
    filterResponseModels: filterResponseModels,
    getAllProperties: getAllProperties,
    getArmResourceIdentifierConfig: getArmResourceIdentifierConfig,
    getAsEmbeddingVector: getAsEmbeddingVector,
    getFinalLocationValue: getFinalLocationValue,
    getFinalStateOverride: getFinalStateOverride,
    getHttpMetadata: getHttpMetadata,
    getItems: getItems,
    getLongRunningStates: getLongRunningStates,
    getLroErrorResult: getLroErrorResult,
    getLroMetadata: getLroMetadata,
    getLroResult: getLroResult,
    getLroStatusProperty: getLroStatusProperty,
    getNextLink: getNextLink,
    getOperationLink: getOperationLink,
    getOperationLinks: getOperationLinks,
    getOperationResponse: getOperationResponse,
    getPagedResult: getPagedResult,
    getPollingLocationInfo: getPollingLocationInfo,
    getPollingOperationParameter: getPollingOperationParameter,
    getRequestParameter: getRequestParameter,
    getResponseProperty: getResponseProperty,
    getResultModelWithProperty: getResultModelWithProperty,
    getSourceTraitName: getSourceTraitName,
    getSuccessResponse: getSuccessResponse,
    getTraitContexts: getTraitContexts,
    getTraitLocation: getTraitLocation,
    getTraitName: getTraitName,
    getUnionAsEnum: getUnionAsEnum,
    isFinalLocation: isFinalLocation,
    isFixed: isFixed,
    isLroCanceledState: isLroCanceledState,
    isLroFailedState: isLroFailedState,
    isLroSucceededState: isLroSucceededState,
    isPollingLocation: isPollingLocation,
    isResourceOperation: isResourceOperation,
    isTraitModel: isTraitModel,
    namespace: namespace,
    get pollingOptionsKind () { return pollingOptionsKind; },
    preventRestLibraryInterfaces: preventRestLibraryInterfaces,
    useStandardOperations: useStandardOperations
});

const TypeSpecJSSources = {
"dist/src/index.js": f0,
};
const TypeSpecSources = {
  "package.json": "{\"name\":\"@azure-tools/typespec-azure-core\",\"version\":\"0.44.0\",\"author\":\"Microsoft Corporation\",\"description\":\"TypeSpec Azure Core library\",\"homepage\":\"https://azure.github.io/typespec-azure\",\"docusaurusWebsite\":\"https://azure.github.io/typespec-azure/docs\",\"readme\":\"https://github.com/Azure/typespec-azure/blob/main/packages/typespec-azure-core/README.md\",\"license\":\"MIT\",\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/Azure/typespec-azure.git\"},\"bugs\":{\"url\":\"https://github.com/Azure/typespec-azure/issues\"},\"keywords\":[\"typespec\"],\"main\":\"dist/src/index.js\",\"tspMain\":\"lib/azure-core.tsp\",\"exports\":{\".\":{\"types\":\"./dist/src/index.d.ts\",\"default\":\"./dist/src/index.js\"},\"./testing\":{\"types\":\"./dist/src/testing/index.d.ts\",\"default\":\"./dist/src/testing/index.js\"}},\"type\":\"module\",\"engines\":{\"node\":\">=18.0.0\"},\"scripts\":{\"clean\":\"rimraf ./dist ./temp\",\"build\":\"tsc -p . && npm run lint-typespec-library\",\"watch\":\"tsc -p . --watch\",\"lint-typespec-library\":\"tsp compile . --warn-as-error --import @typespec/library-linter --no-emit\",\"test\":\"vitest run\",\"test:watch\":\"vitest -w\",\"test:ui\":\"vitest --ui\",\"test:ci\":\"vitest run --coverage  --reporter=junit --reporter=default\",\"lint\":\"eslint .  --max-warnings=0\",\"lint:fix\":\"eslint . --fix \",\"regen-docs\":\"tspd doc .  --enable-experimental  --output-dir ../../docs/libraries/azure-core/reference\"},\"files\":[\"lib/*.tsp\",\"dist/**\",\"!dist/test/**\"],\"peerDependencies\":{\"@typespec/compiler\":\"workspace:~\",\"@typespec/http\":\"workspace:~\",\"@typespec/rest\":\"workspace:~\"},\"devDependencies\":{\"@types/node\":\"~18.11.19\",\"@typespec/compiler\":\"workspace:~\",\"@typespec/http\":\"workspace:~\",\"@typespec/library-linter\":\"workspace:~\",\"@typespec/openapi\":\"workspace:~\",\"@typespec/rest\":\"workspace:~\",\"@typespec/tspd\":\"workspace:~\",\"@typespec/versioning\":\"workspace:~\",\"@vitest/coverage-v8\":\"^1.6.0\",\"@vitest/ui\":\"^1.6.0\",\"c8\":\"^10.1.2\",\"rimraf\":\"~5.0.7\",\"typescript\":\"~5.5.3\",\"vitest\":\"^1.6.0\"}}",
  "../../core/packages/compiler/lib/intrinsics.tsp": "import \"../dist/src/lib/intrinsic-decorators.js\";\n\n// This file contains all the intrinsic types of typespec. Everything here will always be loaded\nnamespace TypeSpec;\n\n/**\n * Represent a byte array\n */\nscalar bytes;\n\n/**\n * A numeric type\n */\nscalar numeric;\n\n/**\n * A whole number. This represent any `integer` value possible.\n * It is commonly represented as `BigInteger` in some languages.\n */\nscalar integer extends numeric;\n\n/**\n * A number with decimal value\n */\nscalar float extends numeric;\n\n/**\n * A 64-bit integer. (`-9,223,372,036,854,775,808` to `9,223,372,036,854,775,807`)\n */\nscalar int64 extends integer;\n\n/**\n * A 32-bit integer. (`-2,147,483,648` to `2,147,483,647`)\n */\nscalar int32 extends int64;\n\n/**\n * A 16-bit integer. (`-32,768` to `32,767`)\n */\nscalar int16 extends int32;\n\n/**\n * A 8-bit integer. (`-128` to `127`)\n */\nscalar int8 extends int16;\n\n/**\n * A 64-bit unsigned integer (`0` to `18,446,744,073,709,551,615`)\n */\nscalar uint64 extends integer;\n\n/**\n * A 32-bit unsigned integer (`0` to `4,294,967,295`)\n */\nscalar uint32 extends uint64;\n\n/**\n * A 16-bit unsigned integer (`0` to `65,535`)\n */\nscalar uint16 extends uint32;\n\n/**\n * A 8-bit unsigned integer (`0` to `255`)\n */\nscalar uint8 extends uint16;\n\n/**\n * An integer that can be serialized to JSON (`−9007199254740991 (−(2^53 − 1))` to `9007199254740991 (2^53 − 1)` )\n */\nscalar safeint extends int64;\n\n/**\n * A 32 bit floating point number. (`±1.5 x 10^−45` to `±3.4 x 10^38`)\n */\nscalar float64 extends float;\n\n/**\n * A 32 bit floating point number. (`±5.0 × 10^−324` to `±1.7 × 10^308`)\n */\nscalar float32 extends float64;\n\n/**\n * A decimal number with any length and precision. This represent any `decimal` value possible.\n * It is commonly represented as `BigDecimal` in some languages.\n */\nscalar decimal extends numeric;\n\n/**\n * A 128-bit decimal number.\n */\nscalar decimal128 extends decimal;\n\n/**\n * A sequence of textual characters.\n */\nscalar string;\n\n/**\n * A date on a calendar without a time zone, e.g. \"April 10th\"\n */\nscalar plainDate {\n  /**\n   * Create a plain date from an ISO 8601 string.\n   * @example\n   *\n   * ```tsp\n   * const time = plainTime.fromISO(\"2024-05-06\");\n   * ```\n   */\n  init fromISO(value: string);\n}\n\n/**\n * A time on a clock without a time zone, e.g. \"3:00 am\"\n */\nscalar plainTime {\n  /**\n   * Create a plain time from an ISO 8601 string.\n   * @example\n   *\n   * ```tsp\n   * const time = plainTime.fromISO(\"12:34\");\n   * ```\n   */\n  init fromISO(value: string);\n}\n\n/**\n * An instant in coordinated universal time (UTC)\"\n */\nscalar utcDateTime {\n  /**\n   * Create a date from an ISO 8601 string.\n   * @example\n   *\n   * ```tsp\n   * const time = utcDateTime.fromISO(\"2024-05-06T12:20-12Z\");\n   * ```\n   */\n  init fromISO(value: string);\n}\n\n/**\n * A date and time in a particular time zone, e.g. \"April 10th at 3:00am in PST\"\n */\nscalar offsetDateTime {\n  /**\n   * Create a date from an ISO 8601 string.\n   * @example\n   *\n   * ```tsp\n   * const time = offsetDateTime.fromISO(\"2024-05-06T12:20-12-0700\");\n   * ```\n   */\n  init fromISO(value: string);\n}\n\n/**\n * A duration/time period. e.g 5s, 10h\n */\nscalar duration {\n  /**\n   * Create a duration from an ISO 8601 string.\n   * @example\n   *\n   * ```tsp\n   * const time = duration.fromISO(\"P1Y1D\");\n   * ```\n   */\n  init fromISO(value: string);\n}\n\n/**\n * Boolean with `true` and `false` values.\n */\nscalar boolean;\n\n/**\n * @dev Array model type, equivalent to `Element[]`\n * @template Element The type of the array elements\n */\n@indexer(integer, Element)\nmodel Array<Element> {}\n\n/**\n * @dev Model with string properties where all the properties have type `Property`\n * @template Element The type of the properties\n */\n@indexer(string, Element)\nmodel Record<Element> {}\n",
  "../../core/packages/compiler/lib/std/main.tsp": "// TypeSpec standard library. Everything in here can be omitted by using `--nostdlib` cli flag or `nostdlib` in the config.\nimport \"./types.tsp\";\nimport \"./decorators.tsp\";\nimport \"./reflection.tsp\";\nimport \"./projected-names.tsp\";\n",
  "../../core/packages/compiler/lib/std/types.tsp": "namespace TypeSpec;\n\n/**\n * Represent a 32-bit unix timestamp datetime with 1s of granularity.\n * It measures time by the number of seconds that have elapsed since 00:00:00 UTC on 1 January 1970.\n */\n@encode(\"unixTimestamp\", int32)\nscalar unixTimestamp32 extends utcDateTime;\n\n/**\n * Represent a model\n */\n// Deprecated June 2023 sprint\n#deprecated \"object is deprecated. Please use {} for an empty model, `Record<unknown>` for a record with unknown property types, `unknown[]` for an array.\"\nmodel object {}\n\n/**\n * Represent a URL string as described by https://url.spec.whatwg.org/\n */\nscalar url extends string;\n\n/**\n * Represents a collection of optional properties.\n *\n * @template Source An object whose spread properties are all optional.\n */\n@doc(\"The template for adding optional properties.\")\n@withOptionalProperties\nmodel OptionalProperties<Source> {\n  ...Source;\n}\n\n/**\n * Represents a collection of updateable properties.\n *\n * @template Source An object whose spread properties are all updateable.\n */\n@doc(\"The template for adding updateable properties.\")\n@withUpdateableProperties\nmodel UpdateableProperties<Source> {\n  ...Source;\n}\n\n/**\n * Represents a collection of omitted properties.\n *\n * @template Source An object whose properties are spread.\n * @template Keys The property keys to omit.\n */\n@doc(\"The template for omitting properties.\")\n@withoutOmittedProperties(Keys)\nmodel OmitProperties<Source, Keys extends string> {\n  ...Source;\n}\n\n/**\n * Represents a collection of properties with only the specified keys included.\n *\n * @template Source An object whose properties are spread.\n * @template Keys The property keys to include.\n */\n@doc(\"The template for picking properties.\")\n@withPickedProperties(Keys)\nmodel PickProperties<Source, Keys extends string> {\n  ...Source;\n}\n\n/**\n * Represents a collection of properties with default values omitted.\n *\n * @template Source An object whose spread property defaults are all omitted.\n */\n@withoutDefaultValues\nmodel OmitDefaults<Source> {\n  ...Source;\n}\n\n/**\n * Applies a visibility setting to a collection of properties.\n *\n * @template Source An object whose properties are spread.\n * @template Visibility The visibility to apply to all properties.\n */\n@doc(\"The template for setting the default visibility of key properties.\")\n@withDefaultKeyVisibility(Visibility)\nmodel DefaultKeyVisibility<Source, Visibility extends valueof string> {\n  ...Source;\n}\n",
  "../../core/packages/compiler/lib/std/decorators.tsp": "import \"../../dist/src/lib/decorators.js\";\n\nusing TypeSpec.Reflection;\n\nnamespace TypeSpec;\n\n/**\n * Typically a short, single-line description.\n * @param summary Summary string.\n *\n * @example\n * ```typespec\n * @summary(\"This is a pet\")\n * model Pet {}\n * ```\n */\nextern dec summary(target: unknown, summary: valueof string);\n\n/**\n * Attach a documentation string.\n * @param doc Documentation string\n * @param formatArgs Record with key value pair that can be interpolated in the doc.\n *\n * @example\n * ```typespec\n * @doc(\"Represent a Pet available in the PetStore\")\n * model Pet {}\n * ```\n */\nextern dec doc(target: unknown, doc: valueof string, formatArgs?: {});\n\n/**\n * Attach a documentation string to describe the successful return types of an operation.\n * If an operation returns a union of success and errors it only describes the success. See `@errorsDoc` for error documentation.\n * @param doc Documentation string\n *\n * @example\n * ```typespec\n * @returnsDoc(\"Returns doc\")\n * op get(): Pet | NotFound;\n * ```\n */\nextern dec returnsDoc(target: Operation, doc: valueof string);\n\n/**\n * Attach a documentation string to describe the error return types of an operation.\n * If an operation returns a union of success and errors it only describes the errors. See `@returnsDoc` for success documentation.\n * @param doc Documentation string\n *\n * @example\n * ```typespec\n * @errorsDoc(\"Errors doc\")\n * op get(): Pet | NotFound;\n * ```\n */\nextern dec errorsDoc(target: Operation, doc: valueof string);\n\n/**\n * Mark this type as deprecated.\n *\n * NOTE: This decorator **should not** be used, use the `#deprecated` directive instead.\n *\n * @deprecated Use the `#deprecated` directive instead.\n * @param message Deprecation message.\n *\n * @example\n *\n * Use the `#deprecated` directive instead:\n *\n * ```typespec\n * #deprecated \"Use ActionV2\"\n * op Action<Result>(): Result;\n * ```\n */\n#deprecated \"@deprecated decorator is deprecated. Use the `#deprecated` directive instead.\"\nextern dec deprecated(target: unknown, message: valueof string);\n\n/**\n * Service options.\n */\nmodel ServiceOptions {\n  /**\n   * Title of the service.\n   */\n  title?: string;\n\n  /**\n   * Version of the service.\n   */\n  version?: string;\n}\n\n/**\n * Mark this namespace as describing a service and configure service properties.\n * @param options Optional configuration for the service.\n *\n * @example\n * ```typespec\n * @service\n * namespace PetStore;\n * ```\n *\n * @example Setting service title\n * ```typespec\n * @service({title: \"Pet store\"})\n * namespace PetStore;\n * ```\n *\n * @example Setting service version\n * ```typespec\n * @service({version: \"1.0\"})\n * namespace PetStore;\n * ```\n */\nextern dec service(target: Namespace, options?: ServiceOptions);\n\n/**\n * Specify that this model is an error type. Operations return error types when the operation has failed.\n *\n * @example\n * ```typespec\n * @error\n * model PetStoreError {\n *   code: string;\n *   message: string;\n * }\n * ```\n */\nextern dec error(target: Model);\n\n/**\n * Specify a known data format hint for this string type. For example `uuid`, `uri`, etc.\n * This differs from the `@pattern` decorator which is meant to specify a regular expression while `@format` accepts a known format name.\n * The format names are open ended and are left to emitter to interpret.\n *\n * @param format format name.\n *\n * @example\n * ```typespec\n * @format(\"uuid\")\n * scalar uuid extends string;\n * ```\n */\nextern dec format(target: string | bytes | ModelProperty, format: valueof string);\n\n/**\n * Specify the the pattern this string should respect using simple regular expression syntax.\n * The following syntax is allowed: alternations (`|`), quantifiers (`?`, `*`, `+`, and `{ }`), wildcard (`.`), and grouping parentheses.\n * Advanced features like look-around, capture groups, and references are not supported.\n *\n * This decorator may optionally provide a custom validation _message_. Emitters may choose to use the message to provide\n * context when pattern validation fails. For the sake of consistency, the message should be a phrase that describes in\n * plain language what sort of content the pattern attempts to validate. For example, a complex regular expression that\n * validates a GUID string might have a message like \"Must be a valid GUID.\"\n *\n * @param pattern Regular expression.\n * @param validationMessage Optional validation message that may provide context when validation fails.\n *\n * @example\n * ```typespec\n * @pattern(\"[a-z]+\", \"Must be a string consisting of only lower case letters and of at least one character.\")\n * scalar LowerAlpha extends string;\n * ```\n */\nextern dec pattern(\n  target: string | bytes | ModelProperty,\n  pattern: valueof string,\n  validationMessage?: valueof string\n);\n\n/**\n * Specify the minimum length this string type should be.\n * @param value Minimum length\n *\n * @example\n * ```typespec\n * @minLength(2)\n * scalar Username extends string;\n * ```\n */\nextern dec minLength(target: string | ModelProperty, value: valueof integer);\n\n/**\n * Specify the maximum length this string type should be.\n * @param value Maximum length\n *\n * @example\n * ```typespec\n * @maxLength(20)\n * scalar Username extends string;\n * ```\n */\nextern dec maxLength(target: string | ModelProperty, value: valueof integer);\n\n/**\n * Specify the minimum number of items this array should have.\n * @param value Minimum number\n *\n * @example\n * ```typespec\n * @minItems(1)\n * model Endpoints is string[];\n * ```\n */\nextern dec minItems(target: unknown[] | ModelProperty, value: valueof integer);\n\n/**\n * Specify the maximum number of items this array should have.\n * @param value Maximum number\n *\n * @example\n * ```typespec\n * @maxItems(5)\n * model Endpoints is string[];\n * ```\n */\nextern dec maxItems(target: unknown[] | ModelProperty, value: valueof integer);\n\n/**\n * Specify the minimum value this numeric type should be.\n * @param value Minimum value\n *\n * @example\n * ```typespec\n * @minValue(18)\n * scalar Age is int32;\n * ```\n */\nextern dec minValue(target: numeric | ModelProperty, value: valueof numeric);\n\n/**\n * Specify the maximum value this numeric type should be.\n * @param value Maximum value\n *\n * @example\n * ```typespec\n * @maxValue(200)\n * scalar Age is int32;\n * ```\n */\nextern dec maxValue(target: numeric | ModelProperty, value: valueof numeric);\n\n/**\n * Specify the minimum value this numeric type should be, exclusive of the given\n * value.\n * @param value Minimum value\n *\n * @example\n * ```typespec\n * @minValueExclusive(0)\n * scalar distance is float64;\n * ```\n */\nextern dec minValueExclusive(target: numeric | ModelProperty, value: valueof numeric);\n\n/**\n * Specify the maximum value this numeric type should be, exclusive of the given\n * value.\n * @param value Maximum value\n *\n * @example\n * ```typespec\n * @maxValueExclusive(50)\n * scalar distance is float64;\n * ```\n */\nextern dec maxValueExclusive(target: numeric | ModelProperty, value: valueof numeric);\n\n/**\n * Mark this string as a secret value that should be treated carefully to avoid exposure\n *\n * @example\n * ```typespec\n * @secret\n * scalar Password is string;\n * ```\n */\nextern dec secret(target: string | ModelProperty);\n\n/**\n * Mark this operation as a `list` operation for resource types.\n * @deprecated Use the `listsResource` decorator in `@typespec/rest` instead.\n * @param listedType Optional type of the items in the list.\n */\nextern dec list(target: Operation, listedType?: Model);\n\n/**\n * Attaches a tag to an operation, interface, or namespace. Multiple `@tag` decorators can be specified to attach multiple tags to a TypeSpec element.\n * @param tag Tag value\n */\nextern dec tag(target: Namespace | Interface | Operation, tag: valueof string);\n\n/**\n * Specifies how a templated type should name their instances.\n * @param name name the template instance should take\n * @param formatArgs Model with key value used to interpolate the name\n *\n * @example\n * ```typespec\n * @friendlyName(\"{name}List\", T)\n * model List<Item> {\n *   value: Item[];\n *   nextLink: string;\n * }\n * ```\n */\nextern dec friendlyName(target: unknown, name: valueof string, formatArgs?: unknown);\n\n/**\n * Provide a set of known values to a string type.\n * @param values Known values enum.\n *\n * @example\n * ```typespec\n * @knownValues(KnownErrorCode)\n * scalar ErrorCode extends string;\n *\n * enum KnownErrorCode {\n *   NotFound,\n *   Invalid,\n * }\n * ```\n */\n#deprecated \"This decorator has been deprecated. Use a named union of string literals with a string variant to achieve the same result without a decorator.\"\nextern dec knownValues(target: string | numeric | ModelProperty, values: Enum);\n\n/**\n * Mark a model property as the key to identify instances of that type\n * @param altName Name of the property. If not specified, the decorated property name is used.\n *\n * @example\n * ```typespec\n * model Pet {\n *   @key id: string;\n * }\n * ```\n */\nextern dec key(target: ModelProperty, altName?: valueof string);\n\n/**\n * Specify this operation is an overload of the given operation.\n * @param overloadbase Base operation that should be a union of all overloads\n *\n * @example\n * ```typespec\n * op upload(data: string | bytes, @header contentType: \"text/plain\" | \"application/octet-stream\"): void;\n * @overload(upload)\n * op uploadString(data: string, @header contentType: \"text/plain\" ): void;\n * @overload(upload)\n * op uploadBytes(data: bytes, @header contentType: \"application/octet-stream\"): void;\n * ```\n */\nextern dec overload(target: Operation, overloadbase: Operation);\n\n/**\n * DEPRECATED: Use `@encodedName` instead.\n *\n * Provide an alternative name for this type.\n * @param targetName Projection target\n * @param projectedName Alternative name\n *\n * @example\n * ```typespec\n * model Certificate {\n *   @projectedName(\"json\", \"exp\")\n *   expireAt: int32;\n * }\n * ```\n */\n#deprecated \"Use `@encodedName` instead for changing the name over the wire.\"\nextern dec projectedName(\n  target: unknown,\n  targetName: valueof string,\n  projectedName: valueof string\n);\n\n/**\n * Provide an alternative name for this type when serialized to the given mime type.\n * @param mimeType Mime type this should apply to. The mime type should be a known mime type as described here https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types without any suffix (e.g. `+json`)\n * @param name Alternative name\n *\n * @example\n *\n * ```typespec\n * model Certificate {\n *   @encodedName(\"application/json\", \"exp\")\n *   @encodedName(\"application/xml\", \"expiry\")\n *   expireAt: int32;\n * }\n * ```\n *\n * @example Invalid values\n *\n * ```typespec\n * @encodedName(\"application/merge-patch+json\", \"exp\")\n *              ^ error cannot use subtype\n * ```\n */\nextern dec encodedName(target: unknown, mimeType: valueof string, name: valueof string);\n\n/**\n * Specify the property to be used to discriminate this type.\n * @param propertyName The property name to use for discrimination\n *\n * @example\n *\n * ```typespec\n * @discriminator(\"kind\")\n * union Pet{ cat: Cat, dog: Dog }\n *\n * model Cat {kind: \"cat\", meow: boolean}\n * model Dog {kind: \"dog\", bark: boolean}\n * ```\n *\n * ```typespec\n * @discriminator(\"kind\")\n * model Pet{ kind: string }\n *\n * model Cat extends Pet {kind: \"cat\", meow: boolean}\n * model Dog extends Pet  {kind: \"dog\", bark: boolean}\n * ```\n */\nextern dec discriminator(target: Model | Union, propertyName: valueof string);\n\n/**\n * Known encoding to use on utcDateTime or offsetDateTime\n */\nenum DateTimeKnownEncoding {\n  /**\n   * RFC 3339 standard. https://www.ietf.org/rfc/rfc3339.txt\n   * Encode to string.\n   */\n  rfc3339: \"rfc3339\",\n\n  /**\n   * RFC 7231 standard. https://www.ietf.org/rfc/rfc7231.txt\n   * Encode to string.\n   */\n  rfc7231: \"rfc7231\",\n\n  /**\n   * Encode a datetime to a unix timestamp.\n   * Unix timestamps are represented as an integer number of seconds since the Unix epoch and usually encoded as an int32.\n   */\n  unixTimestamp: \"unixTimestamp\",\n}\n\n/**\n * Known encoding to use on duration\n */\nenum DurationKnownEncoding {\n  /**\n   * ISO8601 duration\n   */\n  ISO8601: \"ISO8601\",\n\n  /**\n   * Encode to integer or float\n   */\n  seconds: \"seconds\",\n}\n\n/**\n * Known encoding to use on bytes\n */\nenum BytesKnownEncoding {\n  /**\n   * Encode to Base64\n   */\n  base64: \"base64\",\n\n  /**\n   * Encode to Base64 Url\n   */\n  base64url: \"base64url\",\n}\n\n/**\n * Specify how to encode the target type.\n * @param encoding Known name of an encoding.\n * @param encodedAs What target type is this being encoded as. Default to string.\n *\n * @example offsetDateTime encoded with rfc7231\n *\n * ```tsp\n * @encode(\"rfc7231\")\n * scalar myDateTime extends offsetDateTime;\n * ```\n *\n * @example utcDateTime encoded with unixTimestamp\n *\n * ```tsp\n * @encode(\"unixTimestamp\", int32)\n * scalar myDateTime extends unixTimestamp;\n * ```\n */\nextern dec encode(\n  target: Scalar | ModelProperty,\n  encoding: string | EnumMember,\n  encodedAs?: Scalar\n);\n\n/** Options for example decorators */\nmodel ExampleOptions {\n  /** The title of the example */\n  title?: string;\n\n  /** Description of the example */\n  description?: string;\n}\n\n/**\n * Provide an example value for a data type.\n *\n * @param example Example value.\n * @param options Optional metadata for the example.\n *\n * @example\n *\n * ```tsp\n * @example(#{name: \"Fluffy\", age: 2})\n * model Pet {\n *  name: string;\n *  age: int32;\n * }\n * ```\n */\nextern dec example(\n  target: Model | Enum | Scalar | Union | ModelProperty | UnionVariant,\n  example: valueof unknown,\n  options?: valueof ExampleOptions\n);\n\n/**\n * Operation example configuration.\n */\nmodel OperationExample {\n  /** Example request body. */\n  parameters?: unknown;\n\n  /** Example response body. */\n  returnType?: unknown;\n}\n\n/**\n * Provide example values for an operation's parameters and corresponding return type.\n *\n * @param example Example value.\n * @param options Optional metadata for the example.\n *\n * @example\n *\n * ```tsp\n * @example(#{parameters: #{name: \"Fluffy\", age: 2}, returnType: #{name: \"Fluffy\", age: 2, id: \"abc\"})\n * op createPet(pet: Pet): Pet;\n * ```\n */\nextern dec opExample(\n  target: Operation,\n  example: valueof OperationExample,\n  options?: valueof ExampleOptions\n);\n/**\n * Indicates that a property is only considered to be present or applicable (\"visible\") with\n * the in the given named contexts (\"visibilities\"). When a property has no visibilities applied\n * to it, it is implicitly visible always.\n *\n * As far as the TypeSpec core library is concerned, visibilities are open-ended and can be arbitrary\n * strings, but  the following visibilities are well-known to standard libraries and should be used\n * with standard emitters that interpret them as follows:\n *\n * - \"read\": output of any operation.\n * - \"create\": input to operations that create an entity..\n * - \"query\": input to operations that read data.\n * - \"update\": input to operations that update data.\n * - \"delete\": input to operations that delete data.\n *\n * See also: [Automatic visibility](https://typespec.io/docs/libraries/http/operations#automatic-visibility)\n *\n * @param visibilities List of visibilities which apply to this property.\n *\n * @example\n *\n * ```typespec\n * model Dog {\n *   // the service will generate an ID, so you don't need to send it.\n *   @visibility(\"read\") id: int32;\n *   // the service will store this secret name, but won't ever return it\n *   @visibility(\"create\", \"update\") secretName: string;\n *   // the regular name is always present\n *   name: string;\n * }\n * ```\n */\nextern dec visibility(target: ModelProperty, ...visibilities: valueof string[]);\n\n/**\n * Removes properties that are not considered to be present or applicable\n * (\"visible\") in the given named contexts (\"visibilities\"). Can be used\n * together with spread to effectively spread only visible properties into\n * a new model.\n *\n * See also: [Automatic visibility](https://typespec.io/docs/libraries/http/operations#automatic-visibility)\n *\n * When using an emitter that applies visibility automatically, it is generally\n * not necessary to use this decorator.\n *\n * @param visibilities List of visibilities which apply to this property.\n *\n * @example\n * ```typespec\n * model Dog {\n *   @visibility(\"read\") id: int32;\n *   @visibility(\"create\", \"update\") secretName: string;\n *   name: string;\n * }\n *\n * // The spread operator will copy all the properties of Dog into DogRead,\n * // and @withVisibility will then remove those that are not visible with\n * // create or update visibility.\n * //\n * // In this case, the id property is removed, and the name and secretName\n * // properties are kept.\n * @withVisibility(\"create\", \"update\")\n * model DogCreateOrUpdate {\n *   ...Dog;\n * }\n *\n * // In this case the id and name properties are kept and the secretName property\n * // is removed.\n * @withVisibility(\"read\")\n * model DogRead {\n *   ...Dog;\n * }\n * ```\n */\nextern dec withVisibility(target: Model, ...visibilities: valueof string[]);\n\n/**\n * Set the visibility of key properties in a model if not already set.\n *\n * @param visibility The desired default visibility value. If a key property already has a `visibility` decorator then the default visibility is not applied.\n */\nextern dec withDefaultKeyVisibility(target: Model, visibility: valueof string);\n\n/**\n * Returns the model with non-updateable properties removed.\n */\nextern dec withUpdateableProperties(target: Model);\n\n/**\n * Returns the model with required properties removed.\n */\nextern dec withOptionalProperties(target: Model);\n\n/**\n * Returns the model with any default values removed.\n */\nextern dec withoutDefaultValues(target: Model);\n\n/**\n * Returns the model with the given properties omitted.\n * @param omit List of properties to omit\n */\nextern dec withoutOmittedProperties(target: Model, omit: string | Union);\n\n/**\n * Returns the model with only the given properties included.\n * @param pick List of properties to include\n */\nextern dec withPickedProperties(target: Model, pick: string | Union);\n\n//---------------------------------------------------------------------------\n// Debugging\n//---------------------------------------------------------------------------\n\n/**\n * A debugging decorator used to inspect a type.\n * @param text Custom text to log\n */\nextern dec inspectType(target: unknown, text: valueof string);\n\n/**\n * A debugging decorator used to inspect a type name.\n * @param text Custom text to log\n */\nextern dec inspectTypeName(target: unknown, text: valueof string);\n\n/**\n * Sets which visibilities apply to parameters for the given operation.\n * @param visibilities List of visibility strings which apply to this operation.\n */\nextern dec parameterVisibility(target: Operation, ...visibilities: valueof string[]);\n\n/**\n * Sets which visibilities apply to the return type for the given operation.\n * @param visibilities List of visibility strings which apply to this operation.\n */\nextern dec returnTypeVisibility(target: Operation, ...visibilities: valueof string[]);\n",
  "../../core/packages/compiler/lib/std/reflection.tsp": "namespace TypeSpec.Reflection;\n\nmodel Enum {}\nmodel EnumMember {}\nmodel Interface {}\nmodel Model {}\nmodel ModelProperty {}\nmodel Namespace {}\nmodel Operation {}\nmodel Scalar {}\nmodel Union {}\nmodel UnionVariant {}\nmodel StringTemplate {}\n",
  "../../core/packages/compiler/lib/std/projected-names.tsp": "// Set of projections consuming the @projectedName decorator\n#suppress \"projections-are-experimental\"\nprojection op#target {\n  to(targetName) {\n    if hasProjectedName(self, targetName) {\n      self::rename(getProjectedName(self, targetName));\n    };\n  }\n  from(targetName) {\n    if hasProjectedName(self, targetName) {\n      self::rename(self::projectionBase::name);\n    };\n  }\n}\n\n#suppress \"projections-are-experimental\"\nprojection interface#target {\n  to(targetName) {\n    if hasProjectedName(self, targetName) {\n      self::rename(getProjectedName(self, targetName));\n    };\n  }\n  from(targetName) {\n    if hasProjectedName(self, targetName) {\n      self::rename(self::projectionBase::name);\n    };\n  }\n}\n\n#suppress \"projections-are-experimental\"\nprojection model#target {\n  to(targetName) {\n    if hasProjectedName(self, targetName) {\n      self::rename(getProjectedName(self, targetName));\n    };\n\n    self::properties::forEach((p) => {\n      if hasProjectedName(p, targetName) {\n        self::renameProperty(p::name, getProjectedName(p, targetName));\n      };\n    });\n  }\n  from(targetName) {\n    if hasProjectedName(self, targetName) {\n      self::rename(self::projectionBase::name);\n    };\n\n    self::projectionBase::properties::forEach((p) => {\n      if hasProjectedName(p, targetName) {\n        self::renameProperty(getProjectedName(p, targetName), p::name);\n      };\n    });\n  }\n}\n\n#suppress \"projections-are-experimental\"\nprojection enum#target {\n  to(targetName) {\n    if hasProjectedName(self, targetName) {\n      self::rename(getProjectedName(self, targetName));\n    };\n\n    self::members::forEach((p) => {\n      if hasProjectedName(p, targetName) {\n        self::renameMember(p::name, getProjectedName(p, targetName));\n      };\n    });\n  }\n  from(targetName) {\n    if hasProjectedName(self, targetName) {\n      self::rename(self::projectionBase::name);\n    };\n\n    self::projectionBase::members::forEach((p) => {\n      if hasProjectedName(p, targetName) {\n        self::renameMember(getProjectedName(p, targetName), p::name);\n      };\n    });\n  }\n}\n\n#suppress \"projections-are-experimental\"\nprojection union#target {\n  to(targetName) {\n    if hasProjectedName(self, targetName) {\n      self::rename(getProjectedName(self, targetName));\n    };\n  }\n  from(targetName) {\n    if hasProjectedName(self, targetName) {\n      self::rename(self::projectionBase::name);\n    };\n  }\n}\n",
  "lib/azure-core.tsp": "import \"@typespec/http\";\nimport \"@typespec/rest\";\nimport \"@typespec/versioning\";\n\nimport \"./auth.tsp\";\nimport \"./traits.tsp\";\nimport \"./foundations.tsp\";\nimport \"./models.tsp\";\nimport \"./operations.tsp\";\nimport \"./obsolete.tsp\";\nimport \"./decorators.tsp\";\nimport \"../dist/src/index.js\";\n\nusing TypeSpec.Versioning;\n\n@versioned(Versions)\nnamespace Azure.Core;\n\n/**\n * Supported versions of Azure.Core TypeSpec building blocks.\n */\nenum Versions {\n  @doc(\"Version 1.0-preview.1\")\n  v1_0_Preview_1: \"1.0-preview.1\",\n\n  @doc(\"Version 1.0-preview.2\")\n  v1_0_Preview_2: \"1.0-preview.2\",\n}\n",
  "../../core/packages/http/lib/http.tsp": "import \"../dist/src/index.js\";\nimport \"./decorators.tsp\";\nimport \"./private.decorators.tsp\";\nimport \"./auth.tsp\";\n\nnamespace TypeSpec.Http;\n\nusing Private;\n\n/**\n * Describes an HTTP response.\n *\n * @template Status The status code of the response.\n */\n@doc(\"\")\nmodel Response<Status> {\n  @doc(\"The status code.\")\n  @statusCode\n  statusCode: Status;\n}\n\n/**\n * Defines a model with a single property of the given type, marked with `@body`.\n *\n * This can be useful in situations where you cannot use a bare type as the body\n * and it is awkward to add a property.\n *\n * @template Type The type of the model's `body` property.\n */\n@doc(\"\")\nmodel Body<Type> {\n  @body\n  @doc(\"The body type of the operation request or response.\")\n  body: Type;\n}\n\n/**\n * The Location header contains the URL where the status of the long running operation can be checked.\n */\nmodel LocationHeader {\n  @doc(\"The Location header contains the URL where the status of the long running operation can be checked.\")\n  @header\n  location: string;\n}\n\n// Don't put @doc on these, change `getStatusCodeDescription` implementation\n// to update the default descriptions for these status codes. This ensures\n// that we get consistent emit between different ways to spell the same\n// responses in TypeSpec.\n\n/**\n * The request has succeeded.\n */\nmodel OkResponse is Response<200>;\n/**\n * The request has succeeded and a new resource has been created as a result.\n */\nmodel CreatedResponse is Response<201>;\n/**\n * The request has been accepted for processing, but processing has not yet completed.\n */\nmodel AcceptedResponse is Response<202>;\n/**\n * There is no content to send for this request, but the headers may be useful.\n */\nmodel NoContentResponse is Response<204>;\n/**\n * The URL of the requested resource has been changed permanently. The new URL is given in the response.\n */\nmodel MovedResponse is Response<301> {\n  ...LocationHeader;\n}\n/**\n * The client has made a conditional request and the resource has not been modified.\n */\nmodel NotModifiedResponse is Response<304>;\n/**\n * The server could not understand the request due to invalid syntax.\n */\nmodel BadRequestResponse is Response<400>;\n/**\n * Access is unauthorized.\n */\nmodel UnauthorizedResponse is Response<401>;\n/**\n * Access is forbidden.\n */\nmodel ForbiddenResponse is Response<403>;\n/**\n * The server cannot find the requested resource.\n */\nmodel NotFoundResponse is Response<404>;\n/**\n * The request conflicts with the current state of the server.\n */\nmodel ConflictResponse is Response<409>;\n\n/**\n * Produces a new model with the same properties as T, but with `@query`,\n * `@header`, `@body`, and `@path` decorators removed from all properties.\n *\n * @template Data The model to spread as the plain data.\n */\n@plainData\nmodel PlainData<Data> {\n  ...Data;\n}\n\n@Private.httpFile\nmodel File {\n  contentType?: string;\n  filename?: string;\n  contents: bytes;\n}\n\nmodel HttpPartOptions {\n  /** Name of the part when using the array form. */\n  name?: string;\n}\n\n@Private.httpPart(Type, Options)\nmodel HttpPart<Type, Options extends valueof HttpPartOptions = #{}> {}\n",
  "../../core/packages/http/lib/decorators.tsp": "namespace TypeSpec.Http;\n\nusing TypeSpec.Reflection;\n\n/**\n * Header options.\n */\nmodel HeaderOptions {\n  /**\n   * Name of the header when sent over HTTP.\n   */\n  name?: string;\n\n  /**\n   * Determines the format of the array if type array is used.\n   */\n  format?: \"csv\" | \"multi\" | \"tsv\" | \"ssv\" | \"pipes\" | \"simple\" | \"form\";\n}\n\n/**\n * Specify this property is to be sent or received as an HTTP header.\n *\n * @param headerNameOrOptions Optional name of the header when sent over HTTP or header options.\n *  By default the header name will be the property name converted from camelCase to kebab-case. (e.g. `contentType` -> `content-type`)\n *\n * @example\n *\n * ```typespec\n * op read(@header accept: string): {@header(\"ETag\") eTag: string};\n * op create(@header({name: \"X-Color\", format: \"csv\"}) colors: string[]): void;\n * ```\n *\n * @example Implicit header name\n *\n * ```typespec\n * op read(): {@header contentType: string}; // headerName: content-type\n * op update(@header ifMatch: string): void; // headerName: if-match\n * ```\n */\nextern dec header(target: ModelProperty, headerNameOrOptions?: string | HeaderOptions);\n\n/**\n * Query parameter options.\n */\nmodel QueryOptions {\n  /**\n   * Name of the query when included in the url.\n   */\n  name?: string;\n\n  /**\n   * Determines the format of the array if type array is used.\n   */\n  format?: \"multi\" | \"csv\" | \"ssv\" | \"tsv\" | \"simple\" | \"form\" | \"pipes\";\n}\n\n/**\n * Specify this property is to be sent as a query parameter.\n *\n * @param queryNameOrOptions Optional name of the query when included in the url or query parameter options.\n *\n * @example\n *\n * ```typespec\n * op read(@query select: string, @query(\"order-by\") orderBy: string): void;\n * op list(@query({name: \"id\", format: \"multi\"}) ids: string[]): void;\n * ```\n */\nextern dec query(target: ModelProperty, queryNameOrOptions?: string | QueryOptions);\n\n/**\n * Explicitly specify that this property is to be interpolated as a path parameter.\n *\n * @param paramName Optional name of the parameter in the url template.\n *\n * @example\n *\n * ```typespec\n * @route(\"/read/{explicit}/things/{implicit}\")\n * op read(@path explicit: string, implicit: string): void;\n * ```\n */\nextern dec path(target: ModelProperty, paramName?: valueof string);\n\n/**\n * Explicitly specify that this property type will be exactly the HTTP body.\n *\n * This means that any properties under `@body` cannot be marked as headers, query parameters, or path parameters.\n * If wanting to change the resolution of the body but still mix parameters, use `@bodyRoot`.\n *\n * @example\n *\n * ```typespec\n * op upload(@body image: bytes): void;\n * op download(): {@body image: bytes};\n * ```\n */\nextern dec body(target: ModelProperty);\n\n/**\n * Specify that the body resolution should be resolved from that property.\n * By default the body is resolved by including all properties in the operation request/response that are not metadata.\n * This allows to nest the body in a property while still allowing to use headers, query parameters, and path parameters in the same model.\n *\n * @example\n *\n * ```typespec\n * op upload(@bodyRoot user: {name: string, @header id: string}): void;\n * op download(): {@bodyRoot user: {name: string, @header id: string}};\n * ```\n */\nextern dec bodyRoot(target: ModelProperty);\n/**\n * Specify that this property shouldn't be included in the HTTP body.\n * This can be useful when bundling metadata together that would result in an empty property to be included in the body.\n *\n * @example\n *\n * ```typespec\n * op upload(name: string, @bodyIgnore headers: {@header id: string}): void;\n * ```\n */\nextern dec bodyIgnore(target: ModelProperty);\n\n/**\n * @example\n *\n * ```tsp\n * op upload(\n *   @header `content-type`: \"multipart/form-data\",\n *   @multipartBody body: {\n *     fullName: HttpPart<string>,\n *     headShots: HttpPart<Image>[]\n *   }\n * ): void;\n * ```\n */\nextern dec multipartBody(target: ModelProperty);\n\n/**\n * Specify the status code for this response. Property type must be a status code integer or a union of status code integer.\n *\n * @example\n *\n * ```typespec\n * op read(): {\n *   @statusCode _: 200;\n *   @body pet: Pet;\n * };\n * op create(): {\n *   @statusCode _: 201 | 202;\n * };\n * ```\n */\nextern dec statusCode(target: ModelProperty);\n\n/**\n * Specify the HTTP verb for the target operation to be `GET`.\n *\n * @example\n *\n * ```typespec\n * @get op read(): string\n * ```\n */\nextern dec get(target: Operation);\n\n/**\n * Specify the HTTP verb for the target operation to be `PUT`.\n *\n * @example\n *\n * ```typespec\n * @put op set(pet: Pet): void\n * ```\n */\nextern dec put(target: Operation);\n\n/**\n * Specify the HTTP verb for the target operation to be `POST`.\n *\n * @example\n *\n * ```typespec\n * @post op create(pet: Pet): void\n * ```\n */\nextern dec post(target: Operation);\n\n/**\n * Specify the HTTP verb for the target operation to be `PATCH`.\n *\n * @example\n *\n * ```typespec\n * @patch op update(pet: Pet): void\n * ```\n */\nextern dec patch(target: Operation);\n\n/**\n * Specify the HTTP verb for the target operation to be `DELETE`.\n *\n * @example\n *\n * ```typespec\n * @delete op set(petId: string): void\n * ```\n */\nextern dec delete(target: Operation);\n\n/**\n * Specify the HTTP verb for the target operation to be `HEAD`.\n * @example\n *\n * ```typespec\n * @head op ping(petId: string): void\n * ```\n */\nextern dec head(target: Operation);\n\n/**\n * Specify the endpoint for this service.\n *  @param url Server endpoint\n *  @param description Description of the endpoint\n *  @param parameters Optional set of parameters used to interpolate the url.\n *\n * @example\n * ```typespec\n * @service\n * @server(\"https://example.com\", \"Single server endpoint\")\n * namespace PetStore;\n * ```\n *\n * @example parameterized\n *\n * ```typespec\n * @server(\"https://{region}.foo.com\", \"Regional endpoint\", {\n *   @doc(\"Region name\")\n *   region?: string = \"westus\",\n * })\n * ```\n *\n */\nextern dec server(\n  target: Namespace,\n  url: valueof string,\n  description: valueof string,\n  parameters?: Record<unknown>\n);\n\n/**\n * Specify authentication for a whole service or specific methods. See the [documentation in the Http library](https://typespec.io/docs/libraries/http/authentication) for full details.\n *\n * @param auth Authentication configuration. Can be a single security scheme, a union(either option is valid authentication) or a tuple (must use all authentication together)\n * @example\n *\n * ```typespec\n * @service\n * @useAuth(BasicAuth)\n * namespace PetStore;\n * ```\n */\nextern dec useAuth(target: Namespace | Interface | Operation, auth: {} | Union | {}[]);\n\n/**\n * Specify if inapplicable metadata should be included in the payload for the given entity.\n * @param value If true, inapplicable metadata will be included in the payload.\n */\nextern dec includeInapplicableMetadataInPayload(target: unknown, value: valueof boolean);\n\n/**\n * Defines the relative route URI for the target operation\n *\n * The first argument should be a URI fragment that may contain one or more path parameter fields.\n * If the namespace or interface that contains the operation is also marked with a `@route` decorator,\n * it will be used as a prefix to the route URI of the operation.\n *\n * `@route` can only be applied to operations, namespaces, and interfaces.\n *\n * @param path Relative route path. Cannot include query parameters.\n * @param options Set of parameters used to configure the route. Supports `{shared: true}` which indicates that the route may be shared by several operations.\n *\n * @example\n *\n * ```typespec\n * @route(\"/widgets\")\n * op getWidget(@path id: string): Widget;\n * ```\n */\nextern dec route(\n  target: Namespace | Interface | Operation,\n  path: valueof string,\n  options?: {\n    shared?: boolean,\n  }\n);\n\n/**\n * `@sharedRoute` marks the operation as sharing a route path with other operations.\n *\n * When an operation is marked with `@sharedRoute`, it enables other operations to share the same\n * route path as long as those operations are also marked with `@sharedRoute`.\n *\n * `@sharedRoute` can only be applied directly to operations.\n *\n * ```typespec\n * @sharedRoute\n * @route(\"/widgets\")\n * op getWidget(@path id: string): Widget;\n * ```\n */\nextern dec sharedRoute(target: Operation);\n",
  "../../core/packages/http/lib/private.decorators.tsp": "import \"../dist/src/private.decorators.js\";\n\n/**\n * Private decorators. Those are meant for internal use inside Http types only.\n */\nnamespace TypeSpec.Http.Private;\n\nextern dec plainData(target: TypeSpec.Reflection.Model);\nextern dec httpFile(target: TypeSpec.Reflection.Model);\nextern dec httpPart(\n  target: TypeSpec.Reflection.Model,\n  type: unknown,\n  options: valueof HttpPartOptions\n);\n",
  "../../core/packages/http/lib/auth.tsp": "namespace TypeSpec.Http;\n\n@doc(\"Authentication type\")\nenum AuthType {\n  @doc(\"HTTP\")\n  http,\n\n  @doc(\"API key\")\n  apiKey,\n\n  @doc(\"OAuth2\")\n  oauth2,\n\n  @doc(\"OpenID connect\")\n  openIdConnect,\n\n  @doc(\"Empty auth\")\n  noAuth,\n}\n\n/**\n * Basic authentication is a simple authentication scheme built into the HTTP protocol.\n * The client sends HTTP requests with the Authorization header that contains the word Basic word followed by a space and a base64-encoded string username:password.\n * For example, to authorize as demo / `p@55w0rd` the client would send\n * ```\n * Authorization: Basic ZGVtbzpwQDU1dzByZA==\n * ```\n */\n@doc(\"\")\nmodel BasicAuth {\n  @doc(\"Http authentication\")\n  type: AuthType.http;\n\n  @doc(\"basic auth scheme\")\n  scheme: \"basic\";\n}\n\n/**\n * Bearer authentication (also called token authentication) is an HTTP authentication scheme that involves security tokens called bearer tokens.\n * The name “Bearer authentication” can be understood as “give access to the bearer of this token.” The bearer token is a cryptic string, usually generated by the server in response to a login request.\n * The client must send this token in the Authorization header when making requests to protected resources:\n * ```\n * Authorization: Bearer <token>\n * ```\n */\n@doc(\"\")\nmodel BearerAuth {\n  @doc(\"Http authentication\")\n  type: AuthType.http;\n\n  @doc(\"bearer auth scheme\")\n  scheme: \"bearer\";\n}\n\n@doc(\"Describes the location of the API key\")\nenum ApiKeyLocation {\n  @doc(\"API key is a header value\")\n  header,\n\n  @doc(\"API key is a query parameter\")\n  query,\n\n  @doc(\"API key is found in a cookie\")\n  cookie,\n}\n\n/**\n * An API key is a token that a client provides when making API calls. The key can be sent in the query string:\n *\n * ```\n * GET /something?api_key=abcdef12345\n * ```\n *\n * or as a request header\n *\n * ```\n * GET /something HTTP/1.1\n * X-API-Key: abcdef12345\n * ```\n *\n * or as a cookie\n *\n * ```\n * GET /something HTTP/1.1\n * Cookie: X-API-KEY=abcdef12345\n * ```\n *\n * @template Location The location of the API key\n * @template Name The name of the API key\n */\n@doc(\"\")\nmodel ApiKeyAuth<Location extends ApiKeyLocation, Name extends string> {\n  @doc(\"API key authentication\")\n  type: AuthType.apiKey;\n\n  @doc(\"location of the API key\")\n  in: Location;\n\n  @doc(\"name of the API key\")\n  name: Name;\n}\n\n/**\n * OAuth 2.0 is an authorization protocol that gives an API client limited access to user data on a web server.\n *\n * OAuth relies on authentication scenarios called flows, which allow the resource owner (user) to share the protected content from the resource server without sharing their credentials.\n * For that purpose, an OAuth 2.0 server issues access tokens that the client applications can use to access protected resources on behalf of the resource owner.\n * For more information about OAuth 2.0, see oauth.net and RFC 6749.\n *\n * @template Flows The list of supported OAuth2 flows\n * @template Scopes The list of OAuth2 scopes, which are common for every flow from `Flows`. This list is combined with the scopes defined in specific OAuth2 flows.\n */\n@doc(\"\")\nmodel OAuth2Auth<Flows extends OAuth2Flow[], Scopes extends string[] = []> {\n  @doc(\"OAuth2 authentication\")\n  type: AuthType.oauth2;\n\n  @doc(\"Supported OAuth2 flows\")\n  flows: Flows;\n\n  @doc(\"Oauth2 scopes of every flow. Overridden by scope definitions in specific flows\")\n  defaultScopes: Scopes;\n}\n\n@doc(\"Describes the OAuth2 flow type\")\nenum OAuth2FlowType {\n  @doc(\"authorization code flow\")\n  authorizationCode,\n\n  @doc(\"implicit flow\")\n  implicit,\n\n  @doc(\"password flow\")\n  password,\n\n  @doc(\"client credential flow\")\n  clientCredentials,\n}\n\nalias OAuth2Flow = AuthorizationCodeFlow | ImplicitFlow | PasswordFlow | ClientCredentialsFlow;\n\n@doc(\"Authorization Code flow\")\nmodel AuthorizationCodeFlow {\n  @doc(\"authorization code flow\")\n  type: OAuth2FlowType.authorizationCode;\n\n  @doc(\"the authorization URL\")\n  authorizationUrl: string;\n\n  @doc(\"the token URL\")\n  tokenUrl: string;\n\n  @doc(\"the refresh URL\")\n  refreshUrl?: string;\n\n  @doc(\"list of scopes for the credential\")\n  scopes?: string[];\n}\n\n@doc(\"Implicit flow\")\nmodel ImplicitFlow {\n  @doc(\"implicit flow\")\n  type: OAuth2FlowType.implicit;\n\n  @doc(\"the authorization URL\")\n  authorizationUrl: string;\n\n  @doc(\"the refresh URL\")\n  refreshUrl?: string;\n\n  @doc(\"list of scopes for the credential\")\n  scopes?: string[];\n}\n\n@doc(\"Resource Owner Password flow\")\nmodel PasswordFlow {\n  @doc(\"password flow\")\n  type: OAuth2FlowType.password;\n\n  @doc(\"the token URL\")\n  tokenUrl: string;\n\n  @doc(\"the refresh URL\")\n  refreshUrl?: string;\n\n  @doc(\"list of scopes for the credential\")\n  scopes?: string[];\n}\n\n@doc(\"Client credentials flow\")\nmodel ClientCredentialsFlow {\n  @doc(\"client credential flow\")\n  type: OAuth2FlowType.clientCredentials;\n\n  @doc(\"the token URL\")\n  tokenUrl: string;\n\n  @doc(\"the refresh URL\")\n  refreshUrl?: string;\n\n  @doc(\"list of scopes for the credential\")\n  scopes?: string[];\n}\n\n/**\n * OpenID Connect (OIDC) is an identity layer built on top of the OAuth 2.0 protocol and supported by some OAuth 2.0 providers, such as Google and Azure Active Directory.\n * It defines a sign-in flow that enables a client application to authenticate a user, and to obtain information (or \"claims\") about that user, such as the user name, email, and so on.\n * User identity information is encoded in a secure JSON Web Token (JWT), called ID token.\n * OpenID Connect defines a discovery mechanism, called OpenID Connect Discovery, where an OpenID server publishes its metadata at a well-known URL, typically\n *\n * ```http\n * https://server.com/.well-known/openid-configuration\n * ```\n */\nmodel OpenIdConnectAuth<ConnectUrl extends string> {\n  /** Auth type */\n  type: AuthType.openIdConnect;\n\n  /** Connect url. It can be specified relative to the server URL */\n  openIdConnectUrl: ConnectUrl;\n}\n\n/**\n * This authentication option signifies that API is not secured at all.\n * It might be useful when overriding authentication on interface of operation level.\n */\n@doc(\"\")\nmodel NoAuth {\n  type: AuthType.noAuth;\n}\n",
  "../../core/packages/rest/lib/rest.tsp": "import \"@typespec/http\";\nimport \"./rest-decorators.tsp\";\nimport \"./resource.tsp\";\n\nnamespace TypeSpec.Rest;\n\n/**\n * A URL that points to a resource.\n * @template Resource The type of resource that the URL points to.\n */\n@doc(\"The location of an instance of {name}\", Resource)\n@Private.resourceLocation(Resource)\nscalar ResourceLocation<Resource extends {}> extends url;\n",
  "../../core/packages/rest/lib/rest-decorators.tsp": "namespace TypeSpec.Rest;\n\nusing TypeSpec.Reflection;\n\n/**\n * This interface or operation should resolve its route automatically. To be used with resource types where the route segments area defined on the models.\n *\n * @example\n *\n * ```typespec\n * @autoRoute\n * interface Pets {\n *   get(@segment(\"pets\") @path id: string): void; //-> route: /pets/{id}\n * }\n * ```\n */\nextern dec autoRoute(target: Interface | Operation);\n\n/**\n * Defines the preceding path segment for a @path parameter in auto-generated routes.\n *\n * @param name Segment that will be inserted into the operation route before the path parameter's name field.\n *\n * @example\n * @autoRoute\n * interface Pets {\n *   get(@segment(\"pets\") @path id: string): void; //-> route: /pets/{id}\n * }\n */\nextern dec segment(target: Model | ModelProperty | Operation, name: valueof string);\n\n/**\n * Returns the URL segment of a given model if it has `@segment` and `@key` decorator.\n * @param type Target model\n */\nextern dec segmentOf(target: Operation, type: Model);\n\n/**\n * Defines the separator string that is inserted before the action name in auto-generated routes for actions.\n *\n * @param seperator Seperator seperating the action segment from the rest of the url\n */\nextern dec actionSeparator(\n  target: Model | ModelProperty | Operation,\n  seperator: valueof \"/\" | \":\" | \"/:\"\n);\n\n/**\n * Mark this model as a resource type with a name.\n *\n * @param collectionName type's collection name\n */\nextern dec resource(target: Model, collectionName: valueof string);\n\n/**\n * Mark model as a child of the given parent resource.\n * @param parent Parent model.\n */\nextern dec parentResource(target: Model, parent: Model);\n\n/**\n * Specify that this is a Read operation for a given resource.\n *\n * @param resourceType Resource marked with @resource\n */\nextern dec readsResource(target: Operation, resourceType: Model);\n\n/**\n * Specify that this is a Create operation for a given resource.\n *\n * @param resourceType Resource marked with @resource\n */\nextern dec createsResource(target: Operation, resourceType: Model);\n\n/**\n * Specify that this is a CreateOrReplace operation for a given resource.\n *\n * @param resourceType Resource marked with @resource\n */\nextern dec createsOrReplacesResource(target: Operation, resourceType: Model);\n\n/**\n * Specify that this is a CreatesOrUpdate operation for a given resource.\n *\n * @param resourceType Resource marked with @resource\n */\nextern dec createsOrUpdatesResource(target: Operation, resourceType: Model);\n\n/**\n * Specify that this is a Update operation for a given resource.\n *\n * @param resourceType Resource marked with @resource\n */\nextern dec updatesResource(target: Operation, resourceType: Model);\n\n/**\n * Specify that this is a Delete operation for a given resource.\n *\n * @param resourceType Resource marked with @resource\n */\nextern dec deletesResource(target: Operation, resourceType: Model);\n\n/**\n * Specify that this is a List operation for a given resource.\n *\n * @param resourceType Resource marked with @resource\n */\nextern dec listsResource(target: Operation, resourceType: Model);\n\n/**\n * Specify this operation is an action. (Scoped to a resource item /pets/{petId}/my-action)\n * @param name Name of the action. If not specified, the name of the operation will be used.\n */\nextern dec action(target: Operation, name?: valueof string);\n\n/**\n * Specify this operation is a collection action. (Scopped to a resource, /pets/my-action)\n * @param resourceType Resource marked with @resource\n * @param name Name of the action. If not specified, the name of the operation will be used.\n */\nextern dec collectionAction(target: Operation, resourceType: Model, name?: valueof string);\n\n/**\n * Copy the resource key parameters on the model\n * @param filter Filter to exclude certain properties.\n */\nextern dec copyResourceKeyParameters(target: Model, filter?: valueof string);\n\nnamespace Private {\n  extern dec resourceLocation(target: string, resourceType: Model);\n  extern dec validateHasKey(target: unknown, value: unknown);\n  extern dec validateIsError(target: unknown, value: unknown);\n  extern dec actionSegment(target: Operation, value: valueof string);\n  extern dec resourceTypeForKeyParam(entity: ModelProperty, resourceType: Model);\n}\n",
  "../../core/packages/rest/lib/resource.tsp": "import \"@typespec/http\";\nimport \"../dist/src/index.js\";\nimport \"../dist/src/internal-decorators.js\";\n\nnamespace TypeSpec.Rest.Resource;\n\nusing TypeSpec.Http;\n\n@doc(\"The default error response for resource operations.\")\nmodel ResourceError {\n  @doc(\"The error code.\")\n  code: int32;\n\n  @doc(\"The error message.\")\n  message: string;\n}\n\n/**\n * Dynamically gathers keys of the model type `Resource`.\n *\n * @template Resource The target resource model.\n */\n@doc(\"Dynamically gathers keys of the model type Resource.\")\n@copyResourceKeyParameters\n@friendlyName(\"{name}Key\", Resource)\nmodel KeysOf<Resource> {}\n\n/**\n * Dynamically gathers parent keys of the model type `Resource`.\n *\n * @template Resource The target resource model.\n */\n@doc(\"Dynamically gathers parent keys of the model type Resource.\")\n@copyResourceKeyParameters(\"parent\")\n@friendlyName(\"{name}ParentKey\", Resource)\nmodel ParentKeysOf<Resource> {}\n\n/**\n * Represents operation parameters for the resource of type `Resource`.\n *\n * @template Resource The resource model.\n */\n@doc(\"Represents operation parameters for resource Resource.\")\nmodel ResourceParameters<Resource extends {}> {\n  ...KeysOf<Resource>;\n}\n\n/**\n * Represents collection operation parameters for the resource of type `Resource`.\n *\n * @template Resource The resource model.\n */\n@doc(\"Represents collection operation parameters for resource Resource.\")\nmodel ResourceCollectionParameters<Resource extends {}> {\n  ...ParentKeysOf<Resource>;\n}\n\n/**\n * Represents the resource GET operation.\n *\n * @template Resource The resource model.\n * @template Error The error response.\n */\n@Private.validateHasKey(Resource)\n@Private.validateIsError(Error)\ninterface ResourceRead<Resource extends {}, Error> {\n  /**\n   * Gets an instance of the resource.\n   *\n   * @template Resource The resource model.\n   */\n  @autoRoute\n  @doc(\"Gets an instance of the resource.\")\n  @readsResource(Resource)\n  get(...ResourceParameters<Resource>): Resource | Error;\n}\n\n/**\n * Resource create operation completed successfully.\n *\n * @template Resource The resource model that was created.\n */\n@doc(\"Resource create operation completed successfully.\")\nmodel ResourceCreatedResponse<Resource> {\n  ...CreatedResponse;\n  @bodyRoot body: Resource;\n}\n\n/**\n * Resource create or replace operation template.\n *\n * @template Resource The resource model to create or replace.\n * @template Error The error response.\n */\ninterface ResourceCreateOrReplace<Resource extends {}, Error> {\n  /**\n   * Creates or replaces a instance of the resource.\n   *\n   * @template Resource The resource model to create or replace.\n   * @template Error The error response.\n   */\n  @autoRoute\n  @doc(\"Creates or replaces an instance of the resource.\")\n  @createsOrReplacesResource(Resource)\n  createOrReplace(\n    ...ResourceParameters<Resource>,\n    @bodyRoot resource: ResourceCreateModel<Resource>,\n  ): Resource | ResourceCreatedResponse<Resource> | Error;\n}\n\n/**\n * Resource create or update operation model.\n *\n * @template Resource The resource model to create or update.\n */\n@friendlyName(\"{name}Update\", Resource)\nmodel ResourceCreateOrUpdateModel<Resource extends {}>\n  is OptionalProperties<UpdateableProperties<DefaultKeyVisibility<Resource, \"read\">>>;\n\n/**\n * Resource create or update operation template.\n *\n * @template Resource The resource model to create or update.\n * @template Error The error response.\n */\ninterface ResourceCreateOrUpdate<Resource extends {}, Error> {\n  /**\n   * Creates or update an instance of the resource.\n   *\n   * @template Resource The resource model to create or update.\n   * @template Error The error response.\n   */\n  @autoRoute\n  @doc(\"Creates or update an instance of the resource.\")\n  @createsOrUpdatesResource(Resource)\n  createOrUpdate(\n    ...ResourceParameters<Resource>,\n    @bodyRoot resource: ResourceCreateOrUpdateModel<Resource>,\n  ): Resource | ResourceCreatedResponse<Resource> | Error;\n}\n\n/**\n * Resource create operation model.\n *\n * @template Resource The resource model to create.\n */\n@friendlyName(\"{name}Create\", Resource)\n@withVisibility(\"create\")\nmodel ResourceCreateModel<Resource extends {}> is DefaultKeyVisibility<Resource, \"read\">;\n\n/**\n * Resource create operation template.\n *\n * @template Resource The resource model to create.\n * @template Error The error response.\n */\ninterface ResourceCreate<Resource extends {}, Error> {\n  /**\n   * Creates a new instance of the resource.\n   *\n   * @template Resource The resource model to create.\n   * @template Error The error response.\n   */\n  @autoRoute\n  @doc(\"Creates a new instance of the resource.\")\n  @createsResource(Resource)\n  create(\n    ...ResourceCollectionParameters<Resource>,\n    @bodyRoot resource: ResourceCreateModel<Resource>,\n  ): Resource | ResourceCreatedResponse<Resource> | Error;\n}\n\n/**\n * Resource update operation template.\n *\n * @template Resource The resource model to update.\n * @template Error The error response.\n */\n@Private.validateHasKey(Resource)\n@Private.validateIsError(Error)\ninterface ResourceUpdate<Resource extends {}, Error> {\n  /**\n   * Updates an existing instance of the resource.\n   *\n   * @template Resource The resource model to update.\n   * @template Error The error response.\n   */\n  @autoRoute\n  @doc(\"Updates an existing instance of the resource.\")\n  @updatesResource(Resource)\n  update(\n    ...ResourceParameters<Resource>,\n    @bodyRoot properties: ResourceCreateOrUpdateModel<Resource>,\n  ): Resource | Error;\n}\n\n@doc(\"Resource deleted successfully.\")\nmodel ResourceDeletedResponse {\n  @doc(\"The status code.\")\n  @statusCode\n  _: 200;\n}\n\n/**\n * Resource delete operation template.\n *\n * @template Resource The resource model to delete.\n * @template Error The error response.\n */\n@Private.validateHasKey(Resource)\n@Private.validateIsError(Error)\ninterface ResourceDelete<Resource extends {}, Error> {\n  /**\n   * Deletes an existing instance of the resource.\n   *\n   * @template Resource The resource model to delete.\n   * @template Error The error response.\n   */\n  @autoRoute\n  @doc(\"Deletes an existing instance of the resource.\")\n  @deletesResource(Resource)\n  delete(...ResourceParameters<Resource>): ResourceDeletedResponse | Error;\n}\n\n/**\n * Structure for a paging response using `value` and `nextLink` to represent pagination.\n *\n * This only provides the model structure and not actual pagination support. See\n * https://github.com/microsoft/typespec/issues/705 for general paging support.\n *\n * @template Resource The resource type of the collection.\n */\n@doc(\"Paged response of {name} items\", Resource)\n@friendlyName(\"{name}CollectionWithNextLink\", Resource)\nmodel CollectionWithNextLink<Resource extends {}> {\n  @doc(\"The items on this page\")\n  value: Resource[];\n\n  @doc(\"The link to the next page of items\")\n  nextLink?: ResourceLocation<Resource>;\n}\n\n/**\n * Resource list operation template.\n *\n * @template Resource The resource model to list.\n * @template Error The error response.\n */\ninterface ResourceList<Resource extends {}, Error> {\n  /**\n   * Lists all instances of the resource.\n   *\n   * @template Resource The resource model to list.\n   * @template Error The error response.\n   */\n  @autoRoute\n  @doc(\"Lists all instances of the resource.\")\n  @listsResource(Resource)\n  list(...ResourceCollectionParameters<Resource>): CollectionWithNextLink<Resource> | Error;\n}\n\n/**\n * Resource operation templates for resource instances.\n *\n * @template Resource The resource model.\n * @template Error The error response.\n */\n@Private.validateHasKey(Resource)\n@Private.validateIsError(Error)\ninterface ResourceInstanceOperations<Resource extends {}, Error>\n  extends ResourceRead<Resource, Error>,\n    ResourceUpdate<Resource, Error>,\n    ResourceDelete<Resource, Error> {}\n\n/**\n * Resource operation templates for resource collections.\n *\n * @template Resource The resource model.\n * @template Error The error response.\n */\n@Private.validateHasKey(Resource)\n@Private.validateIsError(Error)\ninterface ResourceCollectionOperations<Resource extends {}, Error>\n  extends ResourceCreate<Resource, Error>,\n    ResourceList<Resource, Error> {}\n\n/**\n * Resource operation templates for resources.\n *\n * @template Resource The resource model.\n * @template Error The error response.\n */\n@Private.validateHasKey(Resource)\n@Private.validateIsError(Error)\ninterface ResourceOperations<Resource extends {}, Error>\n  extends ResourceInstanceOperations<Resource, Error>,\n    ResourceCollectionOperations<Resource, Error> {}\n\n/**\n * Singleton resource read operation template.\n *\n * @template Singleton The singleton resource model.\n * @template Resource The resource model.\n * @template Error The error response.\n */\n@Private.validateHasKey(Resource)\n@Private.validateIsError(Error)\ninterface SingletonResourceRead<Singleton extends {}, Resource extends {}, Error> {\n  /**\n   * Gets the singleton resource.\n   *\n   * @template Singleton The singleton resource model.\n   * @template Resource The resource model.\n   */\n  @autoRoute\n  @doc(\"Gets the singleton resource.\")\n  @segmentOf(Singleton)\n  @readsResource(Singleton)\n  get(...ResourceParameters<Resource>): Singleton | Error;\n}\n\n/**\n * Singleton resource update operation template.\n *\n * @template Singleton The singleton resource model.\n * @template Resource The resource model.\n * @template Error The error response.\n */\n@Private.validateHasKey(Resource)\n@Private.validateIsError(Error)\ninterface SingletonResourceUpdate<Singleton extends {}, Resource extends {}, Error> {\n  /**\n   * Updates the singleton resource.\n   *\n   * @template Singleton The singleton resource model.\n   * @template Resource The resource model.\n   */\n  @autoRoute\n  @doc(\"Updates the singleton resource.\")\n  @segmentOf(Singleton)\n  @updatesResource(Singleton)\n  update(\n    ...ResourceParameters<Resource>,\n\n    @body\n    properties: ResourceCreateOrUpdateModel<Singleton>,\n  ): Singleton | Error;\n}\n\n/**\n * Singleton resource operation templates for singleton resource instances.\n *\n * @template Singleton The singleton resource model.\n * @template Resource The resource model.\n * @template Error The error response.\n */\ninterface SingletonResourceOperations<Singleton extends {}, Resource extends {}, Error>\n  extends SingletonResourceRead<Singleton, Resource, Error>,\n    SingletonResourceUpdate<Singleton, Resource, Error> {}\n\n/**\n * Extension resource read operation template.\n *\n * @template Extension The extension resource model.\n * @template Resource The resource model.\n * @template Error The error response.\n */\n@Private.validateHasKey(Resource)\n@Private.validateIsError(Error)\ninterface ExtensionResourceRead<Extension extends {}, Resource extends {}, Error> {\n  /**\n   * Gets an instance of the extension resource.\n   *\n   * @template Extension The extension resource model.\n   * @template Resource The resource model.\n   */\n  @autoRoute\n  @doc(\"Gets an instance of the extension resource.\")\n  @readsResource(Extension)\n  get(...ResourceParameters<Resource>, ...ResourceParameters<Extension>): Extension | Error;\n}\n\n/**\n * Extension resource create or update operation template.\n *\n * @template Extension The extension resource model.\n * @template Resource The resource model.\n * @template Error The error response.\n */\ninterface ExtensionResourceCreateOrUpdate<Extension extends {}, Resource extends {}, Error> {\n  /**\n   * Creates or update an instance of the extension resource.\n   *\n   * @template Extension The extension resource model.\n   * @template Resource The resource model.\n   */\n  @autoRoute\n  @doc(\"Creates or update an instance of the extension resource.\")\n  @createsOrUpdatesResource(Extension)\n  createOrUpdate(\n    ...ResourceParameters<Resource>,\n    ...ResourceParameters<Extension>,\n    @bodyRoot resource: ResourceCreateOrUpdateModel<Extension>,\n  ): Extension | ResourceCreatedResponse<Extension> | Error;\n}\n\n/**\n * Extension resource create operation template.\n *\n * @template Extension The extension resource model.\n * @template Resource The resource model.\n * @template Error The error response.\n */\ninterface ExtensionResourceCreate<Extension extends {}, Resource extends {}, Error> {\n  /**\n   * Creates a new instance of the extension resource.\n   *\n   * @template Extension The extension resource model.\n   * @template Resource The resource model.\n   */\n  @autoRoute\n  @doc(\"Creates a new instance of the extension resource.\")\n  @createsResource(Extension)\n  create(\n    ...ResourceParameters<Resource>,\n    @bodyRoot resource: ResourceCreateModel<Extension>,\n  ): Extension | ResourceCreatedResponse<Extension> | Error;\n}\n\n/**\n * Extension resource update operation template.\n *\n * @template Extension The extension resource model.\n * @template Resource The resource model.\n * @template Error The error response.\n */\ninterface ExtensionResourceUpdate<Extension extends {}, Resource extends {}, Error> {\n  /**\n   * Updates an existing instance of the extension resource.\n   *\n   * @template Extension The extension resource model.\n   * @template Resource The resource model.\n   */\n  @autoRoute\n  @doc(\"Updates an existing instance of the extension resource.\")\n  @updatesResource(Extension)\n  update(\n    ...ResourceParameters<Resource>,\n    ...ResourceParameters<Extension>,\n\n    @body\n    properties: ResourceCreateOrUpdateModel<Extension>,\n  ): Extension | Error;\n}\n\n/**\n * Extension resource delete operation template.\n *\n * @template Extension The extension resource model.\n * @template Resource The resource model.\n * @template Error The error response.\n */\ninterface ExtensionResourceDelete<Extension extends {}, Resource extends {}, Error> {\n  /**\n   * Deletes an existing instance of the extension resource.\n   *\n   * @template Extension The extension resource model.\n   * @template Resource The resource model.\n   */\n  @autoRoute\n  @doc(\"Deletes an existing instance of the extension resource.\")\n  @deletesResource(Extension)\n  delete(\n    ...ResourceParameters<Resource>,\n    ...ResourceParameters<Extension>,\n  ): ResourceDeletedResponse | Error;\n}\n\n/**\n * Extension resource list operation template.\n *\n * @template Extension The extension resource model.\n * @template Resource The resource model.\n * @template Error The error response.\n */\ninterface ExtensionResourceList<Extension extends {}, Resource extends {}, Error> {\n  /**\n   * Lists all instances of the extension resource.\n   *\n   * @template Extension The extension resource model.\n   * @template Resource The resource model.\n   */\n  @autoRoute\n  @doc(\"Lists all instances of the extension resource.\")\n  @listsResource(Extension)\n  list(\n    ...ResourceParameters<Resource>,\n    ...ResourceCollectionParameters<Extension>,\n  ): CollectionWithNextLink<Extension> | Error;\n}\n\n/**\n * Extension resource operation templates for extension resource instances.\n *\n * @template Extension The extension resource model.\n * @template Resource The resource model.\n * @template Error The error response.\n */\ninterface ExtensionResourceInstanceOperations<Extension extends {}, Resource extends {}, Error>\n  extends ExtensionResourceRead<Extension, Resource, Error>,\n    ExtensionResourceUpdate<Extension, Resource, Error>,\n    ExtensionResourceDelete<Extension, Resource, Error> {}\n\n/**\n * Extension resource operation templates for extension resource collections.\n *\n * @template Extension The extension resource model.\n * @template Resource The resource model.\n * @template Error The error response.\n */\ninterface ExtensionResourceCollectionOperations<Extension extends {}, Resource extends {}, Error>\n  extends ExtensionResourceCreate<Extension, Resource, Error>,\n    ExtensionResourceList<Extension, Resource, Error> {}\n\n/**\n * Extension resource operation templates for extension resource instances and collections.\n *\n * @template Extension The extension resource model.\n * @template Resource The resource model.\n * @template Error The error response.\n */\ninterface ExtensionResourceOperations<Extension extends {}, Resource extends {}, Error>\n  extends ExtensionResourceInstanceOperations<Extension, Resource, Error>,\n    ExtensionResourceCollectionOperations<Extension, Resource, Error> {}\n",
  "../../core/packages/versioning/lib/main.tsp": "import \"./decorators.tsp\";\nimport \"./projection.tsp\";\nimport \"../dist/src/validate.js\";\n",
  "../../core/packages/versioning/lib/decorators.tsp": "import \"../dist/src/decorators.js\";\n\nusing TypeSpec.Reflection;\n\nnamespace TypeSpec.Versioning;\n\n/**\n * Identifies that the decorated namespace is versioned by the provided enum.\n * @param versions The enum that describes the supported versions.\n *\n * @example\n *\n * ```tsp\n * @versioned(Versions)\n * namespace MyService;\n * enum Versions {\n *   v1,\n *   v2,\n *   v3,\n * }\n * ```\n */\nextern dec versioned(target: Namespace, versions: Enum);\n\n/**\n * Identifies that a namespace or a given versioning enum member relies upon a versioned package.\n * @param versionRecords The dependent library version(s) for the target namespace or version.\n *\n * @example Select a single version of `MyLib` to use\n *\n * ```tsp\n * @useDependency(MyLib.Versions.v1_1)\n * namespace NonVersionedService;\n * ```\n *\n * @example Select which version of the library match to which version of the service.\n *\n * ```tsp\n * @versioned(Versions)\n * namespace MyService1;\n * enum Version {\n *   @useDependency(MyLib.Versions.v1_1) // V1 use lib v1_1\n *   v1,\n *   @useDependency(MyLib.Versions.v1_1) // V2 use lib v1_1\n *   v2,\n *   @useDependency(MyLib.Versions.v2) // V3 use lib v2\n *   v3,\n * }\n * ```\n */\nextern dec useDependency(target: EnumMember | Namespace, ...versionRecords: EnumMember[]);\n\n/**\n * Identifies when the target was added.\n * @param version The version that the target was added in.\n *\n * @example\n *\n * ```tsp\n * @added(Versions.v2)\n * op addedInV2(): void;\n *\n * @added(Versions.v2)\n * model AlsoAddedInV2 {}\n *\n * model Foo {\n *   name: string;\n *\n *   @added(Versions.v3)\n *   addedInV3: string;\n * }\n * ```\n */\nextern dec added(\n  target:\n    | Model\n    | ModelProperty\n    | Operation\n    | Enum\n    | EnumMember\n    | Union\n    | UnionVariant\n    | Scalar\n    | Interface,\n  version: EnumMember\n);\n\n/**\n * Identifies when the target was removed.\n * @param version The version that the target was removed in.\n *\n * @example\n * ```tsp\n * @removed(Versions.v2)\n * op removedInV2(): void;\n *\n * @removed(Versions.v2)\n * model AlsoRemovedInV2 {}\n *\n * model Foo {\n *   name: string;\n *\n *   @removed(Versions.v3)\n *   removedInV3: string;\n * }\n * ```\n */\nextern dec removed(\n  target:\n    | Model\n    | ModelProperty\n    | Operation\n    | Enum\n    | EnumMember\n    | Union\n    | UnionVariant\n    | Scalar\n    | Interface,\n  version: EnumMember\n);\n\n/**\n * Identifies when the target has been renamed.\n * @param version The version that the target was renamed in.\n * @param oldName The previous name of the target.\n *\n * @example\n * ```tsp\n * @renamedFrom(Versions.v2, \"oldName\")\n * op newName(): void;\n * ```\n */\nextern dec renamedFrom(\n  target:\n    | Model\n    | ModelProperty\n    | Operation\n    | Enum\n    | EnumMember\n    | Union\n    | UnionVariant\n    | Scalar\n    | Interface,\n  version: EnumMember,\n  oldName: valueof string\n);\n\n/**\n * Identifies when a target was made optional.\n * @param version The version that the target was made optional in.\n *\n * @example\n *\n * ```tsp\n * model Foo {\n *   name: string;\n *   @madeOptional(Versions.v2)\n *   nickname?: string;\n * }\n * ```\n */\nextern dec madeOptional(target: ModelProperty, version: EnumMember);\n\n/**\n * Identifies when a target was made required.\n * @param version The version that the target was made required in.\n *\n * @example\n *\n * ```tsp\n * model Foo {\n *   name: string;\n *   @madeRequired(Versions.v2)\n *   nickname: string;\n * }\n * ```\n */\nextern dec madeRequired(target: ModelProperty, version: EnumMember);\n\n/**\n * Identifies when the target type changed.\n * @param version The version that the target type changed in.\n * @param oldType The previous type of the target.\n */\nextern dec typeChangedFrom(target: ModelProperty, version: EnumMember, oldType: unknown);\n\n/**\n * Identifies when the target type changed.\n * @param version The version that the target type changed in.\n * @param oldType The previous type of the target.\n */\nextern dec returnTypeChangedFrom(target: Operation, version: EnumMember, oldType: unknown);\n",
  "../../core/packages/versioning/lib/projection.tsp": "import \"../dist/src/internal-projection-functions.js\";\n\nusing TypeSpec.Versioning;\nusing TypeSpec.Reflection;\n\nnamespace TypeSpec.Versioning;\n\n/**\n * Returns whether the target exists for the given version.\n * @param version The version to check.\n */\nextern fn existsAtVersion(target: unknown, version: EnumMember): boolean;\n\n/**\n * Returns whether the target has a different name for the given version.\n * @param version The version to check.\n */\nextern fn hasDifferentNameAtVersion(target: unknown, version: EnumMember): boolean;\n\n/**\n * Returns whether the target has a different return type for the given version.\n * @param version The version to check.\n */\nextern fn hasDifferentReturnTypeAtVersion(target: unknown, version: EnumMember): boolean;\n\n/**\n * Returns whether the target was made optional after the given version.\n * @param version The version to check.\n */\nextern fn madeOptionalAfter(target: unknown, version: EnumMember): boolean;\n\n/**\n * Returns whether the target was made required after the given version.\n * @param version The version to check.\n */\nextern fn madeRequiredAfter(target: unknown, version: EnumMember): boolean;\n\n#suppress \"projections-are-experimental\"\nprojection op#v {\n  pre to(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  to(version) {\n    if hasDifferentNameAtVersion(self, version) {\n      self::rename(getNameAtVersion(self, version));\n    };\n    if hasDifferentReturnTypeAtVersion(self, version) {\n      self::changeReturnType(getReturnTypeBeforeVersion(self, version));\n    };\n  }\n  pre from(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  from(version) {\n    if hasDifferentNameAtVersion(self, version) {\n      self::rename(self::projectionBase::name);\n    };\n  }\n}\n\n#suppress \"projections-are-experimental\"\nprojection interface#v {\n  pre to(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  to(version) {\n    if hasDifferentNameAtVersion(self, version) {\n      self::rename(getNameAtVersion(self, version));\n    };\n    self::operations::forEach((operation) => {\n      if !existsAtVersion(operation, version) {\n        self::deleteOperation(operation::name);\n      };\n      if hasDifferentReturnTypeAtVersion(operation, version) {\n        operation::changeReturnType(getReturnTypeBeforeVersion(operation, version));\n      };\n    });\n  }\n  pre from(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  from(version) {\n    if hasDifferentNameAtVersion(self, version) {\n      self::rename(self::projectionBase::name);\n    };\n\n    self::projectionBase::operations::forEach((operation) => {\n      if !existsAtVersion(operation, version) {\n        self::addOperation(operation::name, operation::parameters, operation::returnType);\n      };\n    });\n  }\n}\n\n#suppress \"projections-are-experimental\"\nprojection union#v {\n  pre to(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  to(version) {\n    if hasDifferentNameAtVersion(self, version) {\n      self::rename(getNameAtVersion(self, version));\n    };\n\n    self::variants::forEach((variant) => {\n      if hasDifferentNameAtVersion(variant, version) {\n        self::renameVariant(variant::name, getNameAtVersion(variant, version));\n      };\n    });\n  }\n  from(version) {\n    if hasDifferentNameAtVersion(self, version) {\n      self::rename(self::projectionBase::name);\n    };\n\n    self::projectionBase::variants::forEach((variant) => {\n      if !existsAtVersion(variant, version) {\n        self::addVariant(variant::name, variant::type);\n      } else if hasDifferentNameAtVersion(variant, version) {\n        self::renameVariant(getNameAtVersion(variant, version), variant::name);\n      };\n    });\n  }\n}\n\n#suppress \"projections-are-experimental\"\nprojection unionvariant#v {\n  pre to(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  pre from(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n}\n\n#suppress \"projections-are-experimental\"\nprojection model#v {\n  pre to(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  to(version) {\n    if hasDifferentNameAtVersion(self, version) {\n      self::rename(getNameAtVersion(self, version));\n    };\n    self::properties::forEach((p) => {\n      if hasDifferentNameAtVersion(p, version) {\n        self::renameProperty(p::name, getNameAtVersion(p, version));\n      };\n\n      if madeOptionalAfter(p, version) {\n        p::setOptional(false);\n      };\n\n      if madeRequiredAfter(p, version) {\n        p::setOptional(true);\n      };\n\n      if hasDifferentTypeAtVersion(p, version) {\n        self::changePropertyType(p::name, getTypeBeforeVersion(p, version));\n      };\n    });\n  }\n  pre from(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  from(version) {\n    if hasDifferentNameAtVersion(self, version) {\n      self::rename(self::projectionBase::name);\n    };\n\n    self::projectionBase::properties::forEach((p) => {\n      if !existsAtVersion(p, version) {\n        self::addProperty(p::name, p::type);\n      };\n\n      if hasDifferentNameAtVersion(p, version) {\n        self::renameProperty(getNameAtVersion(p, version), p::name);\n      };\n\n      if madeOptionalAfter(p, version) {\n        p::setOptional(true);\n      };\n\n      if madeRequiredAfter(p, version) {\n        p::setOptional(false);\n      };\n\n      if hasDifferentTypeAtVersion(p, version) {\n        self::changePropertyType(p::name, p::type);\n      };\n    });\n  }\n}\n\n#suppress \"projections-are-experimental\"\nprojection modelproperty#v {\n  pre to(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  pre from(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n}\n\n#suppress \"projections-are-experimental\"\nprojection enum#v {\n  pre to(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  to(version) {\n    if hasDifferentNameAtVersion(self, version) {\n      self::rename(getNameAtVersion(self, version));\n    };\n\n    self::members::forEach((m) => {\n      if hasDifferentNameAtVersion(m, version) {\n        self::renameMember(m::name, getNameAtVersion(m, version));\n      };\n    });\n  }\n  pre from(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  from(version) {\n    if hasDifferentNameAtVersion(self, version) {\n      self::rename(self::projectionBase::name);\n    };\n\n    self::projectionBase::members::forEach((m) => {\n      if !existsAtVersion(m, version, self::projectionBase) {\n        self::addMember(m::name, m::type);\n      };\n\n      if hasDifferentNameAtVersion(m, version, self::projectionBase) {\n        self::renameMember(getNameAtVersion(m, version), m::name);\n      };\n    });\n  }\n}\n\n#suppress \"projections-are-experimental\"\nprojection enummember#v {\n  pre to(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  pre from(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n}\n\n#suppress \"projections-are-experimental\"\nprojection scalar#v {\n  pre to(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  to(version) {\n    if hasDifferentNameAtVersion(self, version) {\n      self::rename(getNameAtVersion(self, version));\n    };\n    if hasDifferentReturnTypeAtVersion(self, version) {\n      self::changeReturnType(getReturnTypeBeforeVersion(self, version));\n    };\n  }\n  pre from(version) {\n    if !existsAtVersion(self, version) {\n      return never;\n    };\n  }\n  from(version) {\n    if hasDifferentNameAtVersion(self, version) {\n      self::rename(self::projectionBase::name);\n    };\n  }\n}\n",
  "lib/auth.tsp": "import \"@typespec/http\";\nimport \"@typespec/rest\";\nimport \"@typespec/versioning\";\nimport \"./traits.tsp\";\n\nusing TypeSpec.Http;\nusing TypeSpec.Rest;\nusing TypeSpec.Versioning;\nusing Azure.Core.Traits;\nusing Azure.Core.Traits.Private;\n\nnamespace Azure.Core;\n\n/**\n * Azure Active Directory (AAD) Token Authentication Flow\n * @template AuthUrl The authorization URL.\n * @template TokenUrl The token URL.\n * @template Scopes A list of scopes the token applies to.\n */\nmodel AadTokenAuthFlow<Scopes extends string[], AuthUrl extends string, TokenUrl extends string>\n  extends TypeSpec.Http.AuthorizationCodeFlow {\n  type: OAuth2FlowType.authorizationCode;\n  authorizationUrl: AuthUrl;\n  tokenUrl: TokenUrl;\n  scopes: Scopes;\n}\n\n/**\n * Azure Active Directory OAuth2 Flow\n * @template AuthUrl The authorization URL.\n * @template TokenUrl The token URL.\n * @template Scopes A list of scopes the token applies to.\n */\n@doc(\"The Azure Active Directory OAuth2 Flow\")\nmodel AadOauth2Auth<\n  Scopes extends string[],\n  AuthUrl extends string = \"https://login.microsoftonline.com/common/oauth2/authorize\",\n  TokenUrl extends string = \"https://login.microsoftonline.com/common/oauth2/token\"\n> is OAuth2Auth<[AadTokenAuthFlow<Scopes, AuthUrl, TokenUrl>]>;\n\n/**\n * Azure API Key Authentication using the \"Ocp-Apim-Subscription-Key\" hea\n */\n@doc(\"Azure API Key Authentication\")\nmodel AzureApiKeyAuthentication\n  is TypeSpec.Http.ApiKeyAuth<ApiKeyLocation.header, \"Ocp-Apim-Subscription-Key\">;\n",
  "lib/traits.tsp": "import \"@typespec/versioning\";\n\nnamespace Azure.Core.Traits;\n\nusing TypeSpec.Reflection;\nusing TypeSpec.Versioning;\n\n/**\n * Enumerates the standard trait locations for Azure.Core operations.\n */\n@added(Azure.Core.Versions.v1_0_Preview_2)\n@doc(\"Enumerates the standard trait locations for Azure.Core operations.\")\nenum TraitLocation {\n  @doc(\"Identifies operation parameters as the trait target.\")\n  Parameters,\n\n  @doc(\"Identifies operation response as the trait target.\")\n  Response,\n\n  @doc(\"Identifies the API version parameter as the trait target.\")\n  ApiVersionParameter,\n}\n\n/**\n * Enumerates the standard trait contexts for Azure.Core operations.\n */\n@added(Azure.Core.Versions.v1_0_Preview_2)\n@doc(\"\")\nenum TraitContext {\n  @doc(\"Trait is applicable for resource 'read' operations.\")\n  Read,\n\n  @doc(\"Trait is applicable for resource 'create' operations.\")\n  Create,\n\n  @doc(\"Trait is applicable for resource 'update' operations.\")\n  Update,\n\n  @doc(\"Trait is applicable for resource 'delete' operations.\")\n  Delete,\n\n  @doc(\"Trait is applicable for resource 'list' operations.\")\n  List,\n\n  @doc(\"Trait is applicable for resource actions.\")\n  Action,\n\n  @doc(\"Only traits that did not specify a trait context (and therefore always apply) will be exposed.\")\n  Undefined,\n}\n\n/**\n * Used to override a trait.\n * @template Trait The trait to override.\n */\n@added(Azure.Core.Versions.v1_0_Preview_2)\n@Private.applyTraitOverride(Trait)\nmodel TraitOverride<Trait> {}\n\n/**\n * Declares a trait that is applied as a query parameter.\n * @template Parameters The name of the query parameter.\n * @template Contexts The contexts in which the trait is applicable.\n */\n@trait\n@added(Azure.Core.Versions.v1_0_Preview_2)\n@Private.ensureAllQueryParams(Parameters)\nmodel QueryParametersTrait<Parameters extends Model, Contexts = unknown> {\n  @traitContext(Contexts)\n  queryParams: {\n    @traitLocation(TraitLocation.Parameters)\n    parameters: Parameters;\n  };\n}\n\n/**\n * Declares a trait that is applied as a query parameter for list operations.\n * @template Parameters Object describing the query parameters.\n */\n@trait\n@added(Azure.Core.Versions.v1_0_Preview_2)\nmodel ListQueryParametersTrait<Parameters extends Model>\n  is QueryParametersTrait<Parameters, TraitContext.List>;\n\n/**\n * Declares a trait that is applied as a request header parameter.\n * @template Headers Object describing the request header parameters.\n * @template Contexts The contexts in which the trait is applicable.\n */\n@trait\n@added(Azure.Core.Versions.v1_0_Preview_2)\n@Private.ensureAllHeaderParams(Headers)\nmodel RequestHeadersTrait<Headers extends Model, Contexts = unknown> {\n  @traitContext(Contexts)\n  requestHeaders: {\n    @traitLocation(TraitLocation.Parameters)\n    parameters: Headers;\n  };\n}\n\n/**\n * Declares a trait that is applied as a response header parameter.\n * @template Headers Object describing the response header parameters.\n * @template Contexts The contexts in which the trait is applicable.\n */\n@trait\n@added(Azure.Core.Versions.v1_0_Preview_2)\n@Private.ensureAllHeaderParams(Headers)\nmodel ResponseHeadersTrait<Headers extends Model, Contexts = unknown> {\n  @traitContext(Contexts)\n  responseHeaders: {\n    @traitLocation(TraitLocation.Response)\n    parameters: Headers;\n  };\n}\n\n/**\n * Declares a version parameter trait.\n * @template VersionParameter The type of the version parameter.\n */\n@trait(\"VersionParameter\")\n@added(Azure.Core.Versions.v1_0_Preview_2)\nmodel VersionParameterTrait<VersionParameter> {\n  versionParameter: {\n    @traitLocation(TraitLocation.ApiVersionParameter)\n    apiVersionParam: VersionParameter;\n  };\n}\n\n/**\n * Provides clientRequestId headers for requests and responses.\n * @template VersionAdded The version when the trait was added to the specification.\n *           Leave this empty if the trait is always supported.\n */\n@trait(\"ClientRequestId\")\n@traitAdded(VersionAdded)\nmodel SupportsClientRequestId<VersionAdded extends EnumMember | null = null> {\n  #suppress \"@azure-tools/typespec-providerhub/no-inline-model\" \"This inline model is never used directly in operations.\"\n  clientRequestId: {\n    @traitLocation(TraitLocation.Parameters)\n    parameters: ClientRequestIdHeader;\n\n    @traitLocation(TraitLocation.Response)\n    response: ClientRequestIdHeader;\n  };\n}\n\n/**\n * Indicates that the service or operation does not support clientRequestId headers.\n */\n@trait(\"ClientRequestId\")\nmodel NoClientRequestId {\n  clientRequestId: {};\n}\n\n/**\n * Provides conditional request headers for requests and ETag headers for responses.\n * @template VersionAdded The version when the trait was added to the specification.\n *           Leave this empty if the trait is always supported.\n */\n@trait(\"ConditionalRequests\")\n@traitAdded(VersionAdded)\nmodel SupportsConditionalRequests<VersionAdded extends EnumMember | null = null> {\n  #suppress \"@azure-tools/typespec-providerhub/no-inline-model\" \"This inline model is never used directly in operations.\"\n  conditionalRequests: {\n    @traitContext(\n      TraitContext.Read | TraitContext.Update | TraitContext.Delete | TraitContext.Create\n    )\n    @traitLocation(TraitLocation.Parameters)\n    parameters: ConditionalRequestHeaders;\n\n    @traitContext(TraitContext.Read | TraitContext.Create | TraitContext.Update)\n    @traitLocation(TraitLocation.Response)\n    response: EtagResponseEnvelope;\n  };\n}\n\n/**\n * Indicates that the service or operation does not support conditional requests.\n */\n@trait(\"ConditionalRequests\")\nmodel NoConditionalRequests {\n  conditionalRequests: {};\n}\n\n/**\n * Provides repeatable request headers for requests and responses.\n * @template VersionAdded The version when the trait was added to the specification.\n *           Leave this empty if the trait is always supported.\n */\n@trait(\"RepeatableRequests\")\n@traitAdded(VersionAdded)\nmodel SupportsRepeatableRequests<VersionAdded extends EnumMember | null = null> {\n  #suppress \"@azure-tools/typespec-providerhub/no-inline-model\" \"This inline model is never used directly in operations.\"\n  @traitContext(\n    TraitContext.Create | TraitContext.Update | TraitContext.Delete | TraitContext.Action\n  )\n  repeatableRequests: {\n    @traitLocation(TraitLocation.Parameters)\n    parameters: RepeatabilityRequestHeaders;\n\n    @traitLocation(TraitLocation.Response)\n    response: RepeatabilityResponseHeaders;\n  };\n}\n\n/**\n * Indicates that the service or operation does not support repeatable requests.\n */\n@trait(\"RepeatableRequests\")\nmodel NoRepeatableRequests {\n  repeatableRequests: {};\n}\n\n/**\n * `@trait` marks a model type as representing a 'trait' and performs basic validation\n * checks.\n *\n * @param target The model type to mark as a trait.\n * @param traitName An optional name to uniquely identify the trait.  If unspecified,\n *        the model type name is used.\n */\nextern dec trait(target: unknown, traitName?: valueof string);\n\n/**\n * `@traitContext` sets the applicable context for a trait on its envelope property.\n *\n * @param target The trait envelope property where the context will be applied.\n * @param contexts An enum member or union of enum members representing the trait's\n *        applicable contexts.\n */\nextern dec traitContext(target: ModelProperty, contexts: EnumMember | Union | unknown);\n\n/**\n * `@traitLocation` sets the applicable location for a trait on its envelope property.\n *\n * @param target The trait envelope property where the context will be applied.\n * @param contexts An enum member or union of enum members representing the trait's\n *        applicable contexts.\n */\nextern dec traitLocation(target: ModelProperty, contexts: EnumMember);\n\n/**\n * Sets the version for when the trait was added to the specification.  Can be applied\n * to either a trait model type or its envelope property.\n * @param addedVersion The enum member representing the service version.\n */\nextern dec traitAdded(target: Model | ModelProperty, addedVersion: EnumMember | null);\n\nnamespace Azure.Core.Traits.Private {\n  @added(Azure.Core.Versions.v1_0_Preview_2)\n  @Private.addTraitProperties(Traits, Location, Contexts)\n  model TraitProperties<\n    Traits extends Model,\n    Location extends TypeSpec.Reflection.EnumMember,\n    Contexts = unknown\n  > {}\n\n  @doc(\"Contains the details of a specific trait expected by an interface or operation.\")\n  model ExpectedTrait {\n    @doc(\"The name of the expected trait.\")\n    trait: string;\n\n    @doc(\"The diagnostic to be raised when the trait is not present.\")\n    diagnostic: string;\n  }\n}\n\n// These decorators are not meant to be used by TypeSpec authors\nnamespace Azure {\n  namespace Core {\n    namespace Traits {\n      namespace Private {\n        /**\n         * `@traitSource` stores the `traitName` of its original trait on the envelope property.\n         *\n         * @param target The trait envelope property where `traitName` will be stored.\n         * @param traitName The name of the original trait to which this property belongs.\n         */\n        extern dec traitSource(target: ModelProperty, traitName: valueof string);\n\n        /**\n         * Copies trait properties from `traitModel` into `target` which conform to the\n         * specified location and contexts.\n         * @param traitModel The trait model type to be applied.\n         * @param traitLocation The trait location to use for selecting trait properties.\n         * @param traitContexts The trait contexts to use for selecting trait properties.\n         */\n        extern dec addTraitProperties(\n          target: Model,\n          traitModel: Model,\n          traitLocation: EnumMember,\n          traitContexts: EnumMember | Union | unknown\n        );\n\n        /**\n         * `@applyTraitOverride` copies the `traitModel` into `target` and renames its envelope\n         * property to enable the trait to override another trait sharing the same name.\n         *\n         * @param target The model into which the trait will be copied.\n         * @param traitModel The trait model type to be overridden.\n         */\n        extern dec applyTraitOverride(target: unknown, traitModel: unknown);\n\n        /**\n         * `@ensureTraitsPresent` checks the envelope properties of `traitModel` to ensure all\n         * of the `expectedTraits` are present as envelope properties.\n         *\n         * @param target The interface or operation where the `traitModel` should be checked.\n         * @param traitModel The trait model type to check.\n         * @param expectedTraits The array of `ExpectedTrait` models which describe each expected trait.\n         */\n        extern dec ensureTraitsPresent(\n          target: Interface | TypeSpec.Reflection.Operation,\n          traitModel: Model,\n          expectedTraits: ExpectedTrait[]\n        );\n\n        /**\n         * `@ensureAllQueryParams` checks the properties of `paramModel` to ensure they all are marked\n         * with the `@query` decorator.\n         *\n         * @param target The model type where this check will be established.\n         * @param paramModel The actual model type to check for query parameters.\n         */\n        extern dec ensureAllQueryParams(target: unknown, paramModel: Model);\n\n        /**\n         * `@ensureAllHeaderParams` checks the properties of `paramModel` to ensure they all are marked\n         * with the `@header` decorator.\n         *\n         * @param target The model type where this check will be established.\n         * @param paramModel The actual model type to check for header properties.\n         */\n        extern dec ensureAllHeaderParams(target: unknown, paramModel: Model);\n      }\n    }\n  }\n}\n",
  "lib/foundations.tsp": "import \"@typespec/http\";\nimport \"@typespec/rest\";\nimport \"@typespec/versioning\";\nimport \"./traits.tsp\";\n\nusing TypeSpec.Http;\nusing TypeSpec.Rest;\nusing TypeSpec.Versioning;\nusing Azure.Core.Traits;\nusing Azure.Core.Traits.Private;\n\nnamespace Azure.Core.Foundations;\n\n/**\n * Enum describing allowed operation states.\n */\n@lroStatus\nunion OperationState {\n  @doc(\"The operation has not started.\")\n  NotStarted: \"NotStarted\",\n\n  @doc(\"The operation is in progress.\")\n  Running: \"Running\",\n\n  @doc(\"The operation has completed successfully.\")\n  Succeeded: \"Succeeded\",\n\n  @doc(\"The operation has failed.\")\n  Failed: \"Failed\",\n\n  @doc(\"The operation has been canceled by the user.\")\n  Canceled: \"Canceled\",\n\n  string,\n}\n\n/**\n * Provides status details for long running operations.\n * @template StatusResult The type of the operation status result.\n * @template StatusError The type of the operation status error. If not provided, the default error is used.\n */\n@doc(\"Provides status details for long running operations.\")\nmodel OperationStatus<StatusResult = never, StatusError = Foundations.Error> {\n  @key(\"operationId\")\n  @doc(\"The unique ID of the operation.\")\n  id: string;\n\n  @doc(\"The status of the operation\")\n  status: OperationState;\n\n  @doc(\"Error object that describes the error when status is \\\"Failed\\\".\")\n  error?: StatusError;\n\n  @doc(\"The result of the operation.\")\n  result?: StatusResult;\n}\n\n/**\n * Conveys the resource instance to an operation as a request body.\n * @template Resource The type of the resource instance.\n */\n@added(Azure.Core.Versions.v1_0_Preview_2)\n@doc(\"Conveys the resource instance to an operation as a request body.\")\nmodel ResourceBody<Resource> {\n  @doc(\"The resource instance.\")\n  @body\n  resource: Resource;\n}\n\n// TODO: There is a ARM linter rule that verifies that\n// there is no response body. However, long running\n// operations are allowed to have it.\nalias ResourceCreatedResponse<Resource extends TypeSpec.Reflection.Model> = TypeSpec.Http.Response<201> &\n  Resource;\n\nalias ResourceOkResponse<Resource> = TypeSpec.Http.Response<200> & Resource;\n\nalias ResourceCreatedOrOkResponse<Resource extends TypeSpec.Reflection.Model> = ResourceCreatedResponse<Resource> | ResourceOkResponse<Resource>;\n\n/**\n * Response describing the location of a created resource.\n * @template T The type of the created resource.\n */\nmodel LocationOfCreatedResourceResponse<Resource extends TypeSpec.Reflection.Model>\n  is TypeSpec.Http.CreatedResponse {\n  @finalLocation\n  @TypeSpec.Http.header(\"Location\")\n  location: ResourceLocation<Resource>;\n}\n\n/**\n * Response describing the location of a resource created with a service-provided name.\n * @template T The type of the created resource.\n */\nmodel LocationOfCreatedResourceWithServiceProvidedNameResponse<Resource extends TypeSpec.Reflection.Model>\n  is TypeSpec.Http.AcceptedResponse {\n  @finalLocation\n  @TypeSpec.Http.header(\"Location\")\n  location: ResourceLocation<Resource>;\n}\n\n/**\n * Metadata for long running operation status monitor locations.\n * @template StatusResult The type of the operation status result.\n */\n@doc(\"Metadata for long running operation status monitor locations\")\nmodel LongRunningStatusLocation<StatusResult = never> {\n  @pollingLocation\n  @doc(\"The location for monitoring the operation state.\")\n  @TypeSpec.Http.header(\"Operation-Location\")\n  operationLocation: ResourceLocation<OperationStatus<StatusResult>>;\n}\n\nalias AcceptedResponse<Resource = {}> = TypeSpec.Http.AcceptedResponse & Resource;\n\n/**\n * A response containing error details.\n * @template Error The type of the error object.\n */\n@error\n@doc(\"A response containing error details.\")\nmodel ErrorResponseBase<Error> {\n  @doc(\"The error object.\")\n  error: Error;\n\n  @header(\"x-ms-error-code\")\n  @doc(\"String error code indicating what went wrong.\")\n  errorCode?: string;\n}\n\nmodel ErrorResponse is ErrorResponseBase<Error>;\n\n@doc(\"The ApiVersion query parameter.\")\nmodel ApiVersionParameter {\n  @query(\"api-version\")\n  @minLength(1)\n  @doc(\"The API version to use for this operation.\")\n  apiVersion: string;\n}\n\n@doc(\"The retry-after envelope.\")\nmodel RetryAfterHeader {\n  @doc(\"The Retry-After header can indicate how long the client should wait before polling the operation status.\")\n  @header(\"Retry-After\")\n  retryAfter?: int32;\n}\n\n@doc(\"The error object.\")\nmodel Error {\n  @doc(\"One of a server-defined set of error codes.\")\n  code: string;\n\n  @doc(\"A human-readable representation of the error.\")\n  message: string;\n\n  @doc(\"The target of the error.\")\n  target?: string;\n\n  #suppress \"@azure-tools/typespec-providerhub/no-identifier-property-in-array-item\" \"Error items have no unique identifier.\"\n  @doc(\"An array of details about specific errors that led to this reported error.\")\n  details?: Error[];\n\n  @doc(\"An object containing more specific information than the current object about the error.\")\n  innererror?: InnerError;\n}\n\n@doc(\"An object containing more specific information about the error. As per Microsoft One API guidelines - https://github.com/Microsoft/api-guidelines/blob/vNext/Guidelines.md#7102-error-condition-responses.\")\nmodel InnerError {\n  @doc(\"One of a server-defined set of error codes.\")\n  code?: string;\n\n  @doc(\"Inner error.\")\n  innererror?: InnerError;\n}\n\n/**\n * Version of a model for a create or replace operation which only includes updateable properties.\n * @template Resource The type of the resource.\n */\n@omitKeyProperties\nmodel ResourceCreateOrReplaceModel<Resource extends TypeSpec.Reflection.Model>\n  is UpdateableProperties<DefaultKeyVisibility<Resource, \"read\">>;\n\n/**\n * Collection of properties from a resource that are visible to create or update scopes.\n * @template Resource The type of the resource.\n */\n@withVisibility(\"create\", \"update\")\nmodel CreateableAndUpdateableProperties<Resource> {\n  ...Resource;\n}\n\n/**\n * Version of a model for a create or update operation which only includes updateable properties.\n * @template Resource The type of the resource.\n */\n@omitKeyProperties\nmodel ResourceCreateOrUpdateModel<Resource>\n  is OptionalProperties<CreateableAndUpdateableProperties<DefaultKeyVisibility<Resource, \"read\">>>;\n\n/**\n * Version of a model for an update operation which only includes updateable properties.\n * @template Resource The type of the resource.\n */\n@omitKeyProperties\nmodel ResourceUpdateModel<Resource>\n  is OptionalProperties<UpdateableProperties<DefaultKeyVisibility<Resource, \"read\">>>;\n\n/**\n * A model containing the keys of the provided resource.\n * @template Resource The type of the resource.\n */\n@copyResourceKeyParameters\nmodel ItemKeysOf<Resource> {}\n\n/**\n * A model containing the collection keys of the provided resource's parent resource.\n * @template Resource The type of the resource.\n */\n@copyResourceKeyParameters(\"parent\")\nmodel CollectionKeysOf<Resource> {}\n\n/**\n * A model describing a set of custom request parameters.\n * @template Custom An object describing custom request parameters.\n */\n@Private.spreadCustomParameters(Custom)\nmodel CustomParameters<Custom extends TypeSpec.Reflection.Model> {}\n\n/**\n * A model describing a set of custom response properties.\n * @template Custom An object describing custom response properties.\n */\n@Private.spreadCustomResponseProperties(Custom)\nmodel CustomResponseFields<Custom extends TypeSpec.Reflection.Model> {}\n\n/**\n * A model describing a customized page of resources.\n * @template Resource The type of the resource.\n * @template Traits Traits which apply to the page.\n */\n@pagedResult\n@friendlyName(\"Paged{name}\", Resource)\n@doc(\"Paged collection of {name} items\", Resource)\nmodel CustomPage<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> {\n  @doc(\"The {name} items on this page\", Resource)\n  @items\n  value: Resource[];\n\n  @doc(\"The link to the next page of items\")\n  @nextLink\n  nextLink?: ResourceLocation<Resource>;\n\n  // Include custom response fields\n  ...TraitProperties<Traits, TraitLocation.Response, TraitContext.List>;\n}\n\n/**\n * The expected shape of model types passed to the Custom parameter of operation signatures.\n */\n@doc(\"The expected shape of model types passed to the Custom parameter of operation signatures.\")\nmodel CustomizationFields {\n  @doc(\"An object containing custom parameters that will be included in the operation.\")\n  parameters?: {};\n\n  @doc(\"An object containing custom properties that will be included in the response.\")\n  response?: {};\n}\n\n// Basic Operation Shapes\n\n/**\n * The most basic operation.\n * @template Parameters Object describing the request parameters of the operation.\n * @template Response Object describing the response properties of the operation.\n * @template Traits Traits which apply to the operation.\n * @template ErrorResponse The type of the error response. If not provided, the default error response type will be used.\n */\nop Operation<\n  Parameters extends TypeSpec.Reflection.Model,\n  Response,\n  Traits extends TypeSpec.Reflection.Model = {},\n  ErrorResponse = Azure.Core.Foundations.ErrorResponse\n>(\n  ...TraitProperties<\n    Traits & VersionParameterTrait<ApiVersionParameter>,\n    TraitLocation.ApiVersionParameter\n  >,\n  ...Parameters,\n): Response | ErrorResponse;\n\n/**\n * Long-running operation.\n * @template Parameters Object describing the request parameters of the operation.\n * @template Response Object describing the response properties of the operation. If not provided, the AcceptedResponse type will be used.\n * @template Traits Traits which apply to the operation.\n * @template ErrorResponse The type of the error response. If not provided, the default error response type will be used.\n */\n#suppress \"@azure-tools/typespec-providerhub/no-inline-model\" \"This operation signature is not used in Azure Resource Manager operations (yet)\"\nop LongRunningOperation<\n  Parameters extends TypeSpec.Reflection.Model,\n  Response = AcceptedResponse,\n  Traits extends TypeSpec.Reflection.Model = {},\n  ErrorResponse = Azure.Core.Foundations.ErrorResponse\n> is Operation<Parameters, Response & Foundations.LongRunningStatusLocation, Traits, ErrorResponse>;\n\n/**\n * Operation that returns the status of another operation.\n * @template Parameters Object describing the request parameters of the operation.\n * @template StatusResult The type of the operation status result.\n * @template StatusError The type of the operation status error.\n * @template Traits Traits which apply to the operation.\n * @template ErrorResponse The type of the error response. If not provided, the default error response type will be used.\n */\nop GetOperationStatus<\n  Parameters = {},\n  StatusResult = never,\n  StatusError = Error,\n  Traits extends TypeSpec.Reflection.Model = {},\n  ErrorResponse = Azure.Core.Foundations.ErrorResponse\n> is Foundations.Operation<\n  Parameters & {\n    @doc(\"The unique ID of the operation.\")\n    @path\n    operationId: string;\n  },\n  OperationStatus<StatusResult, StatusError>,\n  Traits,\n  ErrorResponse\n>;\n\n// Fundamental Resource Operation Shapes\n\n/**\n * The most basic operation that applies to a resource.\n * @template Resource The type of the resource.\n * @template Parameters Object describing the request parameters of the operation.\n * @template Response Object describing the response properties of the operation.\n * @template Traits Traits which apply to the operation.\n * @template ErrorResponse The type of the error response. If not provided, the default error response type will be used.\n */\n#suppress \"@azure-tools/typespec-azure-resource-manager/no-response-body\" \"This operation must return a status monitor in its response.\"\n@autoRoute\n@Private.ensureResourceType(Resource)\nop ResourceOperation<\n  Resource extends TypeSpec.Reflection.Model,\n  Parameters extends TypeSpec.Reflection.Model,\n  Response,  // No constraint here on purpose, some responses are unions\n  Traits extends TypeSpec.Reflection.Model = {},\n  ErrorResponse = Azure.Core.Foundations.ErrorResponse\n> is Operation<Foundations.ItemKeysOf<Resource> & Parameters, Response, Traits, ErrorResponse>;\n\n/**\n * Operation that applies to a collection of resources.\n * @template Resource The type of the resource.\n * @template Parameters Object describing the request parameters of the operation.\n * @template Response Object describing the response properties of the operation.\n * @template Traits Traits which apply to the operation.\n * @template ErrorResponse The type of the error response. If not provided, the default error response type will be used.\n */\n#suppress \"@azure-tools/typespec-azure-resource-manager/no-response-body\" \"This operation must return a status monitor in its response.\"\n@autoRoute\n@Private.ensureResourceType(Resource)\nop ResourceCollectionOperation<\n  Resource extends TypeSpec.Reflection.Model,\n  Parameters extends TypeSpec.Reflection.Model,\n  Response extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {},\n  ErrorResponse = Azure.Core.Foundations.ErrorResponse\n> is Operation<\n  Foundations.CollectionKeysOf<Resource> & Parameters,\n  Response,\n  Traits,\n  ErrorResponse\n>;\n\n/**\n * Operation that lists resources in a paginated way.\n * @template Resource The type of the resource.\n * @template Parameters Object describing the request parameters of the operation.\n * @template Response Object describing the response properties of the operation.\n * @template Traits Traits which apply to the operation.\n * @template ErrorResponse The type of the error response. If not provided, the default error response type will be used.\n */\n@listsResource(Resource)\n@Private.ensureResourceType(Resource)\nop ResourceList<\n  Resource extends TypeSpec.Reflection.Model,\n  Parameters extends TypeSpec.Reflection.Model,\n  Response extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {},\n  ErrorResponse = Azure.Core.Foundations.ErrorResponse\n> is ResourceCollectionOperation<Resource, Parameters, Response, Traits, ErrorResponse>;\n\n/**\n * Operation that lists resources in a non-paginated way.\n * @template Resource The type of the resource.\n * @template Traits Traits which apply to the operation.\n * @template ErrorResponse The type of the error response. If not provided, the default error response type will be used.\n */\n#suppress \"@azure-tools/typespec-providerhub/no-inline-model\" \"This operation signature is not used in Azure Resource Manager operations (yet)\"\n@autoRoute\nop NonPagedResourceList<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {},\n  ErrorResponse = Azure.Core.Foundations.ErrorResponse\n> is Foundations.ResourceList<\n  Resource,\n  TraitProperties<Traits, TraitLocation.Parameters, TraitContext.List>,\n  Body<Resource[]> & TraitProperties<Traits, TraitLocation.Response, TraitContext.List>,\n  Traits,\n  ErrorResponse\n>;\n\n/**\n * Long-running operation that updates a resource.\n * @template Resource The type of the resource.\n * @template Traits Traits which apply to the operation.\n * @template ErrorResponse The type of the error response. If not provided, the default error response type will be used.\n */\n@updatesResource(Resource)\nop LongRunningResourceUpdate<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {},\n  ErrorResponse = Azure.Core.Foundations.ErrorResponse\n> is Foundations.ResourceOperation<\n  Resource,\n  {\n    @doc(\"This request has a JSON Merge Patch body.\")\n    @TypeSpec.Http.header(\"Content-Type\")\n    contentType: \"application/merge-patch+json\";\n\n    ...Foundations.ResourceBody<Resource>;\n    ...TraitProperties<Traits, TraitLocation.Parameters, TraitContext.Update>;\n  },\n  Foundations.ResourceOkResponse<Resource &\n    TraitProperties<Traits, TraitLocation.Response, TraitContext.Update> &\n    Foundations.LongRunningStatusLocation<Resource>>,\n  Traits,\n  ErrorResponse\n>;\n",
  "lib/models.tsp": "import \"@typespec/http\";\nimport \"@typespec/rest\";\nimport \"./traits.tsp\";\n\nusing TypeSpec.Http;\nusing TypeSpec.Rest;\n\nnamespace Azure.Core;\n\n/**\n * Describes a page of resource object.\n * @template Resource The resource type.\n */\n@pagedResult\n@friendlyName(\"Paged{name}\", Resource)\n@doc(\"Paged collection of {name} items\", Resource)\nmodel Page<Resource extends TypeSpec.Reflection.Model> {\n  @doc(\"The {name} items on this page\", Resource)\n  @items\n  value: Resource[];\n\n  @doc(\"The link to the next page of items\")\n  @nextLink\n  nextLink?: ResourceLocation<Resource>;\n}\n\n/**\n * Defines a property as a request parameter.\n * @template Name The parameter name.\n */\n@Foundations.requestParameter(Name)\nmodel RequestParameter<Name extends valueof string> {}\n\n/**\n * Defines a property as a response header.\n * @template Name The header name.\n */\n@Foundations.responseProperty(Name)\nmodel ResponseProperty<Name extends valueof string> {}\n\n/**\n * @dev Provides the status of a resource operation.\n * @template Resource The resource type.\n * @template StatusResult Model describing the status result object. If not specified, the default is the resource type.\n * @template StatusError Model describing the status error object. If not specified, the default is the Foundations.Error.\n */\n@resource(\"operations\")\n@parentResource(Resource)\nmodel ResourceOperationStatus<\n  Resource extends TypeSpec.Reflection.Model,\n  StatusResult = Resource,\n  StatusError = Foundations.Error\n> is Azure.Core.Foundations.OperationStatus<StatusResult, StatusError>;\n\n#suppress \"@azure-tools/typespec-providerhub/no-inline-model\" \"This is acceptable in Azure.Core.\"\nalias ResourceOperationStatusResponse<\n  Resource extends TypeSpec.Reflection.Model,\n  StatusResult,\n  StatusError\n> = ResourceOperationStatus<Resource, StatusResult, StatusError>;\n\n@doc(\"Provides the standard 'top' query parameter for list operations.\")\nmodel TopQueryParameter {\n  @query\n  @doc(\"The number of result items to return.\")\n  top?: int32;\n}\n\n@doc(\"Provides the standard 'skip' query parameter for list operations.\")\nmodel SkipQueryParameter {\n  @query\n  @doc(\"The number of result items to skip.\")\n  skip?: int32 = 0;\n}\n\n@doc(\"Provides the standard 'maxpagesize' query parameter for list operations.\")\nmodel MaxPageSizeQueryParameter {\n  @query\n  @doc(\"The maximum number of result items per page.\")\n  maxpagesize?: int32;\n}\n\n@doc(\"Provides the standard 'filter' query parameter for list operations\")\nmodel FilterParameter {\n  @query\n  @doc(\"The maximum number of result items per page.\")\n  filter?: string;\n}\n\n@doc(\"Provides the standard 'orderby' query parameter for list operations.\")\nmodel OrderByQueryParameter {\n  #suppress \"@azure-tools/typespec-azure-core/prefer-csv-collection-format\" \"By design\"\n  @query({\n    format: \"multi\",\n  })\n  @doc(\"Expressions that specify the order of returned results.\")\n  orderby?: string[];\n}\n\n@doc(\"Provides the standard 'filter' query parameter for list operations.\")\nmodel FilterQueryParameter {\n  @query\n  @doc(\"Filter the result list using the given expression.\")\n  filter?: string;\n}\n\n@doc(\"Provides the standard 'select' query parameter for list operations.\")\nmodel SelectQueryParameter {\n  #suppress \"@azure-tools/typespec-azure-core/prefer-csv-collection-format\" \"By design\"\n  @query({\n    format: \"multi\",\n  })\n  @doc(\"Select the specified fields to be included in the response.\")\n  select?: string[];\n}\n\n@doc(\"Provides the standard 'expand' query parameter for list operations.\")\nmodel ExpandQueryParameter {\n  #suppress \"@azure-tools/typespec-azure-core/prefer-csv-collection-format\" \"By design\"\n  @query({\n    format: \"multi\",\n  })\n  @doc(\"Expand the indicated resources into the response.\")\n  expand?: string[];\n}\n\n@doc(\"Provides the most common query parameters for list operations.\")\nmodel StandardListQueryParameters {\n  ...TopQueryParameter;\n  ...SkipQueryParameter;\n  ...MaxPageSizeQueryParameter;\n}\n\n// https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md#conditional-requests\n\n@doc(\"Provides the 'If-*' headers to enable conditional (cached) responses\")\nmodel ConditionalRequestHeaders {\n  @visibility(\"read\", \"query\", \"create\", \"update\", \"delete\")\n  @header(\"If-Match\")\n  @doc(\"The request should only proceed if an entity matches this string.\")\n  ifMatch?: string;\n\n  @visibility(\"read\", \"query\", \"create\", \"update\", \"delete\")\n  @header(\"If-None-Match\")\n  @doc(\"The request should only proceed if no entity matches this string.\")\n  ifNoneMatch?: string;\n\n  @visibility(\"read\", \"query\", \"create\", \"update\", \"delete\")\n  @header(\"If-Unmodified-Since\")\n  @doc(\"The request should only proceed if the entity was not modified after this time.\")\n  ifUnmodifiedSince?: utcDateTime;\n\n  @visibility(\"read\", \"query\", \"create\", \"update\", \"delete\")\n  @header(\"If-Modified-Since\")\n  @doc(\"The request should only proceed if the entity was modified after this time.\")\n  ifModifiedSince?: utcDateTime;\n}\n\n@doc(\"\"\"\n  Provides the 'ETag' field to enable conditional (cached) requests.  This model can be spread\n  into responses and item models to convey the ETag when it cannot simply conveyed in a header.\n  \"\"\")\nmodel EtagProperty {\n  @visibility(\"read\")\n  @doc(\"The entity tag for this resource.\")\n  etag: eTag;\n}\n\n@doc(\"Provides the 'ETag' header to enable conditional (cached) requests\")\nmodel EtagResponseEnvelope {\n  @header(\"ETag\")\n  @visibility(\"read\")\n  @doc(\"The entity tag for the response.\")\n  etagHeader?: string;\n}\n\n// https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md#repeatability-of-requests\n\n@doc(\"Provides the 'Repeatability-*' headers to enable repeatable requests.\")\nmodel RepeatabilityRequestHeaders {\n  @visibility(\"create\", \"update\", \"delete\")\n  @header(\"Repeatability-Request-ID\")\n  @doc(\"An opaque, globally-unique, client-generated string identifier for the request.\")\n  repeatabilityRequestId?: string;\n\n  @visibility(\"create\", \"update\", \"delete\")\n  @doc(\"Specifies the date and time at which the request was first created.\")\n  @header(\"Repeatability-First-Sent\")\n  repeatabilityFirstSent?: utcDateTime;\n}\n\n@doc(\"Provides the 'Repeatability-*' headers to enable repeatable requests.\")\nmodel RepeatabilityResponseHeaders {\n  @visibility(\"read\")\n  @header(\"Repeatability-Result\")\n  @doc(\"Indicates whether the repeatable request was accepted or rejected.\")\n  repeatabilityResult?: RepeatabilityResult;\n}\n\n/** Repeatability Result header options */\nunion RepeatabilityResult {\n  /** If the request was accepted and the server guarantees that the server state reflects a single execution of the operation. */\n  \"accepted\",\n\n  /**\n   * If the request was rejected because the combination of Repeatability-First-Sent and Repeatability-Request-ID were invalid\n   *  or because the Repeatability-First-Sent value was outside the range of values held by the server.\n   */\n  \"rejected\",\n}\n\n// https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md#distributed-tracing--telemetry\n\n@doc(\"Provides the 'x-ms-client-request-id' header to enable request correlation in requests and responses.\")\nmodel ClientRequestIdHeader {\n  @header(\"x-ms-client-request-id\")\n  @doc(\"An opaque, globally-unique, client-generated string identifier for the request.\")\n  clientRequestId?: uuid;\n}\n\n@doc(\"Provides the 'x-ms-request-id' header to enable request correlation in responses.\")\nmodel RequestIdResponseHeader {\n  @visibility(\"read\")\n  @header(\"x-ms-request-id\")\n  @doc(\"An opaque, globally-unique, server-generated string identifier for the request.\")\n  requestId?: uuid;\n}\n\n/**\n * A vector embedding frequently used in similarity search.\n * @template Element The element type of the embedding vector.\n */\n@Foundations.Private.embeddingVector(Element)\nmodel EmbeddingVector<Element extends numeric = float32> is Array<Element>;\n\n/**\n * Options for overriding a polling endpoint that uses a StatusMonitor\n * @template PollingModel The model that is returned when polling should continue.\n * @template FinalResult The model that is returned when polling terminates successfully.\n * @template FinalProperty The property of the status monitor that contains results.\n */\nmodel StatusMonitorPollingOptions<\n  PollingModel extends TypeSpec.Reflection.Model | void = never,\n  FinalResult extends TypeSpec.Reflection.Model | void = never,\n  FinalProperty extends TypeSpec.Reflection.ModelProperty | string = never\n> extends StatusMonitorOptions {\n  /** The kind of polling options */\n  kind: PollingOptionKind.statusMonitor;\n\n  /** The model that is returned when polling should continue */\n  pollingModel: PollingModel;\n\n  /** The model that is returned when polling terminates successfully */\n  finalResult: FinalResult;\n\n  /** The property of the status monitor that contains results */\n  finalProperty: FinalProperty;\n}\n\n/** Options for Lro status monitors. */\nmodel StatusMonitorOptions extends PollingOptions {\n  /** The kind of polling options */\n  kind: PollingOptionKind.statusMonitor;\n\n  /** A reference to or name of the property of the status monitor that contains the response */\n  finalProperty?: TypeSpec.Reflection.ModelProperty | string;\n}\n\n/** Generic polling options for LRO operations. */\nmodel PollingOptions {\n  /** The kind of polling options */\n  kind: PollingOptionKind;\n\n  /** The model that is returned when polling should continue. */\n  pollingModel?: TypeSpec.Reflection.Model | void;\n\n  /** The type that is returned when polling terminates successfully. */\n  finalResult?: TypeSpec.Reflection.Model | void;\n}\n\n/** The available kinds of polling options */\nunion PollingOptionKind {\n  /** Polling options for a status monitor */\n  statusMonitor: \"statusMonitor\",\n\n  string,\n}\n\n/**\n * Universally Unique Identifier\n *\n * @example\n *\n * ```\n * 123e4567-e89b-12d3-a456-426614174000\n * ```\n */\n@format(\"uuid\")\nscalar uuid extends string;\n\n/**\n * Represent an IP V4 address serialized as a string.\n *\n * It is formatted as four 8-bit fields separated by periods.\n *\n * @example\n *\n * ```\n * 129.144.50.56\n * ```\n */\n#suppress \"@azure-tools/typespec-autorest/invalid-format\" \"Foundation.\"\n@format(\"ipV4Address\")\nscalar ipV4Address extends string;\n\n/**\n * Represent an IP V6 address serialized as a string.\n *\n * It is formatted as eight hex decimal values(16-bit) between 0 and FFFF separated by colon. (i.e. `y:y:y:y:y:y:y:y`)\n *\n * @example\n *\n * ```\n * 2001:db8:3333:4444:CCCC:DDDD:EEEE:FFFF\n * ```\n */\n#suppress \"@azure-tools/typespec-autorest/invalid-format\" \"Foundation.\"\n@format(\"ipV6Address\")\nscalar ipV6Address extends string;\n\n/**\n * The ETag (or entity tag) HTTP response header is an identifier for a specific version of a resource.\n * It lets caches be more efficient and save bandwidth, as a web server does not need to resend a full response if the content was not changed.\n *\n * It is a string of ASCII characters placed between double quotes, like \"675af34563dc-tr34\".\n *\n * @example In `ETag` header\n *\n * ```\n * ETag: \"675af34563dc-tr34\"\n * ```\n */\n#suppress \"@azure-tools/typespec-autorest/invalid-format\" \"Foundation.\"\n@format(\"eTag\")\nscalar eTag extends string;\n\n/**\n * Represents an Azure geography region where supported resource providers live.\n *\n * @example\n *\n * ```\n * WestUS\n * ```\n */\nscalar azureLocation extends string;\n\n/**\n * A type definition that refers the id to an Azure Resource Manager resource.\n *\n * Sample usage:\n *   otherArmId: ResourceIdentifier;\n *   networkId: ResourceIdentifier<[{type:\"\\\\Microsoft.Network\\\\vnet\"}]>\n *   vmIds: ResourceIdentifier<[{type:\"\\\\Microsoft.Compute\\\\vm\", scopes[\"*\"]}]>\n * @template AllowedResourceTypes An array of allowed resource types for the resource reference\n */\n@doc(\"A type definition that refers the id to an Azure Resource Manager resource.\")\n@format(\"arm-id\")\n@Azure.Core.Foundations.Private.armResourceIdentifierConfig({\n  allowedResources: AllowedResourceTypes,\n})\nscalar armResourceIdentifier<AllowedResourceTypes extends ArmResourceIdentifierAllowedResource[] = never>\n  extends string;\n\n// Consider replacing `*`\nunion ArmResourceDeploymentScope {\n  \"tenant\",\n  \"subscription\",\n  \"resourceGroup\",\n  \"managementGroup\",\n  \"extension\",\n}\n\nalias AllArmResourceDeploymentScopes = [\n  \"tenant\",\n  \"subscription\",\n  \"resourceGroup\",\n  \"managementGroup\",\n  \"extension\"\n];\n\nmodel ArmResourceIdentifierAllowedResource {\n  /** The type of resource that is being referred to. For example Microsoft.Network/virtualNetworks or Microsoft.Network/virtualNetworks/subnets. See Example Types for more examples. */\n  type: string;\n\n  /**\n   * An array of scopes. If not specified, the default scope is [\"ResourceGroup\"].\n   * See [Allowed Scopes](https://github.com/Azure/autorest/tree/main/docs/extensions#allowed-scopes).\n   */\n  scopes?: ArmResourceDeploymentScope[];\n}\n",
  "lib/operations.tsp": "import \"@typespec/http\";\nimport \"@typespec/rest\";\nimport \"@typespec/versioning\";\nimport \"./models.tsp\";\nimport \"./traits.tsp\";\n\nnamespace Azure.Core;\n\nusing TypeSpec.Http;\nusing TypeSpec.Rest;\nusing TypeSpec.Versioning;\nusing Azure.Core.Traits;\nusing Azure.Core.Traits.Private;\n\n// RPC Operations\n\n/**\n * A remote procedure call (RPC) operation.\n * @template Parameters Object describing the parameters of the operation.\n * @template Response Object describing the response of the operation.\n * @template Traits Object describing the traits of the operation.\n * @template ErrorResponse Error response of the operation. If not specified, the default error response is used.\n * @template TraitContexts Trait contexts applicable to the operation. Defaults to `TraitContext.Undefined` which means that only traits that always apply will appear. Can specify multiple using the | operator.\n */\n@Foundations.Private.needsRoute\nop RpcOperation<\n  Parameters extends TypeSpec.Reflection.Model,\n  Response extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {},\n  ErrorResponse = Azure.Core.Foundations.ErrorResponse,\n  TraitContexts extends TraitContext = TraitContext.Undefined\n> is Foundations.Operation<\n  Parameters & TraitProperties<Traits, TraitLocation.Parameters>,\n  Response & TraitProperties<Traits, TraitLocation.Response, TraitContexts>,\n  Traits,\n  ErrorResponse\n>;\n\n/**\n * A long-running remote procedure call (RPC) operation.\n * @template Parameters Object describing the parameters of the operation.\n * @template Response Object describing the response of the operation.\n * @template StatusResult Object describing the status result of the operation.\n * @template StatusError Error response of the status operation. If not specified, the default error response is used.\n * @template Traits Object describing the traits of the operation.\n * @template ErrorResponse Error response of the operation. If not specified, the default error response is used.\n * @template TraitContexts Trait contexts applicable to the operation. Defaults to `TraitContext.Undefined` which means that only traits that always apply will appear. Can specify multiple using the | operator.\n */\n@Foundations.Private.needsRoute\n@post\nop LongRunningRpcOperation<\n  Parameters extends TypeSpec.Reflection.Model,\n  Response extends TypeSpec.Reflection.Model,\n  StatusResult extends TypeSpec.Reflection.Model,\n  StatusError = Foundations.Error,\n  Traits extends TypeSpec.Reflection.Model = {},\n  ErrorResponse = Azure.Core.Foundations.ErrorResponse,\n  TraitContexts extends TraitContext = TraitContext.Undefined\n> is Foundations.Operation<\n  Parameters & TraitProperties<Traits, TraitLocation.Parameters>,\n  AcceptedResponse &\n    ResourceOperationStatus<Response, StatusResult, StatusError> &\n    Foundations.LongRunningStatusLocation<StatusResult> &\n    TraitProperties<Traits, TraitLocation.Response, TraitContexts>,\n  Traits,\n  ErrorResponse\n>;\n\n// Standard Resource Lifecycle Operations\n\nalias ExpectedResourceOperationTraits = [\n  {\n    trait: \"ConditionalRequests\";\n    diagnostic: \"conditional-requests-trait-missing\";\n  },\n  {\n    trait: \"RepeatableRequests\";\n    diagnostic: \"repeatable-requests-trait-missing\";\n  },\n  {\n    trait: \"ClientRequestId\";\n    diagnostic: \"client-request-id-trait-missing\";\n  }\n];\n\n/**\n * Interface containing common resource operations.\n * @template InterfaceTraits Traits applicable to the operations.\n * @template ErrorResponse Error response of the operations. If not specified, the default error response is used.\n */\n@ensureTraitsPresent(InterfaceTraits, ExpectedResourceOperationTraits)\ninterface ResourceOperations<\n  InterfaceTraits extends TypeSpec.Reflection.Model,\n  ErrorResponse = Azure.Core.Foundations.ErrorResponse\n> {\n  /**\n   * Create or replace operation template.\n   * @template Resource Resource type.\n   * @template Traits Object describing the traits of the operation.\n   */\n  @Foundations.Private.ensureVerb(\"ResourceCreateOrReplace\", \"PUT\")\n  @createsOrReplacesResource(Resource)\n  ResourceCreateOrReplace<\n    Resource extends TypeSpec.Reflection.Model,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceOperation<\n    Resource,\n    Foundations.ResourceBody<Resource> &\n      TraitProperties<\n        Traits & InterfaceTraits,\n        TraitLocation.Parameters,\n        TraitContext.Create | TraitContext.Update\n      >,\n    Foundations.ResourceCreatedOrOkResponse<Resource &\n      TraitProperties<\n        Traits & InterfaceTraits,\n        TraitLocation.Response,\n        TraitContext.Create | TraitContext.Update\n      >>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Long-running resource create or replace operation template.\n   * @template Resource Resource type.\n   * @template Traits Object describing the traits of the operation.\n   */\n  @Foundations.Private.ensureVerb(\"LongRunningResourceCreateOrReplace\", \"PUT\")\n  @createsOrReplacesResource(Resource)\n  LongRunningResourceCreateOrReplace<\n    Resource extends TypeSpec.Reflection.Model,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceOperation<\n    Resource,\n    Foundations.ResourceBody<Resource> &\n      TraitProperties<\n        Traits & InterfaceTraits,\n        TraitLocation.Parameters,\n        TraitContext.Create | TraitContext.Update\n      >,\n    Foundations.ResourceCreatedOrOkResponse<Resource &\n      TraitProperties<\n        Traits & InterfaceTraits,\n        TraitLocation.Response,\n        TraitContext.Create | TraitContext.Update\n      > &\n      Foundations.LongRunningStatusLocation>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Create or update operation template.\n   * @template Resource Resource type.\n   * @template Traits Object describing the traits of the operation.\n   */\n  @Foundations.Private.ensureVerb(\"ResourceCreateOrUpdate\", \"PATCH\")\n  @createsOrUpdatesResource(Resource)\n  @parameterVisibility(\"create\", \"update\")\n  ResourceCreateOrUpdate<\n    Resource extends TypeSpec.Reflection.Model,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceOperation<\n    Resource,\n    {\n      @doc(\"This request has a JSON Merge Patch body.\")\n      @TypeSpec.Http.header(\"Content-Type\")\n      contentType: \"application/merge-patch+json\";\n\n      ...Foundations.ResourceBody<Resource>;\n      ...TraitProperties<\n        Traits & InterfaceTraits,\n        TraitLocation.Parameters,\n        TraitContext.Create | TraitContext.Update\n      >;\n    },\n    Foundations.ResourceCreatedOrOkResponse<Resource &\n      TraitProperties<\n        Traits & InterfaceTraits,\n        TraitLocation.Response,\n        TraitContext.Create | TraitContext.Update\n      >>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Long-running resource create or update operation template.\n   * @template Resource Resource type.\n   * @template Traits Object describing the traits of the operation.\n   */\n  @Foundations.Private.ensureVerb(\"LongRunningResourceCreateOrUpdate\", \"PATCH\")\n  @createsOrUpdatesResource(Resource)\n  @parameterVisibility(\"create\", \"update\")\n  LongRunningResourceCreateOrUpdate<\n    Resource extends TypeSpec.Reflection.Model,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceOperation<\n    Resource,\n    {\n      @doc(\"This request has a JSON Merge Patch body.\")\n      @TypeSpec.Http.header(\"Content-Type\")\n      contentType: \"application/merge-patch+json\";\n\n      ...Foundations.ResourceBody<Resource>;\n      ...TraitProperties<\n        Traits & InterfaceTraits,\n        TraitLocation.Parameters,\n        TraitContext.Create | TraitContext.Update\n      >;\n    },\n    Foundations.ResourceCreatedOrOkResponse<Resource &\n      TraitProperties<\n        Traits & InterfaceTraits,\n        TraitLocation.Response,\n        TraitContext.Create | TraitContext.Update\n      > &\n      Foundations.LongRunningStatusLocation<Resource>>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Resource update operation template.\n   * @template Resource Resource type.\n   * @template Traits Object describing the traits of the operation.\n   */\n  @Foundations.Private.ensureVerb(\"ResourceUpdate\", \"PATCH\")\n  @updatesResource(Resource)\n  ResourceUpdate<\n    Resource extends TypeSpec.Reflection.Model,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceOperation<\n    Resource,\n    {\n      @doc(\"This request has a JSON Merge Patch body.\")\n      @TypeSpec.Http.header(\"Content-Type\")\n      contentType: \"application/merge-patch+json\";\n\n      ...Foundations.ResourceBody<Resource>;\n      ...TraitProperties<Traits & InterfaceTraits, TraitLocation.Parameters, TraitContext.Update>;\n    },\n    Foundations.ResourceOkResponse<Resource &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Response, TraitContext.Update>>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Resource create with service-provided name operation template.\n   * @template Resource Resource type.\n   * @template Traits Object describing the traits of the operation.\n   */\n  #suppress \"@azure-tools/typespec-providerhub/no-inline-model\" \"This operation signature is not used in Azure Resource Manager operations (yet)\"\n  @Foundations.Private.ensureVerb(\"ResourceCreateWithServiceProvidedName\", \"POST\")\n  @createsResource(Resource)\n  ResourceCreateWithServiceProvidedName<\n    Resource extends TypeSpec.Reflection.Model,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceCollectionOperation<\n    Resource,\n    Foundations.ResourceBody<Resource> &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Parameters, TraitContext.Create>,\n    Foundations.LocationOfCreatedResourceResponse<Resource> &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Response, TraitContext.Create>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Long-running resource create with service-provided name operation template.\n   * @template Resource Resource type.\n   * @template Traits Object describing the traits of the operation.\n   */\n  #suppress \"@azure-tools/typespec-providerhub/no-inline-model\" \"This operation signature is not used in Azure Resource Manager operations (yet)\"\n  @Foundations.Private.ensureVerb(\"LongRunningResourceCreateWithServiceProvidedName\", \"POST\")\n  @createsResource(Resource)\n  LongRunningResourceCreateWithServiceProvidedName<\n    Resource extends TypeSpec.Reflection.Model,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceCollectionOperation<\n    Resource,\n    Foundations.ResourceBody<Resource> &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Parameters, TraitContext.Create>,\n    Foundations.LocationOfCreatedResourceWithServiceProvidedNameResponse<Resource> &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Response, TraitContext.Create>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Resource read operation template.\n   * @template Resource Resource type.\n   * @template Traits Object describing the traits of the operation.\n   */\n  @Foundations.Private.ensureVerb(\"ResourceRead\", \"GET\")\n  @readsResource(Resource)\n  ResourceRead<\n    Resource extends TypeSpec.Reflection.Model,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceOperation<\n    Resource,\n    TraitProperties<Traits & InterfaceTraits, TraitLocation.Parameters, TraitContext.Read>,\n    Resource &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Response, TraitContext.Read>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Resource delete operation template.\n   * @template Resource Resource type.\n   * @template Traits Object describing the traits of the operation.\n   */\n  #suppress \"@azure-tools/typespec-providerhub/no-inline-model\" \"This operation signature is not used in Azure Resource Manager operations (yet)\"\n  @Foundations.Private.ensureVerb(\"ResourceDelete\", \"DELETE\")\n  @deletesResource(Resource)\n  ResourceDelete<\n    Resource extends TypeSpec.Reflection.Model,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceOperation<\n    Resource,\n    TraitProperties<Traits & InterfaceTraits, TraitLocation.Parameters, TraitContext.Delete>,\n    TypeSpec.Http.NoContentResponse &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Response, TraitContext.Delete>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Long-running resource delete operation template.\n   * @template Resource Resource type.\n   * @template Traits Object describing the traits of the operation.\n   */\n  #suppress \"@azure-tools/typespec-azure-resource-manager/no-response-body\" \"We do support bodies in data plane service APIs...\"\n  @Foundations.Private.ensureVerb(\"LongRunningResourceDelete\", \"DELETE\")\n  @deletesResource(Resource)\n  LongRunningResourceDelete<\n    Resource extends TypeSpec.Reflection.Model,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceOperation<\n    Resource,\n    TraitProperties<Traits & InterfaceTraits, TraitLocation.Parameters, TraitContext.Delete>,\n    Foundations.AcceptedResponse<Foundations.OperationStatus &\n      Foundations.LongRunningStatusLocation &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Response, TraitContext.Delete>>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Resource list operation template.\n   * @template Resource Resource type.\n   * @template Traits Object describing the traits of the operation.\n   */\n  @Foundations.Private.ensureVerb(\"ResourceList\", \"GET\")\n  ResourceList<\n    Resource extends TypeSpec.Reflection.Model,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceList<\n    Resource,\n    TraitProperties<Traits & InterfaceTraits, TraitLocation.Parameters, TraitContext.List>,\n    Foundations.CustomPage<Resource, Traits & InterfaceTraits>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Resource action operation template.\n   * @template Resource Resource type.\n   * @template Parameters Object describing the parameters of the operation.\n   * @template Response Object describing the response of the operation.\n   * @template Traits Object describing the traits of the operation.\n   */\n  @Foundations.Private.ensureVerb(\"ResourceAction\", \"POST\")\n  @action\n  @actionSeparator(\":\")\n  ResourceAction<\n    Resource extends TypeSpec.Reflection.Model,\n    Parameters extends TypeSpec.Reflection.Model,\n    Response extends TypeSpec.Reflection.Model,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceOperation<\n    Resource,\n    Parameters &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Parameters, TraitContext.Action>,\n    Response &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Response, TraitContext.Action>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Resource collection action operation template.\n   * @template Resource Resource type.\n   * @template Parameters Object describing the parameters of the operation.\n   * @template Response Object describing the response of the operation.\n   * @template Traits Object describing the traits of the operation.\n   */\n  @Foundations.Private.ensureVerb(\"ResourceCollectionAction\", \"POST\")\n  @collectionAction(Resource)\n  @actionSeparator(\":\")\n  ResourceCollectionAction<\n    Resource extends TypeSpec.Reflection.Model,\n    Parameters extends TypeSpec.Reflection.Model,\n    Response extends TypeSpec.Reflection.Model,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceCollectionOperation<\n    Resource,\n    Parameters &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Parameters, TraitContext.Action>,\n    Response &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Response, TraitContext.Action>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Long-running resource action operation template.\n   * @template Resource Resource type.\n   * @template Parameters Object describing the parameters of the operation.\n   * @template StatusResult Object describing the status result of the operation.\n   * @template StatusError Object describing the status error of the operation.\n   * @template Traits Object describing the traits of the operation.\n   */\n  #suppress \"@azure-tools/typespec-providerhub/no-inline-model\" \"This operation signature is not used in Azure Resource Manager operations (yet)\"\n  #suppress \"@azure-tools/typespec-azure-resource-manager/no-response-body\" \"This operation must return a status monitor in its response.\"\n  @Foundations.Private.ensureVerb(\"LongRunningResourceAction\", \"POST\")\n  @action\n  @actionSeparator(\":\")\n  LongRunningResourceAction<\n    Resource extends TypeSpec.Reflection.Model,\n    Parameters extends TypeSpec.Reflection.Model,\n    StatusResult extends TypeSpec.Reflection.Model,\n    StatusError = Foundations.Error,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceOperation<\n    Resource,\n    Parameters &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Parameters, TraitContext.Action>,\n    AcceptedResponse &\n      ResourceOperationStatus<Resource, StatusResult, StatusError> &\n      Foundations.LongRunningStatusLocation<StatusResult> &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Response, TraitContext.Action>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Long-running resource collection action operation template.\n   * @template Resource Resource type.\n   * @template Parameters Object describing the parameters of the operation.\n   * @template StatusResult Object describing the status result of the operation.\n   * @template StatusError Object describing the status error of the operation.\n   * @template Traits Object describing the traits of the operation.\n   */\n  #suppress \"@azure-tools/typespec-providerhub/no-inline-model\" \"This operation signature is not used in Azure Resource Manager operations (yet)\"\n  #suppress \"@azure-tools/typespec-azure-resource-manager/no-response-body\" \"This operation must return a status monitor in its response.\"\n  @Foundations.Private.ensureVerb(\"LongRunningResourceCollectionAction\", \"POST\")\n  @autoRoute\n  @collectionAction(Resource)\n  @actionSeparator(\":\")\n  LongRunningResourceCollectionAction<\n    Resource extends TypeSpec.Reflection.Model,\n    Parameters extends TypeSpec.Reflection.Model,\n    StatusResult extends TypeSpec.Reflection.Model,\n    StatusError = Foundations.Error,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceCollectionOperation<\n    Resource,\n    Parameters &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Parameters, TraitContext.Action>,\n    AcceptedResponse &\n      ResourceOperationStatus<Resource, StatusResult, StatusError> &\n      Foundations.LongRunningStatusLocation<StatusResult> &\n      TraitProperties<Traits & InterfaceTraits, TraitLocation.Response, TraitContext.Action>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n\n  /**\n   * Resource operation status operation template.\n   * @template Resource Resource type.\n   * @template StatusResult Object describing the status result of the operation.\n   * @template StatusError Object describing the status error of the operation.\n   * @template Traits Object describing the traits of the operation.\n   */\n  @Foundations.Private.ensureVerb(\"GetResourceOperationStatus\", \"GET\")\n  @readsResource(ResourceOperationStatus<Resource>)\n  @Foundations.Private.ensureResourceType(Resource)\n  GetResourceOperationStatus<\n    Resource extends TypeSpec.Reflection.Model,\n    StatusResult = Resource,\n    StatusError = Foundations.Error,\n    Traits extends TypeSpec.Reflection.Model = {}\n  > is Foundations.ResourceOperation<\n    ResourceOperationStatus<Resource, StatusResult, StatusError>,\n    {},\n    ResourceOperationStatusResponse<Resource, StatusResult, StatusError>,\n    Traits & InterfaceTraits,\n    ErrorResponse\n  >;\n}\n\n// Resource Status Monitoring\n\n/**\n * Operation signature to retrieve a resource operation status.\n * @template Resource The type of the resource.\n * @template StatusResult Object describing the result of the status operation.\n * @template StatusError Object describing the error of the status operation. If not provided, the default error type is used.\n * @template Traits Traits to apply to the operation.\n */\n@readsResource(ResourceOperationStatus<Resource>)\n@Foundations.Private.ensureResourceType(Resource)\nop GetResourceOperationStatus<\n  Resource extends TypeSpec.Reflection.Model,\n  StatusResult = Resource,\n  StatusError = Foundations.Error,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is Foundations.ResourceOperation<\n  ResourceOperationStatus<Resource, StatusResult, StatusError>,\n  {},\n  ResourceOperationStatusResponse<Resource, StatusResult, StatusError>,\n  Traits\n>;\n",
  "lib/obsolete.tsp": "// This file contains operation template that are deprecated and shouldn't be used.\nimport \"@typespec/http\";\nimport \"@typespec/rest\";\nimport \"@typespec/versioning\";\nimport \"./models.tsp\";\nimport \"./traits.tsp\";\nimport \"./operations.tsp\";\n\nnamespace Azure.Core;\n\nusing TypeSpec.Http;\nusing TypeSpec.Rest;\nusing TypeSpec.Versioning;\nusing Azure.Core.Traits;\nusing Azure.Core.Traits.Private;\n\nalias StandardResourceOperations = ResourceOperations<NoConditionalRequests &\n  NoRepeatableRequests &\n  NoClientRequestId>;\n\n/**\n * DEPRECATED: Use `ResourceCreateOrReplace` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Operation signature to create or replace a resource.\n * @template Resource The type of the resource.\n * @template Traits Traits to apply to the operation.\n */\n#deprecated \"Use `ResourceCreateOrReplace` from a `ResourceOperations` interface instance.\"\nop ResourceCreateOrReplace<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.ResourceCreateOrReplace<Resource, Traits>;\n\n/**\n * DEPRECATED: Use `LongRunningResourceCreateOrReplace` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Long-running operation signature to create or replace a resource.\n * @template Resource The type of the resource.\n * @template Traits Traits to apply to the operation.\n */\n#deprecated \"Use `LongRunningResourceCreateOrReplace` from a `ResourceOperations` interface instance.\"\nop LongRunningResourceCreateOrReplace<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.LongRunningResourceCreateOrReplace<Resource, Traits>;\n\n/**\n * DEPRECATED: Use `ResourceCreateOrUpdate` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Operation signature to create or update a resource.\n * @template Resource The type of the resource.\n * @template Traits Traits to apply to the operation.\n */\n#deprecated \"Use `LongRunningResourceCreateOrReplace` from a `ResourceOperations` interface instance.\"\nop ResourceCreateOrUpdate<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.ResourceCreateOrUpdate<Resource, Traits>;\n\n/**\n * DEPRECATED: Use `LongRunningResourceCreateOrUpdate` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Long-running operation signature to create or update a resource.\n * @template Resource The type of the resource.\n * @template Traits Traits to apply to the operation.\n */\n#deprecated \"Use `LongRunningResourceCreateOrUpdate` from a `ResourceOperations` interface instance.\"\nop LongRunningResourceCreateOrUpdate<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.LongRunningResourceCreateOrUpdate<Resource, Traits>;\n\n/**\n * DEPRECATED: Use `ResourceUpdate` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n * Operation signature to update a resource.\n * @template Resource The type of the resource.\n * @template Traits Traits to apply to the operation.\n */\n#deprecated \"Use `ResourceUpdate` from a `ResourceOperations` interface instance.\"\nop ResourceUpdate<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.ResourceUpdate<Resource, Traits>;\n\n/**\n * DEPRECATED: Use `ResourceCreateWithServiceProvidedName` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Operation signature to synchronously create a resource with a service-provided name.\n * @template Resource The type of the resource.\n * @template Traits Traits to apply to the operation.\n */\n#deprecated \"Use `ResourceCreateWithServiceProvidedName` from a `ResourceOperations` interface instance.\"\nop ResourceCreateWithServiceProvidedName<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.ResourceCreateWithServiceProvidedName<Resource, Traits>;\n\n/**\n * DEPRECATED: Use `LongRunningResourceCreateWithServiceProvidedName` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Long-running operation signature to create a resource with a service-provided name.\n * @template Resource The type of the resource.\n * @template Traits Traits to apply to the operation.\n */\n#deprecated \"Use `LongRunningResourceCreateWithServiceProvidedName` from a `ResourceOperations` interface instance.\"\nop LongRunningResourceCreateWithServiceProvidedName<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.LongRunningResourceCreateWithServiceProvidedName<Resource, Traits>;\n\n/**\n * DEPRECATED: Use `ResourceRead` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Operation signature to retrieve a resource.\n * @template Resource The type of the resource.\n * @template Traits Traits to apply to the operation.\n */\nop ResourceRead<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.ResourceRead<Resource, Traits>;\n\n/**\n * DEPRECATED: Use `ResourceDelete` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Operation signature to delete a resource.\n * @template Resource The type of the resource.\n * @template Traits Traits to apply to the operation.\n */\nop ResourceDelete<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.ResourceDelete<Resource, Traits>;\n\n/**\n * DEPRECATED: Use `LongRunningResourceDelete` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Long-running operation signature to delete a resource.\n * @template Resource The type of the resource.\n * @template Traits Traits to apply to the operation.\n */\nop LongRunningResourceDelete<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.LongRunningResourceDelete<Resource, Traits>;\n\n/**\n * DEPRECATED: Use `ResourceList` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Operation signature to list resources in a paginated way.\n * @template Resource The type of the resource.\n * @template Traits Traits to apply to the operation.\n */\nop ResourceList<\n  Resource extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.ResourceList<Resource, Traits>;\n\n/**\n * DEPRECATED: Use `ResourceAction` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Operation signature for a resource action.\n * @template Resource The type of the resource.\n * @template Parameters Object describing the request parameters.\n * @template Response Object describing the response parameters.\n * @template Traits Traits to apply to the operation.\n */\nop ResourceAction<\n  Resource extends TypeSpec.Reflection.Model,\n  Parameters extends TypeSpec.Reflection.Model,\n  Response extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.ResourceAction<Resource, Parameters, Response, Traits>;\n\n/**\n * DEPRECATED: Use `ResourceCollectionAction` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Operation signature for an action that applies to a collection of resources.\n * @template Resource The type of the resource.\n * @template Parameters Object describing the request parameters.\n * @template Response Object describing the response parameters.\n * @template Traits Traits to apply to the operation.\n */\nop ResourceCollectionAction<\n  Resource extends TypeSpec.Reflection.Model,\n  Parameters extends TypeSpec.Reflection.Model,\n  Response extends TypeSpec.Reflection.Model,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.ResourceCollectionAction<Resource, Parameters, Response, Traits>;\n\n/**\n * DEPRECATED: Use `LongRunningResourceAction` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Long-running operation signature for a resource action.\n * @template Resource The type of the resource.\n * @template Parameters Object describing the request parameters.\n * @template StatusResult Object describing the result of the status operation.\n * @template StatusError Object describing the error of the status operation. If not provided, the default error type is used.\n * @template Traits Traits to apply to the operation.\n */\nop LongRunningResourceAction<\n  Resource extends TypeSpec.Reflection.Model,\n  Parameters extends TypeSpec.Reflection.Model,\n  StatusResult extends TypeSpec.Reflection.Model,\n  StatusError = Foundations.Error,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.LongRunningResourceAction<\n  Resource,\n  Parameters,\n  StatusResult,\n  StatusError,\n  Traits\n>;\n\n/**\n * DEPRECATED: Use `LongRunningResourceCollectionAction` from a `ResourceOperations` interface instance.\n * This can be done by instantiating your own version with the traits you want `alias Operations = Azure.Core.ResourceOperations<ServiceTraits>;`.\n * See https://azure.github.io/typespec-azure/docs/getstarted/azure-core/step05#defining-the-operation-interface for details on how to use.\n *\n * Long-running operation signature for an action that applies to a collection of resources.\n * @template Resource The type of the resource.\n * @template Parameters Object describing the request parameters.\n * @template StatusResult Object describing the result of the status operation.\n * @template StatusError Object describing the error of the status operation. If not provided, the default error type is used.\n * @template Traits Traits to apply to the operation.\n */\nop LongRunningResourceCollectionAction<\n  Resource extends TypeSpec.Reflection.Model,\n  Parameters extends TypeSpec.Reflection.Model,\n  StatusResult extends TypeSpec.Reflection.Model,\n  StatusError = Foundations.Error,\n  Traits extends TypeSpec.Reflection.Model = {}\n> is StandardResourceOperations.LongRunningResourceCollectionAction<\n  Resource,\n  Parameters,\n  StatusResult,\n  StatusError,\n  Traits\n>;\n",
  "lib/decorators.tsp": "using TypeSpec.Reflection;\n\nnamespace Azure.Core {\n  /**\n   * Marks an Enum as being fixed since enums in Azure are\n   * assumed to be extensible.\n   */\n  extern dec fixed(target: Enum);\n\n  /**\n   * Marks a Model as a paged collection.\n   */\n  extern dec pagedResult(entity: Model);\n\n  /**\n   * Identifies the ModelProperty that contains the paged items. Can only be used on a Model marked with `@pagedResult`.\n   */\n  extern dec items(entity: ModelProperty);\n\n  /**\n   * Identifies a ModelProperty that contains the next link value. Can only be used on a Model marked with `@pagedResult`.\n   */\n  extern dec nextLink(entity: ModelProperty);\n\n  /**\n   * Used for custom StatusMonitor implementation.\n   * Identifies an Enum or ModelProperty as containing long-running operation\n   * status.\n   */\n  extern dec lroStatus(entity: Enum | Union | ModelProperty);\n\n  /**\n   * Used for custom StatusMonitor implementation.\n   * Identifies an EnumMember as a long-running \"Succeeded\" terminal state.\n   */\n  extern dec lroSucceeded(entity: EnumMember | UnionVariant);\n\n  /**\n   * Used for custom StatusMonitor implementation.\n   * Identifies an EnumMember as a long-running \"Canceled\" terminal state.\n   */\n  extern dec lroCanceled(entity: EnumMember | UnionVariant);\n\n  /**\n   * Used for custom StatusMonitor implementation.\n   * Identifies an enum member as a long-running \"Failed\" terminal state.\n   */\n  extern dec lroFailed(entity: EnumMember | UnionVariant);\n\n  /**\n   * Used for custom StatusMonitor implementation.\n   * Identifies a model property of a StatusMonitor as containing the result\n   * of a long-running operation that terminates successfully (Succeeded).\n   */\n  extern dec lroResult(entity: ModelProperty);\n\n  /**\n   * Used for custom StatusMonitor implementation.\n   * Identifies a model property of a StatusMonitor as containing the result\n   * of a long-running operation that terminates unsuccessfully (Failed).\n   */\n  extern dec lroErrorResult(entity: ModelProperty);\n\n  /**\n   * Identifies a model property as containing the location to poll for operation state.\n   * @param options PollingOptions for the poller pointed to by this link.  Overrides\n   * settings derived from property value it is decorating, if the value of the\n   * property is ResourceLocation<Resource>\n   */\n  extern dec pollingLocation(entity: ModelProperty, options?: PollingOptions);\n\n  /**\n   * Identifies a ModelProperty as containing the final location for the operation result.\n   * @param finalResult Sets the expected return value for the final result.  Overrides\n   * any value provided in the decorated property, if the property uses ResourceLocation<Resource>.\n   */\n  extern dec finalLocation(entity: ModelProperty, finalResult?: Model | void);\n\n  /**\n   * Identifies an operation that is linked to the target operation.\n   * @param linkedOperation The linked Operation\n   * @param linkType A string indicating the role of the linked operation\n   * @param parameters Map of `RequestParameter<Name>` and/or `ResponseProperty<Name>` that will\n   * be passed to the linked operation request.\n   */\n  extern dec operationLink(\n    entity: Operation,\n    linkedOperation: Operation,\n    linkType: valueof string,\n    parameters?: {}\n  );\n\n  /**\n   * Used to define how to call custom polling operations for long-running operations.\n   *\n   * @param targetParameter A reference to the polling operation parameter this parameter\n   * provides a value for, or the name of that parameter. The default value is the name of\n   * the decorated parameter or property.\n   */\n  extern dec pollingOperationParameter(\n    entity: ModelProperty,\n    targetParameter?: ModelProperty | string\n  );\n\n  /**\n   * Identifies that an operation is a polling operation for an LRO.\n   * @param linkedOperation The linked Operation\n   * @param parameters Map of `RequestParameter<Name>` and/or `ResponseProperty<Name>` that will\n   * be passed to the linked operation request.\n   */\n  extern dec pollingOperation(entity: Operation, linkedOperation: Operation, parameters?: {});\n\n  /**\n   * Identifies that an operation is the final operation for an LRO.\n   * @param linkedOperation The linked Operation\n   * @param parameters Map of `RequestParameter<Name>` and/or `ResponseProperty<Name>` that will\n   * be passed to the linked operation request.\n   */\n  extern dec finalOperation(entity: Operation, linkedOperation: Operation, parameters?: {});\n\n  /**\n   * Overrides the final state value for an operation\n   * @param finalState The desired final state value\n   */\n  extern dec useFinalStateVia(\n    entity: Operation,\n    finalState: valueof \"original-uri\" | \"operation-location\" | \"location\" | \"azure-async-operation\"\n  );\n\n  /**\n   * Identifies that an operation is used to retrieve the next page for paged operations.\n   * @param linkedOperation The linked Operation\n   * @param parameters Map of `RequestParameter<Name>` and/or `ResponseProperty<Name>` that will\n   * be passed to the linked operation request.\n   */\n  extern dec nextPageOperation(entity: Operation, linkedOperation: Operation, parameters?: {});\n}\n\nnamespace Azure.Core.Foundations {\n  /**\n   * Deletes any key properties from the model.\n   */\n  extern dec omitKeyProperties(entity: Model);\n\n  /**\n   * Identifies a property on a request model that serves as a linked operation parameter.\n   * @param name Property name on the target\n   */\n  extern dec requestParameter(entity: Model, name: valueof string);\n\n  /**\n   * Identifies a property on *all* non-error response models that serve as a linked operation parameter.\n   * @param name Property name on the target\n   */\n  extern dec responseProperty(entity: Model, name: valueof string);\n}\n\nnamespace Azure.Core.Foundations.Private {\n  /**\n   * Provides a Model describing parameter customizations to spread into the target.\n   * @param customizations Model describing the customization to spread\n   */\n  extern dec spreadCustomParameters(entity: Model, customizations: {});\n\n  /**\n   * Provides a Model describing response property customizations to spread into the target.\n   * @param customizations Model describing the customization to spread\n   */\n  extern dec spreadCustomResponseProperties(entity: Model, customizations: {});\n\n  /**\n   * Checks the Resource parameter of an operation signature to ensure it's a valid resource type.\n   * Also marks the operation as a resource operation.\n   * @param resourceType The possible resource Type to validate.\n   */\n  extern dec ensureResourceType(entity: TypeSpec.Reflection.Operation, resourceType: unknown);\n\n  /**\n   * Checks the Resource parameter of an operation signature to ensure it's a valid resource type.\n   */\n  extern dec needsRoute(entity: TypeSpec.Reflection.Operation);\n\n  /**\n   * Issues a warning if an operation which derives from an operation templated marked with `@ensureVerb`\n   * differs from the verb specified.\n   * @param templateName: Name of the template operation.\n   * @param verb The intended HTTP verb.\n   */\n  extern dec ensureVerb(\n    entity: TypeSpec.Reflection.Operation,\n    templateName: valueof string,\n    verb: valueof string\n  );\n\n  /**\n   * Identifies that a model should be treated as an embedding vector.\n   */\n  extern dec embeddingVector(entity: TypeSpec.Reflection.Model, type: TypeSpec.Reflection.Scalar);\n\n  model ArmResourceIdentifierConfigOptions {\n    allowedResources: ArmResourceIdentifierAllowedResource[];\n  }\n\n  /** Configuration for the armResourceIdentifier scalar */\n  extern dec armResourceIdentifierConfig(\n    target: Scalar,\n    options: ArmResourceIdentifierConfigOptions\n  );\n\n  /**\n   * Sets the priority order of default final-state-via options for an operation\n   * @param states: list of final-state-via options in priority order\n   */\n  extern dec defaultFinalStateVia(\n    target: TypeSpec.Reflection.Operation,\n    states: valueof (\"operation-location\" | \"location\" | \"azure-async-operation\")[]\n  );\n}\n"
};
const _TypeSpecLibrary_ = {
  jsSourceFiles: TypeSpecJSSources,
  typespecSourceFiles: TypeSpecSources,
};

export { $addTraitProperties, $applyTraitOverride, $armResourceIdentifierConfig, $defaultFinalStateVia, $embeddingVector, $ensureAllHeaderParams, $ensureAllQueryParams, $ensureResourceType, $ensureTraitsPresent, $ensureVerb, $finalLocation, $finalOperation, $fixed, $items, $lib, $linter, $lroCanceled, $lroErrorResult, $lroFailed, $lroResult, $lroStatus, $lroSucceeded, $needsRoute, $nextLink, $nextPageOperation, $omitKeyProperties, $onValidate, $operationLink, $pagedResult, $pollingLocation, $pollingOperation, $pollingOperationParameter, $requestParameter, $responseProperty, $spreadCustomParameters, $spreadCustomResponseProperties, $trait, $traitAdded, $traitContext, $traitLocation, $traitSource, $useFinalStateVia, FinalOperationKey, FinalStateValue, PollingOperationKey, _TypeSpecLibrary_, __unsupported_enable_checkStandardOperations, checkEnsureVerb, checkRpcRoutes, extractLroStates, filterModelProperties, filterResponseModels, getAllProperties, getArmResourceIdentifierConfig, getAsEmbeddingVector, getFinalLocationValue, getFinalStateOverride, getHttpMetadata, getItems, getLongRunningStates, getLroErrorResult, getLroMetadata, getLroResult, getLroStatusProperty, getNextLink, getOperationLink, getOperationLinks, getOperationResponse, getPagedResult, getPollingLocationInfo, getPollingOperationParameter, getRequestParameter, getResponseProperty, getResultModelWithProperty, getSourceTraitName, getSuccessResponse, getTraitContexts, getTraitLocation, getTraitName, getUnionAsEnum, isFinalLocation, isFixed, isLroCanceledState, isLroFailedState, isLroSucceededState, isPollingLocation, isResourceOperation, isTraitModel, namespace, pollingOptionsKind, preventRestLibraryInterfaces, useStandardOperations };
