@azure-tools/typespec-go 0.10.6 → 0.11.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 (71) hide show
  1. package/dist/codegen.go/src/core/clientFactory.d.ts.map +1 -1
  2. package/dist/codegen.go/src/core/clientFactory.js +18 -15
  3. package/dist/codegen.go/src/core/clientFactory.js.map +1 -1
  4. package/dist/codegen.go/src/core/cloudConfig.d.ts.map +1 -1
  5. package/dist/codegen.go/src/core/cloudConfig.js +4 -3
  6. package/dist/codegen.go/src/core/cloudConfig.js.map +1 -1
  7. package/dist/codegen.go/src/core/constants.d.ts.map +1 -1
  8. package/dist/codegen.go/src/core/constants.js +6 -4
  9. package/dist/codegen.go/src/core/constants.js.map +1 -1
  10. package/dist/codegen.go/src/core/example.d.ts.map +1 -1
  11. package/dist/codegen.go/src/core/example.js +57 -52
  12. package/dist/codegen.go/src/core/example.js.map +1 -1
  13. package/dist/codegen.go/src/core/helpers.d.ts +27 -11
  14. package/dist/codegen.go/src/core/helpers.d.ts.map +1 -1
  15. package/dist/codegen.go/src/core/helpers.js +39 -15
  16. package/dist/codegen.go/src/core/helpers.js.map +1 -1
  17. package/dist/codegen.go/src/core/interfaces.d.ts.map +1 -1
  18. package/dist/codegen.go/src/core/interfaces.js +4 -3
  19. package/dist/codegen.go/src/core/interfaces.js.map +1 -1
  20. package/dist/codegen.go/src/core/models.d.ts.map +1 -1
  21. package/dist/codegen.go/src/core/models.js +304 -237
  22. package/dist/codegen.go/src/core/models.js.map +1 -1
  23. package/dist/codegen.go/src/core/operations.d.ts.map +1 -1
  24. package/dist/codegen.go/src/core/operations.js +585 -382
  25. package/dist/codegen.go/src/core/operations.js.map +1 -1
  26. package/dist/codegen.go/src/core/options.js +3 -2
  27. package/dist/codegen.go/src/core/options.js.map +1 -1
  28. package/dist/codegen.go/src/core/polymorphics.d.ts.map +1 -1
  29. package/dist/codegen.go/src/core/polymorphics.js +55 -48
  30. package/dist/codegen.go/src/core/polymorphics.js.map +1 -1
  31. package/dist/codegen.go/src/core/responses.d.ts.map +1 -1
  32. package/dist/codegen.go/src/core/responses.js +28 -19
  33. package/dist/codegen.go/src/core/responses.js.map +1 -1
  34. package/dist/codegen.go/src/core/version.d.ts.map +1 -1
  35. package/dist/codegen.go/src/core/version.js +3 -2
  36. package/dist/codegen.go/src/core/version.js.map +1 -1
  37. package/dist/codegen.go/src/fake/factory.d.ts.map +1 -1
  38. package/dist/codegen.go/src/fake/factory.js +2 -2
  39. package/dist/codegen.go/src/fake/factory.js.map +1 -1
  40. package/dist/codegen.go/src/fake/internal.js +1 -10
  41. package/dist/codegen.go/src/fake/internal.js.map +1 -1
  42. package/dist/codegen.go/src/fake/servers.d.ts.map +1 -1
  43. package/dist/codegen.go/src/fake/servers.js +316 -290
  44. package/dist/codegen.go/src/fake/servers.js.map +1 -1
  45. package/dist/codemodel.go/src/client.d.ts +37 -2
  46. package/dist/codemodel.go/src/client.d.ts.map +1 -1
  47. package/dist/codemodel.go/src/client.js +13 -0
  48. package/dist/codemodel.go/src/client.js.map +1 -1
  49. package/dist/codemodel.go/src/type.d.ts +7 -1
  50. package/dist/codemodel.go/src/type.d.ts.map +1 -1
  51. package/dist/codemodel.go/src/type.js +1 -0
  52. package/dist/codemodel.go/src/type.js.map +1 -1
  53. package/dist/naming.go/src/naming.d.ts.map +1 -1
  54. package/dist/naming.go/src/naming.js +2 -1
  55. package/dist/naming.go/src/naming.js.map +1 -1
  56. package/dist/typespec-go/src/tcgcadapter/adapter.d.ts.map +1 -1
  57. package/dist/typespec-go/src/tcgcadapter/adapter.js +1 -2
  58. package/dist/typespec-go/src/tcgcadapter/adapter.js.map +1 -1
  59. package/dist/typespec-go/src/tcgcadapter/clients.d.ts +8 -0
  60. package/dist/typespec-go/src/tcgcadapter/clients.d.ts.map +1 -1
  61. package/dist/typespec-go/src/tcgcadapter/clients.js +140 -67
  62. package/dist/typespec-go/src/tcgcadapter/clients.js.map +1 -1
  63. package/dist/typespec-go/src/tcgcadapter/helpers.d.ts +37 -1
  64. package/dist/typespec-go/src/tcgcadapter/helpers.d.ts.map +1 -1
  65. package/dist/typespec-go/src/tcgcadapter/helpers.js +82 -48
  66. package/dist/typespec-go/src/tcgcadapter/helpers.js.map +1 -1
  67. package/dist/typespec-go/src/tcgcadapter/types.d.ts +1 -0
  68. package/dist/typespec-go/src/tcgcadapter/types.d.ts.map +1 -1
  69. package/dist/typespec-go/src/tcgcadapter/types.js +55 -2
  70. package/dist/typespec-go/src/tcgcadapter/types.js.map +1 -1
  71. package/package.json +5 -5
@@ -58,6 +58,7 @@ export function generateServers(pkg, target) {
58
58
  let content;
59
59
  content = `// ${serverName} is a fake server for instances of the ${go.getTypeDeclaration(client, pkg)} type.\n`;
60
60
  content += `type ${serverName} struct{\n`;
61
+ const indent = new helpers.Indentation();
61
62
  // we might remove some operations from the list
62
63
  const finalMethods = new Array();
63
64
  let countLROs = 0;
@@ -71,8 +72,8 @@ export function generateServers(pkg, target) {
71
72
  continue;
72
73
  }
73
74
  const serverName = getServerName(clientAccessor.returns);
74
- content += `\t// ${serverName} contains the fakes for client ${clientAccessor.returns.name}\n`;
75
- content += `\t${serverName} ${serverName}\n\n`;
75
+ content += `${indent.get()}// ${serverName} contains the fakes for client ${clientAccessor.returns.name}\n`;
76
+ content += `${indent.get()}${serverName} ${serverName}\n\n`;
76
77
  finalSubClients.push(clientAccessor.returns);
77
78
  }
78
79
  for (const method of client.methods) {
@@ -98,7 +99,7 @@ export function generateServers(pkg, target) {
98
99
  break;
99
100
  }
100
101
  const operationName = fixUpMethodName(method);
101
- content += `\t// ${operationName} is the fake for method ${client.name}.${operationName}\n`;
102
+ content += `${indent.get()}// ${operationName} is the fake for method ${client.name}.${operationName}\n`;
102
103
  const successCodes = new Array();
103
104
  if (method.returns.result?.kind === 'anyResult') {
104
105
  for (const httpStatus of getMethodStatusCodes(method)) {
@@ -110,18 +111,18 @@ export function generateServers(pkg, target) {
110
111
  }
111
112
  successCodes.push(`${helpers.formatStatusCode(httpStatus)} (returns ${go.getTypeDeclaration(result, pkg)})`);
112
113
  }
113
- content += '\t// HTTP status codes to indicate success:\n';
114
+ content += `${indent.get()}// HTTP status codes to indicate success:\n`;
114
115
  for (const successCode of successCodes) {
115
- content += `\t// - ${successCode}\n`;
116
+ content += `${indent.get()}// - ${successCode}\n`;
116
117
  }
117
118
  }
118
119
  else {
119
120
  for (const statusCode of getMethodStatusCodes(method)) {
120
121
  successCodes.push(`${helpers.formatStatusCode(statusCode)}`);
121
122
  }
122
- content += `\t// HTTP status codes to indicate success: ${successCodes.join(', ')}\n`;
123
+ content += `${indent.get()}// HTTP status codes to indicate success: ${successCodes.join(', ')}\n`;
123
124
  }
124
- content += `\t${operationName} func(${getAPIParametersSig(pkg, method, imports)}) (${serverResponse})\n\n`;
125
+ content += `${indent.get()}${operationName} func(${getAPIParametersSig(pkg, method, imports)}) (${serverResponse})\n\n`;
125
126
  finalMethods.push(method);
126
127
  switch (method.kind) {
127
128
  case 'lroMethod':
@@ -141,10 +142,12 @@ export function generateServers(pkg, target) {
141
142
  content += "// azcore.ClientOptions.Transporter field in the client's constructor parameters.\n";
142
143
  content += `func New${serverTransport}(srv *${serverName}) *${serverTransport} {\n`;
143
144
  if (countLROs === 0 && countPagers === 0) {
144
- content += `\treturn &${serverTransport}{srv: srv}\n}\n\n`;
145
+ content += `${indent.get()}return &${serverTransport}{srv: srv}\n}\n\n`;
145
146
  }
146
147
  else {
147
- content += `\treturn &${serverTransport}{\n\t\tsrv: srv,\n`;
148
+ content += `${indent.get()}return &${serverTransport}{\n`;
149
+ indent.push();
150
+ content += `${indent.get()}srv: srv,\n`;
148
151
  for (const method of finalMethods) {
149
152
  let respType = go.getTypeDeclaration(method.returns, pkg);
150
153
  switch (method.kind) {
@@ -154,28 +157,29 @@ export function generateServers(pkg, target) {
154
157
  respType = `azfake.PagerResponder[${go.getTypeDeclaration(method.returns, pkg)}]`;
155
158
  }
156
159
  requiredHelpers.tracker = true;
157
- content += `\t\t${naming.uncapitalize(fixUpMethodName(method))}: newTracker[azfake.PollerResponder[${respType}]](),\n`;
160
+ content += `${indent.get()}${naming.uncapitalize(fixUpMethodName(method))}: newTracker[azfake.PollerResponder[${respType}]](),\n`;
158
161
  break;
159
162
  case 'pageableMethod':
160
163
  requiredHelpers.tracker = true;
161
- content += `\t\t${naming.uncapitalize(fixUpMethodName(method))}: newTracker[azfake.PagerResponder[${respType}]](),\n`;
164
+ content += `${indent.get()}${naming.uncapitalize(fixUpMethodName(method))}: newTracker[azfake.PagerResponder[${respType}]](),\n`;
162
165
  break;
163
166
  }
164
167
  }
165
- content += '\t}\n}\n\n';
168
+ indent.pop();
169
+ content += `${indent.get()}}\n}\n\n`;
166
170
  }
167
171
  content += `// ${serverTransport} connects instances of ${go.getTypeDeclaration(client, pkg)} to instances of ${serverName}.\n`;
168
172
  content += `// Don't use this type directly, use New${serverTransport} instead.\n`;
169
173
  content += `type ${serverTransport} struct {\n`;
170
- content += `\tsrv *${serverName}\n`;
174
+ content += `${indent.get()}srv *${serverName}\n`;
171
175
  // add server transports for client accessors
172
176
  if (finalSubClients.length > 0) {
173
177
  requiredHelpers.initServer = true;
174
178
  imports.add('sync');
175
- content += '\ttrMu sync.Mutex\n';
179
+ content += `${indent.get()}trMu sync.Mutex\n`;
176
180
  for (const subClient of finalSubClients) {
177
181
  const serverName = getServerName(subClient);
178
- content += `\ttr${serverName} *${serverName}Transport\n`;
182
+ content += `${indent.get()}tr${serverName} *${serverName}Transport\n`;
179
183
  }
180
184
  }
181
185
  for (const method of finalMethods) {
@@ -188,23 +192,23 @@ export function generateServers(pkg, target) {
188
192
  respType = `azfake.PagerResponder[${go.getTypeDeclaration(method.returns, pkg)}]`;
189
193
  }
190
194
  requiredHelpers.tracker = true;
191
- content += `\t${naming.uncapitalize(fixUpMethodName(method))} *tracker[azfake.PollerResponder[${respType}]]\n`;
195
+ content += `${indent.get()}${naming.uncapitalize(fixUpMethodName(method))} *tracker[azfake.PollerResponder[${respType}]]\n`;
192
196
  break;
193
197
  case 'pageableMethod':
194
198
  requiredHelpers.tracker = true;
195
- content += `\t${naming.uncapitalize(fixUpMethodName(method))} *tracker[azfake.PagerResponder[${go.getTypeDeclaration(method.returns, pkg)}]]\n`;
199
+ content += `${indent.get()}${naming.uncapitalize(fixUpMethodName(method))} *tracker[azfake.PagerResponder[${go.getTypeDeclaration(method.returns, pkg)}]]\n`;
196
200
  break;
197
201
  }
198
202
  }
199
203
  content += '}\n\n';
200
- content += generateServerTransportDo(serverTransport, client, finalSubClients, finalMethods);
201
- content += generateServerTransportClientDispatch(serverTransport, finalSubClients, imports);
202
- content += generateServerTransportMethodDispatch(serverTransport, client, finalMethods);
203
- content += generateServerTransportMethods(pkg, serverTransport, finalMethods, imports);
204
+ content += generateServerTransportDo(serverTransport, client, finalSubClients, finalMethods, indent);
205
+ content += generateServerTransportClientDispatch(serverTransport, finalSubClients, imports, indent);
206
+ content += generateServerTransportMethodDispatch(serverTransport, client, finalMethods, indent);
207
+ content += generateServerTransportMethods(pkg, serverTransport, finalMethods, imports, indent);
204
208
  content += `// set this to conditionally intercept incoming requests to ${serverTransport}\n`;
205
209
  content += `var ${getTransportInterceptorVarName(client)} interface {\n`;
206
- content += '\t// Do returns true if the server transport should use the returned response/error\n';
207
- content += '\tDo(*http.Request) (*http.Response, error, bool)\n}\n';
210
+ content += `${indent.get()}// Do returns true if the server transport should use the returned response/error\n`;
211
+ content += `${indent.get()}Do(*http.Request) (*http.Response, error, bool)\n}\n`;
208
212
  ///////////////////////////////////////////////////////////////////////////
209
213
  // stitch everything together
210
214
  let text = helpers.contentPreamble(pkg);
@@ -224,83 +228,93 @@ function getTransportInterceptorVarName(client) {
224
228
  // method names for fakes dispatching
225
229
  const dispatchMethodFake = 'dispatchToMethodFake';
226
230
  const dispatchToClientFake = 'dispatchToClientFake';
227
- function generateServerTransportDo(serverTransport, client, finalSubClients, finalMethods) {
231
+ function generateServerTransportDo(serverTransport, client, finalSubClients, finalMethods, indent) {
228
232
  const receiverName = serverTransport[0].toLowerCase();
229
233
  let content = `// Do implements the policy.Transporter interface for ${serverTransport}.\n`;
230
234
  content += `func (${receiverName} *${serverTransport}) Do(req *http.Request) (*http.Response, error) {\n`;
231
- content += '\trawMethod := req.Context().Value(runtime.CtxAPINameKey{})\n';
232
- content += '\tmethod, ok := rawMethod.(string)\n';
233
- content += '\tif !ok {\n\t\treturn nil, nonRetriableError{errors.New("unable to dispatch request, missing value for CtxAPINameKey")}\n\t}\n\n';
235
+ content += `${indent.get()}rawMethod := req.Context().Value(runtime.CtxAPINameKey{})\n`;
236
+ content += `${indent.get()}method, ok := rawMethod.(string)\n`;
237
+ content += `${indent.get()}if !ok {\n`;
238
+ content += `${indent.push().get()}return nil, nonRetriableError{errors.New("unable to dispatch request, missing value for CtxAPINameKey")}\n`;
239
+ content += `${indent.pop().get()}}\n\n`;
234
240
  if (finalSubClients.length > 0 && finalMethods.length > 0) {
235
241
  // client contains client accessors and methods.
236
242
  // if the method isn't for this client, dispatch to the correct client
237
- content += `\tif client := method[:strings.Index(method, ".")]; client != "${client.name}" {\n`;
238
- content += `\t\treturn ${receiverName}.${dispatchToClientFake}(req, client)\n\t}\n`;
243
+ content += `${indent.get()}if client := method[:strings.Index(method, ".")]; client != "${client.name}" {\n`;
244
+ content += `${indent.push().get()}return ${receiverName}.${dispatchToClientFake}(req, client)\n`;
245
+ content += `${indent.pop().get()}}\n`;
239
246
  // else dispatch to our method fakes
240
- content += `\treturn ${receiverName}.${dispatchMethodFake}(req, method)\n`;
247
+ content += `${indent.get()}return ${receiverName}.${dispatchMethodFake}(req, method)\n`;
241
248
  }
242
249
  else if (finalSubClients.length > 0) {
243
- content += `\treturn ${receiverName}.${dispatchToClientFake}(req, method[:strings.Index(method, ".")])\n`;
250
+ content += `${indent.get()}return ${receiverName}.${dispatchToClientFake}(req, method[:strings.Index(method, ".")])\n`;
244
251
  }
245
252
  else {
246
- content += `\treturn ${receiverName}.${dispatchMethodFake}(req, method)\n`;
253
+ content += `${indent.get()}return ${receiverName}.${dispatchMethodFake}(req, method)\n`;
247
254
  }
248
255
  content += '}\n\n'; // end Do
249
256
  return content;
250
257
  }
251
- function generateServerTransportClientDispatch(serverTransport, subClients, imports) {
258
+ function generateServerTransportClientDispatch(serverTransport, subClients, imports, indent) {
252
259
  if (subClients.length === 0) {
253
260
  return '';
254
261
  }
255
262
  const receiverName = serverTransport[0].toLowerCase();
256
263
  imports.add('strings');
257
264
  let content = `func (${receiverName} *${serverTransport}) ${dispatchToClientFake}(req *http.Request, client string) (*http.Response, error) {\n`;
258
- content += '\tvar resp *http.Response\n\tvar err error\n\n';
259
- content += '\tswitch client {\n';
265
+ content += `${indent.get()}var resp *http.Response\n${indent.get()}var err error\n\n`;
266
+ content += `${indent.get()}switch client {\n`;
260
267
  for (const subClient of subClients) {
261
- content += `\tcase "${subClient.name}":\n`;
268
+ content += `${indent.get()}case "${subClient.name}":\n`;
262
269
  const serverName = getServerName(subClient);
263
- content += `\t\tinitServer(&${receiverName}.trMu, &${receiverName}.tr${serverName}, func() *${serverName}Transport {\n\t\treturn New${serverName}Transport(&${receiverName}.srv.${serverName}) })\n`;
264
- content += `\t\tresp, err = ${receiverName}.tr${serverName}.Do(req)\n`;
270
+ indent.push();
271
+ content += `${indent.get()}initServer(&${receiverName}.trMu, &${receiverName}.tr${serverName}, func() *${serverName}Transport {\n`;
272
+ content += `${indent.get()}return New${serverName}Transport(&${receiverName}.srv.${serverName}) })\n`;
273
+ content += `${indent.get()}resp, err = ${receiverName}.tr${serverName}.Do(req)\n`;
274
+ indent.pop();
265
275
  }
266
- content += '\tdefault:\n\t\terr = fmt.Errorf("unhandled client %s", client)\n';
267
- content += '\t}\n\n'; // end switch
268
- content += '\treturn resp, err\n}\n\n';
276
+ content += `${indent.get()}default:\n`;
277
+ content += `${indent.push().get()}err = fmt.Errorf("unhandled client %s", client)\n`;
278
+ indent.pop();
279
+ content += `${indent.get()}}\n\n`; // end switch
280
+ content += `${indent.get()}return resp, err\n}\n\n`;
269
281
  return content;
270
282
  }
271
- function generateServerTransportMethodDispatch(serverTransport, client, finalMethods) {
283
+ function generateServerTransportMethodDispatch(serverTransport, client, finalMethods, indent) {
272
284
  if (finalMethods.length === 0) {
273
285
  return '';
274
286
  }
275
287
  const receiverName = serverTransport[0].toLowerCase();
276
288
  let content = `func (${receiverName} *${serverTransport}) ${dispatchMethodFake}(req *http.Request, method string) (*http.Response, error) {\n`;
277
- content += '\tresultChan := make(chan result)\n';
278
- content += '\tdefer close(resultChan)\n\n';
279
- content += '\tgo func() {\n\t\tvar intercepted bool\n\t\tvar res result\n';
289
+ content += `${indent.get()}resultChan := make(chan result, 1)\n`;
290
+ content += `${indent.get()}go func() {\n`;
291
+ indent.push();
292
+ content += `${indent.get()}var intercepted bool\n${indent.get()}var res result\n`;
280
293
  const interceptorVarName = getTransportInterceptorVarName(client);
281
- content += `\t\t if ${interceptorVarName} != nil {\n`;
282
- content += `\t\t\t res.resp, res.err, intercepted = ${interceptorVarName}.Do(req)\n\t\t}\n`;
283
- content += '\t\tif !intercepted {\n';
284
- content += '\t\t\tswitch method {\n';
294
+ content += `${indent.get()} if ${interceptorVarName} != nil {\n`;
295
+ content += `${indent.push().get()} res.resp, res.err, intercepted = ${interceptorVarName}.Do(req)\n`;
296
+ content += `${indent.pop().get()}}\n`;
297
+ content += `${indent.get()}if !intercepted {\n`;
298
+ indent.push();
299
+ content += `${indent.get()}switch method {\n`;
285
300
  for (const method of finalMethods) {
286
301
  const operationName = fixUpMethodName(method);
287
- content += `\t\t\tcase "${client.name}.${operationName}":\n`;
288
- content += `\t\t\t\tres.resp, res.err = ${receiverName}.dispatch${operationName}(req)\n`;
302
+ content += `${indent.get()}case "${client.name}.${operationName}":\n`;
303
+ content += `${indent.push().get()}res.resp, res.err = ${receiverName}.dispatch${operationName}(req)\n`;
304
+ indent.pop();
289
305
  }
290
- content += '\t\t\t\tdefault:\n\t\tres.err = fmt.Errorf("unhandled API %s", method)\n';
291
- content += '\t\t\t}\n\n'; // end switch
292
- content += '\t\t}\n'; // end if !intercepted
293
- content += '\t\tselect {\n';
294
- content += '\t\tcase resultChan <- res:\n';
295
- content += '\t\tcase <-req.Context().Done():\n';
296
- content += '\t\t}\n';
297
- content += '\t}()\n\n'; // end goroutine
298
- content += '\tselect {\n';
299
- content += '\tcase <-req.Context().Done():\n';
300
- content += '\t\treturn nil, req.Context().Err()\n';
301
- content += '\tcase res := <-resultChan:\n';
302
- content += '\t\treturn res.resp, res.err\n';
303
- content += '\t}\n}\n\n';
306
+ content += `${indent.push().get()}default:\n`;
307
+ content += `${indent.get()}res.err = fmt.Errorf("unhandled API %s", method)\n`;
308
+ content += `${indent.pop().get()}}\n\n`; // end switch
309
+ content += `${indent.pop().get()}}\n`; // end if !intercepted
310
+ content += `${indent.get()}resultChan <- res\n`;
311
+ content += `${indent.pop().get()}}()\n\n`; // end goroutine
312
+ content += `${indent.get()}select {\n`;
313
+ content += `${indent.get()}case <-req.Context().Done():\n`;
314
+ content += `${indent.push().get()}return nil, req.Context().Err()\n`;
315
+ content += `${indent.pop().get()}case res := <-resultChan:\n`;
316
+ content += `${indent.push().get()}return res.resp, res.err\n`;
317
+ content += `${indent.pop().get()}}\n}\n\n`;
304
318
  return content;
305
319
  }
306
320
  /**
@@ -310,61 +324,67 @@ function generateServerTransportMethodDispatch(serverTransport, client, finalMet
310
324
  * @param serverTransport the name of the server transport type
311
325
  * @param finalMethods the array of methods for which to generate the fake transports
312
326
  * @param imports the import manager currently in scope
327
+ * @param indent the indentation helper currently in scope
313
328
  * @returns the text for the server transport methods
314
329
  */
315
- function generateServerTransportMethods(pkg, serverTransport, finalMethods, imports) {
330
+ function generateServerTransportMethods(pkg, serverTransport, finalMethods, imports, indent) {
316
331
  if (finalMethods.length === 0) {
317
332
  return '';
318
333
  }
319
334
  imports.addForPkg(pkg.parent);
320
335
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/fake', 'azfake');
321
336
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/fake/server');
337
+ imports.add('slices');
322
338
  const receiverName = serverTransport[0].toLowerCase();
323
339
  let content = '';
324
340
  for (const method of finalMethods) {
325
341
  content += `func (${receiverName} *${serverTransport}) dispatch${fixUpMethodName(method)}(req *http.Request) (*http.Response, error) {\n`;
326
- content += `\tif ${receiverName}.srv.${fixUpMethodName(method)} == nil {\n`;
327
- content += `\t\treturn nil, &nonRetriableError{errors.New("fake for method ${fixUpMethodName(method)} not implemented")}\n\t}\n`;
342
+ content += `${indent.get()}if ${receiverName}.srv.${fixUpMethodName(method)} == nil {\n`;
343
+ content += `${indent.push().get()}return nil, &nonRetriableError{errors.New("fake for method ${fixUpMethodName(method)} not implemented")}\n`;
344
+ content += `${indent.pop().get()}}\n`;
328
345
  switch (method.kind) {
329
346
  case 'lroMethod':
330
347
  case 'lroPageableMethod':
331
348
  // must check LRO before pager as you can have paged LROs
332
- content += dispatchForLROBody(pkg, receiverName, method, imports);
349
+ content += dispatchForLROBody(pkg, receiverName, method, imports, indent);
333
350
  break;
334
351
  case 'method': {
335
- content += dispatchForOperationBody(pkg, receiverName, method, imports);
336
- content += '\trespContent := server.GetResponseContent(respr)\n';
352
+ content += dispatchForOperationBody(pkg, receiverName, method, imports, indent);
353
+ content += `${indent.get()}respContent := server.GetResponseContent(respr)\n`;
337
354
  const formattedStatusCodes = helpers.formatStatusCodes(method.httpStatusCodes);
338
- content += `\tif !contains([]int{${formattedStatusCodes}}, respContent.HTTPStatus) {\n`;
339
- content += `\t\treturn nil, &nonRetriableError{fmt.Errorf("unexpected status code %d. acceptable values are ${formattedStatusCodes}", respContent.HTTPStatus)}\n\t}\n`;
355
+ content += `${indent.get()}if !slices.Contains([]int{${formattedStatusCodes}}, respContent.HTTPStatus) {\n`;
356
+ content += `${indent.push().get()}return nil, &nonRetriableError{fmt.Errorf("unexpected status code %d. acceptable values are ${formattedStatusCodes}", respContent.HTTPStatus)}\n`;
357
+ content += `${indent.pop().get()}}\n`;
340
358
  if (!method.returns.result || method.returns.result.kind === 'headAsBooleanResult') {
341
- content += '\tresp, err := server.NewResponse(respContent, req, nil)\n';
359
+ content += `${indent.get()}resp, err := server.NewResponse(respContent, req, nil)\n`;
342
360
  }
343
361
  else if (method.returns.result.kind === 'anyResult') {
344
- content += `\tresp, err := server.MarshalResponseAs${method.returns.result.format}(respContent, server.GetResponse(respr).${getResultFieldName(method.returns.result)}, req)\n`;
362
+ content += `${indent.get()}resp, err := server.MarshalResponseAs${method.returns.result.format}(respContent, server.GetResponse(respr).${getResultFieldName(method.returns.result)}, req)\n`;
345
363
  }
346
364
  else if (method.returns.result.kind === 'binaryResult') {
347
- content += '\tresp, err := server.NewResponse(respContent, req, &server.ResponseOptions{\n';
348
- content += `\t\tBody: server.GetResponse(respr).${getResultFieldName(method.returns.result)},\n`;
349
- content += '\t\tContentType: req.Header.Get("Content-Type"),\n';
350
- content += '\t})\n';
365
+ content += `${indent.get()}resp, err := server.NewResponse(respContent, req, &server.ResponseOptions{\n`;
366
+ indent.push();
367
+ content += `${indent.get()}Body: server.GetResponse(respr).${getResultFieldName(method.returns.result)},\n`;
368
+ content += `${indent.get()}ContentType: req.Header.Get("Content-Type"),\n`;
369
+ content += `${indent.pop().get()}})\n`;
351
370
  }
352
371
  else if (method.returns.result.kind === 'monomorphicResult') {
353
372
  if (method.returns.result.monomorphicType.kind === 'encodedBytes') {
354
373
  const encoding = method.returns.result.monomorphicType.encoding;
355
- content += `\tresp, err := server.MarshalResponseAsByteArray(respContent, server.GetResponse(respr).${getResultFieldName(method.returns.result)}, runtime.Base64${encoding}Format, req)\n`;
374
+ content += `${indent.get()}resp, err := server.MarshalResponseAsByteArray(respContent, server.GetResponse(respr).${getResultFieldName(method.returns.result)}, runtime.Base64${encoding}Format, req)\n`;
356
375
  }
357
376
  else if (method.returns.result.monomorphicType.kind === 'rawJSON') {
358
377
  imports.add('bytes');
359
378
  imports.add('io');
360
- content += '\tresp, err := server.NewResponse(respContent, req, &server.ResponseOptions{\n';
361
- content += '\t\tBody: io.NopCloser(bytes.NewReader(server.GetResponse(respr).RawJSON)),\n';
362
- content += '\t\tContentType: "application/json",\n\t})\n';
379
+ content += `${indent.get()}resp, err := server.NewResponse(respContent, req, &server.ResponseOptions{\n`;
380
+ indent.push();
381
+ content += `${indent.get()}Body: io.NopCloser(bytes.NewReader(server.GetResponse(respr).RawJSON)),\n`;
382
+ content += `${indent.get()}ContentType: "application/json",\n`;
383
+ content += `${indent.pop().get()}})\n`;
363
384
  }
364
385
  else {
365
386
  let respField = `.${getResultFieldName(method.returns.result)}`;
366
387
  if (method.returns.result.format === 'XML' && method.returns.result.monomorphicType.kind === 'slice') {
367
- // for XML array responses we use the response type directly as it has the necessary XML tag for proper marshalling
368
388
  respField = '';
369
389
  }
370
390
  let responseField = `server.GetResponse(respr)${respField}`;
@@ -372,34 +392,37 @@ function generateServerTransportMethods(pkg, serverTransport, finalMethods, impo
372
392
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime');
373
393
  responseField = `(*datetime.${method.returns.result.monomorphicType.format})(${responseField})`;
374
394
  }
375
- content += `\tresp, err := server.MarshalResponseAs${method.returns.result.format}(respContent, ${responseField}, req)\n`;
395
+ content += `${indent.get()}resp, err := server.MarshalResponseAs${method.returns.result.format}(respContent, ${responseField}, req)\n`;
376
396
  }
377
397
  }
378
398
  else if (method.returns.result.kind === 'modelResult' || method.returns.result.kind === 'polymorphicResult') {
379
399
  const respField = `.${getResultFieldName(method.returns.result)}`;
380
400
  const responseField = `server.GetResponse(respr)${respField}`;
381
- content += `\tresp, err := server.MarshalResponseAs${method.returns.result.format}(respContent, ${responseField}, req)\n`;
401
+ content += `${indent.get()}resp, err := server.MarshalResponseAs${method.returns.result.format}(respContent, ${responseField}, req)\n`;
382
402
  }
383
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
403
+ content += `${indent.get()}if err != nil {\n`;
404
+ content += `${indent.push().get()}return nil, err\n`;
405
+ content += `${indent.pop().get()}}\n`;
384
406
  // propagate any header response values into the *http.Response
385
407
  for (const header of method.returns.headers) {
386
408
  if (header.kind === 'headerMapResponse') {
387
- content += `\tfor k, v := range server.GetResponse(respr).${header.fieldName} {\n`;
388
- content += '\t\tif v != nil {\n';
389
- content += `\t\t\tresp.Header.Set("${header.headerName}"+k, *v)\n`;
390
- content += '\t\t}\n';
391
- content += '\t}\n';
409
+ content += `${indent.get()}for k, v := range server.GetResponse(respr).${header.fieldName} {\n`;
410
+ content += `${indent.push().get()}if v != nil {\n`;
411
+ content += `${indent.push().get()}resp.Header.Set("${header.headerName}"+k, *v)\n`;
412
+ content += `${indent.pop().get()}}\n`;
413
+ content += `${indent.pop().get()}}\n`;
392
414
  }
393
415
  else {
394
- content += `\tif val := server.GetResponse(respr).${header.fieldName}; val != nil {\n`;
395
- content += `\t\tresp.Header.Set("${header.headerName}", ${helpers.formatValue('val', header.type, imports, true)})\n\t}\n`;
416
+ content += `${indent.get()}if val := server.GetResponse(respr).${header.fieldName}; val != nil {\n`;
417
+ content += `${indent.push().get()}resp.Header.Set("${header.headerName}", ${helpers.formatValue('val', header.type, imports, true)})\n`;
418
+ content += `${indent.pop().get()}}\n`;
396
419
  }
397
420
  }
398
- content += '\treturn resp, nil\n';
421
+ content += `${indent.get()}return resp, nil\n`;
399
422
  break;
400
423
  }
401
424
  case 'pageableMethod':
402
- content += dispatchForPagerBody(pkg, receiverName, method, imports);
425
+ content += dispatchForPagerBody(pkg, receiverName, method, imports, indent);
403
426
  break;
404
427
  default:
405
428
  method;
@@ -416,25 +439,26 @@ function generateServerTransportMethods(pkg, serverTransport, finalMethods, impo
416
439
  * @param receiverName the name of the receiver for the dispatch method
417
440
  * @param method the method for which to emit dispatching logic
418
441
  * @param imports the import manager currently in scope
442
+ * @param indent the indentation helper currently in scope
419
443
  * @returns the text for dispatching logic
420
444
  */
421
- function dispatchForOperationBody(pkg, receiverName, method, imports) {
445
+ function dispatchForOperationBody(pkg, receiverName, method, imports, indent) {
422
446
  const methodParamGroups = helpers.getMethodParamGroups(method);
423
447
  const numPathParams = methodParamGroups.pathParams.filter((each) => !go.isLiteralParameter(each.style)).length;
424
448
  let content = '';
425
449
  if (numPathParams > 0) {
426
450
  imports.add('regexp');
427
- content += `\tconst regexStr = \`${createPathParamsRegex(method, methodParamGroups.pathParams)}\`\n`;
428
- content += '\tregex := regexp.MustCompile(regexStr)\n';
429
- content += '\tmatches := regex.FindStringSubmatch(req.URL.EscapedPath())\n';
451
+ content += `${indent.get()}const regexStr = \`${createPathParamsRegex(method, methodParamGroups.pathParams)}\`\n`;
452
+ content += `${indent.get()}regex := regexp.MustCompile(regexStr)\n`;
453
+ content += `${indent.get()}matches := regex.FindStringSubmatch(req.URL.EscapedPath())\n`;
430
454
  // the total number of matches is the number of capture groups
431
455
  // plus the full match. so we add + 1 to include the full match.
432
- content += `\tif len(matches) < ${numPathParams + 1} {\n`;
433
- content += '\t\treturn nil, fmt.Errorf("failed to parse path %s", req.URL.Path)\n\t}\n';
456
+ content += `${indent.get()}if len(matches) < ${numPathParams + 1} {\n`;
457
+ content += `${indent.push().get()}return nil, fmt.Errorf("failed to parse path %s", req.URL.Path)\n${indent.pop().get()}}\n`;
434
458
  }
435
459
  const allQueryParams = methodParamGroups.encodedQueryParams.concat(methodParamGroups.unencodedQueryParams);
436
460
  if (allQueryParams.find((each) => each.location === 'method' && !go.isLiteralParameter(each.style))) {
437
- content += '\tqp := req.URL.Query()\n';
461
+ content += `${indent.get()}qp := req.URL.Query()\n`;
438
462
  }
439
463
  // note that these are mutually exclusive
440
464
  const bodyParam = methodParamGroups.bodyParam;
@@ -449,21 +473,21 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
449
473
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/fake', 'azfake');
450
474
  switch (bodyParam.type.kind) {
451
475
  case 'encodedBytes':
452
- content += `\tbody, err := server.UnmarshalRequestAsByteArray(req, runtime.Base64${bodyParam.type.encoding}Format)\n`;
453
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
476
+ content += `${indent.get()}body, err := server.UnmarshalRequestAsByteArray(req, runtime.Base64${bodyParam.type.encoding}Format)\n`;
477
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
454
478
  break;
455
479
  case 'interface':
456
480
  requiredHelpers.readRequestBody = true;
457
- content += '\traw, err := readRequestBody(req)\n';
458
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
459
- content += `\tbody, err := unmarshal${bodyParam.type.name}(raw)\n`;
460
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
481
+ content += `${indent.get()}raw, err := readRequestBody(req)\n`;
482
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
483
+ content += `${indent.get()}body, err := unmarshal${bodyParam.type.name}(raw)\n`;
484
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
461
485
  break;
462
486
  case 'rawJSON':
463
487
  imports.add('io');
464
- content += '\tbody, err := io.ReadAll(req.Body)\n';
465
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
466
- content += '\treq.Body.Close()\n';
488
+ content += `${indent.get()}body, err := io.ReadAll(req.Body)\n`;
489
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
490
+ content += `${indent.get()}req.Body.Close()\n`;
467
491
  break;
468
492
  default: {
469
493
  let bodyTypeName = go.getTypeDeclaration(bodyParam.type, pkg);
@@ -471,8 +495,8 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
471
495
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime');
472
496
  bodyTypeName = `datetime.${bodyParam.type.format}`;
473
497
  }
474
- content += `\tbody, err := server.UnmarshalRequestAs${bodyParam.bodyFormat}[${bodyTypeName}](req)\n`;
475
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
498
+ content += `${indent.get()}body, err := server.UnmarshalRequestAs${bodyParam.bodyFormat}[${bodyTypeName}](req)\n`;
499
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
476
500
  }
477
501
  }
478
502
  }
@@ -480,8 +504,8 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
480
504
  case 'Text':
481
505
  if (bodyParam && !go.isLiteralParameter(bodyParam.style)) {
482
506
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/fake', 'azfake');
483
- content += '\tbody, err := server.UnmarshalRequestAsText(req)\n';
484
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
507
+ content += `${indent.get()}body, err := server.UnmarshalRequestAsText(req)\n`;
508
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
485
509
  }
486
510
  break;
487
511
  }
@@ -491,19 +515,20 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
491
515
  imports.add('io');
492
516
  imports.add('mime');
493
517
  imports.add('mime/multipart');
494
- content += '\t_, params, err := mime.ParseMediaType(req.Header.Get("Content-Type"))\n';
495
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
496
- content += '\treader := multipart.NewReader(req.Body, params["boundary"])\n';
518
+ content += `${indent.get()}_, params, err := mime.ParseMediaType(req.Header.Get("Content-Type"))\n`;
519
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
520
+ content += `${indent.get()}reader := multipart.NewReader(req.Body, params["boundary"])\n`;
497
521
  for (const param of multipartBodyParams) {
498
- content += `\tvar ${param.name} ${go.getTypeDeclaration(param.type, pkg)}\n`;
522
+ content += `${indent.get()}var ${param.name} ${go.getTypeDeclaration(param.type, pkg)}\n`;
499
523
  }
500
- content += '\tfor {\n';
501
- content += '\t\tvar part *multipart.Part\n';
502
- content += '\t\tpart, err = reader.NextPart()\n';
503
- content += '\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n';
504
- content += '\t\t} else if err != nil {\n\t\t\treturn nil, err\n\t\t}\n';
505
- content += '\t\tvar content []byte\n';
506
- content += '\t\tswitch fn := part.FormName(); fn {\n';
524
+ content += `${indent.get()}for {\n`;
525
+ indent.push();
526
+ content += `${indent.get()}var part *multipart.Part\n`;
527
+ content += `${indent.get()}part, err = reader.NextPart()\n`;
528
+ content += `${indent.get()}if errors.Is(err, io.EOF) {\n${indent.push().get()}break\n`;
529
+ content += `${indent.pop().get()}} else if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
530
+ content += `${indent.get()}var content []byte\n`;
531
+ content += `${indent.get()}switch fn := part.FormName(); fn {\n`;
507
532
  // specify boolTarget if parsing bools happens in place.
508
533
  // i.e. the result from the parsing doesn't require further conversion (e.g. casting)
509
534
  // otherwise the parsed value is in a local var named parsed.
@@ -516,40 +541,41 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
516
541
  case 'bool':
517
542
  if (boolTarget) {
518
543
  // we reuse the err var declared earlier when calling reader.NextPart()
519
- parsingCode = `\t\t\t${boolTarget}, err = strconv.ParseBool(string(content))\n`;
544
+ parsingCode = `${indent.get()}${boolTarget}, err = strconv.ParseBool(string(content))\n`;
520
545
  parseErr = 'err';
521
546
  }
522
547
  else {
523
- parsingCode = `\t\t\t${parseResults} := strconv.ParseBool(string(content))\n`;
548
+ parsingCode = `${indent.get()}${parseResults} := strconv.ParseBool(string(content))\n`;
524
549
  }
525
550
  break;
526
551
  case 'float32':
527
552
  case 'float64':
528
- parsingCode = `\t\t\t${parseResults} := strconv.ParseFloat(string(content), ${helpers.getBitSizeForNumber(typeName)})\n`;
553
+ parsingCode = `${indent.get()}${parseResults} := strconv.ParseFloat(string(content), ${helpers.getBitSizeForNumber(typeName)})\n`;
529
554
  break;
530
555
  case 'int8':
531
556
  case 'int16':
532
557
  case 'int32':
533
558
  case 'int64':
534
- parsingCode = `\t\t\t${parseResults} := strconv.ParseInt(string(content), 10, ${helpers.getBitSizeForNumber(typeName)})\n`;
559
+ parsingCode = `${indent.get()}${parseResults} := strconv.ParseInt(string(content), 10, ${helpers.getBitSizeForNumber(typeName)})\n`;
535
560
  break;
536
561
  default:
537
562
  throw new CodegenError('InternalError', `unhandled multipart parameter primitive type ${typeName}`);
538
563
  }
539
- parsingCode += `\t\t\tif ${parseErr} != nil {\n\t\t\t\treturn nil, ${parseErr}\n\t\t\t}\n`;
564
+ parsingCode += `${indent.get()}if ${parseErr} != nil {\n${indent.push().get()}return nil, ${parseErr}\n${indent.pop().get()}}\n`;
540
565
  return parsingCode;
541
566
  };
542
567
  const isModelType = function (type) {
543
568
  return type.kind === 'model' || type.kind === 'polymorphicModel';
544
569
  };
545
570
  const emitCase = function (caseValue, paramVar, type) {
546
- let caseContent = `\t\tcase "${caseValue}":\n`;
547
- caseContent += '\t\t\tcontent, err = io.ReadAll(part)\n';
548
- caseContent += '\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n';
571
+ let caseContent = `${indent.get()}case "${caseValue}":\n`;
572
+ indent.push();
573
+ caseContent += `${indent.get()}content, err = io.ReadAll(part)\n`;
574
+ caseContent += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
549
575
  let assignedValue;
550
576
  if (isModelType(helpers.recursiveUnwrapMapSlice(type))) {
551
577
  imports.add('encoding/json');
552
- caseContent += `\t\t\tif err = json.Unmarshal(content, &${paramVar}); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n`;
578
+ caseContent += `${indent.get()}if err = json.Unmarshal(content, &${paramVar}); err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
553
579
  }
554
580
  else if (type.kind === 'readSeekCloser') {
555
581
  imports.add('bytes');
@@ -603,16 +629,17 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
603
629
  const contentType = 'part.Header.Get("Content-Type")';
604
630
  const filename = 'part.FileName()';
605
631
  if (type.kind === 'slice') {
606
- caseContent += `\t\t\t${paramVar} = append(${paramVar}, streaming.MultipartContent{\n`;
607
- caseContent += `\t\t\t\tBody: ${bodyContent},\n`;
608
- caseContent += `\t\t\t\tContentType: ${contentType},\n`;
609
- caseContent += `\t\t\t\tFilename: ${filename},\n`;
610
- caseContent += '\t\t\t})\n';
632
+ caseContent += `${indent.get()}${paramVar} = append(${paramVar}, streaming.MultipartContent{\n`;
633
+ indent.push();
634
+ caseContent += `${indent.get()}Body: ${bodyContent},\n`;
635
+ caseContent += `${indent.get()}ContentType: ${contentType},\n`;
636
+ caseContent += `${indent.get()}Filename: ${filename},\n`;
637
+ caseContent += `${indent.pop().get()}})\n`;
611
638
  }
612
639
  else {
613
- caseContent += `\t\t\t${paramVar}.Body = ${bodyContent}\n`;
614
- caseContent += `\t\t\t${paramVar}.ContentType = ${contentType}\n`;
615
- caseContent += `\t\t\t${paramVar}.Filename = ${filename}\n`;
640
+ caseContent += `${indent.get()}${paramVar}.Body = ${bodyContent}\n`;
641
+ caseContent += `${indent.get()}${paramVar}.ContentType = ${contentType}\n`;
642
+ caseContent += `${indent.get()}${paramVar}.Filename = ${filename}\n`;
616
643
  }
617
644
  }
618
645
  else if (type.kind === 'slice') {
@@ -629,8 +656,9 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
629
656
  throw new CodegenError('InternalError', `uhandled multipart parameter kind ${type.kind}`);
630
657
  }
631
658
  if (assignedValue) {
632
- caseContent += `\t\t\t${paramVar} = ${assignedValue}\n`;
659
+ caseContent += `${indent.get()}${paramVar} = ${assignedValue}\n`;
633
660
  }
661
+ indent.pop();
634
662
  return caseContent;
635
663
  };
636
664
  for (const param of multipartBodyParams) {
@@ -643,19 +671,20 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
643
671
  content += emitCase(param.name, param.name, param.type);
644
672
  }
645
673
  }
646
- content += '\t\tdefault:\n\t\t\treturn nil, fmt.Errorf("unexpected part %s", fn)\n';
647
- content += '\t\t}\n'; // end switch
648
- content += '\t}\n'; // end for
674
+ content += `${indent.get()}default:\n`;
675
+ content += `${indent.push().get()}return nil, fmt.Errorf("unexpected part %s", fn)\n`;
676
+ content += `${indent.pop().get()}}\n`; // end switch
677
+ content += `${indent.pop().get()}}\n`; // end for
649
678
  }
650
679
  else if (formBodyParams.length > 0) {
651
680
  for (const param of formBodyParams) {
652
- content += `\tvar ${param.name} ${go.getTypeDeclaration(param.type, pkg)}\n`;
681
+ content += `${indent.get()}var ${param.name} ${go.getTypeDeclaration(param.type, pkg)}\n`;
653
682
  }
654
- content += '\tif err := req.ParseForm(); err != nil {\n\t\treturn nil, &nonRetriableError{fmt.Errorf("failed parsing form data: %v", err)}\n\t}\n';
655
- content += '\tfor key := range req.Form {\n';
656
- content += '\t\tswitch key {\n';
683
+ content += `${indent.get()}if err := req.ParseForm(); err != nil {\n${indent.push().get()}return nil, &nonRetriableError{fmt.Errorf("failed parsing form data: %v", err)}\n${indent.pop().get()}}\n`;
684
+ content += `${indent.get()}for key := range req.Form {\n`;
685
+ content += `${indent.push().get()}switch key {\n`;
657
686
  for (const param of formBodyParams) {
658
- content += `\t\tcase "${param.formDataName}":\n`;
687
+ content += `${indent.get()}case "${param.formDataName}":\n`;
659
688
  let assignedValue;
660
689
  switch (param.type.kind) {
661
690
  case 'constant':
@@ -667,22 +696,24 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
667
696
  default:
668
697
  throw new CodegenError('InternalError', `uhandled form parameter kind ${param.type.kind}`);
669
698
  }
670
- content += `\t\t\t${param.name} = ${assignedValue}\n`;
699
+ content += `${indent.push().get()}${param.name} = ${assignedValue}\n`;
700
+ indent.pop();
671
701
  }
672
- content += '\t\t}\n'; // end switch
673
- content += '\t}\n'; // end for
702
+ content += `${indent.pop().get()}}\n`; // end switch
703
+ content += `${indent.get()}}\n`; // end for
674
704
  }
675
705
  else if (partialBodyParams.length > 0) {
676
706
  // construct the partial body params type and unmarshal it
677
- content += '\ttype partialBodyParams struct {\n';
707
+ content += `${indent.get()}type partialBodyParams struct {\n`;
708
+ indent.push();
678
709
  for (const partialBodyParam of partialBodyParams) {
679
- content += `\t\t${naming.capitalize(partialBodyParam.name)} ${helpers.star(partialBodyParam.byValue)}${go.getTypeDeclaration(partialBodyParam.type, pkg)} \`json:"${partialBodyParam.serializedName}"\`\n`;
710
+ content += `${indent.get()}${naming.capitalize(partialBodyParam.name)} ${helpers.star(partialBodyParam.byValue)}${go.getTypeDeclaration(partialBodyParam.type, pkg)} \`json:"${partialBodyParam.serializedName}"\`\n`;
680
711
  }
681
- content += '\t}\n';
682
- content += `\tbody, err := server.UnmarshalRequestAs${partialBodyParams[0].format}[partialBodyParams](req)\n`;
683
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
712
+ content += `${indent.pop().get()}}\n`;
713
+ content += `${indent.get()}body, err := server.UnmarshalRequestAs${partialBodyParams[0].format}[partialBodyParams](req)\n`;
714
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
684
715
  }
685
- const result = parseHeaderPathQueryParams(pkg, method, imports);
716
+ const result = parseHeaderPathQueryParams(pkg, method, imports, indent);
686
717
  content += result.content;
687
718
  // translate each partial body param to its field within the unmarshalled body
688
719
  for (const partialBodyParam of partialBodyParams) {
@@ -693,9 +724,9 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
693
724
  content += `resp ${apiCall}\n`;
694
725
  return content;
695
726
  }
696
- content += `\trespr, errRespr ${apiCall}\n`;
697
- content += '\tif respErr := server.GetError(errRespr, req); respErr != nil {\n';
698
- content += '\t\treturn nil, respErr\n\t}\n';
727
+ content += `${indent.get()}respr, errRespr ${apiCall}\n`;
728
+ content += `${indent.get()}if respErr := server.GetError(errRespr, req); respErr != nil {\n`;
729
+ content += `${indent.push().get()}return nil, respErr\n${indent.pop().get()}}\n`;
699
730
  return content;
700
731
  }
701
732
  function getMethodStatusCodes(method) {
@@ -723,27 +754,34 @@ function getMethodStatusCodes(method) {
723
754
  * @param receiverName the name of the receiver for the dispatch method
724
755
  * @param method the LRO method for which to emit the dispatch logic
725
756
  * @param imports the import manager currently in scope
757
+ * @param indent the indentation helper currently in scope
726
758
  * @returns the text for the LRO dispatch logic
727
759
  */
728
- function dispatchForLROBody(pkg, receiverName, method, imports) {
760
+ function dispatchForLROBody(pkg, receiverName, method, imports, indent) {
729
761
  const operationName = fixUpMethodName(method);
730
762
  const localVarName = naming.uncapitalize(operationName);
731
763
  const operationStateMachine = `${receiverName}.${naming.uncapitalize(operationName)}`;
732
- let content = `\t${localVarName} := ${operationStateMachine}.get(req)\n`;
733
- content += `\tif ${localVarName} == nil {\n`;
734
- content += dispatchForOperationBody(pkg, receiverName, method, imports);
735
- content += `\t\t${localVarName} = &respr\n`;
736
- content += `\t\t${operationStateMachine}.add(req, ${localVarName})\n`;
737
- content += '\t}\n\n';
738
- content += `\tresp, err := server.PollerResponderNext(${localVarName}, req)\n`;
739
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n\n';
764
+ let content = `${indent.get()}${localVarName} := ${operationStateMachine}.get(req)\n`;
765
+ content += `${indent.get()}if ${localVarName} == nil {\n`;
766
+ content += dispatchForOperationBody(pkg, receiverName, method, imports, indent);
767
+ indent.push();
768
+ content += `${indent.get()}${localVarName} = &respr\n`;
769
+ content += `${indent.get()}${operationStateMachine}.add(req, ${localVarName})\n`;
770
+ content += `${indent.pop().get()}}\n\n`;
771
+ content += `${indent.get()}resp, err := server.PollerResponderNext(${localVarName}, req)\n`;
772
+ content += `${indent.get()}if err != nil {\n`;
773
+ content += `${indent.push().get()}return nil, err\n`;
774
+ content += `${indent.pop().get()}}\n\n`;
740
775
  const formattedStatusCodes = helpers.formatStatusCodes(getMethodStatusCodes(method));
741
- content += `\tif !contains([]int{${formattedStatusCodes}}, resp.StatusCode) {\n`;
742
- content += `\t\t${operationStateMachine}.remove(req)\n`;
743
- content += `\t\treturn nil, &nonRetriableError{fmt.Errorf("unexpected status code %d. acceptable values are ${formattedStatusCodes}", resp.StatusCode)}\n\t}\n`;
744
- content += `\tif !server.PollerResponderMore(${localVarName}) {\n`;
745
- content += `\t\t${operationStateMachine}.remove(req)\n\t}\n\n`;
746
- content += '\treturn resp, nil\n';
776
+ content += `${indent.get()}if !slices.Contains([]int{${formattedStatusCodes}}, resp.StatusCode) {\n`;
777
+ indent.push();
778
+ content += `${indent.get()}${operationStateMachine}.remove(req)\n`;
779
+ content += `${indent.get()}return nil, &nonRetriableError{fmt.Errorf("unexpected status code %d. acceptable values are ${formattedStatusCodes}", resp.StatusCode)}\n`;
780
+ content += `${indent.pop().get()}}\n`;
781
+ content += `${indent.get()}if !server.PollerResponderMore(${localVarName}) {\n`;
782
+ content += `${indent.push().get()}${operationStateMachine}.remove(req)\n`;
783
+ content += `${indent.pop().get()}}\n\n`;
784
+ content += `${indent.get()}return resp, nil\n`;
747
785
  return content;
748
786
  }
749
787
  /**
@@ -753,33 +791,41 @@ function dispatchForLROBody(pkg, receiverName, method, imports) {
753
791
  * @param receiverName the name of the receiver for the dispatch method
754
792
  * @param method the pageable method for which to emit the dispatch logic
755
793
  * @param imports the import manager currently in scope
794
+ * @param indent the indentation helper currently in scope
756
795
  * @returns the text for the pageable dispatch logic
757
796
  */
758
- function dispatchForPagerBody(pkg, receiverName, method, imports) {
797
+ function dispatchForPagerBody(pkg, receiverName, method, imports, indent) {
759
798
  const operationName = fixUpMethodName(method);
760
799
  const localVarName = naming.uncapitalize(operationName);
761
800
  const operationStateMachine = `${receiverName}.${naming.uncapitalize(operationName)}`;
762
- let content = `\t${localVarName} := ${operationStateMachine}.get(req)\n`;
763
- content += `\tif ${localVarName} == nil {\n`;
764
- content += dispatchForOperationBody(pkg, receiverName, method, imports);
765
- content += `\t\t${localVarName} = &resp\n`;
766
- content += `\t\t${operationStateMachine}.add(req, ${localVarName})\n`;
767
- if (method.nextLinkName) {
801
+ let content = `${indent.get()}${localVarName} := ${operationStateMachine}.get(req)\n`;
802
+ content += `${indent.get()}if ${localVarName} == nil {\n`;
803
+ content += dispatchForOperationBody(pkg, receiverName, method, imports, indent);
804
+ indent.push();
805
+ content += `${indent.get()}${localVarName} = &resp\n`;
806
+ content += `${indent.get()}${operationStateMachine}.add(req, ${localVarName})\n`;
807
+ if (method.strategy?.kind === 'nextLink') {
768
808
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/to');
769
- content += `\t\tserver.PagerResponderInjectNextLinks(${localVarName}, req, func(page *${go.getTypeDeclaration(method.returns, pkg)}, createLink func() string) {\n`;
770
- content += `\t\t\tpage.${method.nextLinkName} = to.Ptr(createLink())\n`;
771
- content += '\t\t})\n';
809
+ content += `${indent.get()}server.PagerResponderInjectNextLinks(${localVarName}, req, func(page *${go.getTypeDeclaration(method.returns, pkg)}, createLink func() string) {\n`;
810
+ content += `${indent.push().get()}page.${helpers.buildNextLinkPath(method.strategy)} = to.Ptr(createLink())\n`;
811
+ content += `${indent.pop().get()}})\n`;
772
812
  }
773
- content += '\t}\n'; // end if
774
- content += `\tresp, err := server.PagerResponderNext(${localVarName}, req)\n`;
775
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
813
+ indent.pop();
814
+ content += `${indent.get()}}\n`; // end if
815
+ content += `${indent.get()}resp, err := server.PagerResponderNext(${localVarName}, req)\n`;
816
+ content += `${indent.get()}if err != nil {\n`;
817
+ content += `${indent.push().get()}return nil, err\n`;
818
+ content += `${indent.pop().get()}}\n`;
776
819
  const formattedStatusCodes = helpers.formatStatusCodes(method.httpStatusCodes);
777
- content += `\tif !contains([]int{${formattedStatusCodes}}, resp.StatusCode) {\n`;
778
- content += `\t\t${operationStateMachine}.remove(req)\n`;
779
- content += `\t\treturn nil, &nonRetriableError{fmt.Errorf("unexpected status code %d. acceptable values are ${formattedStatusCodes}", resp.StatusCode)}\n\t}\n`;
780
- content += `\tif !server.PagerResponderMore(${localVarName}) {\n`;
781
- content += `\t\t${operationStateMachine}.remove(req)\n\t}\n`;
782
- content += '\treturn resp, nil\n';
820
+ content += `${indent.get()}if !slices.Contains([]int{${formattedStatusCodes}}, resp.StatusCode) {\n`;
821
+ indent.push();
822
+ content += `${indent.get()}${operationStateMachine}.remove(req)\n`;
823
+ content += `${indent.get()}return nil, &nonRetriableError{fmt.Errorf("unexpected status code %d. acceptable values are ${formattedStatusCodes}", resp.StatusCode)}\n`;
824
+ content += `${indent.pop().get()}}\n`;
825
+ content += `${indent.get()}if !server.PagerResponderMore(${localVarName}) {\n`;
826
+ content += `${indent.push().get()}${operationStateMachine}.remove(req)\n`;
827
+ content += `${indent.pop().get()}}\n`;
828
+ content += `${indent.get()}return resp, nil\n`;
783
829
  return content;
784
830
  }
785
831
  function sanitizeRegexpCaptureGroupName(name) {
@@ -811,9 +857,10 @@ function createPathParamsRegex(method, pathParams) {
811
857
  * @param pkg contains the package contents
812
858
  * @param method the method for which to emit parameter parsing logic
813
859
  * @param imports the import manager currently in scope
860
+ * @param indent the indentation helper currently in scope
814
861
  * @returns the parsing code and the params that contain the parsed values
815
862
  */
816
- function parseHeaderPathQueryParams(pkg, method, imports) {
863
+ function parseHeaderPathQueryParams(pkg, method, imports, indent) {
817
864
  let content = '';
818
865
  const paramValues = new Map();
819
866
  const createLocalVariableName = function (param, suffix) {
@@ -872,44 +919,18 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
872
919
  // of paramValue will be updated with the var name that
873
920
  // contains the unescaped value.
874
921
  let paramValue = getRawParamValue(param);
875
- // path/query params might be escaped, so we need to unescape them first.
876
- // must handle query collections first as it's a superset of query param.
877
- if (param.kind === 'queryCollectionParam' && param.collectionFormat === 'multi') {
922
+ // path params are escaped, so we need to unescape them first.
923
+ if (go.isPathParameter(param)) {
878
924
  imports.add('net/url');
879
- const escapedParam = createLocalVariableName(param, 'Escaped');
880
- content += `\t${escapedParam} := ${paramValue}\n`;
881
- let paramVar = createLocalVariableName(param, 'Unescaped');
882
- if (param.type.elementType.kind === 'string') {
883
- // by convention, if the value is in its "final form" (i.e. no parsing required)
884
- // then its var is to have the "Param" suffix. the only case is string, everything
885
- // else requires some amount of parsing/conversion.
886
- paramVar = createLocalVariableName(param, 'Param');
887
- }
888
- content += `\t${paramVar} := make([]string, len(${escapedParam}))\n`;
889
- content += `\tfor i, v := range ${escapedParam} {\n`;
890
- content += '\t\tu, unescapeErr := url.QueryUnescape(v)\n';
891
- content += '\t\tif unescapeErr != nil {\n\t\t\treturn nil, unescapeErr\n\t\t}\n';
892
- content += `\t\t${paramVar}[i] = u\n\t}\n`;
893
- paramValue = paramVar;
894
- }
895
- else if (go.isPathParameter(param) || go.isQueryParameter(param)) {
896
- imports.add('net/url');
897
- let where;
898
- if (go.isPathParameter(param)) {
899
- where = 'Path';
900
- }
901
- else {
902
- where = 'Query';
903
- }
904
925
  let paramVar = createLocalVariableName(param, 'Unescaped');
905
926
  if (go.isRequiredParameter(param.style) && param.type.kind === 'constant' && param.type.type === 'string') {
906
927
  // for string-based enums, we perform the conversion as part of unescaping
907
928
  requiredHelpers.parseWithCast = true;
908
929
  paramVar = createLocalVariableName(param, 'Param');
909
- content += `\t${paramVar}, err := parseWithCast(${paramValue}, func (v string) (${go.getTypeDeclaration(param.type, pkg)}, error) {\n`;
910
- content += `\t\tp, unescapeErr := url.${where}Unescape(v)\n`;
911
- content += '\t\tif unescapeErr != nil {\n\t\t\treturn "", unescapeErr\n\t\t}\n';
912
- content += `\t\treturn ${go.getTypeDeclaration(param.type, pkg)}(p), nil\n\t})\n`;
930
+ content += `${indent.get()}${paramVar}, err := parseWithCast(${paramValue}, func (v string) (${go.getTypeDeclaration(param.type, pkg)}, error) {\n`;
931
+ content += `${indent.push().get()}p, unescapeErr := url.PathUnescape(v)\n`;
932
+ content += `${indent.get()}if unescapeErr != nil {\n${indent.push().get()}return "", unescapeErr\n${indent.pop().get()}}\n`;
933
+ content += `${indent.get()}return ${go.getTypeDeclaration(param.type, pkg)}(p), nil\n${indent.pop().get()}})\n`;
913
934
  }
914
935
  else {
915
936
  if (go.isRequiredParameter(param.style) && (param.type.kind === 'string' || (param.type.kind === 'slice' && param.type.elementType.kind === 'string'))) {
@@ -918,9 +939,9 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
918
939
  // else requires some amount of parsing/conversion.
919
940
  paramVar = createLocalVariableName(param, 'Param');
920
941
  }
921
- content += `\t${paramVar}, err := url.${where}Unescape(${paramValue})\n`;
942
+ content += `${indent.get()}${paramVar}, err := url.PathUnescape(${paramValue})\n`;
922
943
  }
923
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
944
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
924
945
  paramValue = paramVar;
925
946
  }
926
947
  // parse params as required
@@ -930,7 +951,7 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
930
951
  if (param.collectionFormat !== 'multi') {
931
952
  requiredHelpers.splitHelper = true;
932
953
  const elementsParam = createLocalVariableName(param, 'Elements');
933
- content += `\t${elementsParam} := splitHelper(${paramValue}, "${helpers.getDelimiterForCollectionFormat(param.collectionFormat)}")\n`;
954
+ content += `${indent.get()}${elementsParam} := splitHelper(${paramValue}, "${helpers.getDelimiterForCollectionFormat(param.collectionFormat)}")\n`;
934
955
  paramValue = elementsParam;
935
956
  }
936
957
  const paramVar = createLocalVariableName(param, 'Param');
@@ -950,20 +971,21 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
950
971
  throw new CodegenError('InternalError', `unhandled element kind ${param.type.elementType.kind}`);
951
972
  }
952
973
  const toType = go.getTypeDeclaration(param.type.elementType, pkg);
953
- content += `\t${paramVar} := make([]${toType}, len(${paramValue}))\n`;
954
- content += `\tfor i := 0; i < len(${paramValue}); i++ {\n`;
974
+ content += `${indent.get()}${paramVar} := make([]${toType}, len(${paramValue}))\n`;
975
+ content += `${indent.get()}for i := 0; i < len(${paramValue}); i++ {\n`;
976
+ indent.push();
955
977
  let fromVar;
956
978
  // TODO: consolidate with non-collection parsing code
957
979
  if (elementFormat === 'bool') {
958
980
  imports.add('strconv');
959
981
  fromVar = 'parsedBool';
960
- content += `\t\t${fromVar}, parseErr := strconv.ParseBool(${paramValue}[i])\n`;
961
- content += '\t\tif parseErr != nil {\n\t\t\treturn nil, parseErr\n\t\t}\n';
982
+ content += `${indent.get()}${fromVar}, parseErr := strconv.ParseBool(${paramValue}[i])\n`;
983
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return nil, parseErr\n${indent.pop().get()}}\n`;
962
984
  }
963
985
  else if (elementFormat === 'float32' || elementFormat === 'float64' || elementFormat === 'int32' || elementFormat === 'int64') {
964
986
  fromVar = `parsed${naming.capitalize(elementFormat)}`;
965
- content += `\t\t${fromVar}, parseErr := ${emitNumericConversion(`${paramValue}[i]`, elementFormat)}\n`;
966
- content += '\t\tif parseErr != nil {\n\t\t\treturn nil, parseErr\n\t\t}\n';
987
+ content += `${indent.get()}${fromVar}, parseErr := ${emitNumericConversion(`${paramValue}[i]`, elementFormat)}\n`;
988
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return nil, parseErr\n${indent.pop().get()}}\n`;
967
989
  }
968
990
  else if (elementFormat === 'string') {
969
991
  // we're casting an enum string value to its const type
@@ -973,39 +995,39 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
973
995
  else if (elementFormat === 'Std' || elementFormat === 'URL') {
974
996
  imports.add('encoding/base64');
975
997
  fromVar = `parsed${naming.capitalize(elementFormat)}`;
976
- content += `\t\t${fromVar}, parseErr := base64.${elementFormat}Encoding.DecodeString(${paramValue}[i])\n`;
977
- content += '\t\tif parseErr != nil {\n\t\t\treturn nil, parseErr\n\t\t}\n';
998
+ content += `${indent.get()}${fromVar}, parseErr := base64.${elementFormat}Encoding.DecodeString(${paramValue}[i])\n`;
999
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return nil, parseErr\n${indent.pop().get()}}\n`;
978
1000
  }
979
1001
  else if (elementFormat === 'RFC1123' || elementFormat === 'RFC3339' || elementFormat === 'Unix') {
980
1002
  imports.add('time');
981
1003
  fromVar = `parsed${naming.capitalize(elementFormat)}`;
982
1004
  if (elementFormat === 'Unix') {
983
1005
  imports.add('strconv');
984
- content += `\t\tp, parseErr := strconv.ParseInt(${paramValue}[i], 10, 64)\n`;
985
- content += '\t\tif parseErr != nil {\n\t\t\treturn nil, parseErr\n\t\t}\n';
986
- content += `\t\t${fromVar} := time.Unix(p, 0).UTC()\n`;
1006
+ content += `${indent.get()}p, parseErr := strconv.ParseInt(${paramValue}[i], 10, 64)\n`;
1007
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return nil, parseErr\n${indent.pop().get()}}\n`;
1008
+ content += `${indent.get()}${fromVar} := time.Unix(p, 0).UTC()\n`;
987
1009
  }
988
1010
  else {
989
1011
  let format = 'time.RFC3339Nano';
990
1012
  if (elementFormat === 'RFC1123') {
991
1013
  format = 'time.RFC1123';
992
1014
  }
993
- content += `\t\t${fromVar}, parseErr := time.Parse(${format}, ${paramValue}[i])\n`;
994
- content += '\t\tif parseErr != nil {\n\t\t\treturn nil, parseErr\n\t\t}\n';
1015
+ content += `${indent.get()}${fromVar}, parseErr := time.Parse(${format}, ${paramValue}[i])\n`;
1016
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return nil, parseErr\n${indent.pop().get()}}\n`;
995
1017
  }
996
1018
  }
997
1019
  else {
998
1020
  throw new CodegenError('InternalError', `unhandled element format ${elementFormat}`);
999
1021
  }
1000
1022
  // TODO: remove cast in some cases
1001
- content += `\t\t${paramVar}[i] = ${toType}(${fromVar})\n\t}\n`;
1023
+ content += `${indent.get()}${paramVar}[i] = ${toType}(${fromVar})\n${indent.pop().get()}}\n`;
1002
1024
  }
1003
1025
  else if (!go.isRequiredParameter(param.style) && param.collectionFormat !== 'multi') {
1004
1026
  // for slices of strings that are required, the call to splitHelper(...) is inlined into
1005
1027
  // the invocation of the fake e.g. srv.FakeFunc(splitHelper...). but if it's optional, we
1006
1028
  // need to create a local first which will later be copied into the optional param group.
1007
1029
  requiredHelpers.splitHelper = true;
1008
- content += `\t${createLocalVariableName(param, 'Param')} := splitHelper(${paramValue}, "${helpers.getDelimiterForCollectionFormat(param.collectionFormat)}")\n`;
1030
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')} := splitHelper(${paramValue}, "${helpers.getDelimiterForCollectionFormat(param.collectionFormat)}")\n`;
1009
1031
  }
1010
1032
  }
1011
1033
  else if (param.type.kind === 'scalar' && param.type.type === 'bool') {
@@ -1015,13 +1037,13 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
1015
1037
  requiredHelpers.parseOptional = true;
1016
1038
  from = `parseOptional(${paramValue}, strconv.ParseBool)`;
1017
1039
  }
1018
- content += `\t${createLocalVariableName(param, 'Param')}, err := ${from}\n`;
1019
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
1040
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := ${from}\n`;
1041
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
1020
1042
  }
1021
1043
  else if (param.type.kind === 'encodedBytes') {
1022
1044
  imports.add('encoding/base64');
1023
- content += `\t${createLocalVariableName(param, 'Param')}, err := base64.${param.type.encoding}Encoding.DecodeString(${paramValue})\n`;
1024
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
1045
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := base64.${param.type.encoding}Encoding.DecodeString(${paramValue})\n`;
1046
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
1025
1047
  }
1026
1048
  else if (param.type.kind === 'time') {
1027
1049
  const formatMap = {
@@ -1038,8 +1060,8 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
1038
1060
  requiredHelpers.parseOptional = true;
1039
1061
  from = `parseOptional(${paramValue}, func(v string) (time.Time, error) { return time.Parse(${format}, v) })`;
1040
1062
  }
1041
- content += `\t${createLocalVariableName(param, 'Param')}, err := ${from}\n`;
1042
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
1063
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := ${from}\n`;
1064
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
1043
1065
  }
1044
1066
  else {
1045
1067
  imports.add('strconv');
@@ -1052,11 +1074,11 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
1052
1074
  requiredHelpers.parseWithCast = true;
1053
1075
  parser = 'parseWithCast';
1054
1076
  }
1055
- content += `\t${createLocalVariableName(param, 'Param')}, err := ${parser}(${paramValue}, func (v string) (time.Time, error) {\n`;
1056
- content += '\t\tp, parseErr := strconv.ParseInt(v, 10, 64)\n';
1057
- content += '\t\tif parseErr != nil {\n\t\t\treturn time.Time{}, parseErr\n\t\t}\n';
1058
- content += '\t\treturn time.Unix(p, 0).UTC(), nil\n\t})\n';
1059
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
1077
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := ${parser}(${paramValue}, func (v string) (time.Time, error) {\n`;
1078
+ content += `${indent.push().get()}p, parseErr := strconv.ParseInt(v, 10, 64)\n`;
1079
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return time.Time{}, parseErr\n${indent.pop().get()}}\n`;
1080
+ content += `${indent.get()}return time.Unix(p, 0).UTC(), nil\n${indent.pop().get()}})\n`;
1081
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
1060
1082
  }
1061
1083
  }
1062
1084
  else if (param.type.kind === 'scalar' && (param.type.type === 'float32' || param.type.type === 'float64' || param.type.type === 'int32' || param.type.type === 'int64')) {
@@ -1070,32 +1092,32 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
1070
1092
  parser = 'parseWithCast';
1071
1093
  }
1072
1094
  if (param.type.type === 'float32' || param.type.type === 'int32' || !go.isRequiredParameter(param.style)) {
1073
- content += `\t${createLocalVariableName(param, 'Param')}, err := ${parser}(${paramValue}, func(v string) (${param.type.type}, error) {\n`;
1074
- content += `\t\tp, parseErr := ${emitNumericConversion('v', param.type.type)}\n`;
1075
- content += '\t\tif parseErr != nil {\n\t\t\treturn 0, parseErr\n\t\t}\n';
1095
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := ${parser}(${paramValue}, func(v string) (${param.type.type}, error) {\n`;
1096
+ content += `${indent.push().get()}p, parseErr := ${emitNumericConversion('v', param.type.type)}\n`;
1097
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return 0, parseErr\n${indent.pop().get()}}\n`;
1076
1098
  let result = 'p';
1077
1099
  if (param.type.type === 'float32' || param.type.type === 'int32') {
1078
1100
  result = `${param.type.type}(${result})`;
1079
1101
  }
1080
- content += `\t\treturn ${result}, nil\n\t})\n`;
1102
+ content += `${indent.get()}return ${result}, nil\n${indent.pop().get()}})\n`;
1081
1103
  }
1082
1104
  else {
1083
- content += `\t${createLocalVariableName(param, 'Param')}, err := ${emitNumericConversion(paramValue, param.type.type)}\n`;
1105
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := ${emitNumericConversion(paramValue, param.type.type)}\n`;
1084
1106
  }
1085
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
1107
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
1086
1108
  }
1087
1109
  else if (param.kind === 'headerMapParam') {
1088
1110
  imports.add('strings');
1089
1111
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/to');
1090
1112
  const localVar = createLocalVariableName(param, 'Param');
1091
- content += `\tvar ${localVar} map[string]*string\n`;
1092
- content += `\tfor hh := range ${paramValue} {\n`;
1113
+ content += `${indent.get()}var ${localVar} map[string]*string\n`;
1114
+ content += `${indent.get()}for hh := range ${paramValue} {\n`;
1093
1115
  const headerPrefix = param.headerName;
1094
1116
  requiredHelpers.getHeaderValue = true;
1095
- content += `\t\tif len(hh) > len("${headerPrefix}") && strings.EqualFold(hh[:len("x-ms-meta-")], "${headerPrefix}") {\n`;
1096
- content += `\t\t\tif ${localVar} == nil {\n\t\t\t\t${localVar} = map[string]*string{}\n\t\t\t}\n`;
1097
- content += `\t\t\t${localVar}[hh[len("${headerPrefix}"):]] = to.Ptr(getHeaderValue(req.Header, hh))\n`;
1098
- content += '\t\t}\n\t}\n';
1117
+ content += `${indent.push().get()}if len(hh) > len("${headerPrefix}") && strings.EqualFold(hh[:len("x-ms-meta-")], "${headerPrefix}") {\n`;
1118
+ content += `${indent.push().get()}if ${localVar} == nil {\n${indent.push().get()}${localVar} = map[string]*string{}\n${indent.pop().get()}}\n`;
1119
+ content += `${indent.get()}${localVar}[hh[len("${headerPrefix}"):]] = to.Ptr(getHeaderValue(req.Header, hh))\n`;
1120
+ content += `${indent.pop().get()}}\n${indent.pop().get()}}\n`;
1099
1121
  }
1100
1122
  else if (param.type.kind === 'constant' && param.type.type !== 'string') {
1101
1123
  let parseHelper;
@@ -1120,11 +1142,11 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
1120
1142
  zeroValue = '0';
1121
1143
  }
1122
1144
  const toConstType = go.getTypeDeclaration(param.type, pkg);
1123
- content += `\t${createLocalVariableName(param, 'Param')}, err := ${parseHelper}(${paramValue}, func(v string) (${toConstType}, error) {\n`;
1124
- content += `\t\tp, parseErr := ${parse}\n`;
1125
- content += `\t\tif parseErr != nil {\n\t\t\treturn ${zeroValue}, parseErr\n\t\t}\n`;
1126
- content += `\t\treturn ${toConstType}(p), nil\n\t})\n`;
1127
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
1145
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := ${parseHelper}(${paramValue}, func(v string) (${toConstType}, error) {\n`;
1146
+ content += `${indent.push().get()}p, parseErr := ${parse}\n`;
1147
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return ${zeroValue}, parseErr\n${indent.pop().get()}}\n`;
1148
+ content += `${indent.get()}return ${toConstType}(p), nil\n${indent.pop().get()}})\n`;
1149
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
1128
1150
  }
1129
1151
  else if (!go.isRequiredParameter(param.style)) {
1130
1152
  // we check this last as it's a superset of the previous conditions
@@ -1133,23 +1155,25 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
1133
1155
  imports.addForType(param.type);
1134
1156
  paramValue = `${go.getTypeDeclaration(param.type, pkg)}(${paramValue})`;
1135
1157
  }
1136
- content += `\t${createLocalVariableName(param, 'Param')} := getOptional(${paramValue})\n`;
1158
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')} := getOptional(${paramValue})\n`;
1137
1159
  }
1138
1160
  }
1139
1161
  // create the param groups and populate their values
1140
1162
  for (const paramGroup of paramGroups.keys()) {
1141
1163
  if (paramGroup.required) {
1142
- content += `\t${naming.uncapitalize(paramGroup.name)} := ${go.getTypeDeclaration(paramGroup, pkg)}{\n`;
1164
+ content += `${indent.get()}${naming.uncapitalize(paramGroup.name)} := ${go.getTypeDeclaration(paramGroup, pkg)}{\n`;
1143
1165
  const params = paramGroups.get(paramGroup);
1144
1166
  if (params) {
1167
+ indent.push();
1145
1168
  for (const param of params) {
1146
- content += `\t\t${naming.capitalize(param.name)}: ${getFinalParamValue(pkg, param, paramValues)},\n`;
1169
+ content += `${indent.get()}${naming.capitalize(param.name)}: ${getFinalParamValue(pkg, param, paramValues)},\n`;
1147
1170
  }
1171
+ indent.pop();
1148
1172
  }
1149
- content += '\t}\n';
1173
+ content += `${indent.get()}}\n`;
1150
1174
  }
1151
1175
  else {
1152
- content += `\tvar ${naming.uncapitalize(paramGroup.name)} *${go.getTypeDeclaration(paramGroup, pkg)}\n`;
1176
+ content += `${indent.get()}var ${naming.uncapitalize(paramGroup.name)} *${go.getTypeDeclaration(paramGroup, pkg)}\n`;
1153
1177
  const params = paramGroups.get(paramGroup);
1154
1178
  const paramNilCheck = new Array();
1155
1179
  if (params) {
@@ -1177,19 +1201,21 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
1177
1201
  }
1178
1202
  }
1179
1203
  }
1180
- content += `\tif ${paramNilCheck.join(' || ')} {\n`;
1181
- content += `\t\t${naming.uncapitalize(paramGroup.name)} = &${go.getTypeDeclaration(paramGroup, pkg)}{\n`;
1204
+ content += `${indent.get()}if ${paramNilCheck.join(' || ')} {\n`;
1205
+ content += `${indent.push().get()}${naming.uncapitalize(paramGroup.name)} = &${go.getTypeDeclaration(paramGroup, pkg)}{\n`;
1182
1206
  if (params) {
1207
+ indent.push();
1183
1208
  for (const param of params) {
1184
1209
  let byRef = '&';
1185
1210
  if (param.byValue || (!go.isRequiredParameter(param.style) && param.kind !== 'bodyParam' && !go.isFormBodyParameter(param) && param.kind !== 'multipartFormBodyParam')) {
1186
1211
  byRef = '';
1187
1212
  }
1188
- content += `\t\t\t${naming.capitalize(param.name)}: ${byRef}${getFinalParamValue(pkg, param, paramValues)},\n`;
1213
+ content += `${indent.get()}${naming.capitalize(param.name)}: ${byRef}${getFinalParamValue(pkg, param, paramValues)},\n`;
1189
1214
  }
1215
+ indent.pop();
1190
1216
  }
1191
- content += '\t\t}\n';
1192
- content += '\t}\n';
1217
+ content += `${indent.get()}}\n`;
1218
+ content += `${indent.pop().get()}}\n`;
1193
1219
  }
1194
1220
  }
1195
1221
  return {
@@ -1309,8 +1335,8 @@ function getFinalParamValue(pkg, param, paramValues) {
1309
1335
  return `splitHelper(${paramValue}, "${helpers.getDelimiterForCollectionFormat(param.collectionFormat)}")`;
1310
1336
  }
1311
1337
  }
1312
- else if (go.isHeaderParameter(param) && param.type.kind === 'constant' && param.type.type === 'string') {
1313
- // since headers aren't escaped, we cast required, string-based enums inline
1338
+ else if ((go.isHeaderParameter(param) || go.isQueryParameter(param)) && param.type.kind === 'constant' && param.type.type === 'string') {
1339
+ // query params from req.URL.Query() are already decoded, so like headers we cast required, string-based enums inline
1314
1340
  return `${go.getTypeDeclaration(param.type, pkg)}(${paramValue})`;
1315
1341
  }
1316
1342
  }