UNPKG

@autorest/go

Version:
194 lines 9.65 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import * as m4 from '@autorest/codemodel'; import { serialize } from '@azure-tools/codegen'; import { values } from '@azure-tools/linq'; import { startSession } from '@autorest/extension-base'; import * as go from '../../../codemodel.go/src/index.js'; import { adaptClients } from './clients.js'; import { adaptConstantType, adaptInterfaceType, adaptModel, adaptModelField } from './types.js'; import { aggregateProperties } from '../transform/helpers.js'; import { fileURLToPath } from 'url'; // converts an M4 code model into a GoCodeModel export function m4ToGoCodeModel(host) { return __awaiter(this, void 0, void 0, function* () { const debug = (yield host.getValue('debug')) || false; try { const session = yield startSession(host, m4.codeModelSchema); const info = new go.Info(session.model.info.title); const options = new go.Options(yield session.getValue('header-text', 'MISSING LICENSE HEADER'), yield session.getValue('generate-fakes', session.model.language.go.azureARM), yield session.getValue('inject-spans', session.model.language.go.azureARM), yield session.getValue('disallow-unknown-fields', false), yield session.getValue('generate-sdk-example', false)); const azcoreVersion = yield session.getValue('azcore-version', ''); if (azcoreVersion !== '') { options.azcoreVersion = azcoreVersion; } let type = 'data-plane'; if (session.model.language.go.azureARM) { type = 'azure-arm'; } const codeModel = new go.CodeModel(info, type, session.model.language.go.packageName, options); if (session.model.language.go.host) { codeModel.host = session.model.language.go.host; } if (session.model.language.go.module && session.model.language.go.moduleVersion) { codeModel.options.module = new go.Module(session.model.language.go.module, session.model.language.go.moduleVersion); } else if (session.model.language.go.module || session.model.language.go.moduleVersion) { throw new Error('--module and --module-version must both or neither be set'); } else if (session.model.language.go.containingModule !== '') { codeModel.options.containingModule = session.model.language.go.containingModule; } adaptConstantTypes(session.model, codeModel); adaptInterfaceTypes(session.model, codeModel); adaptModels(session.model, codeModel); adaptClients(session.model, codeModel); const paramGroups = new Map(); for (const client of values(codeModel.clients)) { for (const method of client.methods) { codeModel.responseEnvelopes.push(method.responseEnvelope); for (const param of values(method.parameters)) { if (param.group) { if (!paramGroups.has(param.group.groupName)) { paramGroups.set(param.group.groupName, param.group); } } } if (!paramGroups.has(method.optionalParamsGroup.groupName)) { // the optional params group wasn't present, that means that it's empty. paramGroups.set(method.optionalParamsGroup.groupName, method.optionalParamsGroup); } } } if (paramGroups.size > 0) { // adapt all of the parameter groups for (const groupName of paramGroups.keys()) { const paramGroup = paramGroups.get(groupName); codeModel.paramGroups.push(adaptParameterGroup(paramGroup)); } } codeModel.sortContent(); // output the model to the pipeline host.writeFile({ filename: 'go-code-model.yaml', content: serialize(codeModel), artifactType: 'go-code-model' }); } catch (E) { if (debug) { console.error(`${fileURLToPath(import.meta.url)} - FAILURE ${JSON.stringify(E)} ${E.stack}`); } throw E; } }); } function adaptConstantTypes(m4CodeModel, goCodeModel) { // group all enum categories into a single array so they can be sorted for (const choice of values(m4CodeModel.schemas.choices)) { if (choice.language.go.omitType) { continue; } const constType = adaptConstantType(choice); goCodeModel.constants.push(constType); } for (const choice of values(m4CodeModel.schemas.sealedChoices)) { if (choice.language.go.omitType || choice.choices.length === 1) { continue; } const constType = adaptConstantType(choice); goCodeModel.constants.push(constType); } } function adaptParameterGroup(paramGroup) { const structType = new go.StructType(paramGroup.groupName); structType.docs = paramGroup.docs; if (paramGroup.params.length > 0) { for (const param of values(paramGroup.params)) { if (param.kind === 'literal') { continue; } let byValue = param.kind === 'required' || (param.location === 'client' && go.isClientSideDefault(param.kind)); // if the param isn't required, check if it should be passed by value or not. // optional params that are implicitly nil-able shouldn't be pointer-to-type. if (!byValue) { byValue = param.byValue; } const field = new go.StructField(param.name, param.type, byValue); field.docs = param.docs; structType.fields.push(field); } } return structType; } function adaptInterfaceTypes(m4CodeModel, goCodeModel) { var _a; if (!m4CodeModel.language.go.discriminators) { return; } const ifaceObjs = new Array(); const discriminators = m4CodeModel.language.go.discriminators; // discriminators contains all of the root discriminated types but *not* any sub-roots (e.g. Salmon). for (const discriminator of values(discriminators)) { if (discriminator.language.go.omitType || ((_a = discriminator.extensions) === null || _a === void 0 ? void 0 : _a['x-ms-external'])) { continue; } // we must adapt all InterfaceTypes first. this is because ModelTypes/PolymorphicTypes can // contain references to InterfaceTypes and/or cyclic references recursiveAdaptInterfaceType(discriminator, goCodeModel.interfaceTypes, ifaceObjs); } // now that the InterfaceTypes have been created, we can populate the rootType and possibleTypes for (const ifaceObj of values(ifaceObjs)) { ifaceObj.iface.rootType = adaptModel(ifaceObj.obj); ifaceObj.iface.possibleTypes = new Array(); for (const disc of values(ifaceObj.obj.discriminator.all)) { const possibleType = adaptModel(disc); ifaceObj.iface.possibleTypes.push(possibleType); } } } function recursiveAdaptInterfaceType(obj, ifaces, ifaceObjs, parent) { const iface = adaptInterfaceType(obj, parent); if (ifaces.includes(iface)) { return; } ifaces.push(iface); ifaceObjs.push({ iface, obj }); for (const val of values(obj.discriminator.immediate)) { const asObj = val; if (asObj.discriminator) { recursiveAdaptInterfaceType(asObj, ifaces, ifaceObjs, iface); } } } function adaptModels(m4CodeModel, goCodeModel) { var _a; const modelObjs = new Array(); for (const obj of values(m4CodeModel.schemas.objects)) { if (obj.language.go.omitType || ((_a = obj.extensions) === null || _a === void 0 ? void 0 : _a['x-ms-external'])) { continue; } // we must adapt all model types first. this is because models can contain cyclic references const modelType = adaptModel(obj); goCodeModel.models.push(modelType); modelObjs.push({ type: modelType, obj: obj }); } for (const modelObj of values(modelObjs)) { const props = aggregateProperties(modelObj.obj); for (const prop of values(props)) { const field = adaptModelField(prop, modelObj.obj); modelObj.type.fields.push(field); } } } //# sourceMappingURL=adapter.js.map