in packages/typespec-go/src/tcgcadapter/clients.ts [45:166]
private recursiveAdaptClient(sdkClient: tcgc.SdkClientType<tcgc.SdkHttpOperation>, parent?: go.Client): go.Client | undefined {
if (sdkClient.methods.length === 0 && (sdkClient.children === undefined || sdkClient.children.length === 0)) {
// skip generating empty clients
return undefined;
}
let clientName = ensureNameCase(sdkClient.name);
// to keep compat with existing ARM packages, don't use hierarchically named clients
if (parent && this.ta.codeModel.type !== 'azure-arm') {
// for hierarchical clients, the child client names are built
// from the parent client name. this is because tsp allows subclients
// with the same name. consider the following example.
//
// namespace Chat {
// interface Completions {
// ...
// }
// }
// interface Completions { ... }
//
// we want to generate two clients from this,
// one name ChatCompletions and the other Completions
// strip off the Client suffix from the parent client name
clientName = parent.name.substring(0, parent.name.length - 6) + clientName;
}
if (!clientName.match(/Client$/)) {
clientName += 'Client';
}
const docs: go.Docs = {
summary: sdkClient.summary,
description: sdkClient.doc,
};
if (docs.summary) {
docs.summary = `${clientName} - ${docs.summary}`;
} else if (docs.description) {
docs.description = `${clientName} - ${docs.description}`;
} else {
// strip clientName's "Client" suffix
const groupName = clientName.substring(0, clientName.length - 6);
docs.summary = `${clientName} contains the methods for the ${groupName} group.`;
}
const goClient = new go.Client(clientName, docs, go.newClientOptions(this.ta.codeModel.type, clientName));
goClient.parent = parent;
// anything other than public means non-instantiable client
if (sdkClient.clientInitialization.initializedBy & tcgc.InitializedByFlags.Individually) {
for (const param of sdkClient.clientInitialization.parameters) {
if (param.kind === 'credential') {
// skip this for now as we don't generate client constructors
continue;
} else if (param.kind === 'endpoint') {
const paramType = getEndpointType(param);
// this will either be a fixed or templated host
// don't set the fixed host for ARM as it isn't used
if (this.ta.codeModel.type !== 'azure-arm') {
goClient.host = paramType.serverUrl;
}
if (paramType.templateArguments.length === 0) {
// this is the param for the fixed host, don't create a param for it
if (!this.ta.codeModel.host) {
this.ta.codeModel.host = goClient.host;
} else if (this.ta.codeModel.host !== goClient.host) {
throw new AdapterError('InternalError', `client ${goClient.name} has a conflicting host ${goClient.host}`, NoTarget);
}
} else {
goClient.templatedHost = true;
for (const templateArg of paramType.templateArguments) {
goClient.parameters.push(this.adaptURIParam(templateArg));
}
}
continue;
} else if (param.kind === 'method') {
// some client params, notably api-version, can be explicitly
// defined in the operation signature:
// e.g. op withQueryApiVersion(@query("api-version") apiVersion: string)
// these get propagated to sdkMethod.operation.parameters thus they
// will be adapted in adaptMethodParameters()
continue;
}
goClient.parameters.push(this.adaptURIParam(param));
}
} else if (parent) {
// this is a sub-client. it will share the client/host params of the parent.
// NOTE: we must propagate parant params before a potential recursive call
// to create a child client that will need to inherit our client params.
goClient.templatedHost = parent.templatedHost;
goClient.host = parent.host;
// make a copy of the client params. this is to prevent
// client method params from being shared across clients
// as not all client method params might be uniform.
goClient.parameters = new Array<go.Parameter>(...parent.parameters);
} else {
throw new AdapterError('InternalError', `uninstantiable client ${sdkClient.name} has no parent`, NoTarget);
}
if (sdkClient.children && sdkClient.children.length > 0) {
for (const child of sdkClient.children) {
const subClient = this.recursiveAdaptClient(child, goClient);
if (subClient) {
goClient.clientAccessors.push(new go.ClientAccessor(`New${subClient.name}`, subClient));
}
}
}
for (const sdkMethod of sdkClient.methods) {
this.adaptMethod(sdkMethod, goClient);
}
if (this.ta.codeModel.type === 'azure-arm' && goClient.clientAccessors.length > 0 && goClient.methods.length === 0) {
// this is the service client. to keep compat with existing
// ARM SDKs we skip adding it to the code model in favor of
// the synthesized client factory.
} else {
this.ta.codeModel.clients.push(goClient);
}
return goClient;
}