@azure-tools/typespec-go 0.8.2 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/codegen.go/src/clientFactory.d.ts.map +1 -1
  2. package/dist/codegen.go/src/clientFactory.js +4 -0
  3. package/dist/codegen.go/src/clientFactory.js.map +1 -1
  4. package/dist/codegen.go/src/cloudConfig.d.ts +10 -0
  5. package/dist/codegen.go/src/cloudConfig.d.ts.map +1 -0
  6. package/dist/codegen.go/src/cloudConfig.js +65 -0
  7. package/dist/codegen.go/src/cloudConfig.js.map +1 -0
  8. package/dist/codegen.go/src/example.d.ts.map +1 -1
  9. package/dist/codegen.go/src/example.js +98 -109
  10. package/dist/codegen.go/src/example.js.map +1 -1
  11. package/dist/codegen.go/src/fake/factory.d.ts.map +1 -1
  12. package/dist/codegen.go/src/fake/factory.js +11 -2
  13. package/dist/codegen.go/src/fake/factory.js.map +1 -1
  14. package/dist/codegen.go/src/fake/servers.d.ts.map +1 -1
  15. package/dist/codegen.go/src/fake/servers.js +58 -65
  16. package/dist/codegen.go/src/fake/servers.js.map +1 -1
  17. package/dist/codegen.go/src/helpers.d.ts +36 -3
  18. package/dist/codegen.go/src/helpers.d.ts.map +1 -1
  19. package/dist/codegen.go/src/helpers.js +72 -17
  20. package/dist/codegen.go/src/helpers.js.map +1 -1
  21. package/dist/codegen.go/src/imports.d.ts +1 -1
  22. package/dist/codegen.go/src/imports.d.ts.map +1 -1
  23. package/dist/codegen.go/src/imports.js +4 -6
  24. package/dist/codegen.go/src/imports.js.map +1 -1
  25. package/dist/codegen.go/src/models.d.ts +0 -1
  26. package/dist/codegen.go/src/models.d.ts.map +1 -1
  27. package/dist/codegen.go/src/models.js +1 -7
  28. package/dist/codegen.go/src/models.js.map +1 -1
  29. package/dist/codegen.go/src/operations.d.ts.map +1 -1
  30. package/dist/codegen.go/src/operations.js +349 -141
  31. package/dist/codegen.go/src/operations.js.map +1 -1
  32. package/dist/codegen.go/src/responses.d.ts.map +1 -1
  33. package/dist/codegen.go/src/responses.js +2 -3
  34. package/dist/codegen.go/src/responses.js.map +1 -1
  35. package/dist/codemodel.go/src/client.d.ts +99 -35
  36. package/dist/codemodel.go/src/client.d.ts.map +1 -1
  37. package/dist/codemodel.go/src/client.js +53 -13
  38. package/dist/codemodel.go/src/client.js.map +1 -1
  39. package/dist/codemodel.go/src/examples.d.ts +3 -11
  40. package/dist/codemodel.go/src/examples.d.ts.map +1 -1
  41. package/dist/codemodel.go/src/examples.js +0 -7
  42. package/dist/codemodel.go/src/examples.js.map +1 -1
  43. package/dist/codemodel.go/src/index.d.ts.map +1 -1
  44. package/dist/codemodel.go/src/index.js +1 -0
  45. package/dist/codemodel.go/src/index.js.map +1 -1
  46. package/dist/codemodel.go/src/method.d.ts +44 -0
  47. package/dist/codemodel.go/src/method.d.ts.map +1 -0
  48. package/dist/codemodel.go/src/method.js +30 -0
  49. package/dist/codemodel.go/src/method.js.map +1 -0
  50. package/dist/codemodel.go/src/package.d.ts +2 -0
  51. package/dist/codemodel.go/src/package.d.ts.map +1 -1
  52. package/dist/codemodel.go/src/package.js +8 -0
  53. package/dist/codemodel.go/src/package.js.map +1 -1
  54. package/dist/codemodel.go/src/param.d.ts +67 -40
  55. package/dist/codemodel.go/src/param.d.ts.map +1 -1
  56. package/dist/codemodel.go/src/param.js +46 -25
  57. package/dist/codemodel.go/src/param.js.map +1 -1
  58. package/dist/codemodel.go/src/result.d.ts +1 -1
  59. package/dist/codemodel.go/src/result.d.ts.map +1 -1
  60. package/dist/codemodel.go/src/result.js +1 -1
  61. package/dist/codemodel.go/src/result.js.map +1 -1
  62. package/dist/codemodel.go/src/type.d.ts +53 -15
  63. package/dist/codemodel.go/src/type.d.ts.map +1 -1
  64. package/dist/codemodel.go/src/type.js +52 -18
  65. package/dist/codemodel.go/src/type.js.map +1 -1
  66. package/dist/typespec-go/src/emitter.d.ts +9 -0
  67. package/dist/typespec-go/src/emitter.d.ts.map +1 -1
  68. package/dist/typespec-go/src/emitter.js +37 -1
  69. package/dist/typespec-go/src/emitter.js.map +1 -1
  70. package/dist/typespec-go/src/lib.d.ts +1 -0
  71. package/dist/typespec-go/src/lib.d.ts.map +1 -1
  72. package/dist/typespec-go/src/lib.js +5 -0
  73. package/dist/typespec-go/src/lib.js.map +1 -1
  74. package/dist/typespec-go/src/tcgcadapter/adapter.d.ts.map +1 -1
  75. package/dist/typespec-go/src/tcgcadapter/adapter.js +4 -1
  76. package/dist/typespec-go/src/tcgcadapter/adapter.js.map +1 -1
  77. package/dist/typespec-go/src/tcgcadapter/clients.d.ts +18 -2
  78. package/dist/typespec-go/src/tcgcadapter/clients.d.ts.map +1 -1
  79. package/dist/typespec-go/src/tcgcadapter/clients.js +233 -53
  80. package/dist/typespec-go/src/tcgcadapter/clients.js.map +1 -1
  81. package/dist/typespec-go/src/tcgcadapter/types.d.ts +7 -0
  82. package/dist/typespec-go/src/tcgcadapter/types.d.ts.map +1 -1
  83. package/dist/typespec-go/src/tcgcadapter/types.js +17 -10
  84. package/dist/typespec-go/src/tcgcadapter/types.js.map +1 -1
  85. package/package.json +21 -20
@@ -3,6 +3,7 @@
3
3
  * Licensed under the MIT License. See License.txt in the project root for license information.
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as go from '../../codemodel.go/src/index.js';
6
+ import { ensureNameCase } from '../../naming.go/src/naming.js';
6
7
  import { capitalize, comment, uncapitalize } from '@azure-tools/codegen';
7
8
  import { values } from '@azure-tools/linq';
8
9
  import * as helpers from './helpers.js';
@@ -35,20 +36,14 @@ export async function generateOperations(codeModel) {
35
36
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/policy');
36
37
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
37
38
  }
38
- let clientPkg = 'azcore';
39
- if (azureARM) {
40
- clientPkg = 'arm';
41
- imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/arm');
42
- client.constructors.push(createARMClientConstructor(client, imports));
43
- }
44
- else {
39
+ if (!azureARM) {
45
40
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore');
46
41
  }
47
42
  // generate client type
48
43
  let clientText = helpers.formatDocComment(client.docs);
49
44
  clientText += '// Don\'t use this type directly, use ';
50
- if (client.constructors.length === 1) {
51
- clientText += `${client.constructors[0].name}() instead.\n`;
45
+ if (client.instance?.kind === 'constructable' && client.instance.constructors.length === 1) {
46
+ clientText += `${client.instance.constructors[0].name}() instead.\n`;
52
47
  }
53
48
  else if (client.parent) {
54
49
  // find the accessor method
@@ -68,7 +63,7 @@ export async function generateOperations(codeModel) {
68
63
  clientText += 'a constructor function instead.\n';
69
64
  }
70
65
  clientText += `type ${client.name} struct {\n`;
71
- clientText += `\tinternal *${clientPkg}.Client\n`;
66
+ clientText += `\tinternal *${azureARM ? 'arm' : 'azcore'}.Client\n`;
72
67
  // check for any optional host params
73
68
  const optionalParams = new Array();
74
69
  const isParamPointer = function (param) {
@@ -79,7 +74,7 @@ export async function generateOperations(codeModel) {
79
74
  if (client.parameters.length > 0) {
80
75
  const addedGroups = new Set();
81
76
  for (const clientParam of values(client.parameters)) {
82
- if (go.isLiteralParameter(clientParam)) {
77
+ if (go.isLiteralParameter(clientParam.style)) {
83
78
  continue;
84
79
  }
85
80
  if (clientParam.group) {
@@ -96,7 +91,7 @@ export async function generateOperations(codeModel) {
96
91
  else {
97
92
  clientText += `${helpers.formatParameterTypeName(clientParam)}\n`;
98
93
  }
99
- if (!go.isRequiredParameter(clientParam)) {
94
+ if (!go.isRequiredParameter(clientParam.style)) {
100
95
  optionalParams.push(clientParam);
101
96
  }
102
97
  }
@@ -106,8 +101,7 @@ export async function generateOperations(codeModel) {
106
101
  if (azureARM && optionalParams.length > 0) {
107
102
  throw new CodegenError('UnsupportedTsp', 'optional client parameters for ARM is not supported');
108
103
  }
109
- // generate client constructors
110
- clientText += generateConstructors(azureARM, client, imports);
104
+ clientText += generateConstructors(client, imports);
111
105
  // generate client accessors and operations
112
106
  let opText = '';
113
107
  for (const clientAccessor of client.clientAccessors) {
@@ -117,6 +111,9 @@ export async function generateOperations(codeModel) {
117
111
  opText += '\t\tinternal: client.internal,\n';
118
112
  // propagate all client params
119
113
  for (const param of client.parameters) {
114
+ if (go.isLiteralParameter(param.style)) {
115
+ continue;
116
+ }
120
117
  opText += `\t\t${param.name}: client.${param.name},\n`;
121
118
  }
122
119
  opText += '\t}\n}\n\n';
@@ -127,13 +124,13 @@ export async function generateOperations(codeModel) {
127
124
  // it must be done before the imports are written out
128
125
  if (go.isLROMethod(method)) {
129
126
  // generate Begin method
130
- opText += generateLROBeginMethod(client, method, imports, codeModel.options.injectSpans, codeModel.options.generateFakes);
127
+ opText += generateLROBeginMethod(method, imports, codeModel.options.injectSpans, codeModel.options.generateFakes);
131
128
  }
132
- opText += generateOperation(client, method, imports, codeModel.options.injectSpans, codeModel.options.generateFakes);
133
- opText += createProtocolRequest(azureARM, client, method, imports);
129
+ opText += generateOperation(method, imports, codeModel.options.injectSpans, codeModel.options.generateFakes);
130
+ opText += createProtocolRequest(azureARM, method, imports);
134
131
  if (method.kind !== 'lroMethod') {
135
132
  // LRO responses are handled elsewhere, with the exception of pageable LROs
136
- opText += createProtocolResponse(client, method, imports);
133
+ opText += createProtocolResponse(method, imports);
137
134
  }
138
135
  if ((method.kind === 'lroPageableMethod' || method.kind === 'pageableMethod') && method.nextPageMethod && !nextPageMethods.includes(method.nextPageMethod)) {
139
136
  // track the next page methods to generate as multiple operations can use the same next page operation
@@ -141,7 +138,7 @@ export async function generateOperations(codeModel) {
141
138
  }
142
139
  }
143
140
  for (const method of nextPageMethods) {
144
- opText += createProtocolRequest(azureARM, client, method, imports);
141
+ opText += createProtocolRequest(azureARM, method, imports);
145
142
  }
146
143
  // stitch it all together
147
144
  let text = helpers.contentPreamble(codeModel);
@@ -152,65 +149,222 @@ export async function generateOperations(codeModel) {
152
149
  }
153
150
  return operations;
154
151
  }
155
- // generates all modeled client constructors
156
- function generateConstructors(azureARM, client, imports) {
157
- if (client.constructors.length === 0) {
152
+ /**
153
+ * generates all modeled client constructors and client options types.
154
+ * if there are no client constructors, the empty string is returned.
155
+ *
156
+ * @param client the client for which to generate constructors and the client options type
157
+ * @param imports the import manager currently in scope
158
+ * @returns the client constructor code or the empty string
159
+ */
160
+ function generateConstructors(client, imports) {
161
+ if (client.instance?.kind !== 'constructable') {
158
162
  return '';
159
163
  }
164
+ const clientOptions = client.instance.options;
160
165
  let ctorText = '';
161
- for (const constructor of client.constructors) {
166
+ if (clientOptions.kind === 'clientOptions') {
167
+ // for non-ARM, the options type will always be a parameter group
168
+ ctorText += `// ${clientOptions.name} contains the optional values for creating a [${client.name}].\n`;
169
+ ctorText += `type ${clientOptions.name} struct {\n\tazcore.ClientOptions\n`;
170
+ for (const param of clientOptions.params) {
171
+ if (go.isAPIVersionParameter(param)) {
172
+ // we use azcore.ClientOptions.APIVersion
173
+ continue;
174
+ }
175
+ ctorText += helpers.formatDocCommentWithPrefix(ensureNameCase(param.name), param.docs);
176
+ if (go.isClientSideDefault(param.style)) {
177
+ if (!param.docs.description && !param.docs.summary) {
178
+ ctorText += '\n';
179
+ }
180
+ ctorText += `\t${comment(`The default value is ${helpers.formatLiteralValue(param.style.defaultValue, false)}`, '// ')}.\n`;
181
+ }
182
+ ctorText += `\t${ensureNameCase(param.name)} *${go.getTypeDeclaration(param.type)}\n`;
183
+ }
184
+ ctorText += '}\n\n';
185
+ }
186
+ for (const constructor of client.instance.constructors) {
162
187
  const ctorParams = new Array();
163
188
  const paramDocs = new Array();
164
- constructor.parameters.sort(helpers.sortParametersByRequired);
165
- for (const ctorParam of constructor.parameters) {
189
+ // ctor params can also be present in the supplemental endpoint parameters
190
+ const consolidatedCtorParams = new Array(...constructor.parameters);
191
+ if (client.instance.endpoint) {
192
+ consolidatedCtorParams.push(...client.instance.endpoint.parameters);
193
+ }
194
+ consolidatedCtorParams.sort(helpers.sortParametersByRequired);
195
+ for (const ctorParam of consolidatedCtorParams) {
196
+ if (!go.isRequiredParameter(ctorParam.style)) {
197
+ // param is part of the options group
198
+ continue;
199
+ }
166
200
  imports.addImportForType(ctorParam.type);
167
201
  ctorParams.push(`${ctorParam.name} ${helpers.formatParameterTypeName(ctorParam)}`);
168
202
  if (ctorParam.docs.summary || ctorParam.docs.description) {
169
203
  paramDocs.push(helpers.formatCommentAsBulletItem(ctorParam.name, ctorParam.docs));
170
204
  }
171
205
  }
206
+ const emitProlog = function (optionsTypeName, tokenAuth, plOpts) {
207
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
208
+ let bodyText = `\tif options == nil {\n\t\toptions = &${optionsTypeName}{}\n\t}\n`;
209
+ let apiVersionConfig = '';
210
+ // check if there's an api version parameter
211
+ let apiVersionParam;
212
+ for (const param of consolidatedCtorParams) {
213
+ switch (param.kind) {
214
+ case 'headerScalarParam':
215
+ case 'pathScalarParam':
216
+ case 'queryScalarParam':
217
+ case 'uriParam':
218
+ if (param.isApiVersion) {
219
+ apiVersionParam = param;
220
+ }
221
+ }
222
+ }
223
+ if (tokenAuth) {
224
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud');
225
+ imports.add('fmt');
226
+ imports.add('reflect');
227
+ bodyText += '\tif reflect.ValueOf(options.Cloud).IsZero() {\n';
228
+ bodyText += '\t\toptions.Cloud = cloud.AzurePublic\n\t}\n';
229
+ bodyText += '\tc, ok := options.Cloud.Services[ServiceName]\n';
230
+ bodyText += '\tif !ok {\n';
231
+ bodyText += '\t\treturn nil, fmt.Errorf("provided Cloud field is missing configuration for %s", ServiceName)\n';
232
+ bodyText += '\t} else if c.Audience == "" {\n';
233
+ bodyText += '\t\treturn nil, fmt.Errorf("provided Cloud field is missing Audience for %s", ServiceName)\n\t}\n';
234
+ }
235
+ if (apiVersionParam) {
236
+ let location;
237
+ let name;
238
+ switch (apiVersionParam.kind) {
239
+ case 'headerScalarParam':
240
+ location = 'Header';
241
+ name = apiVersionParam.headerName;
242
+ break;
243
+ case 'pathScalarParam':
244
+ case 'uriParam':
245
+ location = 'Path';
246
+ // name isn't used for the path case
247
+ break;
248
+ case 'queryScalarParam':
249
+ location = 'QueryParam';
250
+ name = apiVersionParam.queryParameter;
251
+ break;
252
+ }
253
+ if (name) {
254
+ name = `\n\t\t\tName: "${name}",`;
255
+ }
256
+ else {
257
+ name = '';
258
+ }
259
+ apiVersionConfig = `\n\t\tAPIVersion: runtime.APIVersionOptions{${name}\n\t\t\tLocation: runtime.APIVersionLocation${location},\n\t\t},`;
260
+ if (!plOpts) {
261
+ apiVersionConfig += '\n';
262
+ }
263
+ }
264
+ bodyText += `\tcl, err := azcore.NewClient(moduleName, moduleVersion, runtime.PipelineOptions{${apiVersionConfig}${plOpts ?? ''}}, &options.ClientOptions)\n`;
265
+ return bodyText;
266
+ };
267
+ let prolog;
268
+ switch (constructor.authentication.kind) {
269
+ case 'none':
270
+ if (clientOptions.kind !== 'clientOptions') {
271
+ throw new CodegenError('InternalError', `unexpected client options kind ${clientOptions.kind}`);
272
+ }
273
+ prolog = emitProlog(clientOptions.name, false);
274
+ break;
275
+ case 'token':
276
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore');
277
+ ctorParams.push('credential azcore.TokenCredential');
278
+ paramDocs.push(helpers.formatCommentAsBulletItem('credential', { summary: 'used to authorize requests. Usually a credential from azidentity.' }));
279
+ switch (clientOptions.kind) {
280
+ case 'clientOptions': {
281
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/policy');
282
+ const tokenPolicyOpts = '&policy.BearerTokenOptions{\n\t\t\tInsecureAllowCredentialWithHTTP: options.InsecureAllowCredentialWithHTTP,\n\t\t}';
283
+ // we assume a single scope. this is enforced when adapting the data from tcgc
284
+ const tokenPolicy = `\n\t\tPerCall: []policy.Policy{\n\t\truntime.NewBearerTokenPolicy(credential, []string{c.Audience + "${helpers.splitScope(constructor.authentication.scopes[0]).scope}"}, ${tokenPolicyOpts}),\n\t\t},\n`;
285
+ prolog = emitProlog(clientOptions.name, true, tokenPolicy);
286
+ break;
287
+ }
288
+ case 'parameter':
289
+ // this is the ARM case
290
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/arm');
291
+ prolog = '\tcl, err := arm.NewClient(moduleName, moduleVersion, credential, options)\n';
292
+ break;
293
+ }
294
+ break;
295
+ }
172
296
  // add client options last
173
- ctorParams.push(`${client.options.name} ${helpers.formatParameterTypeName(client.options)}`);
174
- paramDocs.push(helpers.formatCommentAsBulletItem(client.options.name, client.options.docs));
297
+ ctorParams.push(`options ${helpers.formatParameterTypeName(clientOptions)}`);
298
+ paramDocs.push(helpers.formatCommentAsBulletItem('options', { summary: 'Contains optional client configuration. Pass nil to accept the default values.' }));
175
299
  ctorText += `// ${constructor.name} creates a new instance of ${client.name} with the specified values.\n`;
176
300
  for (const doc of paramDocs) {
177
301
  ctorText += doc;
178
302
  }
179
303
  ctorText += `func ${constructor.name}(${ctorParams.join(', ')}) (*${client.name}, error) {\n`;
180
- let clientType = 'azcore';
181
- if (azureARM) {
182
- clientType = 'arm';
183
- }
184
- ctorText += `\tcl, err := ${clientType}.NewClient(moduleName, moduleVersion, credential, options)\n`;
304
+ ctorText += prolog;
185
305
  ctorText += '\tif err != nil {\n';
186
306
  ctorText += '\t\treturn nil, err\n';
187
307
  ctorText += '\t}\n';
308
+ const emitClientSideDefault = function (param) {
309
+ if (go.isClientSideDefault(param.style)) {
310
+ let name;
311
+ if (go.isAPIVersionParameter(param)) {
312
+ name = 'APIVersion';
313
+ }
314
+ else {
315
+ name = ensureNameCase(param.name);
316
+ }
317
+ ctorText += `\t${param.name} := ${helpers.formatLiteralValue(param.style.defaultValue, false)}\n`;
318
+ ctorText += `\tif options.${name} != ${helpers.zeroValue(param)} {\n\t\t${param.name} = ${helpers.star(param.byValue)}options.${name}\n\t}\n`;
319
+ }
320
+ };
321
+ // handle any client-side defaults
322
+ if (clientOptions.kind === 'clientOptions') {
323
+ for (const param of clientOptions.params) {
324
+ emitClientSideDefault(param);
325
+ }
326
+ }
327
+ // construct the supplemental path and join it to the endpoint
328
+ if (client.instance.endpoint) {
329
+ for (const param of client.instance.endpoint.parameters) {
330
+ emitClientSideDefault(param);
331
+ }
332
+ imports.add('strings');
333
+ ctorText += `\thost := "${client.instance.endpoint.path}"\n`;
334
+ for (const param of client.instance.endpoint.parameters) {
335
+ ctorText += `\thost = strings.ReplaceAll(host, "{${param.uriPathSegment}}", ${helpers.formatValue(param.name, param.type, imports)})\n`;
336
+ }
337
+ // the endpoint param is always the first ctor param
338
+ const endpointParam = client.instance.constructors[0].parameters[0];
339
+ ctorText += `\t${endpointParam.name} = runtime.JoinPaths(${endpointParam.name}, host)\n`;
340
+ }
188
341
  // construct client literal
189
- ctorText += `\tclient := &${client.name}{\n`;
342
+ let clientVar = 'client';
343
+ // ensure clientVar doesn't collide with any params
344
+ for (const param of consolidatedCtorParams) {
345
+ if (param.name === clientVar) {
346
+ clientVar = ensureNameCase(client.name, true);
347
+ break;
348
+ }
349
+ }
350
+ ctorText += `\t${clientVar} := &${client.name}{\n`;
351
+ // NOTE: we don't enumerate consolidatedCtorParams here
352
+ // as any supplemental endpoint params are ephemeral and
353
+ // consumed during client construction.
190
354
  for (const parameter of values(client.parameters)) {
355
+ if (go.isLiteralParameter(parameter.style)) {
356
+ continue;
357
+ }
191
358
  // each client field will have a matching parameter with the same name
192
359
  ctorText += `\t\t${parameter.name}: ${parameter.name},\n`;
193
360
  }
194
361
  ctorText += '\tinternal: cl,\n';
195
362
  ctorText += '\t}\n';
196
- ctorText += '\treturn client, nil\n';
363
+ ctorText += `\treturn ${clientVar}, nil\n`;
197
364
  ctorText += '}\n\n';
198
365
  }
199
366
  return ctorText;
200
367
  }
201
- // creates a modeled constructor for an ARM client
202
- function createARMClientConstructor(client, imports) {
203
- imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/arm');
204
- const ctor = new go.Constructor(`New${client.name}`);
205
- // add any modeled parameter first, which should only be the subscriptionID, then add TokenCredential
206
- for (const param of client.parameters) {
207
- ctor.parameters.push(param);
208
- }
209
- const tokenCredParam = new go.Parameter('credential', new go.QualifiedType('TokenCredential', 'github.com/Azure/azure-sdk-for-go/sdk/azcore'), 'required', true, 'client');
210
- tokenCredParam.docs.summary = 'used to authorize requests. Usually a credential from azidentity.';
211
- ctor.parameters.push(tokenCredParam);
212
- return ctor;
213
- }
214
368
  // use this to generate the code that will help process values returned in response headers
215
369
  function formatHeaderResponseValue(headerResp, imports, respObj, zeroResp) {
216
370
  // dictionaries are handled slightly different so we do that first
@@ -305,7 +459,7 @@ function formatHeaderResponseValue(headerResp, imports, respObj, zeroResp) {
305
459
  return text;
306
460
  }
307
461
  function getZeroReturnValue(method, apiType) {
308
- let returnType = `${method.responseEnvelope.name}{}`;
462
+ let returnType = `${method.returns.name}{}`;
309
463
  if (go.isLROMethod(method)) {
310
464
  if (apiType === 'api' || apiType === 'op') {
311
465
  // the api returns a *Poller[T]
@@ -325,10 +479,10 @@ function generateNilChecks(path, prefix = 'page') {
325
479
  }
326
480
  return checks.join(' && ');
327
481
  }
328
- function emitPagerDefinition(client, method, imports, injectSpans, generateFakes) {
482
+ function emitPagerDefinition(method, imports, injectSpans, generateFakes) {
329
483
  imports.add('context');
330
- let text = `runtime.NewPager(runtime.PagingHandler[${method.responseEnvelope.name}]{\n`;
331
- text += `\t\tMore: func(page ${method.responseEnvelope.name}) bool {\n`;
484
+ let text = `runtime.NewPager(runtime.PagingHandler[${method.returns.name}]{\n`;
485
+ text += `\t\tMore: func(page ${method.returns.name}) bool {\n`;
332
486
  // there is no advancer for single-page pagers
333
487
  if (method.nextLinkName) {
334
488
  const nilChecks = generateNilChecks(method.nextLinkName);
@@ -339,10 +493,10 @@ function emitPagerDefinition(client, method, imports, injectSpans, generateFakes
339
493
  text += '\t\t\treturn false\n';
340
494
  text += '\t\t},\n';
341
495
  }
342
- text += `\t\tFetcher: func(ctx context.Context, page *${method.responseEnvelope.name}) (${method.responseEnvelope.name}, error) {\n`;
496
+ text += `\t\tFetcher: func(ctx context.Context, page *${method.returns.name}) (${method.returns.name}, error) {\n`;
343
497
  const reqParams = helpers.getCreateRequestParameters(method);
344
498
  if (generateFakes) {
345
- text += `\t\tctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "${client.name}.${fixUpMethodName(method)}")\n`;
499
+ text += `\t\tctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "${method.receiver.type.name}.${fixUpMethodName(method)}")\n`;
346
500
  }
347
501
  if (method.nextLinkName) {
348
502
  let nextLinkVar;
@@ -378,7 +532,7 @@ function emitPagerDefinition(client, method, imports, injectSpans, generateFakes
378
532
  else {
379
533
  text += 'nil)\n';
380
534
  }
381
- text += `\t\t\tif err != nil {\n\t\t\t\treturn ${method.responseEnvelope.name}{}, err\n\t\t\t}\n`;
535
+ text += `\t\t\tif err != nil {\n\t\t\t\treturn ${method.returns.name}{}, err\n\t\t\t}\n`;
382
536
  text += `\t\t\treturn client.${method.naming.responseMethod}(resp)\n`;
383
537
  text += '\t\t\t},\n';
384
538
  }
@@ -386,14 +540,14 @@ function emitPagerDefinition(client, method, imports, injectSpans, generateFakes
386
540
  // this is the singular page case, no fetcher helper required
387
541
  text += `\t\t\treq, err := client.${method.naming.requestMethod}(${reqParams})\n`;
388
542
  text += '\t\t\tif err != nil {\n';
389
- text += `\t\t\t\treturn ${method.responseEnvelope.name}{}, err\n`;
543
+ text += `\t\t\t\treturn ${method.returns.name}{}, err\n`;
390
544
  text += '\t\t\t}\n';
391
545
  text += '\t\t\tresp, err := client.internal.Pipeline().Do(req)\n';
392
546
  text += '\t\t\tif err != nil {\n';
393
- text += `\t\t\t\treturn ${method.responseEnvelope.name}{}, err\n`;
547
+ text += `\t\t\t\treturn ${method.returns.name}{}, err\n`;
394
548
  text += '\t\t\t}\n';
395
549
  text += '\t\t\tif !runtime.HasStatusCode(resp, http.StatusOK) {\n';
396
- text += `\t\t\t\treturn ${method.responseEnvelope.name}{}, runtime.NewResponseError(resp)\n`;
550
+ text += `\t\t\t\treturn ${method.returns.name}{}, runtime.NewResponseError(resp)\n`;
397
551
  text += '\t\t\t}\n';
398
552
  text += `\t\t\treturn client.${method.naming.responseMethod}(resp)\n`;
399
553
  text += '\t\t},\n';
@@ -411,14 +565,23 @@ function genApiVersionDoc(apiVersions) {
411
565
  return `//\n// Generated from API version ${apiVersions.join(', ')}\n`;
412
566
  }
413
567
  function genRespErrorDoc(method) {
414
- if (!(method.responseEnvelope.result?.kind === 'headAsBooleanResult') && !go.isPageableMethod(method)) {
568
+ if (!(method.returns.result?.kind === 'headAsBooleanResult') && !go.isPageableMethod(method)) {
415
569
  // when head-as-boolean is enabled, no error is returned for 4xx status codes.
416
570
  // pager constructors don't return an error
417
571
  return '// If the operation fails it returns an *azcore.ResponseError type.\n';
418
572
  }
419
573
  return '';
420
574
  }
421
- function generateOperation(client, method, imports, injectSpans, generateFakes) {
575
+ /**
576
+ * returns the receiver definition for a client
577
+ *
578
+ * @param receiver the receiver for which to emit the definition
579
+ * @returns the receiver definition
580
+ */
581
+ function getClientReceiverDefinition(receiver) {
582
+ return `(${receiver.name} ${receiver.byValue ? '' : '*'}${receiver.type.name})`;
583
+ }
584
+ function generateOperation(method, imports, injectSpans, generateFakes) {
422
585
  const params = getAPIParametersSig(method, imports);
423
586
  const returns = generateReturnsInfo(method, 'op');
424
587
  let methodName = method.name;
@@ -447,16 +610,16 @@ function generateOperation(client, method, imports, injectSpans, generateFakes)
447
610
  text += helpers.formatCommentAsBulletItem(param.name, param.docs);
448
611
  }
449
612
  }
450
- text += `func (client *${client.name}) ${methodName}(${params}) (${returns.join(', ')}) {\n`;
613
+ text += `func ${getClientReceiverDefinition(method.receiver)} ${methodName}(${params}) (${returns.join(', ')}) {\n`;
451
614
  const reqParams = helpers.getCreateRequestParameters(method);
452
615
  if (method.kind === 'pageableMethod') {
453
616
  text += '\treturn ';
454
- text += emitPagerDefinition(client, method, imports, injectSpans, generateFakes);
617
+ text += emitPagerDefinition(method, imports, injectSpans, generateFakes);
455
618
  text += '}\n\n';
456
619
  return text;
457
620
  }
458
621
  text += '\tvar err error\n';
459
- let operationName = `"${client.name}.${fixUpMethodName(method)}"`;
622
+ let operationName = `"${method.receiver.type.name}.${fixUpMethodName(method)}"`;
460
623
  if (generateFakes && injectSpans) {
461
624
  text += `\tconst operationName = ${operationName}\n`;
462
625
  operationName = 'operationName';
@@ -482,8 +645,8 @@ function generateOperation(client, method, imports, injectSpans, generateFakes)
482
645
  text += `\t\treturn ${zeroResp}, err\n`;
483
646
  text += '\t}\n';
484
647
  // HAB with headers response is handled in protocol responder
485
- if (method.responseEnvelope.result?.kind === 'headAsBooleanResult' && method.responseEnvelope.headers.length === 0) {
486
- text += `\treturn ${method.responseEnvelope.name}{${method.responseEnvelope.result.fieldName}: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil\n`;
648
+ if (method.returns.result?.kind === 'headAsBooleanResult' && method.returns.headers.length === 0) {
649
+ text += `\treturn ${method.returns.name}{${method.returns.result.fieldName}: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil\n`;
487
650
  }
488
651
  else {
489
652
  if (go.isLROMethod(method)) {
@@ -494,32 +657,32 @@ function generateOperation(client, method, imports, injectSpans, generateFakes)
494
657
  text += `\tresp, err := client.${method.naming.responseMethod}(httpResp)\n`;
495
658
  text += '\treturn resp, err\n';
496
659
  }
497
- else if (method.responseEnvelope.result?.kind === 'binaryResult') {
498
- text += `\treturn ${method.responseEnvelope.name}{${method.responseEnvelope.result.fieldName}: httpResp.Body}, nil\n`;
660
+ else if (method.returns.result?.kind === 'binaryResult') {
661
+ text += `\treturn ${method.returns.name}{${method.returns.result.fieldName}: httpResp.Body}, nil\n`;
499
662
  }
500
663
  else {
501
- text += `\treturn ${method.responseEnvelope.name}{}, nil\n`;
664
+ text += `\treturn ${method.returns.name}{}, nil\n`;
502
665
  }
503
666
  }
504
667
  text += '}\n\n';
505
668
  return text;
506
669
  }
507
- function createProtocolRequest(azureARM, client, method, imports) {
670
+ function createProtocolRequest(azureARM, method, imports) {
508
671
  let name = method.name;
509
672
  if (method.kind !== 'nextPageMethod') {
510
673
  name = method.naming.requestMethod;
511
674
  }
512
675
  for (const param of values(method.parameters)) {
513
- if (param.location !== 'method' || !go.isRequiredParameter(param)) {
676
+ if (param.location !== 'method' || !go.isRequiredParameter(param.style)) {
514
677
  continue;
515
678
  }
516
679
  imports.addImportForType(param.type);
517
680
  }
518
681
  const returns = ['*policy.Request', 'error'];
519
682
  let text = `${comment(name, '// ')} creates the ${method.name} request.\n`;
520
- text += `func (client *${client.name}) ${name}(${helpers.getCreateRequestParametersSig(method)}) (${returns.join(', ')}) {\n`;
683
+ text += `func ${getClientReceiverDefinition(method.receiver)} ${name}(${helpers.getCreateRequestParametersSig(method)}) (${returns.join(', ')}) {\n`;
521
684
  const hostParams = new Array();
522
- for (const parameter of client.parameters) {
685
+ for (const parameter of method.receiver.type.parameters) {
523
686
  if (parameter.kind === 'uriParam') {
524
687
  hostParams.push(parameter);
525
688
  }
@@ -528,10 +691,10 @@ function createProtocolRequest(azureARM, client, method, imports) {
528
691
  if (azureARM) {
529
692
  hostParam = 'client.internal.Endpoint()';
530
693
  }
531
- else if (client.templatedHost) {
694
+ else if (method.receiver.type.instance?.kind === 'templatedHost') {
532
695
  imports.add('strings');
533
696
  // we have a templated host
534
- text += `\thost := "${client.templatedHost}"\n`;
697
+ text += `\thost := "${method.receiver.type.instance.path}"\n`;
535
698
  // get all the host params on the client
536
699
  for (const hostParam of hostParams) {
537
700
  text += `\thost = strings.ReplaceAll(host, "{${hostParam.uriPathSegment}}", ${helpers.formatValue(`client.${hostParam.name}`, hostParam.type, imports)})\n`;
@@ -549,7 +712,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
549
712
  hostParam = 'client.' + hostParams[0].name;
550
713
  }
551
714
  else {
552
- throw new CodegenError('InternalError', `no host or endpoint defined for method ${client.name}.${method.name}`);
715
+ throw new CodegenError('InternalError', `no host or endpoint defined for method ${method.receiver.type.name}.${method.name}`);
553
716
  }
554
717
  const methodParamGroups = helpers.getMethodParamGroups(method);
555
718
  const hasPathParams = methodParamGroups.pathParams.length > 0;
@@ -565,36 +728,6 @@ function createProtocolRequest(azureARM, client, method, imports) {
565
728
  text += `\turlPath := "${method.httpPath}"\n`;
566
729
  hostParam = `runtime.JoinPaths(${hostParam}, urlPath)`;
567
730
  }
568
- if (hasPathParams) {
569
- // swagger defines path params, emit path and replace tokens
570
- imports.add('strings');
571
- // replace path parameters
572
- for (const pp of methodParamGroups.pathParams) {
573
- // emit check to ensure path param isn't an empty string. we only need
574
- // to do this for params that have an underlying type of string.
575
- const choiceIsString = function (type) {
576
- return type.kind === 'constant' && type.type === 'string';
577
- };
578
- // TODO: https://github.com/Azure/autorest.go/issues/1593
579
- if (pp.kind === 'pathScalarParam' && ((pp.type.kind === 'string' || choiceIsString(pp.type)) && pp.isEncoded)) {
580
- const paramName = helpers.getParamName(pp);
581
- imports.add('errors');
582
- text += `\tif ${paramName} == "" {\n`;
583
- text += `\t\treturn nil, errors.New("parameter ${paramName} cannot be empty")\n`;
584
- text += '\t}\n';
585
- }
586
- let paramValue = helpers.formatParamValue(pp, imports);
587
- if (pp.isEncoded) {
588
- imports.add('net/url');
589
- paramValue = `url.PathEscape(${helpers.formatParamValue(pp, imports)})`;
590
- }
591
- text += `\turlPath = strings.ReplaceAll(urlPath, "{${pp.pathSegment}}", ${paramValue})\n`;
592
- }
593
- }
594
- text += `\treq, err := runtime.NewRequest(ctx, http.Method${capitalize(method.httpMethod)}, ${hostParam})\n`;
595
- text += '\tif err != nil {\n';
596
- text += '\t\treturn nil, err\n';
597
- text += '\t}\n';
598
731
  // helper to build nil checks for param groups
599
732
  const emitParamGroupCheck = function (param) {
600
733
  if (!param.group) {
@@ -611,6 +744,81 @@ function createProtocolRequest(azureARM, client, method, imports) {
611
744
  }
612
745
  return `\tif ${optionalParamGroupCheck}${client}${paramGroupName}.${capitalize(param.name)} != nil {\n`;
613
746
  };
747
+ if (hasPathParams) {
748
+ // swagger defines path params, emit path and replace tokens
749
+ imports.add('strings');
750
+ // replace path parameters
751
+ for (const pp of methodParamGroups.pathParams) {
752
+ let paramValue;
753
+ let optionalPathSep = false;
754
+ if (pp.style !== 'optional') {
755
+ // emit check to ensure path param isn't an empty string
756
+ if (pp.kind === 'pathScalarParam') {
757
+ const choiceIsString = function (type) {
758
+ return type.kind === 'constant' && type.type === 'string';
759
+ };
760
+ // we only need to do this for params that have an underlying type of string
761
+ if ((pp.type.kind === 'string' || choiceIsString(pp.type)) && !pp.omitEmptyStringCheck) {
762
+ const paramName = helpers.getParamName(pp);
763
+ imports.add('errors');
764
+ text += `\tif ${paramName} == "" {\n`;
765
+ text += `\t\treturn nil, errors.New("parameter ${paramName} cannot be empty")\n`;
766
+ text += '\t}\n';
767
+ }
768
+ }
769
+ paramValue = helpers.formatParamValue(pp, imports);
770
+ // for collection-based path params, we emit the empty check
771
+ // after calling helpers.formatParamValue as that will have the
772
+ // var name that contains the slice.
773
+ if (pp.kind === 'pathCollectionParam') {
774
+ const paramName = helpers.getParamName(pp);
775
+ const joinedParamName = `${paramName}Param`;
776
+ text += `\t${joinedParamName} := ${paramValue}\n`;
777
+ imports.add('errors');
778
+ text += `\tif len(${joinedParamName}) == 0 {\n`;
779
+ text += `\t\treturn nil, errors.New("parameter ${paramName} cannot be empty")\n`;
780
+ text += '\t}\n';
781
+ paramValue = joinedParamName;
782
+ }
783
+ }
784
+ else {
785
+ // param isn't required, so emit a local var with
786
+ // the correct default value, then populate it with
787
+ // the optional value when set.
788
+ paramValue = `optional${capitalize(pp.name)}`;
789
+ text += `\t${paramValue} := ""\n`;
790
+ text += emitParamGroupCheck(pp);
791
+ text += `\t${paramValue} = ${helpers.formatParamValue(pp, imports)}\n\t}\n`;
792
+ // there are two cases for optional path params.
793
+ // - /foo/bar/{optional}
794
+ // - /foo/bar{/optional}
795
+ // for the second case, we need to include a forward slash
796
+ if (method.httpPath[method.httpPath.indexOf(`{${pp.pathSegment}}`) - 1] !== '/') {
797
+ optionalPathSep = true;
798
+ }
799
+ }
800
+ const emitPathEscape = function () {
801
+ if (pp.isEncoded) {
802
+ imports.add('net/url');
803
+ return `url.PathEscape(${paramValue})`;
804
+ }
805
+ return paramValue;
806
+ };
807
+ if (optionalPathSep) {
808
+ text += `\tif len(${paramValue}) > 0 {\n`;
809
+ text += `\t\t${paramValue} = "/"+${emitPathEscape()}\n`;
810
+ text += '\t}\n';
811
+ }
812
+ else {
813
+ paramValue = emitPathEscape();
814
+ }
815
+ text += `\turlPath = strings.ReplaceAll(urlPath, "{${pp.pathSegment}}", ${paramValue})\n`;
816
+ }
817
+ }
818
+ text += `\treq, err := runtime.NewRequest(ctx, http.Method${capitalize(method.httpMethod)}, ${hostParam})\n`;
819
+ text += '\tif err != nil {\n';
820
+ text += '\t\treturn nil, err\n';
821
+ text += '\t}\n';
614
822
  // add query parameters
615
823
  const encodedParams = methodParamGroups.encodedQueryParams;
616
824
  const unencodedParams = methodParamGroups.unencodedQueryParams;
@@ -619,7 +827,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
619
827
  if (qp.location === 'method' && go.isClientSideDefault(qp.style)) {
620
828
  qpText = emitClientSideDefault(qp, qp.style, (name, val) => { return `\treqQP.Set(${name}, ${val})`; }, imports);
621
829
  }
622
- else if (go.isRequiredParameter(qp) || go.isLiteralParameter(qp) || (qp.location === 'client' && go.isClientSideDefault(qp.style))) {
830
+ else if (go.isRequiredParameter(qp.style) || go.isLiteralParameter(qp.style) || (qp.location === 'client' && go.isClientSideDefault(qp.style))) {
623
831
  qpText = `\t${setter}\n`;
624
832
  }
625
833
  else if (qp.location === 'client' && !qp.group) {
@@ -697,7 +905,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
697
905
  imports.add('strings');
698
906
  text += '\treq.Raw().URL.RawQuery = strings.Join(unencodedParams, "&")\n';
699
907
  }
700
- if (method.kind !== 'nextPageMethod' && method.responseEnvelope.result?.kind === 'binaryResult') {
908
+ if (method.kind !== 'nextPageMethod' && method.returns.result?.kind === 'binaryResult') {
701
909
  // skip auto-body downloading for binary stream responses
702
910
  text += '\truntime.SkipBodyDownload(req)\n';
703
911
  }
@@ -733,7 +941,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
733
941
  // we do it like this as tsp specifies content-type while swagger does not.
734
942
  contentType = helpers.formatParamValue(param, imports);
735
943
  }
736
- else if (go.isRequiredParameter(param) || go.isLiteralParameter(param) || go.isClientSideDefault(param.style)) {
944
+ else if (go.isRequiredParameter(param.style) || go.isLiteralParameter(param.style) || go.isClientSideDefault(param.style)) {
737
945
  text += emitHeaderSet(param, '\t');
738
946
  }
739
947
  else if (param.location === 'client' && !param.group) {
@@ -785,7 +993,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
785
993
  text += `\t\t${fieldName} *${go.getTypeDeclaration(bodyParam.type)} \`xml:"${tag}"\`\n`;
786
994
  text += '\t}\n';
787
995
  let addr = '&';
788
- if (!go.isRequiredParameter(bodyParam) && !bodyParam.byValue) {
996
+ if (!go.isRequiredParameter(bodyParam.style) && !bodyParam.byValue) {
789
997
  addr = '';
790
998
  }
791
999
  body = `wrapper{${fieldName}: ${addr}${body}}`;
@@ -821,7 +1029,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
821
1029
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming');
822
1030
  setBody = `req.SetBody(streaming.NopCloser(bytes.NewReader(${body})), "application/${bodyParam.bodyFormat.toLowerCase()}")`;
823
1031
  }
824
- if (go.isRequiredParameter(bodyParam) || go.isLiteralParameter(bodyParam)) {
1032
+ if (go.isRequiredParameter(bodyParam.style) || go.isLiteralParameter(bodyParam.style)) {
825
1033
  text += `\t${emitSetBodyWithErrCheck(setBody, contentType)}`;
826
1034
  text += '\treturn req, nil\n';
827
1035
  }
@@ -834,7 +1042,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
834
1042
  }
835
1043
  }
836
1044
  else if (bodyParam.bodyFormat === 'binary') {
837
- if (go.isRequiredParameter(bodyParam)) {
1045
+ if (go.isRequiredParameter(bodyParam.style)) {
838
1046
  text += `\t${emitSetBodyWithErrCheck(`req.SetBody(${bodyParam.name}, ${bodyParam.contentType})`, contentType)}`;
839
1047
  text += '\treturn req, nil\n';
840
1048
  }
@@ -849,7 +1057,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
849
1057
  else if (bodyParam.bodyFormat === 'Text') {
850
1058
  imports.add('strings');
851
1059
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming');
852
- if (go.isRequiredParameter(bodyParam)) {
1060
+ if (go.isRequiredParameter(bodyParam.style)) {
853
1061
  text += `\tbody := streaming.NopCloser(strings.NewReader(${bodyParam.name}))\n`;
854
1062
  text += `\t${emitSetBodyWithErrCheck(`req.SetBody(body, ${bodyParam.contentType})`, contentType)}`;
855
1063
  text += '\treturn req, nil\n';
@@ -869,19 +1077,19 @@ function createProtocolRequest(azureARM, client, method, imports) {
869
1077
  // define and instantiate an instance of the wire type, using the values from each param.
870
1078
  text += '\tbody := struct {\n';
871
1079
  for (const partialBodyParam of partialBodyParams) {
872
- text += `\t\t${capitalize(partialBodyParam.serializedName)} ${helpers.star(partialBodyParam)}${go.getTypeDeclaration(partialBodyParam.type)} \`${partialBodyParam.format.toLowerCase()}:"${partialBodyParam.serializedName}"\`\n`;
1080
+ text += `\t\t${capitalize(partialBodyParam.serializedName)} ${helpers.star(partialBodyParam.byValue)}${go.getTypeDeclaration(partialBodyParam.type)} \`${partialBodyParam.format.toLowerCase()}:"${partialBodyParam.serializedName}"\`\n`;
873
1081
  }
874
1082
  text += '\t}{\n';
875
1083
  // required params are emitted as initializers in the struct literal
876
1084
  for (const partialBodyParam of partialBodyParams) {
877
- if (go.isRequiredParameter(partialBodyParam)) {
1085
+ if (go.isRequiredParameter(partialBodyParam.style)) {
878
1086
  text += `\t\t${capitalize(partialBodyParam.serializedName)}: ${uncapitalize(partialBodyParam.name)},\n`;
879
1087
  }
880
1088
  }
881
1089
  text += '\t}\n';
882
1090
  // now populate any optional params from the options type
883
1091
  for (const partialBodyParam of partialBodyParams) {
884
- if (!go.isRequiredParameter(partialBodyParam)) {
1092
+ if (!go.isRequiredParameter(partialBodyParam.style)) {
885
1093
  text += emitParamGroupCheck(partialBodyParam);
886
1094
  text += `\t\tbody.${capitalize(partialBodyParam.serializedName)} = options.${capitalize(partialBodyParam.name)}\n\t}\n`;
887
1095
  }
@@ -900,7 +1108,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
900
1108
  text += '\tformData := map[string]any{}\n';
901
1109
  for (const param of multipartBodyParams) {
902
1110
  const setter = `formData["${param.name}"] = ${helpers.getParamName(param)}`;
903
- if (go.isRequiredParameter(param)) {
1111
+ if (go.isRequiredParameter(param.style)) {
904
1112
  text += `\t${setter}\n`;
905
1113
  }
906
1114
  else {
@@ -915,7 +1123,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
915
1123
  else if (formBodyParams.length > 0) {
916
1124
  const emitFormData = function (param, setter) {
917
1125
  let formDataText = '';
918
- if (go.isRequiredParameter(param)) {
1126
+ if (go.isRequiredParameter(param.style)) {
919
1127
  formDataText = `\t${setter}\n`;
920
1128
  }
921
1129
  else {
@@ -997,7 +1205,7 @@ function isArrayOfDateTimeForMarshalling(paramType) {
997
1205
  // returns true if the method requires a response handler.
998
1206
  // this is used to unmarshal the response body, parse response headers, or both.
999
1207
  function needsResponseHandler(method) {
1000
- return helpers.hasSchemaResponse(method) || method.responseEnvelope.headers.length > 0;
1208
+ return helpers.hasSchemaResponse(method) || method.returns.headers.length > 0;
1001
1209
  }
1002
1210
  function generateResponseUnmarshaller(method, type, format, unmarshalTarget) {
1003
1211
  let unmarshallerText = '';
@@ -1065,34 +1273,34 @@ function generateResponseUnmarshaller(method, type, format, unmarshalTarget) {
1065
1273
  }
1066
1274
  else {
1067
1275
  // the remaining formats should have been handled elsewhere
1068
- throw new CodegenError('InternalError', `unhandled format ${format} for operation ${method.client.name}.${method.name}`);
1276
+ throw new CodegenError('InternalError', `unhandled format ${format} for operation ${method.receiver.type.name}.${method.name}`);
1069
1277
  }
1070
1278
  return unmarshallerText;
1071
1279
  }
1072
- function createProtocolResponse(client, method, imports) {
1280
+ function createProtocolResponse(method, imports) {
1073
1281
  if (!needsResponseHandler(method)) {
1074
1282
  return '';
1075
1283
  }
1076
1284
  const name = method.naming.responseMethod;
1077
1285
  let text = `${comment(name, '// ')} handles the ${method.name} response.\n`;
1078
- text += `func (client *${client.name}) ${name}(resp *http.Response) (${generateReturnsInfo(method, 'handler').join(', ')}) {\n`;
1286
+ text += `func ${getClientReceiverDefinition(method.receiver)} ${name}(resp *http.Response) (${generateReturnsInfo(method, 'handler').join(', ')}) {\n`;
1079
1287
  const addHeaders = function (headers) {
1080
1288
  for (const header of values(headers)) {
1081
- text += formatHeaderResponseValue(header, imports, 'result', `${method.responseEnvelope.name}{}`);
1289
+ text += formatHeaderResponseValue(header, imports, 'result', `${method.returns.name}{}`);
1082
1290
  }
1083
1291
  };
1084
- const result = method.responseEnvelope.result;
1292
+ const result = method.returns.result;
1085
1293
  if (!result) {
1086
1294
  // only headers
1087
- text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1088
- addHeaders(method.responseEnvelope.headers);
1295
+ text += `\tresult := ${method.returns.name}{}\n`;
1296
+ addHeaders(method.returns.headers);
1089
1297
  }
1090
1298
  else {
1091
1299
  switch (result.kind) {
1092
1300
  case 'anyResult':
1093
1301
  imports.add('fmt');
1094
- text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1095
- addHeaders(method.responseEnvelope.headers);
1302
+ text += `\tresult := ${method.returns.name}{}\n`;
1303
+ addHeaders(method.returns.headers);
1096
1304
  text += '\tswitch resp.StatusCode {\n';
1097
1305
  for (const statusCode of method.httpStatusCodes) {
1098
1306
  text += `\tcase ${helpers.formatStatusCodes([statusCode])}:\n`;
@@ -1110,21 +1318,21 @@ function createProtocolResponse(client, method, imports) {
1110
1318
  text += '\t}\n';
1111
1319
  break;
1112
1320
  case 'binaryResult':
1113
- text += `\tresult := ${method.responseEnvelope.name}{${result.fieldName}: resp.Body}\n`;
1114
- addHeaders(method.responseEnvelope.headers);
1321
+ text += `\tresult := ${method.returns.name}{${result.fieldName}: resp.Body}\n`;
1322
+ addHeaders(method.returns.headers);
1115
1323
  break;
1116
1324
  case 'headAsBooleanResult':
1117
- text += `\tresult := ${method.responseEnvelope.name}{${result.fieldName}: resp.StatusCode >= 200 && resp.StatusCode < 300}\n`;
1118
- addHeaders(method.responseEnvelope.headers);
1325
+ text += `\tresult := ${method.returns.name}{${result.fieldName}: resp.StatusCode >= 200 && resp.StatusCode < 300}\n`;
1326
+ addHeaders(method.returns.headers);
1119
1327
  break;
1120
1328
  case 'modelResult':
1121
- text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1122
- addHeaders(method.responseEnvelope.headers);
1329
+ text += `\tresult := ${method.returns.name}{}\n`;
1330
+ addHeaders(method.returns.headers);
1123
1331
  text += generateResponseUnmarshaller(method, result.modelType, result.format, `result.${helpers.getResultFieldName(method)}`);
1124
1332
  break;
1125
1333
  case 'monomorphicResult':
1126
- text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1127
- addHeaders(method.responseEnvelope.headers);
1334
+ text += `\tresult := ${method.returns.name}{}\n`;
1335
+ addHeaders(method.returns.headers);
1128
1336
  let target = `result.${helpers.getResultFieldName(method)}`;
1129
1337
  // when unmarshalling a wrapped XML array, unmarshal into the response envelope
1130
1338
  if (result.format === 'XML' && result.monomorphicType.kind === 'slice') {
@@ -1133,8 +1341,8 @@ function createProtocolResponse(client, method, imports) {
1133
1341
  text += generateResponseUnmarshaller(method, result.monomorphicType, result.format, target);
1134
1342
  break;
1135
1343
  case 'polymorphicResult':
1136
- text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1137
- addHeaders(method.responseEnvelope.headers);
1344
+ text += `\tresult := ${method.returns.name}{}\n`;
1345
+ addHeaders(method.returns.headers);
1138
1346
  text += generateResponseUnmarshaller(method, result.interface, result.format, 'result');
1139
1347
  break;
1140
1348
  default:
@@ -1187,7 +1395,7 @@ function getAPIParametersSig(method, imports, pkgName) {
1187
1395
  // op - for the operation
1188
1396
  // handler - for the response handler
1189
1397
  function generateReturnsInfo(method, apiType) {
1190
- let returnType = method.responseEnvelope.name;
1398
+ let returnType = method.returns.name;
1191
1399
  switch (method.kind) {
1192
1400
  case 'lroMethod':
1193
1401
  case 'lroPageableMethod':
@@ -1222,7 +1430,7 @@ function generateReturnsInfo(method, apiType) {
1222
1430
  }
1223
1431
  return [returnType, 'error'];
1224
1432
  }
1225
- function generateLROBeginMethod(client, method, imports, injectSpans, generateFakes) {
1433
+ function generateLROBeginMethod(method, imports, injectSpans, generateFakes) {
1226
1434
  const params = getAPIParametersSig(method, imports);
1227
1435
  const returns = generateReturnsInfo(method, 'api');
1228
1436
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
@@ -1237,15 +1445,15 @@ function generateLROBeginMethod(client, method, imports, injectSpans, generateFa
1237
1445
  for (const param of values(methodParams)) {
1238
1446
  text += helpers.formatCommentAsBulletItem(param.name, param.docs);
1239
1447
  }
1240
- text += `func (client *${client.name}) ${fixUpMethodName(method)}(${params}) (${returns.join(', ')}) {\n`;
1448
+ text += `func ${getClientReceiverDefinition(method.receiver)} ${fixUpMethodName(method)}(${params}) (${returns.join(', ')}) {\n`;
1241
1449
  let pollerType = 'nil';
1242
- let pollerTypeParam = `[${method.responseEnvelope.name}]`;
1450
+ let pollerTypeParam = `[${method.returns.name}]`;
1243
1451
  if (method.kind === 'lroPageableMethod') {
1244
1452
  // for paged LROs, we construct a pager and pass it to the LRO ctor.
1245
1453
  pollerTypeParam = `[*runtime.Pager${pollerTypeParam}]`;
1246
1454
  pollerType = '&pager';
1247
1455
  text += '\tpager := ';
1248
- text += emitPagerDefinition(client, method, imports, injectSpans, generateFakes);
1456
+ text += emitPagerDefinition(method, imports, injectSpans, generateFakes);
1249
1457
  }
1250
1458
  text += '\tif options == nil || options.ResumeToken == "" {\n';
1251
1459
  // creating the poller from response branch