function createResponseEnvelope()

in packages/autorest.go/src/transform/transform.ts [799:924]


function createResponseEnvelope(codeModel: m4.CodeModel, group: m4.OperationGroup, op: m4.Operation) {
  // create the `type <type>Response struct` response

  // aggregate headers from all responses as all of them will go into the same result envelope
  const headers = new Map<string, HttpHeaderWithDescription>();
  // skip adding headers for LROs for now, this is to avoid adding
  // any LRO-specific polling headers.
  // TODO: maybe switch to skip specific polling ones in the future?
  if (!helpers.isLROOperation(op)) {
    for (const resp of values(op.responses)) {
      // check if the response is expecting information from headers
      for (const header of values(resp.protocol.http!.headers)) {
        const head = <m4.HttpHeader>header;
        // convert each header to a property and append it to the response properties list
        const name = head.language.go!.name;
        if (!headers.has(name)) {
          const description = `${name} contains the information returned from the ${head.header} header response.`;
          headers.set(name, <HttpHeaderWithDescription>{
            ...head,
            description: description
          });
        }
      }
    }
  }

  // contains all the response envelopes
  const responseEnvelopes = <Array<m4.ObjectSchema>>codeModel.language.go!.responseEnvelopes;
  // first create the response envelope, each operation gets one
  // if single-client is enabled, omit the <OperationGroup> prefix
  let clientPrefix = capitalize(group.language.go!.clientName);
  if (codeModel.language.go!.singleClient) {
    clientPrefix = '';
  }
  const respEnvName = ensureUniqueModelName(codeModel, `${clientPrefix}${op.language.go!.name}Response`, 'Envelope');
  const opName = helpers.isLROOperation(op) ? 'Begin' + op.language.go!.name : op.language.go!.name;
  const respEnv = newObject(respEnvName, createResponseEnvelopeDescription(respEnvName, `${group.language.go!.clientName}.${helpers.isPageableOperation(op) && !helpers.isLROOperation(op) ? `New${opName}Pager` : opName}`));
  respEnv.language.go!.responseType = true;
  respEnv.properties = new Array<m4.Property>();
  responseEnvelopes.push(respEnv);
  op.language.go!.responseEnv = respEnv;
  if (helpers.isLROOperation(op)) {
    respEnv.language.go!.forLRO = true;
  }

  // add any headers to the response
  for (const item of items(headers)) {
    const prop = newRespProperty(item.key, item.value.description, item.value.schema, false);
    // propagate any extensions so we can access them through the property
    prop.extensions = item.value.extensions;
    prop.language.go!.fromHeader = item.value.header;
    respEnv.properties.push(prop);
  }

  // now create the result field

  if (codeModel.language.go!.headAsBoolean && op.requests![0].protocol.http!.method === 'head') {
    op.language.go!.headAsBoolean = true;
    const successProp = newProperty('Success', 'Success indicates if the operation succeeded or failed.', newBoolean('bool', 'bool response'));
    successProp.language.go!.byValue = true;
    respEnv.properties.push(successProp);
    respEnv.language.go!.resultProp = successProp;
    return;
  }
  if (helpers.isMultiRespOperation(op)) {
    const resultTypes = new Array<string>();
    for (const response of values(op.responses)) {
      // the operation might contain a mix of schemas and non-schema responses.
      // we only care about the ones that return a schema.
      if (helpers.isSchemaResponse(response)) {
        resultTypes.push(response.schema.language.go!.name);
      }
    }
    const resultProp = newRespProperty('Value', `Possible types are ${resultTypes.join(', ')}\n`, newAny('multi-response value'), true);
    respEnv.properties.push(resultProp);
    respEnv.language.go!.resultProp = resultProp;
    return;
  }
  const response = helpers.getSchemaResponse(op);
  // if the response defines a schema then add it to the response envelope
  if (response) {
    const rawJSONAsBytes = <boolean>codeModel.language.go!.rawJSONAsBytes;
    // propagate marshalling format to the response envelope
    respEnv.language.go!.marshallingFormat = response.schema.language.go!.marshallingFormat;
    // for operations that return scalar types we use a fixed field name
    let propName = scalarResponsePropName;
    if (response.schema.type === m4.SchemaType.Object) {
      // for object types use the type's name as the field name
      propName = response.schema.language.go!.name;
    } else if (response.schema.type === m4.SchemaType.Array) {
      // for array types use the element type's name
      propName = recursiveTypeName(response.schema);
    } else if (rawJSONAsBytes && (response.schema.type === m4.SchemaType.Any || response.schema.type === m4.SchemaType.AnyObject)) {
      propName = 'RawJSON';
    } else if (response.schema.type === m4.SchemaType.Any) {
      propName = 'Interface';
    } else if (response.schema.type === m4.SchemaType.AnyObject) {
      propName = 'Object';
    }
    if (response.schema.serialization?.xml && response.schema.serialization.xml.name) {
      // always prefer the XML name
      propName = capitalize(response.schema.serialization.xml.name);
    }
    // we want to pass integral types byref to maintain parity with struct fields
    const byValue = helpers.isTypePassedByValue(response.schema) || response.schema.type === m4.SchemaType.Object;
    const resultSchema = substitueDiscriminator(response);
    const resultProp = newRespProperty(propName, response.schema.language.go!.description, resultSchema, byValue);
    if (resultSchema.language.go!.discriminatorInterface) {
      // if the schema is a discriminator we need to flag this on the property itself.
      // this is so the correct unmarshaller is created for the response envelope.
      resultProp.isDiscriminator = true;
    }
    respEnv.properties.push(resultProp);
    respEnv.language.go!.resultProp = resultProp;
  } else if (helpers.isBinaryResponseOperation(op)) {
    const binaryProp = newProperty('Body', 'Body contains the streaming response.', newBinary('binary response'));
    binaryProp.language.go!.byValue = true;
    respEnv.properties.push(binaryProp);
    respEnv.language.go!.resultProp = binaryProp;
  }
  if (respEnv.properties.length === 0) {
    // if we get here it means the operation doesn't return anything. we set
    // this to undefined to simplify detection of an empty response envelope
    respEnv.properties = undefined;
  }
}