in packages/typespec-go/src/tcgcadapter/types.ts [31:117]
adaptTypes(sdkContext: tcgc.SdkContext) {
for (const enumType of sdkContext.sdkPackage.enums) {
if (enumType.usage === tcgc.UsageFlags.ApiVersionEnum) {
// we have a pipeline policy for controlling the api-version
continue;
} else if ((enumType.usage & tcgc.UsageFlags.Input) === 0 && (enumType.usage & tcgc.UsageFlags.Output) === 0) {
// skip types without input and output usage
continue;
}
const constType = this.getConstantType(enumType);
this.codeModel.constants.push(constType);
}
// we must adapt all interface/model types first. this is because models can contain cyclic references
const modelTypes = new Array<ModelTypeSdkModelType>();
const ifaceTypes = new Array<InterfaceTypeSdkModelType>();
for (const modelType of sdkContext.sdkPackage.models) {
if (modelType.name.length === 0) {
// tcgc creates some unnamed models for spread params.
// we don't use these so just skip them.
continue;
} else if (modelType.access === 'internal' && <tcgc.UsageFlags>(modelType.usage & tcgc.UsageFlags.Spread) === tcgc.UsageFlags.Spread) {
// we don't use the internal models for spread params
continue;
} else if ((modelType.usage & tcgc.UsageFlags.Input) === 0 && (modelType.usage & tcgc.UsageFlags.Output) === 0) {
// skip types without input and output usage
continue;
}
if (modelType.discriminatedSubtypes) {
// this is a root discriminated type
const iface = this.getInterfaceType(modelType);
this.codeModel.interfaceTypes.push(iface);
ifaceTypes.push({go: iface, tcgc: modelType});
}
// TODO: what's the equivalent of x-ms-external?
const model = this.getModel(modelType);
modelTypes.push({go: model, tcgc: modelType});
}
// add the synthesized models from TCGC for paged results
const pagedResponses = this.getPagedResponses(sdkContext);
for (const pagedResponse of pagedResponses) {
// tsp allows custom paged responses, so we must check both the synthesized list and the models list
if (values(modelTypes).any(each => { return each.tcgc.name === pagedResponse.name; })) {
continue;
}
const model = this.getModel(pagedResponse);
modelTypes.push({go: model, tcgc: pagedResponse});
}
// now that the interface/model types have been generated, we can populate the rootType and possibleTypes
for (const ifaceType of ifaceTypes) {
ifaceType.go.rootType = <go.PolymorphicType>this.getModel(ifaceType.tcgc);
for (const subType of values(ifaceType.tcgc.discriminatedSubtypes)) {
const possibleType = <go.PolymorphicType>this.getModel(subType);
ifaceType.go.possibleTypes.push(possibleType);
}
}
// now adapt model fields
for (const modelType of modelTypes) {
const content = aggregateProperties(modelType.tcgc);
for (const prop of values(content.props)) {
if (prop.kind === 'header') {
// the common case here is the @header decorator specifying
// the content-type for the model. we can just skip it.
// TODO: follow up with tcgc to see if we can remove the entry.
continue;
}
if (prop.kind === 'query') {
// skip query params for now, wait for confirming visibility behavior
continue;
}
const field = this.getModelField(prop, modelType.tcgc);
modelType.go.fields.push(field);
}
if (content.addlProps) {
const annotations = new go.ModelFieldAnnotations(false, false, true, false);
const addlPropsType = new go.MapType(this.getPossibleType(content.addlProps, false, false), isTypePassedByValue(content.addlProps));
const addlProps = new go.ModelField('AdditionalProperties', addlPropsType, true, '', annotations);
modelType.go.fields.push(addlProps);
}
this.codeModel.models.push(modelType.go);
}
}