UNPKG

@autorest/powershell

Version:
705 lines (702 loc) 54.7 kB
"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 = '';