function adaptMethodParameter()

in packages/autorest.go/src/m4togocodemodel/clients.ts [305:452]


function adaptMethodParameter(op: m4.Operation, param: m4.Parameter): go.Parameter {
  let adaptedParam: go.Parameter;
  let location: go.ParameterLocation = 'method';
  if (param.implementation === m4.ImplementationLocation.Client) {
    // check if we've already adapted this client parameter
    // TODO: grouped client params
    const clientParam = clientParams.get(param.language.go!.name);
    if (clientParam) {
      return clientParam;
    }
    location = 'client';
  }

  switch (param.protocol.http?.in) {
    case 'body': {
      if (!op.requests![0].protocol.http!.mediaTypes) {
        throw new Error(`no media types defined for operation ${op.operationId}`);
      }
      let contentType = `"${op.requests![0].protocol.http!.mediaTypes[0]}"`;
      if (op.requests![0].protocol.http!.mediaTypes.length > 1) {
        for (const param of values(op.requests![0].parameters)) {
          // If a request defined more than one possible media type, then the param is expected to be synthesized from modelerfour
          // and should be a SealedChoice schema type that account for the acceptable media types defined in the swagger.
          if (param.origin === 'modelerfour:synthesized/content-type' && param.schema.type === m4.SchemaType.SealedChoice) {
            contentType = `string(${param.language.go!.name})`;
          }
        }
      }
      const bodyType = adaptPossibleType(param.schema);
      const placement = adaptParameterKind(param);
      if (op.requests![0].protocol.http!.knownMediaType === KnownMediaType.Form) {
        const collectionFormat = adaptCollectionFormat(param);
        if (collectionFormat) {
          if (!go.isSliceType(bodyType)) {
            throw new Error(`unexpected type ${go.getTypeDeclaration(bodyType)} for FormBodyCollectionParameter ${param.language.go!.name}`);
          }
          adaptedParam = new go.FormBodyCollectionParameter(param.language.go!.name, param.language.go!.serializedName, bodyType, collectionFormat, placement, param.language.go!.byValue);
        } else {
          adaptedParam = new go.FormBodyParameter(param.language.go!.name, param.language.go!.serializedName, bodyType, placement, param.language.go!.byValue);
        }
      } else if (op.requests![0].protocol.http!.knownMediaType === KnownMediaType.Multipart) {
        adaptedParam = new go.MultipartFormBodyParameter(param.language.go!.name, bodyType, placement, param.language.go!.byValue);
      } else {
        const format = adaptBodyFormat(op.requests![0].protocol);
        adaptedParam = new go.BodyParameter(param.language.go!.name, format, contentType, bodyType, placement, param.language.go!.byValue);
        (<go.BodyParameter>adaptedParam).xml = adaptXMLInfo(param.schema);
      }

      break;
    }
    case 'header': {
      const collectionFormat = adaptCollectionFormat(param);
      if (param.schema.language.go!.headerCollectionPrefix) {
        const headerType = adaptPossibleType(param.schema, true);
        if (!go.isMapType(headerType)) {
          throw new Error(`unexpected type ${go.getTypeDeclaration(headerType)} for HeaderMapParameter ${param.language.go!.name}`);
        }
        adaptedParam = new go.HeaderMapParameter(param.language.go!.name, param.language.go!.serializedName, headerType, param.schema.language.go!.headerCollectionPrefix, adaptParameterKind(param),
          param.language.go!.byValue, location);
      } else if (collectionFormat) {
        const headerType = adaptPossibleType(param.schema, true);
        if (!go.isSliceType(headerType)) {
          throw new Error(`unexpected type ${go.getTypeDeclaration(headerType)} for HeaderCollectionParameter ${param.language.go!.name}`);
        }
        adaptedParam = new go.HeaderCollectionParameter(param.language.go!.name, param.language.go!.serializedName, headerType, collectionFormat, adaptParameterKind(param),
          param.language.go!.byValue, location);
      } else {
        adaptedParam = new go.HeaderParameter(param.language.go!.name, param.language.go!.serializedName, adaptHeaderType(param.schema, true),
          adaptParameterKind(param), param.language.go!.byValue, location);
      }
      break;
    }
    case 'path': {
      const collectionFormat = adaptCollectionFormat(param);
      if (collectionFormat) {
        const pathType = adaptPossibleType(param.schema);
        if (!go.isSliceType(pathType)) {
          throw new Error(`unexpected type ${go.getTypeDeclaration(pathType)} for PathCollectionParameter ${param.language.go!.name}`);
        }
        adaptedParam = new go.PathCollectionParameter(param.language.go!.name, param.language.go!.serializedName, !skipURLEncoding(param),
          pathType, collectionFormat, adaptParameterKind(param), param.language.go!.byValue, location);
      } else {
        adaptedParam = new go.PathParameter(param.language.go!.name, param.language.go!.serializedName, !skipURLEncoding(param),
          adaptPathParameterType(param.schema), adaptParameterKind(param), param.language.go!.byValue, location);
      }
      break;
    }
    case 'query': {
      const collectionFormat = adaptExtendedCollectionFormat(param);
      if (collectionFormat) {
        const queryType = adaptPossibleType(param.schema);
        if (!go.isSliceType(queryType)) {
          throw new Error(`unexpected type ${go.getTypeDeclaration(queryType)} for QueryCollectionParameter ${param.language.go!.name}`);
        }
        adaptedParam = new go.QueryCollectionParameter(param.language.go!.name, param.language.go!.serializedName, !skipURLEncoding(param),
          queryType, collectionFormat, adaptParameterKind(param), param.language.go!.byValue, location);
      } else {
        adaptedParam = new go.QueryParameter(param.language.go!.name, param.language.go!.serializedName, !skipURLEncoding(param),
          adaptQueryParameterType(param.schema), adaptParameterKind(param), param.language.go!.byValue, location);
      }
      break;
    }
    case 'uri':
      adaptedParam = new go.URIParameter(param.language.go!.name, param.language.go!.serializedName, adaptURIPrameterType(param.schema),
        adaptParameterKind(param), param.language.go!.byValue, adaptParameterlocation(param));
      break;
    default: {
      if (param.protocol.http?.in) {
        throw new Error(`unhandled parameter location type ${param.protocol.http.in}`);
      }
      // this is a synthesized parameter (e.g. ResumeToken)
      if (param.language.go!.isResumeToken) {
        adaptedParam = new go.ResumeTokenParameter();
      } else {
        const type = adaptPossibleType(param.schema);
        const placement = adaptParameterKind(param);
        const paramLoc = adaptParameterlocation(param);
        adaptedParam = new go.Parameter(param.language.go!.name, type, placement, param.language.go!.byValue, paramLoc);
      }
    }
  }

  if (hasDescription(param.language.go!)) {
    adaptedParam.docs.description = param.language.go!.description;
  }

  // track client parameter for later use
  if (adaptedParam.location === 'client') {
    clientParams.set(param.language.go!.name, adaptedParam);
  }
  
  if (param.language.go!.paramGroup) {
    const paramGroup = findOrAdaptParamsGroup(param);
    // parameter groups can be shared across methods so don't add any duplicate parameters
    if (values(paramGroup.params).where((each: go.Parameter) => { return each.name === adaptedParam.name; }).count() === 0) {
      paramGroup.params.push(adaptedParam);
    }
    if (adaptedParam.kind === 'required') {
      // if at least one param within a group is required then the group must be required.
      // however, it's possible that the param group was initially created from a non-required
      // param. so we need to be sure to update it as required.
      paramGroup.required = true;
    }
    adaptedParam.group = paramGroup;
  }

  return adaptedParam;
}