@azure-tools/typespec-go 0.1.0

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 (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +16 -0
  3. package/dist/codegen.go/src/clientFactory.d.ts +3 -0
  4. package/dist/codegen.go/src/clientFactory.d.ts.map +1 -0
  5. package/dist/codegen.go/src/clientFactory.js +77 -0
  6. package/dist/codegen.go/src/clientFactory.js.map +1 -0
  7. package/dist/codegen.go/src/constants.d.ts +3 -0
  8. package/dist/codegen.go/src/constants.d.ts.map +1 -0
  9. package/dist/codegen.go/src/constants.js +59 -0
  10. package/dist/codegen.go/src/constants.js.map +1 -0
  11. package/dist/codegen.go/src/fake/factory.d.ts +3 -0
  12. package/dist/codegen.go/src/fake/factory.d.ts.map +1 -0
  13. package/dist/codegen.go/src/fake/factory.js +69 -0
  14. package/dist/codegen.go/src/fake/factory.js.map +1 -0
  15. package/dist/codegen.go/src/fake/internal.d.ts +14 -0
  16. package/dist/codegen.go/src/fake/internal.d.ts.map +1 -0
  17. package/dist/codegen.go/src/fake/internal.js +197 -0
  18. package/dist/codegen.go/src/fake/internal.js.map +1 -0
  19. package/dist/codegen.go/src/fake/servers.d.ts +14 -0
  20. package/dist/codegen.go/src/fake/servers.d.ts.map +1 -0
  21. package/dist/codegen.go/src/fake/servers.js +1255 -0
  22. package/dist/codegen.go/src/fake/servers.js.map +1 -0
  23. package/dist/codegen.go/src/gomod.d.ts +3 -0
  24. package/dist/codegen.go/src/gomod.d.ts.map +1 -0
  25. package/dist/codegen.go/src/gomod.js +55 -0
  26. package/dist/codegen.go/src/gomod.js.map +1 -0
  27. package/dist/codegen.go/src/helpers.d.ts +32 -0
  28. package/dist/codegen.go/src/helpers.d.ts.map +1 -0
  29. package/dist/codegen.go/src/helpers.js +586 -0
  30. package/dist/codegen.go/src/helpers.js.map +1 -0
  31. package/dist/codegen.go/src/imports.d.ts +11 -0
  32. package/dist/codegen.go/src/imports.d.ts.map +1 -0
  33. package/dist/codegen.go/src/imports.js +65 -0
  34. package/dist/codegen.go/src/imports.js.map +1 -0
  35. package/dist/codegen.go/src/interfaces.d.ts +3 -0
  36. package/dist/codegen.go/src/interfaces.d.ts.map +1 -0
  37. package/dist/codegen.go/src/interfaces.js +36 -0
  38. package/dist/codegen.go/src/interfaces.js.map +1 -0
  39. package/dist/codegen.go/src/models.d.ts +9 -0
  40. package/dist/codegen.go/src/models.d.ts.map +1 -0
  41. package/dist/codegen.go/src/models.js +849 -0
  42. package/dist/codegen.go/src/models.js.map +1 -0
  43. package/dist/codegen.go/src/operations.d.ts +9 -0
  44. package/dist/codegen.go/src/operations.d.ts.map +1 -0
  45. package/dist/codegen.go/src/operations.js +1337 -0
  46. package/dist/codegen.go/src/operations.js.map +1 -0
  47. package/dist/codegen.go/src/options.d.ts +3 -0
  48. package/dist/codegen.go/src/options.d.ts.map +1 -0
  49. package/dist/codegen.go/src/options.js +64 -0
  50. package/dist/codegen.go/src/options.js.map +1 -0
  51. package/dist/codegen.go/src/polymorphics.d.ts +3 -0
  52. package/dist/codegen.go/src/polymorphics.d.ts.map +1 -0
  53. package/dist/codegen.go/src/polymorphics.js +169 -0
  54. package/dist/codegen.go/src/polymorphics.js.map +1 -0
  55. package/dist/codegen.go/src/responses.d.ts +7 -0
  56. package/dist/codegen.go/src/responses.d.ts.map +1 -0
  57. package/dist/codegen.go/src/responses.js +167 -0
  58. package/dist/codegen.go/src/responses.js.map +1 -0
  59. package/dist/codegen.go/src/time.d.ts +8 -0
  60. package/dist/codegen.go/src/time.d.ts.map +1 -0
  61. package/dist/codegen.go/src/time.js +511 -0
  62. package/dist/codegen.go/src/time.js.map +1 -0
  63. package/dist/codemodel.go/src/client.d.ts +96 -0
  64. package/dist/codemodel.go/src/client.d.ts.map +1 -0
  65. package/dist/codemodel.go/src/client.js +114 -0
  66. package/dist/codemodel.go/src/client.js.map +1 -0
  67. package/dist/codemodel.go/src/index.d.ts +6 -0
  68. package/dist/codemodel.go/src/index.d.ts.map +1 -0
  69. package/dist/codemodel.go/src/index.js +10 -0
  70. package/dist/codemodel.go/src/index.js.map +1 -0
  71. package/dist/codemodel.go/src/package.d.ts +49 -0
  72. package/dist/codemodel.go/src/package.d.ts.map +1 -0
  73. package/dist/codemodel.go/src/package.js +86 -0
  74. package/dist/codemodel.go/src/package.js.map +1 -0
  75. package/dist/codemodel.go/src/param.d.ts +162 -0
  76. package/dist/codemodel.go/src/param.d.ts.map +1 -0
  77. package/dist/codemodel.go/src/param.js +189 -0
  78. package/dist/codemodel.go/src/param.js.map +1 -0
  79. package/dist/codemodel.go/src/result.d.ts +102 -0
  80. package/dist/codemodel.go/src/result.d.ts.map +1 -0
  81. package/dist/codemodel.go/src/result.js +119 -0
  82. package/dist/codemodel.go/src/result.js.map +1 -0
  83. package/dist/codemodel.go/src/type.d.ts +181 -0
  84. package/dist/codemodel.go/src/type.d.ts.map +1 -0
  85. package/dist/codemodel.go/src/type.js +242 -0
  86. package/dist/codemodel.go/src/type.js.map +1 -0
  87. package/dist/naming.go/src/mappings.d.ts +3 -0
  88. package/dist/naming.go/src/mappings.d.ts.map +1 -0
  89. package/dist/naming.go/src/mappings.js +128 -0
  90. package/dist/naming.go/src/mappings.js.map +1 -0
  91. package/dist/naming.go/src/naming.d.ts +10 -0
  92. package/dist/naming.go/src/naming.d.ts.map +1 -0
  93. package/dist/naming.go/src/naming.js +114 -0
  94. package/dist/naming.go/src/naming.js.map +1 -0
  95. package/dist/typespec-go/src/emitter.d.ts +5 -0
  96. package/dist/typespec-go/src/emitter.d.ts.map +1 -0
  97. package/dist/typespec-go/src/emitter.js +122 -0
  98. package/dist/typespec-go/src/emitter.js.map +1 -0
  99. package/dist/typespec-go/src/index.d.ts +3 -0
  100. package/dist/typespec-go/src/index.d.ts.map +1 -0
  101. package/dist/typespec-go/src/index.js +7 -0
  102. package/dist/typespec-go/src/index.js.map +1 -0
  103. package/dist/typespec-go/src/lib.d.ts +25 -0
  104. package/dist/typespec-go/src/lib.d.ts.map +1 -0
  105. package/dist/typespec-go/src/lib.js +36 -0
  106. package/dist/typespec-go/src/lib.js.map +1 -0
  107. package/dist/typespec-go/src/tcgcadapter/adapter.d.ts +5 -0
  108. package/dist/typespec-go/src/tcgcadapter/adapter.d.ts.map +1 -0
  109. package/dist/typespec-go/src/tcgcadapter/adapter.js +119 -0
  110. package/dist/typespec-go/src/tcgcadapter/adapter.js.map +1 -0
  111. package/dist/typespec-go/src/tcgcadapter/clients.d.ts +26 -0
  112. package/dist/typespec-go/src/tcgcadapter/clients.d.ts.map +1 -0
  113. package/dist/typespec-go/src/tcgcadapter/clients.js +621 -0
  114. package/dist/typespec-go/src/tcgcadapter/clients.js.map +1 -0
  115. package/dist/typespec-go/src/tcgcadapter/types.d.ts +29 -0
  116. package/dist/typespec-go/src/tcgcadapter/types.d.ts.map +1 -0
  117. package/dist/typespec-go/src/tcgcadapter/types.js +975 -0
  118. package/dist/typespec-go/src/tcgcadapter/types.js.map +1 -0
  119. package/package.json +77 -0
@@ -0,0 +1,1337 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import * as go from '../../codemodel.go/src/index.js';
6
+ import { capitalize, comment, uncapitalize } from '@azure-tools/codegen';
7
+ import { values } from '@azure-tools/linq';
8
+ import * as helpers from './helpers.js';
9
+ import { ImportManager } from './imports.js';
10
+ // represents the generated content for an operation group
11
+ export class OperationGroupContent {
12
+ constructor(name, content) {
13
+ this.name = name;
14
+ this.content = content;
15
+ }
16
+ }
17
+ // Creates the content for all <operation>.go files
18
+ export async function generateOperations(codeModel) {
19
+ // generate protocol operations
20
+ const operations = new Array();
21
+ if (codeModel.clients.length === 0) {
22
+ return operations;
23
+ }
24
+ const azureARM = codeModel.type === 'azure-arm';
25
+ for (const client of codeModel.clients) {
26
+ // the list of packages to import
27
+ const imports = new ImportManager();
28
+ if (client.methods.length > 0) {
29
+ // add standard imports for clients with methods.
30
+ // clients that are purely hierarchical (i.e. having no APIs) won't need them.
31
+ imports.add('net/http');
32
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/policy');
33
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
34
+ }
35
+ let clientPkg = 'azcore';
36
+ if (azureARM) {
37
+ clientPkg = 'arm';
38
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/arm');
39
+ client.constructors.push(createARMClientConstructor(client, imports));
40
+ }
41
+ else {
42
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore');
43
+ }
44
+ // generate client type
45
+ let clientText = '';
46
+ clientText += `${comment(`${client.description}`, '//', undefined, helpers.commentLength)}\n`;
47
+ clientText += '// Don\'t use this type directly, use ';
48
+ if (client.constructors.length === 1) {
49
+ clientText += `${client.constructors[0].name}() instead.\n`;
50
+ }
51
+ else if (client.parent) {
52
+ // find the accessor method
53
+ let accessorMethod;
54
+ for (const clientAccessor of client.parent.clientAccessors) {
55
+ if (clientAccessor.subClient === client) {
56
+ accessorMethod = clientAccessor.name;
57
+ break;
58
+ }
59
+ }
60
+ if (!accessorMethod) {
61
+ throw new Error(`didn't find accessor method for client ${client.name} on parent client ${client.parent.name}`);
62
+ }
63
+ clientText += `[${client.parent.name}.${accessorMethod}] instead.\n`;
64
+ }
65
+ else {
66
+ clientText += 'a constructor function instead.\n';
67
+ }
68
+ clientText += `type ${client.name} struct {\n`;
69
+ clientText += `\tinternal *${clientPkg}.Client\n`;
70
+ // check for any optional host params
71
+ const optionalParams = new Array();
72
+ const isParamPointer = function (param) {
73
+ // for client params, only optional and flag types are passed by pointer
74
+ return param.kind === 'flag' || param.kind === 'optional';
75
+ };
76
+ // now emit any client params (non parameterized host params case)
77
+ if (client.parameters.length > 0) {
78
+ const addedGroups = new Set();
79
+ for (const clientParam of values(client.parameters)) {
80
+ if (go.isLiteralParameter(clientParam)) {
81
+ continue;
82
+ }
83
+ if (clientParam.group) {
84
+ if (!addedGroups.has(clientParam.group.groupName)) {
85
+ clientText += `\t${uncapitalize(clientParam.group.groupName)} ${!isParamPointer(clientParam) ? '' : '*'}${clientParam.group.groupName}\n`;
86
+ addedGroups.add(clientParam.group.groupName);
87
+ }
88
+ continue;
89
+ }
90
+ clientText += `\t${clientParam.name} `;
91
+ if (!isParamPointer(clientParam)) {
92
+ clientText += `${go.getTypeDeclaration(clientParam.type)}\n`;
93
+ }
94
+ else {
95
+ clientText += `${helpers.formatParameterTypeName(clientParam)}\n`;
96
+ }
97
+ if (!go.isRequiredParameter(clientParam)) {
98
+ optionalParams.push(clientParam);
99
+ }
100
+ }
101
+ }
102
+ // end of client definition
103
+ clientText += '}\n\n';
104
+ if (azureARM && optionalParams.length > 0) {
105
+ throw new Error('optional client parameters for ARM is not supported');
106
+ }
107
+ // generate client constructors
108
+ clientText += generateConstructors(azureARM, client, imports);
109
+ // generate client accessors and operations
110
+ let opText = '';
111
+ for (const clientAccessor of client.clientAccessors) {
112
+ opText += `// ${clientAccessor.name} creates a new instance of [${clientAccessor.subClient.name}].\n`;
113
+ opText += `func (client *${client.name}) ${clientAccessor.name}() *${clientAccessor.subClient.name} {\n`;
114
+ opText += `\treturn &${clientAccessor.subClient.name}{\n`;
115
+ opText += '\t\tinternal: client.internal,\n';
116
+ // propagate all client params
117
+ for (const param of client.parameters) {
118
+ opText += `\t\t${param.name}: client.${param.name},\n`;
119
+ }
120
+ opText += '\t}\n}\n\n';
121
+ }
122
+ const nextPageMethods = new Array();
123
+ for (const method of client.methods) {
124
+ // protocol creation can add imports to the list so
125
+ // it must be done before the imports are written out
126
+ if (go.isLROMethod(method)) {
127
+ // generate Begin method
128
+ opText += generateLROBeginMethod(client, method, imports, codeModel.options.injectSpans, codeModel.options.generateFakes);
129
+ }
130
+ opText += generateOperation(client, method, imports, codeModel.options.injectSpans, codeModel.options.generateFakes);
131
+ opText += createProtocolRequest(azureARM, client, method, imports);
132
+ if (!go.isLROMethod(method) || go.isPageableMethod(method)) {
133
+ // LRO responses are handled elsewhere, with the exception of pageable LROs
134
+ opText += createProtocolResponse(client, method, imports);
135
+ }
136
+ if (go.isPageableMethod(method) && method.nextPageMethod && !nextPageMethods.includes(method.nextPageMethod)) {
137
+ // track the next page methods to generate as multiple operations can use the same next page operation
138
+ nextPageMethods.push(method.nextPageMethod);
139
+ }
140
+ }
141
+ for (const method of nextPageMethods) {
142
+ opText += createProtocolRequest(azureARM, client, method, imports);
143
+ }
144
+ // stitch it all together
145
+ let text = helpers.contentPreamble(codeModel);
146
+ text += imports.text();
147
+ text += clientText;
148
+ text += opText;
149
+ operations.push(new OperationGroupContent(client.name, text));
150
+ }
151
+ return operations;
152
+ }
153
+ // generates all modeled client constructors
154
+ function generateConstructors(azureARM, client, imports) {
155
+ if (client.constructors.length === 0) {
156
+ return '';
157
+ }
158
+ let ctorText = '';
159
+ for (const constructor of client.constructors) {
160
+ const ctorParams = new Array();
161
+ const paramDocs = new Array();
162
+ constructor.parameters.sort(helpers.sortParametersByRequired);
163
+ for (const ctorParam of constructor.parameters) {
164
+ imports.addImportForType(ctorParam.type);
165
+ ctorParams.push(`${ctorParam.name} ${helpers.formatParameterTypeName(ctorParam)}`);
166
+ if (ctorParam.description) {
167
+ paramDocs.push(helpers.formatCommentAsBulletItem(`${ctorParam.name} - ${ctorParam.description}`));
168
+ }
169
+ }
170
+ // add client options last
171
+ ctorParams.push(`${client.options.name} ${helpers.formatParameterTypeName(client.options)}`);
172
+ paramDocs.push(helpers.formatCommentAsBulletItem(`${client.options.name} - ${client.options.description}`));
173
+ ctorText += `// ${constructor.name} creates a new instance of ${client.name} with the specified values.\n`;
174
+ for (const doc of paramDocs) {
175
+ ctorText += `${doc}\n`;
176
+ }
177
+ ctorText += `func ${constructor.name}(${ctorParams.join(', ')}) (*${client.name}, error) {\n`;
178
+ let clientType = 'azcore';
179
+ if (azureARM) {
180
+ clientType = 'arm';
181
+ }
182
+ ctorText += `\tcl, err := ${clientType}.NewClient(moduleName, moduleVersion, credential, options)\n`;
183
+ ctorText += '\tif err != nil {\n';
184
+ ctorText += '\t\treturn nil, err\n';
185
+ ctorText += '\t}\n';
186
+ // construct client literal
187
+ ctorText += `\tclient := &${client.name}{\n`;
188
+ for (const parameter of values(client.parameters)) {
189
+ // each client field will have a matching parameter with the same name
190
+ ctorText += `\t\t${parameter.name}: ${parameter.name},\n`;
191
+ }
192
+ ctorText += '\tinternal: cl,\n';
193
+ ctorText += '\t}\n';
194
+ ctorText += '\treturn client, nil\n';
195
+ ctorText += '}\n\n';
196
+ }
197
+ return ctorText;
198
+ }
199
+ // creates a modeled constructor for an ARM client
200
+ function createARMClientConstructor(client, imports) {
201
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/arm');
202
+ const ctor = new go.Constructor(`New${client.name}`);
203
+ // add any modeled parameter first, which should only be the subscriptionID, then add TokenCredential
204
+ for (const param of client.parameters) {
205
+ ctor.parameters.push(param);
206
+ }
207
+ const tokenCredParam = new go.Parameter('credential', new go.QualifiedType('TokenCredential', 'github.com/Azure/azure-sdk-for-go/sdk/azcore'), 'required', true, 'client');
208
+ tokenCredParam.description = 'used to authorize requests. Usually a credential from azidentity.';
209
+ ctor.parameters.push(tokenCredParam);
210
+ return ctor;
211
+ }
212
+ // use this to generate the code that will help process values returned in response headers
213
+ function formatHeaderResponseValue(headerResp, imports, respObj, zeroResp) {
214
+ // dictionaries are handled slightly different so we do that first
215
+ if (go.isHeaderMapResponse(headerResp)) {
216
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/to');
217
+ imports.add('strings');
218
+ const headerPrefix = headerResp.collectionPrefix;
219
+ let text = '\tfor hh := range resp.Header {\n';
220
+ text += `\t\tif len(hh) > len("${headerPrefix}") && strings.EqualFold(hh[:len("${headerPrefix}")], "${headerPrefix}") {\n`;
221
+ text += `\t\t\tif ${respObj}.${headerResp.fieldName} == nil {\n`;
222
+ text += `\t\t\t\t${respObj}.${headerResp.fieldName} = map[string]*string{}\n`;
223
+ text += '\t\t\t}\n';
224
+ text += `\t\t\t${respObj}.${headerResp.fieldName}[hh[len("${headerPrefix}"):]] = to.Ptr(resp.Header.Get(hh))\n`;
225
+ text += '\t\t}\n';
226
+ text += '\t}\n';
227
+ return text;
228
+ }
229
+ let text = `\tif val := resp.Header.Get("${headerResp.headerName}"); val != "" {\n`;
230
+ let name = uncapitalize(headerResp.fieldName);
231
+ let byRef = '&';
232
+ if (go.isConstantType(headerResp.type)) {
233
+ text += `\t\t${respObj}.${headerResp.fieldName} = (*${headerResp.type.name})(&val)\n`;
234
+ text += '\t}\n';
235
+ return text;
236
+ }
237
+ else if (go.isPrimitiveType(headerResp.type)) {
238
+ if (headerResp.type.typeName === 'bool') {
239
+ imports.add('strconv');
240
+ text += `\t\t${name}, err := strconv.ParseBool(val)\n`;
241
+ }
242
+ else if (headerResp.type.typeName === 'int32' || headerResp.type.typeName === 'int64') {
243
+ imports.add('strconv');
244
+ if (headerResp.type.typeName === 'int32') {
245
+ text += `\t\t${name}32, err := strconv.ParseInt(val, 10, 32)\n`;
246
+ text += `\t\t${name} := int32(${name}32)\n`;
247
+ }
248
+ else {
249
+ text += `\t\t${name}, err := strconv.ParseInt(val, 10, 64)\n`;
250
+ }
251
+ }
252
+ else if (headerResp.type.typeName === 'float32' || headerResp.type.typeName === 'float64') {
253
+ imports.add('strconv');
254
+ if (headerResp.type.typeName === 'float32') {
255
+ text += `\t\t${name}32, err := strconv.ParseFloat(val, 32)\n`;
256
+ text += `\t\t${name} := float32(${name}32)\n`;
257
+ }
258
+ else {
259
+ text += `\t\t${name}, err := strconv.ParseFloat(val, 64)\n`;
260
+ }
261
+ }
262
+ else if (headerResp.type.typeName === 'string') {
263
+ text += `\t\t${respObj}.${headerResp.fieldName} = &val\n`;
264
+ text += '\t}\n';
265
+ return text;
266
+ }
267
+ else {
268
+ throw new Error(`unhandled primitive type ${headerResp.type.typeName}`);
269
+ }
270
+ }
271
+ else if (go.isTimeType(headerResp.type)) {
272
+ imports.add('time');
273
+ if (headerResp.type.dateTimeFormat === 'dateType') {
274
+ text += `\t\t${name}, err := time.Parse("${helpers.dateFormat}", val)\n`;
275
+ }
276
+ else if (headerResp.type.dateTimeFormat === 'timeRFC3339') {
277
+ text += `\t\t${name}, err := time.Parse("${helpers.timeRFC3339Format}", val)\n`;
278
+ }
279
+ else if (headerResp.type.dateTimeFormat === 'timeUnix') {
280
+ imports.add('strconv');
281
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/to');
282
+ text += '\t\tsec, err := strconv.ParseInt(val, 10, 64)\n';
283
+ name = 'to.Ptr(time.Unix(sec, 0))';
284
+ byRef = '';
285
+ }
286
+ else {
287
+ let format = helpers.datetimeRFC3339Format;
288
+ if (headerResp.type.dateTimeFormat === 'dateTimeRFC1123') {
289
+ format = helpers.datetimeRFC1123Format;
290
+ }
291
+ text += `\t\t${name}, err := time.Parse(${format}, val)\n`;
292
+ }
293
+ }
294
+ else if (go.isBytesType(headerResp.type)) {
295
+ // ByteArray is a base-64 encoded value in string format
296
+ imports.add('encoding/base64');
297
+ text += `\t\t${name}, err := base64.${helpers.formatBytesEncoding(headerResp.type.encoding)}Encoding.DecodeString(val)\n`;
298
+ byRef = '';
299
+ }
300
+ else if (go.isLiteralValue(headerResp.type)) {
301
+ text += `\t\t${respObj}.${headerResp.fieldName} = &val\n`;
302
+ text += '\t}\n';
303
+ return text;
304
+ }
305
+ else {
306
+ throw new Error(`unsupported header type ${go.getTypeDeclaration(headerResp.type)}`);
307
+ }
308
+ text += '\t\tif err != nil {\n';
309
+ text += `\t\t\treturn ${zeroResp}, err\n`;
310
+ text += '\t\t}\n';
311
+ text += `\t\t${respObj}.${headerResp.fieldName} = ${byRef}${name}\n`;
312
+ text += '\t}\n';
313
+ return text;
314
+ }
315
+ function getZeroReturnValue(method, apiType) {
316
+ let returnType = `${method.responseEnvelope.name}{}`;
317
+ if (go.isLROMethod(method)) {
318
+ if (apiType === 'api' || apiType === 'op') {
319
+ // the api returns a *Poller[T]
320
+ // the operation returns an *http.Response
321
+ returnType = 'nil';
322
+ }
323
+ }
324
+ return returnType;
325
+ }
326
+ function emitPagerDefinition(client, method, imports, injectSpans, generateFakes) {
327
+ imports.add('context');
328
+ let text = `runtime.NewPager(runtime.PagingHandler[${method.responseEnvelope.name}]{\n`;
329
+ text += `\t\tMore: func(page ${method.responseEnvelope.name}) bool {\n`;
330
+ // there is no advancer for single-page pagers
331
+ if (method.nextLinkName) {
332
+ text += `\t\t\treturn page.${method.nextLinkName} != nil && len(*page.${method.nextLinkName}) > 0\n`;
333
+ text += '\t\t},\n';
334
+ }
335
+ else {
336
+ text += '\t\t\treturn false\n';
337
+ text += '\t\t},\n';
338
+ }
339
+ text += `\t\tFetcher: func(ctx context.Context, page *${method.responseEnvelope.name}) (${method.responseEnvelope.name}, error) {\n`;
340
+ const reqParams = helpers.getCreateRequestParameters(method);
341
+ if (generateFakes) {
342
+ text += `\t\tctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, "${client.name}.${fixUpMethodName(method)}")\n`;
343
+ }
344
+ if (method.nextLinkName) {
345
+ let nextLinkVar;
346
+ if (!go.isLROMethod(method)) {
347
+ text += '\t\t\tnextLink := ""\n';
348
+ nextLinkVar = 'nextLink';
349
+ text += '\t\t\tif page != nil {\n';
350
+ text += `\t\t\t\tnextLink = *page.${method.nextLinkName}\n\t\t\t}\n`;
351
+ }
352
+ else {
353
+ nextLinkVar = `*page.${method.nextLinkName}`;
354
+ }
355
+ text += `\t\t\tresp, err := runtime.FetcherForNextLink(ctx, client.internal.Pipeline(), ${nextLinkVar}, func(ctx context.Context) (*policy.Request, error) {\n`;
356
+ text += `\t\t\t\treturn client.${method.naming.requestMethod}(${reqParams})\n\t\t\t}, `;
357
+ // nextPageMethod might be absent in some cases, see https://github.com/Azure/autorest/issues/4393
358
+ if (method.nextPageMethod) {
359
+ const nextOpParams = helpers.getCreateRequestParametersSig(method.nextPageMethod).split(',');
360
+ // keep the parameter names from the name/type tuples and find nextLink param
361
+ for (let i = 0; i < nextOpParams.length; ++i) {
362
+ const paramName = nextOpParams[i].trim().split(' ')[0];
363
+ const paramType = nextOpParams[i].trim().split(' ')[1];
364
+ if (paramName.startsWith('next') && paramType === 'string') {
365
+ nextOpParams[i] = 'encodedNextLink';
366
+ }
367
+ else {
368
+ nextOpParams[i] = paramName;
369
+ }
370
+ }
371
+ // add a definition for the nextReq func that uses the nextLinkOperation
372
+ text += '&runtime.FetcherForNextLinkOptions{\n\t\t\t\tNextReq: func(ctx context.Context, encodedNextLink string) (*policy.Request, error) {\n';
373
+ text += `\t\t\t\t\treturn client.${method.nextPageMethod.name}(${nextOpParams.join(', ')})\n\t\t\t\t},\n\t\t\t})\n`;
374
+ }
375
+ else {
376
+ text += 'nil)\n';
377
+ }
378
+ text += `\t\t\tif err != nil {\n\t\t\t\treturn ${method.responseEnvelope.name}{}, err\n\t\t\t}\n`;
379
+ text += `\t\t\treturn client.${method.naming.responseMethod}(resp)\n`;
380
+ text += '\t\t\t},\n';
381
+ }
382
+ else {
383
+ // this is the singular page case, no fetcher helper required
384
+ text += `\t\t\treq, err := client.${method.naming.requestMethod}(${reqParams})\n`;
385
+ text += '\t\t\tif err != nil {\n';
386
+ text += `\t\t\t\treturn ${method.responseEnvelope.name}{}, err\n`;
387
+ text += '\t\t\t}\n';
388
+ text += '\t\t\tresp, err := client.internal.Pipeline().Do(req)\n';
389
+ text += '\t\t\tif err != nil {\n';
390
+ text += `\t\t\t\treturn ${method.responseEnvelope.name}{}, err\n`;
391
+ text += '\t\t\t}\n';
392
+ text += '\t\t\tif !runtime.HasStatusCode(resp, http.StatusOK) {\n';
393
+ text += `\t\t\t\treturn ${method.responseEnvelope.name}{}, runtime.NewResponseError(resp)\n`;
394
+ text += '\t\t\t}\n';
395
+ text += `\t\t\treturn client.${method.naming.responseMethod}(resp)\n`;
396
+ text += '\t\t},\n';
397
+ }
398
+ if (injectSpans) {
399
+ text += '\t\tTracer: client.internal.Tracer(),\n';
400
+ }
401
+ text += '\t})\n';
402
+ return text;
403
+ }
404
+ function genApiVersionDoc(apiVersions) {
405
+ if (apiVersions.length === 0) {
406
+ return '';
407
+ }
408
+ return `//\n// Generated from API version ${apiVersions.join(', ')}\n`;
409
+ }
410
+ function genRespErrorDoc(method) {
411
+ if (!(method.responseEnvelope.result && go.isHeadAsBooleanResult(method.responseEnvelope.result)) && !go.isPageableMethod(method)) {
412
+ // when head-as-boolean is enabled, no error is returned for 4xx status codes.
413
+ // pager constructors don't return an error
414
+ return '// If the operation fails it returns an *azcore.ResponseError type.\n';
415
+ }
416
+ return '';
417
+ }
418
+ function generateOperation(client, method, imports, injectSpans, generateFakes) {
419
+ const params = getAPIParametersSig(method, imports);
420
+ const returns = generateReturnsInfo(method, 'op');
421
+ let methodName = method.name;
422
+ if (go.isPageableMethod(method) && !go.isLROMethod(method)) {
423
+ methodName = fixUpMethodName(method);
424
+ }
425
+ let text = '';
426
+ const respErrDoc = genRespErrorDoc(method);
427
+ const apiVerDoc = genApiVersionDoc(method.apiVersions);
428
+ if (method.description) {
429
+ text += `${comment(`${methodName} - ${method.description}`, '//', undefined, helpers.commentLength)}\n`;
430
+ }
431
+ else if (respErrDoc.length > 0 || apiVerDoc.length > 0) {
432
+ // if the method has no doc comment but we're adding other
433
+ // doc comments, add an empty method name comment. this preserves
434
+ // existing behavior and makes the docs look better overall.
435
+ text += `// ${methodName} -\n`;
436
+ }
437
+ text += respErrDoc;
438
+ text += apiVerDoc;
439
+ if (go.isLROMethod(method)) {
440
+ methodName = method.naming.internalMethod;
441
+ }
442
+ else {
443
+ for (const param of values(helpers.getMethodParameters(method))) {
444
+ if (param.description) {
445
+ text += `${helpers.formatCommentAsBulletItem(`${param.name} - ${param.description}`)}\n`;
446
+ }
447
+ }
448
+ }
449
+ text += `func (client *${client.name}) ${methodName}(${params}) (${returns.join(', ')}) {\n`;
450
+ const reqParams = helpers.getCreateRequestParameters(method);
451
+ if (go.isPageableMethod(method) && !go.isLROMethod(method)) {
452
+ text += '\treturn ';
453
+ text += emitPagerDefinition(client, method, imports, injectSpans, generateFakes);
454
+ text += '}\n\n';
455
+ return text;
456
+ }
457
+ text += '\tvar err error\n';
458
+ let operationName = `"${client.name}.${fixUpMethodName(method)}"`;
459
+ if (generateFakes && injectSpans) {
460
+ text += `\tconst operationName = ${operationName}\n`;
461
+ operationName = 'operationName';
462
+ }
463
+ if (generateFakes) {
464
+ text += `\tctx = context.WithValue(ctx, runtime.CtxAPINameKey{}, ${operationName})\n`;
465
+ }
466
+ if (injectSpans) {
467
+ text += `\tctx, endSpan := runtime.StartSpan(ctx, ${operationName}, client.internal.Tracer(), nil)\n`;
468
+ text += '\tdefer func() { endSpan(err) }()\n';
469
+ }
470
+ const zeroResp = getZeroReturnValue(method, 'op');
471
+ text += `\treq, err := client.${method.naming.requestMethod}(${reqParams})\n`;
472
+ text += '\tif err != nil {\n';
473
+ text += `\t\treturn ${zeroResp}, err\n`;
474
+ text += '\t}\n';
475
+ text += '\thttpResp, err := client.internal.Pipeline().Do(req)\n';
476
+ text += '\tif err != nil {\n';
477
+ text += `\t\treturn ${zeroResp}, err\n`;
478
+ text += '\t}\n';
479
+ text += `\tif !runtime.HasStatusCode(httpResp, ${helpers.formatStatusCodes(method.httpStatusCodes)}) {\n`;
480
+ text += '\t\terr = runtime.NewResponseError(httpResp)\n';
481
+ text += `\t\treturn ${zeroResp}, err\n`;
482
+ text += '\t}\n';
483
+ // HAB with headers response is handled in protocol responder
484
+ if (method.responseEnvelope.result && go.isHeadAsBooleanResult(method.responseEnvelope.result) && method.responseEnvelope.headers.length === 0) {
485
+ text += `\treturn ${method.responseEnvelope.name}{${method.responseEnvelope.result.fieldName}: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil\n`;
486
+ }
487
+ else {
488
+ if (go.isLROMethod(method)) {
489
+ text += '\treturn httpResp, nil\n';
490
+ }
491
+ else if (needsResponseHandler(method)) {
492
+ // also cheating here as at present the only param to the responder is an http.Response
493
+ text += `\tresp, err := client.${method.naming.responseMethod}(httpResp)\n`;
494
+ text += '\treturn resp, err\n';
495
+ }
496
+ else if (method.responseEnvelope.result && go.isBinaryResult(method.responseEnvelope.result)) {
497
+ text += `\treturn ${method.responseEnvelope.name}{${method.responseEnvelope.result.fieldName}: httpResp.Body}, nil\n`;
498
+ }
499
+ else {
500
+ text += `\treturn ${method.responseEnvelope.name}{}, nil\n`;
501
+ }
502
+ }
503
+ text += '}\n\n';
504
+ return text;
505
+ }
506
+ function createProtocolRequest(azureARM, client, method, imports) {
507
+ var _a, _b;
508
+ let name = method.name;
509
+ if (go.isMethod(method)) {
510
+ name = method.naming.requestMethod;
511
+ }
512
+ for (const param of values(method.parameters)) {
513
+ if (param.location !== 'method' || !go.isRequiredParameter(param)) {
514
+ continue;
515
+ }
516
+ imports.addImportForType(param.type);
517
+ }
518
+ const returns = ['*policy.Request', 'error'];
519
+ let text = `${comment(name, '// ')} creates the ${method.name} request.\n`;
520
+ text += `func (client *${client.name}) ${name}(${helpers.getCreateRequestParametersSig(method)}) (${returns.join(', ')}) {\n`;
521
+ const hostParams = new Array();
522
+ for (const parameter of client.parameters) {
523
+ if (go.isURIParameter(parameter)) {
524
+ hostParams.push(parameter);
525
+ }
526
+ }
527
+ let hostParam;
528
+ if (azureARM) {
529
+ hostParam = 'client.internal.Endpoint()';
530
+ }
531
+ else if (client.templatedHost) {
532
+ imports.add('strings');
533
+ // we have a templated host
534
+ text += `\thost := "${client.host}"\n`;
535
+ // get all the host params on the client
536
+ for (const hostParam of hostParams) {
537
+ text += `\thost = strings.ReplaceAll(host, "{${hostParam.uriPathSegment}}", ${helpers.formatValue(`client.${hostParam.name}`, hostParam.type, imports)})\n`;
538
+ }
539
+ // check for any method local host params
540
+ for (const param of values(method.parameters)) {
541
+ if (param.location === 'method' && go.isURIParameter(param)) {
542
+ text += `\thost = strings.ReplaceAll(host, "{${param.uriPathSegment}}", ${helpers.formatValue(helpers.getParamName(param), param.type, imports)})\n`;
543
+ }
544
+ }
545
+ hostParam = 'host';
546
+ }
547
+ else if (hostParams.length === 1) {
548
+ // simple parameterized host case
549
+ hostParam = 'client.' + hostParams[0].name;
550
+ }
551
+ else if (client.host) {
552
+ // swagger defines a host, use its const
553
+ hostParam = '\thost';
554
+ }
555
+ else {
556
+ throw new Error(`no host or endpoint defined for method ${client.name}.${method.name}`);
557
+ }
558
+ const hasPathParams = values(method.parameters).where((each) => { return go.isPathParameter(each); }).any();
559
+ // storage needs the client.u to be the source-of-truth for the full path.
560
+ // however, swagger requires that all operations specify a path, which is at odds with storage.
561
+ // to work around this, storage specifies x-ms-path paths with path params but doesn't
562
+ // actually reference the path params (i.e. no params with which to replace the tokens).
563
+ // so, if a path contains tokens but there are no path params, skip emitting the path.
564
+ const pathStr = method.httpPath;
565
+ const pathContainsParms = pathStr.includes('{');
566
+ if (hasPathParams || (!pathContainsParms && pathStr.length > 1)) {
567
+ // there are path params, or the path doesn't contain tokens and is not "/" so emit it
568
+ text += `\turlPath := "${method.httpPath}"\n`;
569
+ hostParam = `runtime.JoinPaths(${hostParam}, urlPath)`;
570
+ }
571
+ if (hasPathParams) {
572
+ // swagger defines path params, emit path and replace tokens
573
+ imports.add('strings');
574
+ // replace path parameters
575
+ for (const pp of values(method.parameters)) {
576
+ if (!go.isPathParameter(pp)) {
577
+ continue;
578
+ }
579
+ // emit check to ensure path param isn't an empty string. we only need
580
+ // to do this for params that have an underlying type of string.
581
+ const choiceIsString = function (type) {
582
+ if (!go.isConstantType(type)) {
583
+ return false;
584
+ }
585
+ return type.type === 'string';
586
+ };
587
+ if (((go.isPrimitiveType(pp.type) && pp.type.typeName === 'string') || choiceIsString(pp.type)) && pp.isEncoded) {
588
+ const paramName = helpers.getParamName(pp);
589
+ imports.add('errors');
590
+ text += `\tif ${paramName} == "" {\n`;
591
+ text += `\t\treturn nil, errors.New("parameter ${paramName} cannot be empty")\n`;
592
+ text += '\t}\n';
593
+ }
594
+ let paramValue = helpers.formatParamValue(pp, imports);
595
+ if (pp.isEncoded) {
596
+ imports.add('net/url');
597
+ paramValue = `url.PathEscape(${helpers.formatParamValue(pp, imports)})`;
598
+ }
599
+ text += `\turlPath = strings.ReplaceAll(urlPath, "{${pp.pathSegment}}", ${paramValue})\n`;
600
+ }
601
+ }
602
+ text += `\treq, err := runtime.NewRequest(ctx, http.Method${capitalize(method.httpMethod)}, ${hostParam})\n`;
603
+ text += '\tif err != nil {\n';
604
+ text += '\t\treturn nil, err\n';
605
+ text += '\t}\n';
606
+ // helper to build nil checks for param groups
607
+ const emitParamGroupCheck = function (param) {
608
+ if (!param.group) {
609
+ throw new Error(`emitParamGroupCheck called for ungrouped parameter ${param.name}`);
610
+ }
611
+ let client = '';
612
+ if (param.location === 'client') {
613
+ client = 'client.';
614
+ }
615
+ const paramGroupName = uncapitalize(param.group.name);
616
+ let optionalParamGroupCheck = `${client}${paramGroupName} != nil && `;
617
+ if (param.group.required) {
618
+ optionalParamGroupCheck = '';
619
+ }
620
+ return `\tif ${optionalParamGroupCheck}${client}${paramGroupName}.${capitalize(param.name)} != nil {\n`;
621
+ };
622
+ // add query parameters
623
+ const encodedParams = new Array();
624
+ const unencodedParams = new Array();
625
+ for (const qp of values(method.parameters)) {
626
+ if (!go.isQueryParameter(qp)) {
627
+ continue;
628
+ }
629
+ if (qp.isEncoded) {
630
+ encodedParams.push(qp);
631
+ }
632
+ else {
633
+ unencodedParams.push(qp);
634
+ }
635
+ }
636
+ const emitQueryParam = function (qp, setter) {
637
+ let qpText = '';
638
+ if (qp.location === 'method' && go.isClientSideDefault(qp.kind)) {
639
+ qpText = emitClientSideDefault(qp, qp.kind, (name, val) => { return `\treqQP.Set(${name}, ${val})`; }, imports);
640
+ }
641
+ else if (go.isRequiredParameter(qp) || go.isLiteralParameter(qp) || (qp.location === 'client' && go.isClientSideDefault(qp.kind))) {
642
+ qpText = `\t${setter}\n`;
643
+ }
644
+ else if (qp.location === 'client' && !qp.group) {
645
+ // global optional param
646
+ qpText = `\tif client.${qp.name} != nil {\n`;
647
+ qpText += `\t\t${setter}\n`;
648
+ qpText += '\t}\n';
649
+ }
650
+ else {
651
+ qpText = emitParamGroupCheck(qp);
652
+ qpText += `\t\t${setter}\n`;
653
+ qpText += '\t}\n';
654
+ }
655
+ return qpText;
656
+ };
657
+ // emit encoded params first
658
+ if (encodedParams.length > 0) {
659
+ text += '\treqQP := req.Raw().URL.Query()\n';
660
+ for (const qp of values(encodedParams.sort((a, b) => { return helpers.sortAscending(a.queryParameter, b.queryParameter); }))) {
661
+ let setter;
662
+ if (go.isQueryCollectionParameter(qp) && qp.collectionFormat === 'multi') {
663
+ setter = `\tfor _, qv := range ${helpers.getParamName(qp)} {\n`;
664
+ // emit a type conversion for the qv based on the array's element type
665
+ let queryVal;
666
+ const arrayQP = qp.type;
667
+ if (go.isConstantType(arrayQP.elementType)) {
668
+ const ch = arrayQP.elementType;
669
+ // only string and number types are supported for enums
670
+ if (ch.type === 'string') {
671
+ queryVal = 'string(qv)';
672
+ }
673
+ else {
674
+ imports.add('fmt');
675
+ queryVal = 'fmt.Sprintf("%d", qv)';
676
+ }
677
+ }
678
+ else if (go.isPrimitiveType(arrayQP.elementType) && arrayQP.elementType.typeName === 'string') {
679
+ queryVal = 'qv';
680
+ }
681
+ else {
682
+ imports.add('fmt');
683
+ queryVal = 'fmt.Sprintf("%v", qv)';
684
+ }
685
+ setter += `\t\treqQP.Add("${qp.queryParameter}", ${queryVal})\n`;
686
+ setter += '\t}';
687
+ }
688
+ else {
689
+ // cannot initialize setter to this value as helpers.formatParamValue() can change imports
690
+ setter = `reqQP.Set("${qp.queryParameter}", ${helpers.formatParamValue(qp, imports)})`;
691
+ }
692
+ text += emitQueryParam(qp, setter);
693
+ }
694
+ text += '\treq.Raw().URL.RawQuery = reqQP.Encode()\n';
695
+ }
696
+ // tack on any unencoded params to the end
697
+ if (unencodedParams.length > 0) {
698
+ if (encodedParams.length > 0) {
699
+ text += '\tunencodedParams := []string{req.Raw().URL.RawQuery}\n';
700
+ }
701
+ else {
702
+ text += '\tunencodedParams := []string{}\n';
703
+ }
704
+ for (const qp of values(unencodedParams.sort((a, b) => { return helpers.sortAscending(a.queryParameter, b.queryParameter); }))) {
705
+ let setter;
706
+ if (go.isQueryCollectionParameter(qp) && qp.collectionFormat === 'multi') {
707
+ setter = `\tfor _, qv := range ${helpers.getParamName(qp)} {\n`;
708
+ setter += `\t\tunencodedParams = append(unencodedParams, "${qp.queryParameter}="+qv)\n`;
709
+ setter += '\t}';
710
+ }
711
+ else {
712
+ setter = `unencodedParams = append(unencodedParams, "${qp.queryParameter}="+${helpers.formatParamValue(qp, imports)})`;
713
+ }
714
+ text += emitQueryParam(qp, setter);
715
+ }
716
+ imports.add('strings');
717
+ text += '\treq.Raw().URL.RawQuery = strings.Join(unencodedParams, "&")\n';
718
+ }
719
+ if (go.isMethod(method) && method.responseEnvelope.result && go.isBinaryResult(method.responseEnvelope.result)) {
720
+ // skip auto-body downloading for binary stream responses
721
+ text += '\truntime.SkipBodyDownload(req)\n';
722
+ }
723
+ // add specific request headers
724
+ const emitHeaderSet = function (headerParam, prefix) {
725
+ if (headerParam.location === 'method' && go.isClientSideDefault(headerParam.kind)) {
726
+ return emitClientSideDefault(headerParam, headerParam.kind, (name, val) => {
727
+ return `${prefix}req.Raw().Header[${name}] = []string{${val}}`;
728
+ }, imports);
729
+ }
730
+ else if (go.isHeaderMapParameter(headerParam)) {
731
+ let headerText = `${prefix}for k, v := range ${helpers.getParamName(headerParam)} {\n`;
732
+ headerText += `${prefix}\tif v != nil {\n`;
733
+ headerText += `${prefix}\t\treq.Raw().Header["${headerParam.collectionPrefix}"+k] = []string{*v}\n`;
734
+ headerText += `${prefix}}\n`;
735
+ headerText += `${prefix}}\n`;
736
+ return headerText;
737
+ }
738
+ else {
739
+ return `${prefix}req.Raw().Header["${headerParam.headerName}"] = []string{${helpers.formatParamValue(headerParam, imports)}}\n`;
740
+ }
741
+ };
742
+ const headerParams = new Array();
743
+ for (const param of values(method.parameters)) {
744
+ if (go.isHeaderParameter(param)) {
745
+ headerParams.push(param);
746
+ }
747
+ }
748
+ for (const param of headerParams.sort((a, b) => { return helpers.sortAscending(a.headerName, b.headerName); })) {
749
+ if (param.headerName.match(/^content-type$/)) {
750
+ // canonicalize content-type as req.SetBody checks for it via its canonicalized name :(
751
+ param.headerName = 'Content-Type';
752
+ }
753
+ if (go.isRequiredParameter(param) || go.isLiteralParameter(param) || go.isClientSideDefault(param.kind)) {
754
+ text += emitHeaderSet(param, '\t');
755
+ }
756
+ else if (param.location === 'client' && !param.group) {
757
+ // global optional param
758
+ text += `\tif client.${param.name} != nil {\n`;
759
+ text += emitHeaderSet(param, '\t');
760
+ text += '\t}\n';
761
+ }
762
+ else {
763
+ text += emitParamGroupCheck(param);
764
+ text += emitHeaderSet(param, '\t\t');
765
+ text += '\t}\n';
766
+ }
767
+ }
768
+ const partialBodyParams = values(method.parameters).where((param) => { return go.isPartialBodyParameter(param); }).toArray();
769
+ const bodyParam = values(method.parameters).where((each) => { return go.isBodyParameter(each) || go.isFormBodyParameter(each) || go.isMultipartFormBodyParameter(each); }).first();
770
+ const emitSetBodyWithErrCheck = function (setBodyParam) {
771
+ return `if err := ${setBodyParam}; err != nil {\n\treturn nil, err\n}\n`;
772
+ };
773
+ if (partialBodyParams.length > 0) {
774
+ // partial body params are discrete params that are all fields within an internal struct.
775
+ // define and instantiate an instance of the wire type, using the values from each param.
776
+ text += '\tbody := struct {\n';
777
+ for (const partialBodyParam of partialBodyParams) {
778
+ text += `\t\t${capitalize(partialBodyParam.serializedName)} ${helpers.star(partialBodyParam)}${go.getTypeDeclaration(partialBodyParam.type)} \`${partialBodyParam.format.toLowerCase()}:"${partialBodyParam.serializedName}"\`\n`;
779
+ }
780
+ text += '\t}{\n';
781
+ for (const partialBodyParam of partialBodyParams) {
782
+ let addr = '&';
783
+ if (go.isRequiredParameter(partialBodyParam)) {
784
+ addr = '';
785
+ }
786
+ text += `\t\t${capitalize(partialBodyParam.serializedName)}: ${addr}${uncapitalize(partialBodyParam.name)},\n`;
787
+ }
788
+ text += '\t}\n\tif err := runtime.MarshalAsJSON(req, body); err != nil {\n\t\treturn nil, err\n\t}\n';
789
+ text += '\treturn req, nil\n';
790
+ }
791
+ else if (!bodyParam) {
792
+ text += '\treturn req, nil\n';
793
+ }
794
+ else if (bodyParam.bodyFormat === 'JSON' || bodyParam.bodyFormat === 'XML') {
795
+ // default to the body param name
796
+ let body = helpers.getParamName(bodyParam);
797
+ if (go.isLiteralValue(bodyParam.type)) {
798
+ // if the value is constant, embed it directly
799
+ body = helpers.formatLiteralValue(bodyParam.type, true);
800
+ }
801
+ else if (bodyParam.bodyFormat === 'XML' && go.isSliceType(bodyParam.type)) {
802
+ // for XML payloads, create a wrapper type if the payload is an array
803
+ imports.add('encoding/xml');
804
+ text += '\ttype wrapper struct {\n';
805
+ let tagName = go.getTypeDeclaration(bodyParam.type);
806
+ if ((_a = bodyParam.xml) === null || _a === void 0 ? void 0 : _a.name) {
807
+ tagName = bodyParam.xml.name;
808
+ }
809
+ text += `\t\tXMLName xml.Name \`xml:"${tagName}"\`\n`;
810
+ const fieldName = capitalize(bodyParam.name);
811
+ let tag = go.getTypeDeclaration(bodyParam.type.elementType);
812
+ if (go.isModelType(bodyParam.type.elementType) && ((_b = bodyParam.type.elementType.xml) === null || _b === void 0 ? void 0 : _b.name)) {
813
+ tag = bodyParam.type.elementType.xml.name;
814
+ }
815
+ text += `\t\t${fieldName} *${go.getTypeDeclaration(bodyParam.type)} \`xml:"${tag}"\`\n`;
816
+ text += '\t}\n';
817
+ let addr = '&';
818
+ if (!go.isRequiredParameter(bodyParam) && !bodyParam.byValue) {
819
+ addr = '';
820
+ }
821
+ body = `wrapper{${fieldName}: ${addr}${body}}`;
822
+ }
823
+ else if (go.isTimeType(bodyParam.type) && bodyParam.type.dateTimeFormat !== 'dateTimeRFC3339') {
824
+ // wrap the body in the internal time type
825
+ // no need for dateTimeRFC3339 as the JSON marshaler defaults to that.
826
+ body = `${bodyParam.type.dateTimeFormat}(${body})`;
827
+ }
828
+ else if (isArrayOfDateTimeForMarshalling(bodyParam.type)) {
829
+ const timeInfo = isArrayOfDateTimeForMarshalling(bodyParam.type);
830
+ let elementPtr = '*';
831
+ if (timeInfo === null || timeInfo === void 0 ? void 0 : timeInfo.elemByVal) {
832
+ elementPtr = '';
833
+ }
834
+ text += `\taux := make([]${elementPtr}${timeInfo === null || timeInfo === void 0 ? void 0 : timeInfo.format}, len(${body}))\n`;
835
+ text += `\tfor i := 0; i < len(${body}); i++ {\n`;
836
+ text += `\t\taux[i] = (${elementPtr}${timeInfo === null || timeInfo === void 0 ? void 0 : timeInfo.format})(${body}[i])\n`;
837
+ text += '\t}\n';
838
+ body = 'aux';
839
+ }
840
+ else if (isMapOfDateTime(bodyParam.type)) {
841
+ const timeType = isMapOfDateTime(bodyParam.type);
842
+ text += `\taux := map[string]*${timeType}{}\n`;
843
+ text += `\tfor k, v := range ${body} {\n`;
844
+ text += `\t\taux[k] = (*${timeType})(v)\n`;
845
+ text += '\t}\n';
846
+ body = 'aux';
847
+ }
848
+ let setBody = `runtime.MarshalAs${getMediaFormat(bodyParam.type, bodyParam.bodyFormat, `req, ${body}`)}`;
849
+ if (go.isSliceType(bodyParam.type) && bodyParam.type.rawJSONAsBytes) {
850
+ imports.add('bytes');
851
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming');
852
+ setBody = `req.SetBody(streaming.NopCloser(bytes.NewReader(${body})), "application/${bodyParam.bodyFormat.toLowerCase()}")`;
853
+ }
854
+ if (go.isRequiredParameter(bodyParam) || go.isLiteralParameter(bodyParam)) {
855
+ text += `\t${emitSetBodyWithErrCheck(setBody)}`;
856
+ text += '\treturn req, nil\n';
857
+ }
858
+ else {
859
+ text += emitParamGroupCheck(bodyParam);
860
+ text += `\t${emitSetBodyWithErrCheck(setBody)}`;
861
+ text += '\t\treturn req, nil\n';
862
+ text += '\t}\n';
863
+ text += '\treturn req, nil\n';
864
+ }
865
+ }
866
+ else if (bodyParam.bodyFormat === 'binary') {
867
+ if (go.isRequiredParameter(bodyParam)) {
868
+ text += `\t${emitSetBodyWithErrCheck(`req.SetBody(${bodyParam.name}, ${bodyParam.contentType})`)}`;
869
+ text += '\treturn req, nil\n';
870
+ }
871
+ else {
872
+ text += emitParamGroupCheck(bodyParam);
873
+ text += `\t${emitSetBodyWithErrCheck(`req.SetBody(${helpers.getParamName(bodyParam)}, ${bodyParam.contentType})`)}`;
874
+ text += '\treturn req, nil\n';
875
+ text += '\t}\n';
876
+ text += '\treturn req, nil\n';
877
+ }
878
+ }
879
+ else if (bodyParam.bodyFormat === 'Text') {
880
+ imports.add('strings');
881
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming');
882
+ const bodyParam = values(method.parameters).where((each) => { return go.isBodyParameter(each); }).first();
883
+ if (go.isRequiredParameter(bodyParam)) {
884
+ text += `\tbody := streaming.NopCloser(strings.NewReader(${bodyParam.name}))\n`;
885
+ text += `\t${emitSetBodyWithErrCheck(`req.SetBody(body, ${bodyParam.contentType})`)}`;
886
+ text += '\treturn req, nil\n';
887
+ }
888
+ else {
889
+ text += emitParamGroupCheck(bodyParam);
890
+ text += `\tbody := streaming.NopCloser(strings.NewReader(${helpers.getParamName(bodyParam)}))\n`;
891
+ text += `\t${emitSetBodyWithErrCheck(`req.SetBody(body, ${bodyParam.contentType})`)}`;
892
+ text += '\treturn req, nil\n';
893
+ text += '\t}\n';
894
+ text += '\treturn req, nil\n';
895
+ }
896
+ }
897
+ else if (go.isMultipartFormBodyParameter(bodyParam)) {
898
+ if (go.isModelType(bodyParam.type) && bodyParam.type.annotations.multipartFormData) {
899
+ text += `\tformData, err := ${bodyParam.name}.toMultipartFormData()\n`;
900
+ text += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
901
+ }
902
+ else {
903
+ text += '\tformData := map[string]any{}\n';
904
+ for (const param of values(method.parameters)) {
905
+ if (!go.isMultipartFormBodyParameter(param)) {
906
+ continue;
907
+ }
908
+ const setter = `formData["${param.name}"] = ${helpers.getParamName(param)}`;
909
+ if (go.isRequiredParameter(param)) {
910
+ text += `\t${setter}\n`;
911
+ }
912
+ else {
913
+ text += emitParamGroupCheck(param);
914
+ text += `\t${setter}\n\t}\n`;
915
+ }
916
+ }
917
+ }
918
+ text += '\tif err := runtime.SetMultipartFormData(req, formData); err != nil {\n\t\treturn nil, err\n\t}\n';
919
+ text += '\treturn req, nil\n';
920
+ }
921
+ else if (go.isFormBodyParameter(bodyParam)) {
922
+ const emitFormData = function (param, setter) {
923
+ let formDataText = '';
924
+ if (go.isRequiredParameter(param)) {
925
+ formDataText = `\t${setter}\n`;
926
+ }
927
+ else {
928
+ formDataText = emitParamGroupCheck(param);
929
+ formDataText += `\t\t${setter}\n`;
930
+ formDataText += '\t}\n';
931
+ }
932
+ return formDataText;
933
+ };
934
+ imports.add('net/url');
935
+ imports.add('strings');
936
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming');
937
+ text += '\tformData := url.Values{}\n';
938
+ // find all the form body params
939
+ for (const param of values(method.parameters)) {
940
+ if (go.isFormBodyParameter(param)) {
941
+ const setter = `formData.Set("${param.formDataName}", ${helpers.formatParamValue(param, imports)})`;
942
+ text += emitFormData(param, setter);
943
+ }
944
+ }
945
+ text += '\tbody := streaming.NopCloser(strings.NewReader(formData.Encode()))\n';
946
+ text += `\t${emitSetBodyWithErrCheck('req.SetBody(body, "application/x-www-form-urlencoded")')}`;
947
+ text += '\treturn req, nil\n';
948
+ }
949
+ else {
950
+ text += '\treturn req, nil\n';
951
+ }
952
+ text += '}\n\n';
953
+ return text;
954
+ }
955
+ function emitClientSideDefault(param, csd, setterFormat, imports) {
956
+ const defaultVar = uncapitalize(param.name) + 'Default';
957
+ let text = `\t${defaultVar} := ${helpers.formatLiteralValue(csd.defaultValue, true)}\n`;
958
+ text += `\tif options != nil && options.${capitalize(param.name)} != nil {\n`;
959
+ text += `\t\t${defaultVar} = *options.${capitalize(param.name)}\n`;
960
+ text += '}\n';
961
+ let serializedName;
962
+ if (go.isHeaderParameter(param)) {
963
+ serializedName = param.headerName;
964
+ }
965
+ else {
966
+ serializedName = param.queryParameter;
967
+ }
968
+ text += setterFormat(`"${serializedName}"`, helpers.formatValue(defaultVar, param.type, imports)) + '\n';
969
+ return text;
970
+ }
971
+ function getMediaFormat(type, mediaType, param) {
972
+ let marshaller = mediaType;
973
+ let format = '';
974
+ if (go.isBytesType(type)) {
975
+ marshaller = 'ByteArray';
976
+ format = `, runtime.Base64${type.encoding}Format`;
977
+ }
978
+ return `${marshaller}(${param}${format})`;
979
+ }
980
+ function isArrayOfDateTimeForMarshalling(paramType) {
981
+ if (!go.isSliceType(paramType)) {
982
+ return undefined;
983
+ }
984
+ if (!go.isTimeType(paramType.elementType)) {
985
+ return undefined;
986
+ }
987
+ switch (paramType.elementType.dateTimeFormat) {
988
+ case 'dateType':
989
+ case 'dateTimeRFC1123':
990
+ case 'timeRFC3339':
991
+ case 'timeUnix':
992
+ return {
993
+ format: paramType.elementType.dateTimeFormat,
994
+ elemByVal: paramType.elementTypeByValue
995
+ };
996
+ default:
997
+ // dateTimeRFC3339 uses the default marshaller
998
+ return undefined;
999
+ }
1000
+ }
1001
+ // returns true if the method requires a response handler.
1002
+ // this is used to unmarshal the response body, parse response headers, or both.
1003
+ function needsResponseHandler(method) {
1004
+ return helpers.hasSchemaResponse(method) || method.responseEnvelope.headers.length > 0;
1005
+ }
1006
+ function generateResponseUnmarshaller(method, type, format, unmarshalTarget) {
1007
+ let unmarshallerText = '';
1008
+ const zeroValue = getZeroReturnValue(method, 'handler');
1009
+ if (go.isTimeType(type)) {
1010
+ // use the designated time type for unmarshalling
1011
+ unmarshallerText += `\tvar aux *${type.dateTimeFormat}\n`;
1012
+ unmarshallerText += `\tif err := runtime.UnmarshalAs${format}(resp, &aux); err != nil {\n`;
1013
+ unmarshallerText += `\t\treturn ${zeroValue}, err\n`;
1014
+ unmarshallerText += '\t}\n';
1015
+ unmarshallerText += `\tresult.${helpers.getResultFieldName(method)} = (*time.Time)(aux)\n`;
1016
+ return unmarshallerText;
1017
+ }
1018
+ else if (isArrayOfDateTime(type)) {
1019
+ // unmarshalling arrays of date/time is a little more involved
1020
+ const timeInfo = isArrayOfDateTime(type);
1021
+ let elementPtr = '*';
1022
+ if (timeInfo === null || timeInfo === void 0 ? void 0 : timeInfo.elemByVal) {
1023
+ elementPtr = '';
1024
+ }
1025
+ unmarshallerText += `\tvar aux []${elementPtr}${timeInfo === null || timeInfo === void 0 ? void 0 : timeInfo.format}\n`;
1026
+ unmarshallerText += `\tif err := runtime.UnmarshalAs${format}(resp, &aux); err != nil {\n`;
1027
+ unmarshallerText += `\t\treturn ${zeroValue}, err\n`;
1028
+ unmarshallerText += '\t}\n';
1029
+ unmarshallerText += `\tcp := make([]${elementPtr}time.Time, len(aux))\n`;
1030
+ unmarshallerText += '\tfor i := 0; i < len(aux); i++ {\n';
1031
+ unmarshallerText += `\t\tcp[i] = (${elementPtr}time.Time)(aux[i])\n`;
1032
+ unmarshallerText += '\t}\n';
1033
+ unmarshallerText += `\tresult.${helpers.getResultFieldName(method)} = cp\n`;
1034
+ return unmarshallerText;
1035
+ }
1036
+ else if (isMapOfDateTime(type)) {
1037
+ unmarshallerText += `\taux := map[string]*${isMapOfDateTime(type)}{}\n`;
1038
+ unmarshallerText += `\tif err := runtime.UnmarshalAs${format}(resp, &aux); err != nil {\n`;
1039
+ unmarshallerText += `\t\treturn ${zeroValue}, err\n`;
1040
+ unmarshallerText += '\t}\n';
1041
+ unmarshallerText += '\tcp := map[string]*time.Time{}\n';
1042
+ unmarshallerText += '\tfor k, v := range aux {\n';
1043
+ unmarshallerText += '\t\tcp[k] = (*time.Time)(v)\n';
1044
+ unmarshallerText += '\t}\n';
1045
+ unmarshallerText += `\tresult.${helpers.getResultFieldName(method)} = cp\n`;
1046
+ return unmarshallerText;
1047
+ }
1048
+ if (format === 'JSON' || format === 'XML') {
1049
+ if (go.isSliceType(type) && type.rawJSONAsBytes) {
1050
+ unmarshallerText += '\tbody, err := runtime.Payload(resp)\n';
1051
+ unmarshallerText += '\tif err != nil {\n';
1052
+ unmarshallerText += `\t\treturn ${zeroValue}, err\n`;
1053
+ unmarshallerText += '\t}\n';
1054
+ unmarshallerText += `\t${unmarshalTarget} = body\n`;
1055
+ }
1056
+ else {
1057
+ unmarshallerText += `\tif err := runtime.UnmarshalAs${getMediaFormat(type, format, `resp, &${unmarshalTarget}`)}; err != nil {\n`;
1058
+ unmarshallerText += `\t\treturn ${zeroValue}, err\n`;
1059
+ unmarshallerText += '\t}\n';
1060
+ }
1061
+ }
1062
+ else if (format === 'Text') {
1063
+ unmarshallerText += '\tbody, err := runtime.Payload(resp)\n';
1064
+ unmarshallerText += '\tif err != nil {\n';
1065
+ unmarshallerText += `\t\treturn ${zeroValue}, err\n`;
1066
+ unmarshallerText += '\t}\n';
1067
+ unmarshallerText += '\ttxt := string(body)\n';
1068
+ unmarshallerText += `\t${unmarshalTarget} = &txt\n`;
1069
+ }
1070
+ else {
1071
+ // the remaining formats should have been handled elsewhere
1072
+ throw new Error(`unhandled format ${format} for operation ${method.client.name}.${method.name}`);
1073
+ }
1074
+ return unmarshallerText;
1075
+ }
1076
+ function createProtocolResponse(client, method, imports) {
1077
+ if (!needsResponseHandler(method)) {
1078
+ return '';
1079
+ }
1080
+ const name = method.naming.responseMethod;
1081
+ let text = `${comment(name, '// ')} handles the ${method.name} response.\n`;
1082
+ text += `func (client *${client.name}) ${name}(resp *http.Response) (${generateReturnsInfo(method, 'handler').join(', ')}) {\n`;
1083
+ const addHeaders = function (headers) {
1084
+ for (const header of values(headers)) {
1085
+ text += formatHeaderResponseValue(header, imports, 'result', `${method.responseEnvelope.name}{}`);
1086
+ }
1087
+ };
1088
+ const result = method.responseEnvelope.result;
1089
+ if (!result) {
1090
+ // only headers
1091
+ text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1092
+ addHeaders(method.responseEnvelope.headers);
1093
+ }
1094
+ else if (go.isAnyResult(result)) {
1095
+ imports.add('fmt');
1096
+ text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1097
+ addHeaders(method.responseEnvelope.headers);
1098
+ text += '\tswitch resp.StatusCode {\n';
1099
+ for (const statusCode of method.httpStatusCodes) {
1100
+ text += `\tcase ${helpers.formatStatusCodes([statusCode])}:\n`;
1101
+ const resultType = result.httpStatusCodeType[statusCode];
1102
+ if (!resultType) {
1103
+ // the operation contains a mix of schemas and non-schema responses
1104
+ continue;
1105
+ }
1106
+ text += `\tvar val ${go.getTypeDeclaration(resultType)}\n`;
1107
+ text += generateResponseUnmarshaller(method, resultType, result.format, 'val');
1108
+ text += '\tresult.Value = val\n';
1109
+ }
1110
+ text += '\tdefault:\n';
1111
+ text += `\t\treturn ${getZeroReturnValue(method, 'handler')}, fmt.Errorf("unhandled HTTP status code %d", resp.StatusCode)\n`;
1112
+ text += '\t}\n';
1113
+ }
1114
+ else if (go.isBinaryResult(result)) {
1115
+ text += `\tresult := ${method.responseEnvelope.name}{${result.fieldName}: resp.Body}\n`;
1116
+ addHeaders(method.responseEnvelope.headers);
1117
+ }
1118
+ else if (go.isHeadAsBooleanResult(result)) {
1119
+ text += `\tresult := ${method.responseEnvelope.name}{${result.fieldName}: resp.StatusCode >= 200 && resp.StatusCode < 300}\n`;
1120
+ addHeaders(method.responseEnvelope.headers);
1121
+ }
1122
+ else if (go.isMonomorphicResult(result)) {
1123
+ text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1124
+ addHeaders(method.responseEnvelope.headers);
1125
+ let target = `result.${helpers.getResultFieldName(method)}`;
1126
+ // when unmarshalling a wrapped XML array, unmarshal into the response envelope
1127
+ if (result.format === 'XML' && go.isSliceType(result.monomorphicType)) {
1128
+ target = 'result';
1129
+ }
1130
+ text += generateResponseUnmarshaller(method, result.monomorphicType, result.format, target);
1131
+ }
1132
+ else if (go.isPolymorphicResult(result)) {
1133
+ text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1134
+ addHeaders(method.responseEnvelope.headers);
1135
+ text += generateResponseUnmarshaller(method, result.interfaceType, result.format, 'result');
1136
+ }
1137
+ else if (go.isModelResult(result)) {
1138
+ text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1139
+ addHeaders(method.responseEnvelope.headers);
1140
+ text += generateResponseUnmarshaller(method, result.modelType, result.format, `result.${helpers.getResultFieldName(method)}`);
1141
+ }
1142
+ else {
1143
+ throw new Error(`unhandled result type for ${client.name}.${method.name}`);
1144
+ }
1145
+ text += '\treturn result, nil\n';
1146
+ text += '}\n\n';
1147
+ return text;
1148
+ }
1149
+ function isArrayOfDateTime(paramType) {
1150
+ if (!go.isSliceType(paramType)) {
1151
+ return undefined;
1152
+ }
1153
+ if (!go.isTimeType(paramType.elementType)) {
1154
+ return undefined;
1155
+ }
1156
+ return {
1157
+ format: paramType.elementType.dateTimeFormat,
1158
+ elemByVal: paramType.elementTypeByValue
1159
+ };
1160
+ }
1161
+ function isMapOfDateTime(paramType) {
1162
+ if (!go.isMapType(paramType)) {
1163
+ return undefined;
1164
+ }
1165
+ if (!go.isTimeType(paramType.valueType)) {
1166
+ return undefined;
1167
+ }
1168
+ return paramType.valueType.dateTimeFormat;
1169
+ }
1170
+ // returns the parameters for the public API
1171
+ // e.g. "ctx context.Context, i int, s string"
1172
+ function getAPIParametersSig(method, imports, pkgName) {
1173
+ const methodParams = helpers.getMethodParameters(method);
1174
+ const params = new Array();
1175
+ if (!go.isPageableMethod(method) || go.isLROMethod(method)) {
1176
+ imports.add('context');
1177
+ params.push('ctx context.Context');
1178
+ }
1179
+ for (const methodParam of values(methodParams)) {
1180
+ params.push(`${uncapitalize(methodParam.name)} ${helpers.formatParameterTypeName(methodParam, pkgName)}`);
1181
+ }
1182
+ return params.join(', ');
1183
+ }
1184
+ // returns the return signature where each entry is the type name
1185
+ // e.g. [ '*string', 'error' ]
1186
+ // apiType describes where the return sig is used.
1187
+ // api - for the API definition
1188
+ // op - for the operation
1189
+ // handler - for the response handler
1190
+ function generateReturnsInfo(method, apiType) {
1191
+ let returnType = method.responseEnvelope.name;
1192
+ if (go.isLROMethod(method)) {
1193
+ switch (apiType) {
1194
+ case 'api':
1195
+ if (go.isPageableMethod(method)) {
1196
+ returnType = `*runtime.Poller[*runtime.Pager[${returnType}]]`;
1197
+ }
1198
+ else {
1199
+ returnType = `*runtime.Poller[${returnType}]`;
1200
+ }
1201
+ break;
1202
+ case 'handler':
1203
+ // we only have a handler for operations that return a schema
1204
+ if (!go.isPageableMethod(method)) {
1205
+ throw new Error(`handler being generated for non-pageable LRO ${method.name} which is unexpected`);
1206
+ }
1207
+ break;
1208
+ case 'op':
1209
+ returnType = '*http.Response';
1210
+ break;
1211
+ }
1212
+ }
1213
+ else if (go.isPageableMethod(method)) {
1214
+ switch (apiType) {
1215
+ case 'api':
1216
+ case 'op':
1217
+ // pager operations don't return an error
1218
+ return [`*runtime.Pager[${returnType}]`];
1219
+ }
1220
+ }
1221
+ return [returnType, 'error'];
1222
+ }
1223
+ function generateLROBeginMethod(client, method, imports, injectSpans, generateFakes) {
1224
+ const params = getAPIParametersSig(method, imports);
1225
+ const returns = generateReturnsInfo(method, 'api');
1226
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
1227
+ let text = '';
1228
+ if (method.description) {
1229
+ text += `${comment(`${fixUpMethodName(method)} - ${method.description}`, '//', undefined, helpers.commentLength)}\n`;
1230
+ text += genRespErrorDoc(method);
1231
+ text += genApiVersionDoc(method.apiVersions);
1232
+ }
1233
+ const zeroResp = getZeroReturnValue(method, 'api');
1234
+ const methodParams = helpers.getMethodParameters(method);
1235
+ for (const param of values(methodParams)) {
1236
+ if (param.description) {
1237
+ text += `${helpers.formatCommentAsBulletItem(`${param.name} - ${param.description}`)}\n`;
1238
+ }
1239
+ }
1240
+ text += `func (client *${client.name}) ${fixUpMethodName(method)}(${params}) (${returns.join(', ')}) {\n`;
1241
+ let pollerType = 'nil';
1242
+ let pollerTypeParam = `[${method.responseEnvelope.name}]`;
1243
+ if (go.isPageableMethod(method)) {
1244
+ // for paged LROs, we construct a pager and pass it to the LRO ctor.
1245
+ pollerTypeParam = `[*runtime.Pager${pollerTypeParam}]`;
1246
+ pollerType = '&pager';
1247
+ text += '\tpager := ';
1248
+ text += emitPagerDefinition(client, method, imports, injectSpans, generateFakes);
1249
+ }
1250
+ text += '\tif options == nil || options.ResumeToken == "" {\n';
1251
+ // creating the poller from response branch
1252
+ const opName = method.naming.internalMethod;
1253
+ text += `\t\tresp, err := client.${opName}(${helpers.getCreateRequestParameters(method)})\n`;
1254
+ text += '\t\tif err != nil {\n';
1255
+ text += `\t\t\treturn ${zeroResp}, err\n`;
1256
+ text += '\t\t}\n';
1257
+ let finalStateVia = '';
1258
+ // LRO operation might have a special configuration set in x-ms-long-running-operation-options
1259
+ // which indicates a specific url to perform the final Get operation on
1260
+ if (method.finalStateVia) {
1261
+ switch (method.finalStateVia) {
1262
+ case 'azure-async-operation':
1263
+ finalStateVia = 'runtime.FinalStateViaAzureAsyncOp';
1264
+ break;
1265
+ case 'location':
1266
+ finalStateVia = 'runtime.FinalStateViaLocation';
1267
+ break;
1268
+ case 'original-uri':
1269
+ finalStateVia = 'runtime.FinalStateViaOriginalURI';
1270
+ break;
1271
+ case 'operation-location':
1272
+ finalStateVia = 'runtime.FinalStateViaOpLocation';
1273
+ break;
1274
+ default:
1275
+ throw new Error(`unhandled final-state-via value ${finalStateVia}`);
1276
+ }
1277
+ }
1278
+ text += '\t\tpoller, err := runtime.NewPoller';
1279
+ if (finalStateVia === '' && pollerType === 'nil' && !injectSpans) {
1280
+ // the generic type param is redundant when it's also specified in the
1281
+ // options struct so we only include it when there's no options.
1282
+ text += pollerTypeParam;
1283
+ }
1284
+ text += '(resp, client.internal.Pipeline(), ';
1285
+ if (finalStateVia === '' && pollerType === 'nil' && !injectSpans) {
1286
+ // no options
1287
+ text += 'nil)\n';
1288
+ }
1289
+ else {
1290
+ // at least one option
1291
+ text += `&runtime.NewPollerOptions${pollerTypeParam}{\n`;
1292
+ if (finalStateVia !== '') {
1293
+ text += `\t\t\tFinalStateVia: ${finalStateVia},\n`;
1294
+ }
1295
+ if (pollerType !== 'nil') {
1296
+ text += `\t\t\tResponse: ${pollerType},\n`;
1297
+ }
1298
+ if (injectSpans) {
1299
+ text += '\t\t\tTracer: client.internal.Tracer(),\n';
1300
+ }
1301
+ text += '\t\t})\n';
1302
+ }
1303
+ text += '\t\treturn poller, err\n';
1304
+ text += '\t} else {\n';
1305
+ // creating the poller from resume token branch
1306
+ text += '\t\treturn runtime.NewPollerFromResumeToken';
1307
+ if (pollerType === 'nil' && !injectSpans) {
1308
+ text += pollerTypeParam;
1309
+ }
1310
+ text += '(options.ResumeToken, client.internal.Pipeline(), ';
1311
+ if (pollerType === 'nil' && !injectSpans) {
1312
+ text += 'nil)\n';
1313
+ }
1314
+ else {
1315
+ text += `&runtime.NewPollerFromResumeTokenOptions${pollerTypeParam}{\n`;
1316
+ if (pollerType !== 'nil') {
1317
+ text += `\t\t\tResponse: ${pollerType},\n`;
1318
+ }
1319
+ if (injectSpans) {
1320
+ text += '\t\t\tTracer: client.internal.Tracer(),\n';
1321
+ }
1322
+ text += '\t\t})\n';
1323
+ }
1324
+ text += '\t}\n';
1325
+ text += '}\n\n';
1326
+ return text;
1327
+ }
1328
+ export function fixUpMethodName(method) {
1329
+ if (go.isLROMethod(method)) {
1330
+ return `Begin${method.name}`;
1331
+ }
1332
+ else if (go.isPageableMethod(method)) {
1333
+ return `New${method.name}Pager`;
1334
+ }
1335
+ return method.name;
1336
+ }
1337
+ //# sourceMappingURL=operations.js.map