@autorest/powershell
Version:
AutoRest PowerShell Cmdlet Generator
705 lines (702 loc) • 54.7 kB
JavaScript
"use strict";
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ValidationMethod = exports.CallMethod = exports.ResolveResponseType = exports.OperationMethod = exports.EventListener = void 0;
const codemodel_v3_1 = require("@azure-tools/codemodel-v3");
const codemodel_1 = require("@autorest/codemodel");
const linq_1 = require("@azure-tools/linq");
const codegen_1 = require("@azure-tools/codegen");
const codegen_csharp_1 = require("@azure-tools/codegen-csharp");
const binary_1 = require("../schema/binary");
const codegen_csharp_2 = require("@azure-tools/codegen-csharp");
const codegen_csharp_3 = require("@azure-tools/codegen-csharp");
const codegen_csharp_4 = require("@azure-tools/codegen-csharp");
const codegen_csharp_5 = require("@azure-tools/codegen-csharp");
const codegen_csharp_6 = require("@azure-tools/codegen-csharp");
const codegen_csharp_7 = require("@azure-tools/codegen-csharp");
const codegen_csharp_8 = require("@azure-tools/codegen-csharp");
const codegen_csharp_9 = require("@azure-tools/codegen-csharp");
const codegen_csharp_10 = require("@azure-tools/codegen-csharp");
const codegen_csharp_11 = require("@azure-tools/codegen-csharp");
const codegen_csharp_12 = require("@azure-tools/codegen-csharp");
const clientruntime_1 = require("../clientruntime");
const parameter_1 = require("../operation/parameter");
const schema_1 = require("../../utils/schema");
const codemodel_v3_2 = require("@azure-tools/codemodel-v3");
const codegen_csharp_13 = require("@azure-tools/codegen-csharp");
const codegen_csharp_14 = require("@azure-tools/codegen-csharp");
function removeEncoding(pp, paramName, kmt) {
const up = pp.typeDeclaration.serializeToNode(kmt, pp, paramName, clientruntime_1.ClientRuntime.SerializationMode.None).value;
return pp.param.extensions && pp.param.extensions['x-ms-skip-url-encoding'] ? up.replace(/global::System.Uri.EscapeDataString|System.Uri.EscapeDataString/g, '') : up;
}
class EventListener {
constructor(expression, emitSignals, withResult) {
this.expression = expression;
this.emitSignals = emitSignals;
this.withResult = withResult;
}
*signalNoCheck(eventName, ...additionalParameters) {
if (this.emitSignals) {
const params = (0, linq_1.length)(additionalParameters) > 0 ? `, ${additionalParameters.joinWith(each => typeof each === 'string' ? each : each.value)}` : '';
yield `await ${this.expression.value}.Signal(${eventName}${params});`;
}
}
*syncSignalNoCheck(eventName, ...additionalParameters) {
if (this.emitSignals) {
const params = (0, linq_1.length)(additionalParameters) > 0 ? `, ${additionalParameters.joinWith(each => typeof each === 'string' ? each : each.value)}` : '';
yield `${this.expression.value}.Signal(${eventName}${params}).Wait();`;
}
}
*signal(eventName, ...additionalParameters) {
if (this.emitSignals) {
const params = (0, linq_1.length)(additionalParameters) > 0 ? `, ${additionalParameters.joinWith(each => typeof each === 'string' ? each : each.value)}` : '';
yield `await ${this.expression.value}.Signal(${eventName}${params}); if( ${this.expression.value}.Token.IsCancellationRequested ) { return${this.withResult ? ' null' : ''}; }`;
}
else {
yield `if( ${this.expression.value}.CancellationToken.IsCancellationRequested ) { throw ${codegen_csharp_13.System.OperationCanceledException.new()}; }`;
}
}
*syncSignal(eventName, ...additionalParameters) {
if (this.emitSignals) {
const params = (0, linq_1.length)(additionalParameters) > 0 ? `, ${additionalParameters.joinWith(each => typeof each === 'string' ? each : each.value)}` : '';
yield `${this.expression.value}.Signal(${eventName}${params}).Wait(); if( ${this.expression.value}.Token.IsCancellationRequested ) { return${this.withResult ? ' null' : ''}; }`;
}
else {
yield `if( ${this.expression.value}.CancellationToken.IsCancellationRequested ) { throw ${codegen_csharp_13.System.OperationCanceledException.new()} }`;
}
}
}
exports.EventListener = EventListener;
class OperationMethod extends codegen_csharp_3.Method {
constructor(parent, operation, viaIdentity, state, viaJson = false, withResult, objectInitializer) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
super(viaJson
? `${(_a = operation.language.csharp) === null || _a === void 0 ? void 0 : _a.name}ViaJsonString${withResult ? 'WithResult' : ''}`
: viaIdentity
? `${(_b = operation.language.csharp) === null || _b === void 0 ? void 0 : _b.name}ViaIdentity${withResult ? 'WithResult' : ''}`
: `${(_c = operation.language.csharp) === null || _c === void 0 ? void 0 : _c.name}${withResult ? 'WithResult' : ''}` || '', withResult ? codegen_csharp_13.System.Threading.Tasks.Task(ResolveResponseType(undefined, operation, state)) : codegen_csharp_13.System.Threading.Tasks.Task());
this.parent = parent;
this.operation = operation;
this.viaIdentity = viaIdentity;
this.state = state;
this.viaJson = viaJson;
this.callbacks = new Array();
this.apply(objectInitializer);
this.async = codegen_csharp_1.Modifier.Async;
this.returnsDescription = `A <see cref="${withResult ? codegen_csharp_13.System.Threading.Tasks.Task(ResolveResponseType(undefined, operation, state)) : codegen_csharp_13.System.Threading.Tasks.Task()}" /> that will be complete when handling of the response is completed.`;
const $this = this;
this.callName = `${(_d = operation.language.csharp) === null || _d === void 0 ? void 0 : _d.name}${withResult ? 'WithResult' : ''}_Call`;
this.push((0, codegen_csharp_11.Using)('NoSynchronizationContext', ''));
// add parameters
this.methodParameters = [];
const identity = new codegen_csharp_4.Parameter('viaIdentity', codegen_csharp_13.System.String);
if (this.viaIdentity) {
this.addParameter(identity);
}
let baseUrl = '';
const paths = [];
const headers = [];
const queries = [];
const others = [];
for (let index = 0; index < (0, linq_1.length)(this.operation.parameters) && this.operation.parameters; index++) {
const value = this.operation.parameters[index];
if (value.language.default.name === '$host') {
baseUrl = value.clientDefaultValue;
continue;
}
const p = new parameter_1.OperationParameter(this, value, this.state.path('parameters', index));
if ((_e = value.language.csharp) === null || _e === void 0 ? void 0 : _e.constantValue) {
const constTd = state.project.modelsNamespace.NewResolveTypeDeclaration(value.schema, true, state);
p.defaultInitializer = constTd.deserializeFromString(codemodel_v3_2.KnownMediaType.UriParameter, new codegen_csharp_2.StringExpression(`${value.language.csharp.constantValue}`), (0, codegen_csharp_2.toExpression)(constTd.defaultOfType));
}
// don't add path parameters when we're in identity mode
if (!this.viaIdentity || ((_f = value.protocol.http) === null || _f === void 0 ? void 0 : _f.in) !== codemodel_v3_1.ParameterLocation.Path) {
switch ((_g = value.protocol.http) === null || _g === void 0 ? void 0 : _g.in) {
case codemodel_v3_1.ParameterLocation.Path:
paths.push(p);
break;
case codemodel_v3_1.ParameterLocation.Header:
headers.push(p);
break;
case codemodel_v3_1.ParameterLocation.Query:
queries.push(p);
break;
default:
others.push(p);
break;
}
}
else {
this.add(function* () {
yield '';
});
}
this.methodParameters.push(p);
}
[...paths, ...headers, ...queries, ...others].forEach(p => this.addParameter(p));
if (baseUrl === '') {
// Some services will make the host as an input parameter
baseUrl = this.operation.requests ? (_h = this.operation.requests[0].protocol.http) === null || _h === void 0 ? void 0 : _h.uri : '';
}
this.description = ((_j = this.operation.language.csharp) === null || _j === void 0 ? void 0 : _j.description) || '';
// add body paramter if there should be one.
if (this.operation.requests && this.operation.requests.length && this.operation.requests[0].parameters && this.operation.requests[0].parameters.length) {
// this request does have a request body.
const param = this.operation.requests[0].parameters.find((p) => !p.origin || p.origin.indexOf('modelerfour:synthesized') < 0);
if (param) {
if (!viaJson) {
this.bodyParameter = new parameter_1.OperationBodyParameter(this, 'body', param.language.default.description, param.schema, (_k = param.required) !== null && _k !== void 0 ? _k : false, this.state, {
// TODO: temp solution. We need a class like NewKnowMediaType
mediaType: (0, codemodel_v3_2.knownMediaType)(codemodel_v3_2.KnownMediaType.Json),
contentType: codemodel_v3_2.KnownMediaType.Json
});
this.addParameter(this.bodyParameter);
}
else {
this.addParameter(new codegen_csharp_4.Parameter('jsonString', codegen_csharp_13.System.String, {
description: `Json string supplied to the ${(_l = operation.language.csharp) === null || _l === void 0 ? void 0 : _l.name} operation`,
}));
}
}
}
for (const response of [...(0, linq_1.values)(this.operation.responses), ...(0, linq_1.values)(this.operation.exceptions)]) {
const responseType = response.binary ? new binary_1.Binary(new codemodel_1.BinarySchema(''), true) : (response.schema ? state.project.modelsNamespace.NewResolveTypeDeclaration((response.schema), true, state) : null);
const headerType = response.language.default.headerSchema ? state.project.modelsNamespace.NewResolveTypeDeclaration(response.language.default.headerSchema, true, state) : null;
const newCallbackParameter = new parameter_1.CallbackParameter(((_m = response.language.csharp) === null || _m === void 0 ? void 0 : _m.name) || '', responseType, headerType, this.state, { description: (_o = response.language.csharp) === null || _o === void 0 ? void 0 : _o.description });
if (!withResult) {
this.addParameter(newCallbackParameter);
}
this.callbacks.push(newCallbackParameter);
}
// add eventhandler parameter
this.contextParameter = this.addParameter(new codegen_csharp_4.Parameter('eventListener', clientruntime_1.ClientRuntime.IEventListener, { description: `an <see cref="${clientruntime_1.ClientRuntime.IEventListener}" /> instance that will receive events.` }));
// add optional parameter for sender
this.senderParameter = this.addParameter(new codegen_csharp_4.Parameter('sender', clientruntime_1.ClientRuntime.ISendAsync, { description: `an instance of an ${clientruntime_1.ClientRuntime.ISendAsync} pipeline to use to make the request.` }));
let rx = this.operation.requests ? (_p = this.operation.requests[0].protocol.http) === null || _p === void 0 ? void 0 : _p.path : '';
const path = rx;
let pathWithoutOperation = path;
// For post API, Some URI may contain an action string .e.x '/start' at the end
// of the URI, for such cases, we will drop the action string if identityCorrection
// is set in the configuration
if (this.operation.requests && this.operation.requests.length && ((_q = this.operation.requests[0].protocol.http) === null || _q === void 0 ? void 0 : _q.method) === 'post' && this.state.project.identityCorrection) {
const idx = rx.lastIndexOf('/');
rx = rx.substr(0, idx);
pathWithoutOperation = rx;
}
let url = `/${path.startsWith('/') ? path.substr(1) : path}`;
const serverParams = this.methodParameters.filter(each => { var _a; return ((_a = each.param.protocol.http) === null || _a === void 0 ? void 0 : _a.in) === codemodel_v3_1.ParameterLocation.Uri; });
const headerParams = this.methodParameters.filter(each => { var _a; return ((_a = each.param.protocol.http) === null || _a === void 0 ? void 0 : _a.in) === codemodel_v3_1.ParameterLocation.Header; });
const pathParams = this.methodParameters.filter(each => { var _a; return ((_a = each.param.protocol.http) === null || _a === void 0 ? void 0 : _a.in) === codemodel_v3_1.ParameterLocation.Path; });
const queryParams = this.methodParameters.filter(each => { var _a; return ((_a = each.param.protocol.http) === null || _a === void 0 ? void 0 : _a.in) === codemodel_v3_1.ParameterLocation.Query; });
const cookieParams = this.methodParameters.filter(each => { var _a; return ((_a = each.param.protocol.http) === null || _a === void 0 ? void 0 : _a.in) === codemodel_v3_1.ParameterLocation.Cookie; });
// replace any server params in the uri
for (const pp of serverParams) {
url = url.replace(`{${pp.param.language.default.serializedName}}`, `"
+ ${pp.name}
+ "`);
}
for (const pp of pathParams) {
rx = rx.replace(`{${pp.param.language.default.serializedName}}`, `(?<${pp.param.language.default.serializedName}>[^/]+)`);
if (this.viaIdentity) {
url = url.replace(`{${pp.param.language.default.serializedName}}`, `"
+ ${pp.name}
+ "`);
}
else {
url = url.replace(`{${pp.param.language.default.serializedName}}`, `"
+ ${removeEncoding(pp, '', codemodel_v3_2.KnownMediaType.UriParameter)}
+ "`);
}
}
rx = `"^${rx}$"`;
url = url.replace(/\s*\+ ""/gm, '');
const bp = this.bodyParameter;
if (bp) {
this.serializationMode = clientruntime_1.ClientRuntime.SerializationMode.IncludeCreateOrUpdate;
if (operation.language.default.name === 'Patch') {
this.serializationMode = clientruntime_1.ClientRuntime.SerializationMode.IncludeUpdate;
}
// add optional parameter for json serialization mode
this.serializationModeParameter = this.addParameter(new codegen_csharp_4.Parameter('serializationMode', clientruntime_1.ClientRuntime.SerializationMode, { description: `Allows the caller to choose the depth of the serialization. See <see cref="${clientruntime_1.ClientRuntime.SerializationMode}"/>.`, defaultInitializer: this.serializationMode }));
}
// add method implementation...
this.add(function* () {
var _a;
const eventListener = new EventListener($this.contextParameter, $this.state.project.emitSignals, withResult);
yield codegen_1.EOL;
if ($this.viaIdentity) {
yield '// verify that Identity format is an exact match for uri';
yield codegen_1.EOL;
const match = (0, codegen_csharp_12.Local)('_match', `${codegen_csharp_13.System.Text.RegularExpressions.Regex.new(rx, 'global::System.Text.RegularExpressions.RegexOptions.IgnoreCase').value}.Match(${identity.value})`);
yield match.declarationStatement;
yield (0, codegen_csharp_7.If)(`!${match}.Success`, `throw new global::System.Exception("Invalid identity for URI '${pathWithoutOperation}'");`);
yield codegen_1.EOL;
yield '// replace URI parameters with values from identity';
for (const pp of pathParams) {
yield `var ${pp.name} = ${match.value}.Groups["${pp.param.language.default.serializedName}"].Value;`;
}
}
yield '// construct URL';
const pathAndQueryV = (0, codegen_csharp_12.Local)('pathAndQuery', `${codegen_csharp_13.System.Text.RegularExpressions.Regex.declaration}.Replace(
"${url}"
${queryParams.length > 0 ? '+ "?"' : ''}${queryParams.joinWith(pp => `
+ ${removeEncoding(pp, pp.param.language.default.serializedName, codemodel_v3_2.KnownMediaType.QueryParameter)}`, `
+ "&"`)}
,"\\\\?&*$|&*$|(\\\\?)&+|(&)&+","$1$2")`.replace(/\s*\+ ""/gm, ''));
yield pathAndQueryV.declarationStatement;
yield codegen_1.EOL;
yield eventListener.signal(clientruntime_1.ClientRuntime.Events.URLCreated, pathAndQueryV.value);
yield codegen_1.EOL;
yield '// generate request object ';
const urlV = new codegen_csharp_12.LocalVariable('_url', codegen_csharp_13.dotnet.Var, {
initializer: codegen_csharp_13.System.Uri.new(`$"${baseUrl}{${pathAndQueryV.value}}"`)
});
yield urlV.declarationStatement;
const method = $this.operation.requests ? (_a = $this.operation.requests[0].protocol.http) === null || _a === void 0 ? void 0 : _a.method : '';
yield `var request = ${codegen_csharp_13.System.Net.Http.HttpRequestMessage.new(`${clientruntime_1.ClientRuntime.fullName}.Method.${method.capitalize()}, ${urlV.value}`)};`;
yield eventListener.signal(clientruntime_1.ClientRuntime.Events.RequestCreated, 'request.RequestUri.PathAndQuery');
yield codegen_1.EOL;
if ((0, linq_1.length)(headerParams) > 0) {
yield '// add headers parameters';
for (const hp of headerParams) {
if (hp.param.language.default.name === 'Content-Length') {
// content length is set when the request body is set
continue;
}
yield hp.serializeToContainerMember(codemodel_v3_2.KnownMediaType.Header, new codegen_csharp_12.LocalVariable('request.Headers', codegen_csharp_13.dotnet.Var), hp.param.language.default.serializedName, clientruntime_1.ClientRuntime.SerializationMode.None);
}
yield codegen_1.EOL;
}
yield eventListener.signal(clientruntime_1.ClientRuntime.Events.HeaderParametersAdded);
if (bp) {
yield '// set body content';
yield `request.Content = ${bp.serializeToContent(bp.mediaType, new codegen_csharp_2.LiteralExpression('serializationMode'))};`;
yield `request.Content.Headers.ContentType = ${codegen_csharp_13.System.Net.Http.Headers.MediaTypeHeaderValue.Parse(bp.contentType)};`;
yield eventListener.signal(clientruntime_1.ClientRuntime.Events.BodyContentSet);
}
if (viaJson) {
yield '// set body content';
yield 'request.Content = new global::System.Net.Http.StringContent(jsonString, global::System.Text.Encoding.UTF8);';
yield 'request.Content.Headers.ContentType = global::System.Net.Http.Headers.MediaTypeHeaderValue.Parse("application/json");';
yield eventListener.signal(clientruntime_1.ClientRuntime.Events.BodyContentSet);
}
yield '// make the call ';
});
}
emitCall(returnFromCall, withResult) {
// storage will return from the call for download, etc.
if (returnFromCall) {
this.returnType = codegen_csharp_13.System.Threading.Tasks.Task(codegen_csharp_13.System.Net.Http.HttpResponseMessage);
}
this.add(`${withResult ? 'return ' : ''}await this.${this.callName} (request, ${withResult ? '' : `${this.callbacks.joinWith(each => each.use, ',')},`}${this.contextParameter.use},${this.senderParameter.use}); `);
// remove constant parameters and make them locals instead.
this.insert('// Constant Parameters');
for (let i = (0, linq_1.length)(this.parameters); i--; i < 0) {
const p = this.parameters[i];
if (p && p.defaultInitializer && p.name !== 'serializationMode') {
this.parameters.splice(i, 1);
this.insert(new codegen_csharp_12.LocalVariable(p.name, codegen_csharp_13.dotnet.Var, { initializer: p.defaultInitializer }));
}
}
}
}
exports.OperationMethod = OperationMethod;
function ResolveResponseType(opMethod, operation, state) {
let typeCount = 0;
let responseType = undefined;
if (opMethod) {
opMethod.callbacks.filter(each => each.name !== 'onDefault').forEach(each => {
if (each.responseType && responseType && each.responseType !== responseType) {
typeCount++;
}
else if (each.responseType && !responseType) {
responseType = each.responseType;
typeCount = 1;
}
});
}
else if (operation && state) {
for (const response of [...(0, linq_1.values)(operation.responses), ...(0, linq_1.values)(operation.exceptions)].filter(each => { var _a, _b; return ((_b = (_a = each.language) === null || _a === void 0 ? void 0 : _a.csharp) === null || _b === void 0 ? void 0 : _b.name) !== 'onDefault'; })) {
const eachResponseType = response.binary ? new binary_1.Binary(new codemodel_1.BinarySchema(''), true) : (response.schema ? state.project.modelsNamespace.NewResolveTypeDeclaration((response.schema), true, state) : undefined);
if (eachResponseType && responseType && eachResponseType !== responseType) {
typeCount++;
}
else if (eachResponseType && !responseType) {
responseType = eachResponseType;
typeCount = 1;
}
}
}
return typeCount === 1 ? responseType : undefined;
}
exports.ResolveResponseType = ResolveResponseType;
class CallMethod extends codegen_csharp_3.Method {
constructor(parent, opMethod, state, objectInitializer, withResult) {
super(`${opMethod.name}_Call`, withResult && ResolveResponseType(opMethod) ? codegen_csharp_13.System.Threading.Tasks.Task(ResolveResponseType(opMethod)) : codegen_csharp_13.System.Threading.Tasks.Task());
this.parent = parent;
this.opMethod = opMethod;
this.state = state;
this.returnNull = false;
this.description = `Actual wire call for <see cref= "${opMethod.name}" /> method.`;
this.returnsDescription = opMethod.returnsDescription;
this.apply(objectInitializer);
this.access = codegen_csharp_1.Access.Internal;
this.async = codegen_csharp_1.Modifier.Async;
this.push((0, codegen_csharp_11.Using)('NoSynchronizationContext', ''));
const $this = this;
// add parameters
// request, listener, sender
const reqParameter = this.addParameter(new codegen_csharp_4.Parameter('request', codegen_csharp_13.System.Net.Http.HttpRequestMessage, { description: 'the prepared HttpRequestMessage to send.' }));
if (!withResult) {
opMethod.callbacks.forEach(each => this.addParameter(each));
}
this.addParameter(opMethod.contextParameter);
this.addParameter(opMethod.senderParameter);
// add statements to this method
this.add(function* () {
const eventListener = new EventListener(opMethod.contextParameter, $this.state.project.emitSignals, withResult);
const response = (0, codegen_csharp_12.Local)('_response', codegen_csharp_13.dotnet.Null, codegen_csharp_13.System.Net.Http.HttpResponseMessage);
yield response;
yield (0, codegen_csharp_10.Try)(function* () {
var _a, _b, _c, _d, _e, _f;
const responder = function* () {
// TODO: omit generating _contentType var if it will never be used
// const contentType = new LocalVariable('_contentType', dotnet.Var, { initializer: `_response.Content.Headers.ContentType?.MediaType` });
const contentType = (0, codegen_csharp_12.Local)('_contentType', `${response}.Content.Headers.ContentType?.MediaType`);
yield contentType;
// add response handlers
yield (0, codegen_csharp_9.Switch)(`${response}.StatusCode`, function* () {
var _a;
const responses = [...(0, linq_1.values)(opMethod.operation.responses), ...(0, linq_1.values)(opMethod.operation.exceptions)].sort(function (a, b) { var _a, _b; return ((_a = a.protocol.http) === null || _a === void 0 ? void 0 : _a.statusCodes[0]).localeCompare(((_b = b.protocol.http) === null || _b === void 0 ? void 0 : _b.statusCodes[0])); });
for (const resp of responses) {
const responseCode = (_a = resp.protocol.http) === null || _a === void 0 ? void 0 : _a.statusCodes[0];
if (responseCode !== 'default' /*TODO: !== not found, handle other exception response */) {
const leadNum = parseInt(responseCode[0]);
// will use enum when it can, fall back to casting int when it can't
if (withResult) {
yield (0, codegen_csharp_5.TerminalCase)(codegen_csharp_13.System.Net.HttpStatusCode[responseCode] ? codegen_csharp_13.System.Net.HttpStatusCode[responseCode].value : `${codegen_csharp_13.System.Net.HttpStatusCode.declaration} n when((int)n >= ${leadNum * 100} && (int)n < ${leadNum * 100 + 100})`, $this.responsesEmitter($this, opMethod, [resp], response, eventListener, withResult));
}
else {
yield (0, codegen_csharp_5.Case)(codegen_csharp_13.System.Net.HttpStatusCode[responseCode] ? codegen_csharp_13.System.Net.HttpStatusCode[responseCode].value : `${codegen_csharp_13.System.Net.HttpStatusCode.declaration} n when((int)n >= ${leadNum * 100} && (int)n < ${leadNum * 100 + 100})`, $this.responsesEmitter($this, opMethod, [resp], response, eventListener, false));
}
}
else {
if (withResult) {
yield (0, codegen_csharp_5.TerminalDefaultCase)($this.responsesEmitter($this, opMethod, [resp], response, eventListener, withResult));
}
else {
yield (0, codegen_csharp_5.DefaultCase)($this.responsesEmitter($this, opMethod, [resp], response, eventListener, false));
}
}
}
// missing default response?
if (!opMethod.operation.exceptions) {
// if no default, we need one that handles the rest of the stuff.
yield (0, codegen_csharp_5.TerminalDefaultCase)(function* () {
yield `throw new ${clientruntime_1.ClientRuntime.fullName}.UndeclaredResponseException(_response);`;
});
}
});
};
const originalUri = (0, codegen_csharp_12.Local)('_originalUri', new codegen_csharp_2.LiteralExpression(`${reqParameter.use}.RequestUri.AbsoluteUri`));
if ((_a = $this.opMethod.operation.language.csharp) === null || _a === void 0 ? void 0 : _a.lro) {
yield '// this operation supports x-ms-long-running-operation';
yield originalUri;
}
// try statements
const sendTask = (0, codegen_csharp_12.Local)('sendTask', new codegen_csharp_2.LiteralExpression(`${opMethod.senderParameter.value}.SendAsync(${reqParameter.use}, ${opMethod.contextParameter.value})`));
yield sendTask;
// delay sending BeforeCall event until URI has been replaced by HTTP pipeline
yield eventListener.signal(clientruntime_1.ClientRuntime.Events.BeforeCall, reqParameter.use);
if ((_b = $this.opMethod.operation.language.csharp) === null || _b === void 0 ? void 0 : _b.lro) {
yield eventListener.signal(clientruntime_1.ClientRuntime.Events.Progress, new codegen_csharp_2.LiteralExpression('"intentional placeholder"'), new codegen_csharp_2.LiteralExpression('0'));
}
yield `${response.value} = await ${sendTask.value}; `;
yield eventListener.signal(clientruntime_1.ClientRuntime.Events.ResponseCreated, response.value);
const EOL = 'EOL';
// LRO processing (if appropriate)
if ((_c = $this.opMethod.operation.language.csharp) === null || _c === void 0 ? void 0 : _c.lro) {
yield `// declared final-state-via: ${$this.opMethod.operation.language.csharp.lro['final-state-via']}`;
const fsv = $this.opMethod.operation.language.csharp.lro['final-state-via'];
let finalUri;
switch (fsv) {
case 'original-uri':
// perform a final GET on the original URI.
finalUri = originalUri;
break;
case 'location':
// perform a final GET on the uri in Location header
finalUri = (0, codegen_csharp_12.Local)('_finalUri', response.invokeMethod('GetFirstHeader', new codegen_csharp_2.StringExpression('Location')));
yield finalUri;
break;
case 'operation-location':
// perform a final GET on the uri in Operation-Location header
finalUri = (0, codegen_csharp_12.Local)('_finalUri', response.invokeMethod('GetFirstHeader', new codegen_csharp_2.StringExpression('Operation-Location')));
yield finalUri;
break;
case 'azure-asyncoperation':
case 'azure-async-operation':
//depending on the type of request, do the appropriate behavior
switch ((_e = (_d = $this.opMethod.operation.requests) === null || _d === void 0 ? void 0 : _d[0].protocol.http) === null || _e === void 0 ? void 0 : _e.method.toLowerCase()) {
case 'post':
case 'delete':
finalUri = (0, codegen_csharp_12.Local)('_finalUri', response.invokeMethod('GetFirstHeader', new codegen_csharp_2.StringExpression('Azure-AsyncOperation')));
yield finalUri;
break;
case 'patch':
case 'put':
// perform a final GET on the original URI.
finalUri = originalUri;
break;
}
break;
default:
// depending on the type of request, fall back to the appropriate behavior
if ($this.opMethod.operation.requests) {
switch ((_f = $this.opMethod.operation.requests[0].protocol.http) === null || _f === void 0 ? void 0 : _f.method.toLowerCase()) {
case 'post':
case 'delete':
finalUri = (0, codegen_csharp_12.Local)('_finalUri', response.invokeMethod('GetFirstHeader', new codegen_csharp_2.StringExpression('Location')));
yield finalUri;
break;
case 'patch':
case 'put':
// perform a final GET on the original URI.
finalUri = originalUri;
break;
}
}
break;
}
const asyncOperation = (0, codegen_csharp_12.Local)('asyncOperation', response.invokeMethod('GetFirstHeader', new codegen_csharp_2.StringExpression('Azure-AsyncOperation')));
yield asyncOperation;
const location = (0, codegen_csharp_12.Local)('location', response.invokeMethod('GetFirstHeader', new codegen_csharp_2.StringExpression('Location')));
yield location;
const operationLocation = (0, codegen_csharp_12.Local)('operationLocation', response.invokeMethod('GetFirstHeader', new codegen_csharp_2.StringExpression('Operation-Location')));
yield operationLocation;
yield (0, codegen_csharp_7.While)(new codegen_csharp_2.LiteralExpression(`${reqParameter.use}.Method == System.Net.Http.HttpMethod.Put && ${response.value}.StatusCode == ${codegen_csharp_13.System.Net.HttpStatusCode[200].value} || ${response.value}.StatusCode == ${codegen_csharp_13.System.Net.HttpStatusCode[201].value} || ${response.value}.StatusCode == ${codegen_csharp_13.System.Net.HttpStatusCode[202].value} `), function* () {
yield '// delay before making the next polling request';
yield eventListener.signal(clientruntime_1.ClientRuntime.Events.DelayBeforePolling, response.value);
yield EOL;
yield '// while we wait, let\'s grab the headers and get ready to poll. ';
yield 'if (!System.String.IsNullOrEmpty(_response.GetFirstHeader(@"Azure-AsyncOperation"))) {';
yield ' ' + asyncOperation.assign(response.invokeMethod('GetFirstHeader', new codegen_csharp_2.StringExpression('Azure-AsyncOperation')));
yield '}';
yield 'if (!global::System.String.IsNullOrEmpty(_response.GetFirstHeader(@"Location"))) {';
yield ' ' + location.assign(response.invokeMethod('GetFirstHeader', new codegen_csharp_2.StringExpression('Location')));
yield '}';
yield 'if (!global::System.String.IsNullOrEmpty(_response.GetFirstHeader(@"Operation-Location"))) {';
yield ' ' + operationLocation.assign(response.invokeMethod('GetFirstHeader', new codegen_csharp_2.StringExpression('Operation-Location')));
yield '}';
const uriLocal = (0, codegen_csharp_12.Local)('_uri', (0, codegen_csharp_14.Ternery)(codegen_csharp_13.System.String.IsNullOrEmpty(asyncOperation), (0, codegen_csharp_14.Ternery)(codegen_csharp_13.System.String.IsNullOrEmpty(location), (0, codegen_csharp_14.Ternery)(codegen_csharp_13.System.String.IsNullOrEmpty(operationLocation), originalUri, operationLocation), location), asyncOperation));
yield uriLocal;
yield `${reqParameter.use} = ${reqParameter.use}.CloneAndDispose(${codegen_csharp_13.System.Uri.new(uriLocal)}, ${clientruntime_1.ClientRuntime.Method.Get});`;
yield EOL;
yield '// and let\'s look at the current response body and see if we have some information we can give back to the listener';
const content = (0, codegen_csharp_12.Local)('content', new codegen_csharp_2.LiteralExpression(`await ${response.value}.Content.ReadAsStringAsync()`));
yield content;
yield EOL;
yield '// drop the old response';
yield `${response.value}?.Dispose();`;
yield EOL;
yield '// make the polling call';
yield `${response.value} = await ${opMethod.senderParameter}.SendAsync(${reqParameter.value}, ${opMethod.contextParameter});`;
yield eventListener.signal(clientruntime_1.ClientRuntime.Events.Polling, response.value);
yield EOL;
yield `
// if we got back an OK, take a peek inside and see if it's done
if( ${response.value}.StatusCode == ${codegen_csharp_13.System.Net.HttpStatusCode.OK})
{
var error = false;
try {
if( ${clientruntime_1.ClientRuntime.JsonNode.Parse((0, codegen_csharp_2.toExpression)(`await ${response.value}.Content.ReadAsStringAsync()`))} is ${clientruntime_1.ClientRuntime.JsonObject} json)
{
var state = json.Property("properties")?.PropertyT<${clientruntime_1.ClientRuntime.JsonString}>("provisioningState") ?? json.PropertyT<${clientruntime_1.ClientRuntime.JsonString}>("status");
if( state is null )
{
// the body doesn't contain any information that has the state of the LRO
// we're going to just get out, and let the consumer have the result
break;
}
switch( state?.ToString()?.ToLower() )
{
case "failed":
error = true;
break;
case "succeeded":
case "canceled":
// we're done polling.
break;
default:
// need to keep polling!
${response.value}.StatusCode = ${codegen_csharp_13.System.Net.HttpStatusCode.Created};
continue;
}
}
} catch {
// if we run into a problem peeking into the result,
// we really don't want to do anything special.
}
if (error) {
throw new ${clientruntime_1.ClientRuntime.fullName}.UndeclaredResponseException(${response.value});
}
}`;
yield EOL;
yield '// check for terminal status code';
yield (0, codegen_csharp_7.If)(new codegen_csharp_2.LiteralExpression(`${response.value}.StatusCode == ${codegen_csharp_13.System.Net.HttpStatusCode[201].value} || ${response.value}.StatusCode == ${codegen_csharp_13.System.Net.HttpStatusCode[202].value} `), 'continue;');
yield '// we are done polling, do a request on final target?';
switch (fsv) {
case 'original-uri':
case 'azure-asyncoperation':
case 'azure-async-operation':
case 'location':
case 'operation-location':
// perform a final GET on the specified final URI.
yield $this.finalGet(eventListener, finalUri, reqParameter, response);
break;
default:
yield (0, codegen_csharp_7.If)(`!string.IsNullOrWhiteSpace(${finalUri})`, function* () {
yield $this.finalGet(eventListener, finalUri, reqParameter, response);
});
break;
}
});
}
yield eventListener.signal(clientruntime_1.ClientRuntime.Events.Progress, new codegen_csharp_2.LiteralExpression('"intentional placeholder"'), new codegen_csharp_2.LiteralExpression('100'));
yield responder();
});
yield (0, codegen_csharp_6.Finally)(function* () {
yield '// finally statements';
yield eventListener.signalNoCheck(clientruntime_1.ClientRuntime.Events.Finally, 'request', '_response');
yield `${response.value}?.Dispose();`;
yield `${reqParameter.use}?.Dispose();`;
});
if ($this.returnNull) {
yield (0, codegen_csharp_8.Return)('result');
$this.insert(new codegen_csharp_12.LocalVariable('result', codegen_csharp_13.System.Net.Http.HttpResponseMessage, { initializer: codegen_csharp_13.dotnet.Null }));
}
});
this.opMethod.emitCall($this.returnNull, withResult);
}
*finalGet(eventListener, finalLocation, reqParameter, response) {
yield '// create a new request with the final uri';
yield reqParameter.assign(`${(0, codegen_csharp_2.valueOf)(reqParameter)}.CloneAndDispose(${codegen_csharp_13.System.Uri.new(finalLocation)}, ${clientruntime_1.ClientRuntime.Method.Get})`);
yield codegen_1.EOL;
yield '// drop the old response';
yield `${response.value}?.Dispose();`;
yield codegen_1.EOL;
yield '// make the final call';
yield response.assign(`await ${this.opMethod.senderParameter}.SendAsync(${(0, codegen_csharp_2.valueOf)(reqParameter)}, ${this.opMethod.contextParameter})`);
yield eventListener.signal(clientruntime_1.ClientRuntime.Events.Polling, response.value);
// make sure we're not polling anymore.
yield 'break;';
}
*responsesEmitter($this, opMethod, responses, responseVariable, eventListener, withResult) {
var _a;
if ((0, linq_1.length)(responses) > 1) {
yield (0, codegen_csharp_9.Switch)('_contentType', function* () {
var _a, _b, _c, _d;
for (const eachResponse of (0, linq_1.values)(responses)) {
const mimetype = (0, linq_1.length)((_a = eachResponse.protocol.http) === null || _a === void 0 ? void 0 : _a.mediaTypes) > 0 ? (_b = eachResponse.protocol.http) === null || _b === void 0 ? void 0 : _b.mimeTypes[0] : '';
const callbackParameter = (0, linq_1.values)(opMethod.callbacks).first(each => { var _a; return each.name === ((_a = eachResponse.language.csharp) === null || _a === void 0 ? void 0 : _a.name); });
let count = (0, linq_1.length)((_c = eachResponse.protocol.http) === null || _c === void 0 ? void 0 : _c.mediaTypes);
for (const mt of (0, linq_1.values)((_d = eachResponse.protocol.http) === null || _d === void 0 ? void 0 : _d.mediaTypes)) {
count--;
const mediaType = (0, codemodel_v3_2.normalizeMediaType)(mt);
if (mediaType) {
if (count === 0) {
yield (0, codegen_csharp_5.Case)(new codegen_csharp_2.StringExpression(mediaType).toString(), $this.NewResponseHandler(mimetype, eachResponse, callbackParameter, responseVariable, withResult));
}
else {
yield (0, codegen_csharp_5.TerminalCase)(new codegen_csharp_2.StringExpression(mediaType).toString(), '');
}
}
}
}
});
}
else {
const response = responses[0];
const callbackParameter = (0, linq_1.values)(opMethod.callbacks).first(each => { var _a; return each.name === ((_a = response.language.csharp) === null || _a === void 0 ? void 0 : _a.name); });
// all mimeTypes per for this response code.
yield eventListener.signal(clientruntime_1.ClientRuntime.Events.BeforeResponseDispatch, responseVariable.value);
yield $this.NewResponseHandler((0, linq_1.values)((_a = response.protocol.http) === null || _a === void 0 ? void 0 : _a.mediaTypes).first() || '', response, callbackParameter, responseVariable, withResult);
}
}
*responseHandlerForNormalPipeline(mimetype, eachResponse, callbackParameter) {
const callbackParameters = new Array();
if (callbackParameter.responseType) {
// hande the body response
const r = callbackParameter.responseType.deserializeFromResponse((0, codemodel_v3_2.knownMediaType)(mimetype), (0, codegen_csharp_2.toExpression)('_response'), (0, codegen_csharp_2.toExpression)('null'));
if (r) {
callbackParameters.push(r);
}
// if (parseMediaType(mimetype)) {
// this media type isn't directly supported by deserialization
// we can return a stream to the consumer instead
// }
}
if (callbackParameter.headerType) {
// header model deserialization...
const r = callbackParameter.headerType.deserializeFromResponse(codemodel_v3_2.KnownMediaType.Header, (0, codegen_csharp_2.toExpression)('_response'), (0, codegen_csharp_2.toExpression)('null'));
if (r) {
callbackParameters.push(r);
}
}
// make the callback with the appropriate parameters
yield `await ${eachResponse.details.csharp.name}(_response${callbackParameters.length === 0 ? '' : ','}${callbackParameters.joinWith(codegen_csharp_2.valueOf)});`;
}
*NewResponseHandlerForNormalPipeline(mimetype, eachResponse, callbackParameter, responseVariable) {
var _a;
const callbackParameters = new Array();
if (callbackParameter.responseType) {
// hande the body response
const r = callbackParameter.responseType.deserializeFromResponse((0, codemodel_v3_2.knownMediaType)(mimetype), (0, codegen_csharp_2.toExpression)(responseVariable.value), (0, codegen_csharp_2.toExpression)('null'));
if (r) {
callbackParameters.push(r);
}
// if (parseMediaType(mimetype)) {
// this media type isn't directly supported by deserialization
// we can return a stream to the consumer instead
// }
}
if (callbackParameter.headerType) {
// header model deserialization...
const r = callbackParameter.headerType.deserializeFromResponse(codemodel_v3_2.KnownMediaType.Header, (0, codegen_csharp_2.toExpression)(responseVariable.value), (0, codegen_csharp_2.toExpression)('null'));
if (r) {
callbackParameters.push(r);
}
}
// make the callback with the appropriate parameters
yield `await ${(_a = eachResponse.language.csharp) === null || _a === void 0 ? void 0 : _a.name}(_response${callbackParameters.length === 0 ? '' : ','}${callbackParameters.joinWith(codegen_csharp_2.valueOf)});`;
}
*NewResponseHandlerWithResult(mimetype, response, callbackParameter, responseVariable) {
var _a, _b, _c, _d;
const responseType = callbackParameter.responseType;
if (!responseType) {
yield `throw new ${clientruntime_1.ClientRuntime.fullName}.UndeclaredResponseException(${responseVariable.value});`;
return;
}
const deserializeResponseAsync = responseType.deserializeFromResponse((0, codemodel_v3_2.knownMediaType)(mimetype), (0, codegen_csharp_2.toExpression)(responseVariable.value), (0, codegen_csharp_2.toExpression)('null'));
yield `var _result = ${deserializeResponseAsync};`;
switch ((_a = response.protocol.http) === null || _a === void 0 ? void 0 : _a.statusCodes[0]) {
case 'default': {
// this should write an error to the error channel.
yield `// Error Response : ${(_b = response.protocol.http) === null || _b === void 0 ? void 0 : _b.statusCodes[0]}`;
const unexpected = function* () {
yield '// Unrecognized Response. Create an error record based on what we have.';
const ex = responseType ?
(0, codegen_csharp_12.Local)('ex', `new ${clientruntime_1.ClientRuntime.name}.RestException<${responseType}>(${responseVariable.value}, await _result)`) :
(0, codegen_csharp_12.Local)('ex', `new ${clientruntime_1.ClientRuntime.name}.RestException(responseMessage)`);
yield ex.declarationStatement;
yield `throw ${ex};`;
};
if (response.schema !== undefined) {
// the schema should be the error information.
// this supports both { error { message, code} } and { message, code}
let props = (0, schema_1.getAllPublicVirtualProperties)((_c = response.schema.language.csharp) === null || _c === void 0 ? void 0 : _c.virtualProperties);
const errorProperty = (0, linq_1.values)(props).first(p => p.property.serializedName === 'error');
let ep = '';