@azure-tools/typespec-go 0.10.7 → 0.11.1

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.js +51 -52
  11. package/dist/codegen.go/src/core/example.js.map +1 -1
  12. package/dist/codegen.go/src/core/helpers.d.ts +27 -11
  13. package/dist/codegen.go/src/core/helpers.d.ts.map +1 -1
  14. package/dist/codegen.go/src/core/helpers.js +56 -17
  15. package/dist/codegen.go/src/core/helpers.js.map +1 -1
  16. package/dist/codegen.go/src/core/interfaces.d.ts.map +1 -1
  17. package/dist/codegen.go/src/core/interfaces.js +4 -3
  18. package/dist/codegen.go/src/core/interfaces.js.map +1 -1
  19. package/dist/codegen.go/src/core/models.d.ts.map +1 -1
  20. package/dist/codegen.go/src/core/models.js +289 -230
  21. package/dist/codegen.go/src/core/models.js.map +1 -1
  22. package/dist/codegen.go/src/core/operations.d.ts.map +1 -1
  23. package/dist/codegen.go/src/core/operations.js +689 -407
  24. package/dist/codegen.go/src/core/operations.js.map +1 -1
  25. package/dist/codegen.go/src/core/options.js +3 -2
  26. package/dist/codegen.go/src/core/options.js.map +1 -1
  27. package/dist/codegen.go/src/core/polymorphics.d.ts.map +1 -1
  28. package/dist/codegen.go/src/core/polymorphics.js +55 -48
  29. package/dist/codegen.go/src/core/polymorphics.js.map +1 -1
  30. package/dist/codegen.go/src/core/responses.d.ts.map +1 -1
  31. package/dist/codegen.go/src/core/responses.js +28 -19
  32. package/dist/codegen.go/src/core/responses.js.map +1 -1
  33. package/dist/codegen.go/src/core/version.d.ts.map +1 -1
  34. package/dist/codegen.go/src/core/version.js +3 -2
  35. package/dist/codegen.go/src/core/version.js.map +1 -1
  36. package/dist/codegen.go/src/emitter.js +4 -1
  37. package/dist/codegen.go/src/emitter.js.map +1 -1
  38. package/dist/codegen.go/src/fake/factory.d.ts.map +1 -1
  39. package/dist/codegen.go/src/fake/factory.js +2 -2
  40. package/dist/codegen.go/src/fake/factory.js.map +1 -1
  41. package/dist/codegen.go/src/fake/servers.d.ts.map +1 -1
  42. package/dist/codegen.go/src/fake/servers.js +386 -259
  43. package/dist/codegen.go/src/fake/servers.js.map +1 -1
  44. package/dist/codemodel.go/src/client.d.ts +42 -5
  45. package/dist/codemodel.go/src/client.d.ts.map +1 -1
  46. package/dist/codemodel.go/src/client.js +13 -2
  47. package/dist/codemodel.go/src/client.js.map +1 -1
  48. package/dist/codemodel.go/src/param.d.ts +13 -2
  49. package/dist/codemodel.go/src/param.d.ts.map +1 -1
  50. package/dist/codemodel.go/src/param.js +6 -0
  51. package/dist/codemodel.go/src/param.js.map +1 -1
  52. package/dist/codemodel.go/src/type.d.ts +35 -12
  53. package/dist/codemodel.go/src/type.d.ts.map +1 -1
  54. package/dist/codemodel.go/src/type.js +14 -3
  55. package/dist/codemodel.go/src/type.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 +16 -1
  60. package/dist/typespec-go/src/tcgcadapter/clients.d.ts.map +1 -1
  61. package/dist/typespec-go/src/tcgcadapter/clients.js +205 -89
  62. package/dist/typespec-go/src/tcgcadapter/clients.js.map +1 -1
  63. package/dist/typespec-go/src/tcgcadapter/helpers.d.ts +22 -0
  64. package/dist/typespec-go/src/tcgcadapter/helpers.d.ts.map +1 -1
  65. package/dist/typespec-go/src/tcgcadapter/helpers.js +58 -0
  66. package/dist/typespec-go/src/tcgcadapter/helpers.js.map +1 -1
  67. package/dist/typespec-go/src/tcgcadapter/types.d.ts +23 -1
  68. package/dist/typespec-go/src/tcgcadapter/types.d.ts.map +1 -1
  69. package/dist/typespec-go/src/tcgcadapter/types.js +113 -26
  70. package/dist/typespec-go/src/tcgcadapter/types.js.map +1 -1
  71. package/package.json +11 -10
@@ -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,79 +228,127 @@ 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
  }
262
+ /** gathers all children, not just immediate children, in breadth first order */
263
+ const getAllSubClientsForCase = function (client) {
264
+ const result = new Array();
265
+ const visited = new Set();
266
+ const queue = new Array();
267
+ for (const clientAccessor of client.clientAccessors) {
268
+ if (helpers.clientHasNoExportedMethods(clientAccessor.returns)) {
269
+ continue;
270
+ }
271
+ if (!visited.has(clientAccessor.returns)) {
272
+ visited.add(clientAccessor.returns);
273
+ queue.push(clientAccessor.returns);
274
+ result.push(clientAccessor.returns);
275
+ }
276
+ }
277
+ while (queue.length > 0) {
278
+ const current = queue.shift();
279
+ for (const clientAccessor of current.clientAccessors) {
280
+ if (helpers.clientHasNoExportedMethods(clientAccessor.returns)) {
281
+ continue;
282
+ }
283
+ if (!visited.has(clientAccessor.returns)) {
284
+ visited.add(clientAccessor.returns);
285
+ queue.push(clientAccessor.returns);
286
+ result.push(clientAccessor.returns);
287
+ }
288
+ }
289
+ }
290
+ return result;
291
+ };
255
292
  const receiverName = serverTransport[0].toLowerCase();
256
293
  imports.add('strings');
257
294
  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';
295
+ content += `${indent.get()}var resp *http.Response\n${indent.get()}var err error\n\n`;
296
+ content += `${indent.get()}switch client {\n`;
260
297
  for (const subClient of subClients) {
261
- content += `\tcase "${subClient.name}":\n`;
298
+ // we must include all child clients, not just the immediate children
299
+ const subClientsForCase = getAllSubClientsForCase(subClient);
300
+ const allClientNamesForCase = new Array(`"${subClient.name}"`);
301
+ allClientNamesForCase.push(...subClientsForCase.map((each) => `"${each.name}"`));
302
+ content += `${indent.get()}case ${allClientNamesForCase.join(', ')}:\n`;
262
303
  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`;
304
+ indent.push();
305
+ content += `${indent.get()}initServer(&${receiverName}.trMu, &${receiverName}.tr${serverName}, func() *${serverName}Transport {\n`;
306
+ content += `${indent.get()}return New${serverName}Transport(&${receiverName}.srv.${serverName}) })\n`;
307
+ content += `${indent.get()}resp, err = ${receiverName}.tr${serverName}.Do(req)\n`;
308
+ indent.pop();
265
309
  }
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';
310
+ content += `${indent.get()}default:\n`;
311
+ content += `${indent.push().get()}err = fmt.Errorf("unhandled client %s", client)\n`;
312
+ indent.pop();
313
+ content += `${indent.get()}}\n\n`; // end switch
314
+ content += `${indent.get()}return resp, err\n}\n\n`;
269
315
  return content;
270
316
  }
271
- function generateServerTransportMethodDispatch(serverTransport, client, finalMethods) {
317
+ function generateServerTransportMethodDispatch(serverTransport, client, finalMethods, indent) {
272
318
  if (finalMethods.length === 0) {
273
319
  return '';
274
320
  }
275
321
  const receiverName = serverTransport[0].toLowerCase();
276
322
  let content = `func (${receiverName} *${serverTransport}) ${dispatchMethodFake}(req *http.Request, method string) (*http.Response, error) {\n`;
277
- content += '\tresultChan := make(chan result, 1)\n';
278
- content += '\tgo func() {\n\t\tvar intercepted bool\n\t\tvar res result\n';
323
+ content += `${indent.get()}resultChan := make(chan result, 1)\n`;
324
+ content += `${indent.get()}go func() {\n`;
325
+ indent.push();
326
+ content += `${indent.get()}var intercepted bool\n${indent.get()}var res result\n`;
279
327
  const interceptorVarName = getTransportInterceptorVarName(client);
280
- content += `\t\t if ${interceptorVarName} != nil {\n`;
281
- content += `\t\t\t res.resp, res.err, intercepted = ${interceptorVarName}.Do(req)\n\t\t}\n`;
282
- content += '\t\tif !intercepted {\n';
283
- content += '\t\t\tswitch method {\n';
328
+ content += `${indent.get()} if ${interceptorVarName} != nil {\n`;
329
+ content += `${indent.push().get()} res.resp, res.err, intercepted = ${interceptorVarName}.Do(req)\n`;
330
+ content += `${indent.pop().get()}}\n`;
331
+ content += `${indent.get()}if !intercepted {\n`;
332
+ indent.push();
333
+ content += `${indent.get()}switch method {\n`;
284
334
  for (const method of finalMethods) {
285
335
  const operationName = fixUpMethodName(method);
286
- content += `\t\t\tcase "${client.name}.${operationName}":\n`;
287
- content += `\t\t\t\tres.resp, res.err = ${receiverName}.dispatch${operationName}(req)\n`;
336
+ content += `${indent.get()}case "${client.name}.${operationName}":\n`;
337
+ content += `${indent.push().get()}res.resp, res.err = ${receiverName}.dispatch${operationName}(req)\n`;
338
+ indent.pop();
288
339
  }
289
- content += '\t\t\t\tdefault:\n\t\tres.err = fmt.Errorf("unhandled API %s", method)\n';
290
- content += '\t\t\t}\n\n'; // end switch
291
- content += '\t\t}\n'; // end if !intercepted
292
- content += '\t\tresultChan <- res\n';
293
- content += '\t}()\n\n'; // end goroutine
294
- content += '\tselect {\n';
295
- content += '\tcase <-req.Context().Done():\n';
296
- content += '\t\treturn nil, req.Context().Err()\n';
297
- content += '\tcase res := <-resultChan:\n';
298
- content += '\t\treturn res.resp, res.err\n';
299
- content += '\t}\n}\n\n';
340
+ content += `${indent.push().get()}default:\n`;
341
+ content += `${indent.get()}res.err = fmt.Errorf("unhandled API %s", method)\n`;
342
+ content += `${indent.pop().get()}}\n\n`; // end switch
343
+ content += `${indent.pop().get()}}\n`; // end if !intercepted
344
+ content += `${indent.get()}resultChan <- res\n`;
345
+ content += `${indent.pop().get()}}()\n\n`; // end goroutine
346
+ content += `${indent.get()}select {\n`;
347
+ content += `${indent.get()}case <-req.Context().Done():\n`;
348
+ content += `${indent.push().get()}return nil, req.Context().Err()\n`;
349
+ content += `${indent.pop().get()}case res := <-resultChan:\n`;
350
+ content += `${indent.push().get()}return res.resp, res.err\n`;
351
+ content += `${indent.pop().get()}}\n}\n\n`;
300
352
  return content;
301
353
  }
302
354
  /**
@@ -306,9 +358,10 @@ function generateServerTransportMethodDispatch(serverTransport, client, finalMet
306
358
  * @param serverTransport the name of the server transport type
307
359
  * @param finalMethods the array of methods for which to generate the fake transports
308
360
  * @param imports the import manager currently in scope
361
+ * @param indent the indentation helper currently in scope
309
362
  * @returns the text for the server transport methods
310
363
  */
311
- function generateServerTransportMethods(pkg, serverTransport, finalMethods, imports) {
364
+ function generateServerTransportMethods(pkg, serverTransport, finalMethods, imports, indent) {
312
365
  if (finalMethods.length === 0) {
313
366
  return '';
314
367
  }
@@ -320,48 +373,79 @@ function generateServerTransportMethods(pkg, serverTransport, finalMethods, impo
320
373
  let content = '';
321
374
  for (const method of finalMethods) {
322
375
  content += `func (${receiverName} *${serverTransport}) dispatch${fixUpMethodName(method)}(req *http.Request) (*http.Response, error) {\n`;
323
- content += `\tif ${receiverName}.srv.${fixUpMethodName(method)} == nil {\n`;
324
- content += `\t\treturn nil, &nonRetriableError{errors.New("fake for method ${fixUpMethodName(method)} not implemented")}\n\t}\n`;
376
+ content += `${indent.get()}if ${receiverName}.srv.${fixUpMethodName(method)} == nil {\n`;
377
+ content += `${indent.push().get()}return nil, &nonRetriableError{errors.New("fake for method ${fixUpMethodName(method)} not implemented")}\n`;
378
+ content += `${indent.pop().get()}}\n`;
325
379
  switch (method.kind) {
326
380
  case 'lroMethod':
327
381
  case 'lroPageableMethod':
328
382
  // must check LRO before pager as you can have paged LROs
329
- content += dispatchForLROBody(pkg, receiverName, method, imports);
383
+ content += dispatchForLROBody(pkg, receiverName, method, imports, indent);
330
384
  break;
331
385
  case 'method': {
332
- content += dispatchForOperationBody(pkg, receiverName, method, imports);
333
- content += '\trespContent := server.GetResponseContent(respr)\n';
386
+ content += dispatchForOperationBody(pkg, receiverName, method, imports, indent);
387
+ content += `${indent.get()}respContent := server.GetResponseContent(respr)\n`;
334
388
  const formattedStatusCodes = helpers.formatStatusCodes(method.httpStatusCodes);
335
- content += `\tif !slices.Contains([]int{${formattedStatusCodes}}, respContent.HTTPStatus) {\n`;
336
- content += `\t\treturn nil, &nonRetriableError{fmt.Errorf("unexpected status code %d. acceptable values are ${formattedStatusCodes}", respContent.HTTPStatus)}\n\t}\n`;
389
+ content += `${indent.get()}if !slices.Contains([]int{${formattedStatusCodes}}, respContent.HTTPStatus) {\n`;
390
+ content += `${indent.push().get()}return nil, &nonRetriableError{fmt.Errorf("unexpected status code %d. acceptable values are ${formattedStatusCodes}", respContent.HTTPStatus)}\n`;
391
+ content += `${indent.pop().get()}}\n`;
337
392
  if (!method.returns.result || method.returns.result.kind === 'headAsBooleanResult') {
338
- content += '\tresp, err := server.NewResponse(respContent, req, nil)\n';
393
+ content += `${indent.get()}resp, err := server.NewResponse(respContent, req, nil)\n`;
339
394
  }
340
395
  else if (method.returns.result.kind === 'anyResult') {
341
- content += `\tresp, err := server.MarshalResponseAs${method.returns.result.format}(respContent, server.GetResponse(respr).${getResultFieldName(method.returns.result)}, req)\n`;
396
+ content += `${indent.get()}resp, err := server.MarshalResponseAs${method.returns.result.format}(respContent, server.GetResponse(respr).${getResultFieldName(method.returns.result)}, req)\n`;
342
397
  }
343
398
  else if (method.returns.result.kind === 'binaryResult') {
344
- content += '\tresp, err := server.NewResponse(respContent, req, &server.ResponseOptions{\n';
345
- content += `\t\tBody: server.GetResponse(respr).${getResultFieldName(method.returns.result)},\n`;
346
- content += '\t\tContentType: req.Header.Get("Content-Type"),\n';
347
- content += '\t})\n';
399
+ content += `${indent.get()}resp, err := server.NewResponse(respContent, req, &server.ResponseOptions{\n`;
400
+ indent.push();
401
+ content += `${indent.get()}Body: server.GetResponse(respr).${getResultFieldName(method.returns.result)},\n`;
402
+ content += `${indent.get()}ContentType: req.Header.Get("Content-Type"),\n`;
403
+ content += `${indent.pop().get()}})\n`;
348
404
  }
349
405
  else if (method.returns.result.kind === 'monomorphicResult') {
350
406
  if (method.returns.result.monomorphicType.kind === 'encodedBytes') {
351
407
  const encoding = method.returns.result.monomorphicType.encoding;
352
- content += `\tresp, err := server.MarshalResponseAsByteArray(respContent, server.GetResponse(respr).${getResultFieldName(method.returns.result)}, runtime.Base64${encoding}Format, req)\n`;
408
+ content += `${indent.get()}resp, err := server.MarshalResponseAsByteArray(respContent, server.GetResponse(respr).${getResultFieldName(method.returns.result)}, runtime.Base64${encoding}Format, req)\n`;
353
409
  }
354
410
  else if (method.returns.result.monomorphicType.kind === 'rawJSON') {
355
411
  imports.add('bytes');
356
412
  imports.add('io');
357
- content += '\tresp, err := server.NewResponse(respContent, req, &server.ResponseOptions{\n';
358
- content += '\t\tBody: io.NopCloser(bytes.NewReader(server.GetResponse(respr).RawJSON)),\n';
359
- content += '\t\tContentType: "application/json",\n\t})\n';
413
+ content += `${indent.get()}resp, err := server.NewResponse(respContent, req, &server.ResponseOptions{\n`;
414
+ indent.push();
415
+ content += `${indent.get()}Body: io.NopCloser(bytes.NewReader(server.GetResponse(respr).RawJSON)),\n`;
416
+ content += `${indent.get()}ContentType: "application/json",\n`;
417
+ content += `${indent.pop().get()}})\n`;
418
+ }
419
+ else if (method.returns.result.format === 'Text') {
420
+ let contentToMarshal;
421
+ const respField = getResultFieldName(method.returns.result);
422
+ const getResponseField = `server.GetResponse(respr).${respField}`;
423
+ switch (method.returns.result.monomorphicType.kind) {
424
+ case 'scalar': {
425
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/to');
426
+ // create a local var that will hold the string-formatted scalar
427
+ contentToMarshal = `formatted${respField}`;
428
+ content += `${indent.get()}var ${contentToMarshal} *string\n`;
429
+ const localVar = naming.uncapitalize(respField);
430
+ const resultType = method.returns.result.monomorphicType;
431
+ // if value := server.GetResponse(respr).Value; value != nil {...format as string...}
432
+ content += `${indent.get()}${helpers.buildIfBlock(indent, {
433
+ condition: `${localVar} := ${getResponseField}; ${localVar} != nil`,
434
+ body: (indent) => `${indent.get()}${contentToMarshal} = to.Ptr(${helpers.formatValue(localVar, resultType, imports, true)})\n`,
435
+ })}\n`;
436
+ break;
437
+ }
438
+ case 'string':
439
+ contentToMarshal = getResponseField;
440
+ break;
441
+ default:
442
+ throw new CodegenError('UnsupportedTsp', `unsupported text return kind ${method.returns.result.monomorphicType.kind} for method ${method.receiver.type.name}.${method.name}`);
443
+ }
444
+ content += `${indent.get()}resp, err := server.MarshalResponseAsText(respContent, ${contentToMarshal}, req)\n`;
360
445
  }
361
446
  else {
362
447
  let respField = `.${getResultFieldName(method.returns.result)}`;
363
448
  if (method.returns.result.format === 'XML' && method.returns.result.monomorphicType.kind === 'slice') {
364
- // for XML array responses we use the response type directly as it has the necessary XML tag for proper marshalling
365
449
  respField = '';
366
450
  }
367
451
  let responseField = `server.GetResponse(respr)${respField}`;
@@ -369,34 +453,37 @@ function generateServerTransportMethods(pkg, serverTransport, finalMethods, impo
369
453
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime');
370
454
  responseField = `(*datetime.${method.returns.result.monomorphicType.format})(${responseField})`;
371
455
  }
372
- content += `\tresp, err := server.MarshalResponseAs${method.returns.result.format}(respContent, ${responseField}, req)\n`;
456
+ content += `${indent.get()}resp, err := server.MarshalResponseAs${method.returns.result.format}(respContent, ${responseField}, req)\n`;
373
457
  }
374
458
  }
375
459
  else if (method.returns.result.kind === 'modelResult' || method.returns.result.kind === 'polymorphicResult') {
376
460
  const respField = `.${getResultFieldName(method.returns.result)}`;
377
461
  const responseField = `server.GetResponse(respr)${respField}`;
378
- content += `\tresp, err := server.MarshalResponseAs${method.returns.result.format}(respContent, ${responseField}, req)\n`;
462
+ content += `${indent.get()}resp, err := server.MarshalResponseAs${method.returns.result.format}(respContent, ${responseField}, req)\n`;
379
463
  }
380
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
464
+ content += `${indent.get()}if err != nil {\n`;
465
+ content += `${indent.push().get()}return nil, err\n`;
466
+ content += `${indent.pop().get()}}\n`;
381
467
  // propagate any header response values into the *http.Response
382
468
  for (const header of method.returns.headers) {
383
469
  if (header.kind === 'headerMapResponse') {
384
- content += `\tfor k, v := range server.GetResponse(respr).${header.fieldName} {\n`;
385
- content += '\t\tif v != nil {\n';
386
- content += `\t\t\tresp.Header.Set("${header.headerName}"+k, *v)\n`;
387
- content += '\t\t}\n';
388
- content += '\t}\n';
470
+ content += `${indent.get()}for k, v := range server.GetResponse(respr).${header.fieldName} {\n`;
471
+ content += `${indent.push().get()}if v != nil {\n`;
472
+ content += `${indent.push().get()}resp.Header.Set("${header.headerName}"+k, *v)\n`;
473
+ content += `${indent.pop().get()}}\n`;
474
+ content += `${indent.pop().get()}}\n`;
389
475
  }
390
476
  else {
391
- content += `\tif val := server.GetResponse(respr).${header.fieldName}; val != nil {\n`;
392
- content += `\t\tresp.Header.Set("${header.headerName}", ${helpers.formatValue('val', header.type, imports, true)})\n\t}\n`;
477
+ content += `${indent.get()}if val := server.GetResponse(respr).${header.fieldName}; val != nil {\n`;
478
+ content += `${indent.push().get()}resp.Header.Set("${header.headerName}", ${helpers.formatValue('val', header.type, imports, true)})\n`;
479
+ content += `${indent.pop().get()}}\n`;
393
480
  }
394
481
  }
395
- content += '\treturn resp, nil\n';
482
+ content += `${indent.get()}return resp, nil\n`;
396
483
  break;
397
484
  }
398
485
  case 'pageableMethod':
399
- content += dispatchForPagerBody(pkg, receiverName, method, imports);
486
+ content += dispatchForPagerBody(pkg, receiverName, method, imports, indent);
400
487
  break;
401
488
  default:
402
489
  method;
@@ -413,25 +500,26 @@ function generateServerTransportMethods(pkg, serverTransport, finalMethods, impo
413
500
  * @param receiverName the name of the receiver for the dispatch method
414
501
  * @param method the method for which to emit dispatching logic
415
502
  * @param imports the import manager currently in scope
503
+ * @param indent the indentation helper currently in scope
416
504
  * @returns the text for dispatching logic
417
505
  */
418
- function dispatchForOperationBody(pkg, receiverName, method, imports) {
506
+ function dispatchForOperationBody(pkg, receiverName, method, imports, indent) {
419
507
  const methodParamGroups = helpers.getMethodParamGroups(method);
420
508
  const numPathParams = methodParamGroups.pathParams.filter((each) => !go.isLiteralParameter(each.style)).length;
421
509
  let content = '';
422
510
  if (numPathParams > 0) {
423
511
  imports.add('regexp');
424
- content += `\tconst regexStr = \`${createPathParamsRegex(method, methodParamGroups.pathParams)}\`\n`;
425
- content += '\tregex := regexp.MustCompile(regexStr)\n';
426
- content += '\tmatches := regex.FindStringSubmatch(req.URL.EscapedPath())\n';
512
+ content += `${indent.get()}const regexStr = \`${createPathParamsRegex(method, methodParamGroups.pathParams)}\`\n`;
513
+ content += `${indent.get()}regex := regexp.MustCompile(regexStr)\n`;
514
+ content += `${indent.get()}matches := regex.FindStringSubmatch(req.URL.EscapedPath())\n`;
427
515
  // the total number of matches is the number of capture groups
428
516
  // plus the full match. so we add + 1 to include the full match.
429
- content += `\tif len(matches) < ${numPathParams + 1} {\n`;
430
- content += '\t\treturn nil, fmt.Errorf("failed to parse path %s", req.URL.Path)\n\t}\n';
517
+ content += `${indent.get()}if len(matches) < ${numPathParams + 1} {\n`;
518
+ content += `${indent.push().get()}return nil, fmt.Errorf("failed to parse path %s", req.URL.Path)\n${indent.pop().get()}}\n`;
431
519
  }
432
520
  const allQueryParams = methodParamGroups.encodedQueryParams.concat(methodParamGroups.unencodedQueryParams);
433
521
  if (allQueryParams.find((each) => each.location === 'method' && !go.isLiteralParameter(each.style))) {
434
- content += '\tqp := req.URL.Query()\n';
522
+ content += `${indent.get()}qp := req.URL.Query()\n`;
435
523
  }
436
524
  // note that these are mutually exclusive
437
525
  const bodyParam = methodParamGroups.bodyParam;
@@ -446,21 +534,21 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
446
534
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/fake', 'azfake');
447
535
  switch (bodyParam.type.kind) {
448
536
  case 'encodedBytes':
449
- content += `\tbody, err := server.UnmarshalRequestAsByteArray(req, runtime.Base64${bodyParam.type.encoding}Format)\n`;
450
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
537
+ content += `${indent.get()}body, err := server.UnmarshalRequestAsByteArray(req, runtime.Base64${bodyParam.type.encoding}Format)\n`;
538
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
451
539
  break;
452
540
  case 'interface':
453
541
  requiredHelpers.readRequestBody = true;
454
- content += '\traw, err := readRequestBody(req)\n';
455
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
456
- content += `\tbody, err := unmarshal${bodyParam.type.name}(raw)\n`;
457
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
542
+ content += `${indent.get()}raw, err := readRequestBody(req)\n`;
543
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
544
+ content += `${indent.get()}body, err := unmarshal${bodyParam.type.name}(raw)\n`;
545
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
458
546
  break;
459
547
  case 'rawJSON':
460
548
  imports.add('io');
461
- content += '\tbody, err := io.ReadAll(req.Body)\n';
462
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
463
- content += '\treq.Body.Close()\n';
549
+ content += `${indent.get()}body, err := io.ReadAll(req.Body)\n`;
550
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
551
+ content += `${indent.get()}req.Body.Close()\n`;
464
552
  break;
465
553
  default: {
466
554
  let bodyTypeName = go.getTypeDeclaration(bodyParam.type, pkg);
@@ -468,8 +556,8 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
468
556
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime');
469
557
  bodyTypeName = `datetime.${bodyParam.type.format}`;
470
558
  }
471
- content += `\tbody, err := server.UnmarshalRequestAs${bodyParam.bodyFormat}[${bodyTypeName}](req)\n`;
472
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
559
+ content += `${indent.get()}body, err := server.UnmarshalRequestAs${bodyParam.bodyFormat}[${bodyTypeName}](req)\n`;
560
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
473
561
  }
474
562
  }
475
563
  }
@@ -477,8 +565,8 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
477
565
  case 'Text':
478
566
  if (bodyParam && !go.isLiteralParameter(bodyParam.style)) {
479
567
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/fake', 'azfake');
480
- content += '\tbody, err := server.UnmarshalRequestAsText(req)\n';
481
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
568
+ content += `${indent.get()}body, err := server.UnmarshalRequestAsText(req)\n`;
569
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
482
570
  }
483
571
  break;
484
572
  }
@@ -488,19 +576,20 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
488
576
  imports.add('io');
489
577
  imports.add('mime');
490
578
  imports.add('mime/multipart');
491
- content += '\t_, params, err := mime.ParseMediaType(req.Header.Get("Content-Type"))\n';
492
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
493
- content += '\treader := multipart.NewReader(req.Body, params["boundary"])\n';
579
+ content += `${indent.get()}_, params, err := mime.ParseMediaType(req.Header.Get("Content-Type"))\n`;
580
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
581
+ content += `${indent.get()}reader := multipart.NewReader(req.Body, params["boundary"])\n`;
494
582
  for (const param of multipartBodyParams) {
495
- content += `\tvar ${param.name} ${go.getTypeDeclaration(param.type, pkg)}\n`;
583
+ content += `${indent.get()}var ${param.name} ${go.getTypeDeclaration(param.type, pkg)}\n`;
496
584
  }
497
- content += '\tfor {\n';
498
- content += '\t\tvar part *multipart.Part\n';
499
- content += '\t\tpart, err = reader.NextPart()\n';
500
- content += '\t\tif errors.Is(err, io.EOF) {\n\t\t\tbreak\n';
501
- content += '\t\t} else if err != nil {\n\t\t\treturn nil, err\n\t\t}\n';
502
- content += '\t\tvar content []byte\n';
503
- content += '\t\tswitch fn := part.FormName(); fn {\n';
585
+ content += `${indent.get()}for {\n`;
586
+ indent.push();
587
+ content += `${indent.get()}var part *multipart.Part\n`;
588
+ content += `${indent.get()}part, err = reader.NextPart()\n`;
589
+ content += `${indent.get()}if errors.Is(err, io.EOF) {\n${indent.push().get()}break\n`;
590
+ content += `${indent.pop().get()}} else if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
591
+ content += `${indent.get()}var content []byte\n`;
592
+ content += `${indent.get()}switch fn := part.FormName(); fn {\n`;
504
593
  // specify boolTarget if parsing bools happens in place.
505
594
  // i.e. the result from the parsing doesn't require further conversion (e.g. casting)
506
595
  // otherwise the parsed value is in a local var named parsed.
@@ -513,40 +602,41 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
513
602
  case 'bool':
514
603
  if (boolTarget) {
515
604
  // we reuse the err var declared earlier when calling reader.NextPart()
516
- parsingCode = `\t\t\t${boolTarget}, err = strconv.ParseBool(string(content))\n`;
605
+ parsingCode = `${indent.get()}${boolTarget}, err = strconv.ParseBool(string(content))\n`;
517
606
  parseErr = 'err';
518
607
  }
519
608
  else {
520
- parsingCode = `\t\t\t${parseResults} := strconv.ParseBool(string(content))\n`;
609
+ parsingCode = `${indent.get()}${parseResults} := strconv.ParseBool(string(content))\n`;
521
610
  }
522
611
  break;
523
612
  case 'float32':
524
613
  case 'float64':
525
- parsingCode = `\t\t\t${parseResults} := strconv.ParseFloat(string(content), ${helpers.getBitSizeForNumber(typeName)})\n`;
614
+ parsingCode = `${indent.get()}${parseResults} := strconv.ParseFloat(string(content), ${helpers.getBitSizeForNumber(typeName)})\n`;
526
615
  break;
527
616
  case 'int8':
528
617
  case 'int16':
529
618
  case 'int32':
530
619
  case 'int64':
531
- parsingCode = `\t\t\t${parseResults} := strconv.ParseInt(string(content), 10, ${helpers.getBitSizeForNumber(typeName)})\n`;
620
+ parsingCode = `${indent.get()}${parseResults} := strconv.ParseInt(string(content), 10, ${helpers.getBitSizeForNumber(typeName)})\n`;
532
621
  break;
533
622
  default:
534
623
  throw new CodegenError('InternalError', `unhandled multipart parameter primitive type ${typeName}`);
535
624
  }
536
- parsingCode += `\t\t\tif ${parseErr} != nil {\n\t\t\t\treturn nil, ${parseErr}\n\t\t\t}\n`;
625
+ parsingCode += `${indent.get()}if ${parseErr} != nil {\n${indent.push().get()}return nil, ${parseErr}\n${indent.pop().get()}}\n`;
537
626
  return parsingCode;
538
627
  };
539
628
  const isModelType = function (type) {
540
629
  return type.kind === 'model' || type.kind === 'polymorphicModel';
541
630
  };
542
- const emitCase = function (caseValue, paramVar, type) {
543
- let caseContent = `\t\tcase "${caseValue}":\n`;
544
- caseContent += '\t\t\tcontent, err = io.ReadAll(part)\n';
545
- caseContent += '\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n';
631
+ const emitCase = function (caseValue, paramVar, type, destIsByValue) {
632
+ let caseContent = `${indent.get()}case "${caseValue}":\n`;
633
+ indent.push();
634
+ caseContent += `${indent.get()}content, err = io.ReadAll(part)\n`;
635
+ caseContent += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
546
636
  let assignedValue;
547
637
  if (isModelType(helpers.recursiveUnwrapMapSlice(type))) {
548
638
  imports.add('encoding/json');
549
- caseContent += `\t\t\tif err = json.Unmarshal(content, &${paramVar}); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n`;
639
+ caseContent += `${indent.get()}if err = json.Unmarshal(content, &${paramVar}); err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
550
640
  }
551
641
  else if (type.kind === 'readSeekCloser') {
552
642
  imports.add('bytes');
@@ -600,16 +690,17 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
600
690
  const contentType = 'part.Header.Get("Content-Type")';
601
691
  const filename = 'part.FileName()';
602
692
  if (type.kind === 'slice') {
603
- caseContent += `\t\t\t${paramVar} = append(${paramVar}, streaming.MultipartContent{\n`;
604
- caseContent += `\t\t\t\tBody: ${bodyContent},\n`;
605
- caseContent += `\t\t\t\tContentType: ${contentType},\n`;
606
- caseContent += `\t\t\t\tFilename: ${filename},\n`;
607
- caseContent += '\t\t\t})\n';
693
+ caseContent += `${indent.get()}${paramVar} = append(${paramVar}, streaming.MultipartContent{\n`;
694
+ indent.push();
695
+ caseContent += `${indent.get()}Body: ${bodyContent},\n`;
696
+ caseContent += `${indent.get()}ContentType: ${contentType},\n`;
697
+ caseContent += `${indent.get()}Filename: ${filename},\n`;
698
+ caseContent += `${indent.pop().get()}})\n`;
608
699
  }
609
700
  else {
610
- caseContent += `\t\t\t${paramVar}.Body = ${bodyContent}\n`;
611
- caseContent += `\t\t\t${paramVar}.ContentType = ${contentType}\n`;
612
- caseContent += `\t\t\t${paramVar}.Filename = ${filename}\n`;
701
+ caseContent += `${indent.get()}${paramVar}.Body = ${bodyContent}\n`;
702
+ caseContent += `${indent.get()}${paramVar}.ContentType = ${contentType}\n`;
703
+ caseContent += `${indent.get()}${paramVar}.Filename = ${filename}\n`;
613
704
  }
614
705
  }
615
706
  else if (type.kind === 'slice') {
@@ -622,37 +713,50 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
622
713
  throw new CodegenError('InternalError', `uhandled multipart parameter array element kind ${type.elementType.kind}`);
623
714
  }
624
715
  }
716
+ else if (type.kind === 'encodedBytes') {
717
+ imports.add('encoding/base64');
718
+ caseContent += `${indent.get()}${paramVar}, err = base64.${type.encoding}Encoding.DecodeString(string(content))\n`;
719
+ caseContent += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
720
+ }
625
721
  else {
626
722
  throw new CodegenError('InternalError', `uhandled multipart parameter kind ${type.kind}`);
627
723
  }
628
724
  if (assignedValue) {
629
- caseContent += `\t\t\t${paramVar} = ${assignedValue}\n`;
725
+ if (!destIsByValue) {
726
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/to');
727
+ assignedValue = `to.Ptr(${assignedValue})`;
728
+ }
729
+ caseContent += `${indent.get()}${paramVar} = ${assignedValue}\n`;
630
730
  }
731
+ indent.pop();
631
732
  return caseContent;
632
733
  };
633
734
  for (const param of multipartBodyParams) {
634
735
  if (isModelType(param.type)) {
635
736
  for (const field of param.type.fields) {
636
- content += emitCase(field.serializedName, `${param.name}.${field.name}`, field.type);
737
+ content += emitCase(field.serializedName, `${param.name}.${field.name}`, field.type, field.byValue);
637
738
  }
638
739
  }
639
740
  else {
640
- content += emitCase(param.name, param.name, param.type);
741
+ // for this case we've emitted local vars of the underlying
742
+ // type which is why we pass true for param destIsByValue
743
+ content += emitCase(param.name, param.name, param.type, true);
641
744
  }
642
745
  }
643
- content += '\t\tdefault:\n\t\t\treturn nil, fmt.Errorf("unexpected part %s", fn)\n';
644
- content += '\t\t}\n'; // end switch
645
- content += '\t}\n'; // end for
746
+ content += `${indent.get()}default:\n`;
747
+ content += `${indent.push().get()}return nil, fmt.Errorf("unexpected part %s", fn)\n`;
748
+ content += `${indent.pop().get()}}\n`; // end switch
749
+ content += `${indent.pop().get()}}\n`; // end for
646
750
  }
647
751
  else if (formBodyParams.length > 0) {
648
752
  for (const param of formBodyParams) {
649
- content += `\tvar ${param.name} ${go.getTypeDeclaration(param.type, pkg)}\n`;
753
+ content += `${indent.get()}var ${param.name} ${go.getTypeDeclaration(param.type, pkg)}\n`;
650
754
  }
651
- content += '\tif err := req.ParseForm(); err != nil {\n\t\treturn nil, &nonRetriableError{fmt.Errorf("failed parsing form data: %v", err)}\n\t}\n';
652
- content += '\tfor key := range req.Form {\n';
653
- content += '\t\tswitch key {\n';
755
+ 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`;
756
+ content += `${indent.get()}for key := range req.Form {\n`;
757
+ content += `${indent.push().get()}switch key {\n`;
654
758
  for (const param of formBodyParams) {
655
- content += `\t\tcase "${param.formDataName}":\n`;
759
+ content += `${indent.get()}case "${param.formDataName}":\n`;
656
760
  let assignedValue;
657
761
  switch (param.type.kind) {
658
762
  case 'constant':
@@ -664,22 +768,24 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
664
768
  default:
665
769
  throw new CodegenError('InternalError', `uhandled form parameter kind ${param.type.kind}`);
666
770
  }
667
- content += `\t\t\t${param.name} = ${assignedValue}\n`;
771
+ content += `${indent.push().get()}${param.name} = ${assignedValue}\n`;
772
+ indent.pop();
668
773
  }
669
- content += '\t\t}\n'; // end switch
670
- content += '\t}\n'; // end for
774
+ content += `${indent.pop().get()}}\n`; // end switch
775
+ content += `${indent.get()}}\n`; // end for
671
776
  }
672
777
  else if (partialBodyParams.length > 0) {
673
778
  // construct the partial body params type and unmarshal it
674
- content += '\ttype partialBodyParams struct {\n';
779
+ content += `${indent.get()}type partialBodyParams struct {\n`;
780
+ indent.push();
675
781
  for (const partialBodyParam of partialBodyParams) {
676
- content += `\t\t${naming.capitalize(partialBodyParam.name)} ${helpers.star(partialBodyParam.byValue)}${go.getTypeDeclaration(partialBodyParam.type, pkg)} \`json:"${partialBodyParam.serializedName}"\`\n`;
782
+ content += `${indent.get()}${naming.capitalize(partialBodyParam.name)} ${helpers.star(partialBodyParam.byValue)}${go.getTypeDeclaration(partialBodyParam.type, pkg)} \`json:"${partialBodyParam.serializedName}"\`\n`;
677
783
  }
678
- content += '\t}\n';
679
- content += `\tbody, err := server.UnmarshalRequestAs${partialBodyParams[0].format}[partialBodyParams](req)\n`;
680
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
784
+ content += `${indent.pop().get()}}\n`;
785
+ content += `${indent.get()}body, err := server.UnmarshalRequestAs${partialBodyParams[0].format}[partialBodyParams](req)\n`;
786
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
681
787
  }
682
- const result = parseHeaderPathQueryParams(pkg, method, imports);
788
+ const result = parseHeaderPathQueryParams(pkg, method, imports, indent);
683
789
  content += result.content;
684
790
  // translate each partial body param to its field within the unmarshalled body
685
791
  for (const partialBodyParam of partialBodyParams) {
@@ -690,9 +796,9 @@ function dispatchForOperationBody(pkg, receiverName, method, imports) {
690
796
  content += `resp ${apiCall}\n`;
691
797
  return content;
692
798
  }
693
- content += `\trespr, errRespr ${apiCall}\n`;
694
- content += '\tif respErr := server.GetError(errRespr, req); respErr != nil {\n';
695
- content += '\t\treturn nil, respErr\n\t}\n';
799
+ content += `${indent.get()}respr, errRespr ${apiCall}\n`;
800
+ content += `${indent.get()}if respErr := server.GetError(errRespr, req); respErr != nil {\n`;
801
+ content += `${indent.push().get()}return nil, respErr\n${indent.pop().get()}}\n`;
696
802
  return content;
697
803
  }
698
804
  function getMethodStatusCodes(method) {
@@ -720,27 +826,34 @@ function getMethodStatusCodes(method) {
720
826
  * @param receiverName the name of the receiver for the dispatch method
721
827
  * @param method the LRO method for which to emit the dispatch logic
722
828
  * @param imports the import manager currently in scope
829
+ * @param indent the indentation helper currently in scope
723
830
  * @returns the text for the LRO dispatch logic
724
831
  */
725
- function dispatchForLROBody(pkg, receiverName, method, imports) {
832
+ function dispatchForLROBody(pkg, receiverName, method, imports, indent) {
726
833
  const operationName = fixUpMethodName(method);
727
834
  const localVarName = naming.uncapitalize(operationName);
728
835
  const operationStateMachine = `${receiverName}.${naming.uncapitalize(operationName)}`;
729
- let content = `\t${localVarName} := ${operationStateMachine}.get(req)\n`;
730
- content += `\tif ${localVarName} == nil {\n`;
731
- content += dispatchForOperationBody(pkg, receiverName, method, imports);
732
- content += `\t\t${localVarName} = &respr\n`;
733
- content += `\t\t${operationStateMachine}.add(req, ${localVarName})\n`;
734
- content += '\t}\n\n';
735
- content += `\tresp, err := server.PollerResponderNext(${localVarName}, req)\n`;
736
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n\n';
836
+ let content = `${indent.get()}${localVarName} := ${operationStateMachine}.get(req)\n`;
837
+ content += `${indent.get()}if ${localVarName} == nil {\n`;
838
+ content += dispatchForOperationBody(pkg, receiverName, method, imports, indent);
839
+ indent.push();
840
+ content += `${indent.get()}${localVarName} = &respr\n`;
841
+ content += `${indent.get()}${operationStateMachine}.add(req, ${localVarName})\n`;
842
+ content += `${indent.pop().get()}}\n\n`;
843
+ content += `${indent.get()}resp, err := server.PollerResponderNext(${localVarName}, req)\n`;
844
+ content += `${indent.get()}if err != nil {\n`;
845
+ content += `${indent.push().get()}return nil, err\n`;
846
+ content += `${indent.pop().get()}}\n\n`;
737
847
  const formattedStatusCodes = helpers.formatStatusCodes(getMethodStatusCodes(method));
738
- content += `\tif !slices.Contains([]int{${formattedStatusCodes}}, resp.StatusCode) {\n`;
739
- content += `\t\t${operationStateMachine}.remove(req)\n`;
740
- content += `\t\treturn nil, &nonRetriableError{fmt.Errorf("unexpected status code %d. acceptable values are ${formattedStatusCodes}", resp.StatusCode)}\n\t}\n`;
741
- content += `\tif !server.PollerResponderMore(${localVarName}) {\n`;
742
- content += `\t\t${operationStateMachine}.remove(req)\n\t}\n\n`;
743
- content += '\treturn resp, nil\n';
848
+ content += `${indent.get()}if !slices.Contains([]int{${formattedStatusCodes}}, resp.StatusCode) {\n`;
849
+ indent.push();
850
+ content += `${indent.get()}${operationStateMachine}.remove(req)\n`;
851
+ content += `${indent.get()}return nil, &nonRetriableError{fmt.Errorf("unexpected status code %d. acceptable values are ${formattedStatusCodes}", resp.StatusCode)}\n`;
852
+ content += `${indent.pop().get()}}\n`;
853
+ content += `${indent.get()}if !server.PollerResponderMore(${localVarName}) {\n`;
854
+ content += `${indent.push().get()}${operationStateMachine}.remove(req)\n`;
855
+ content += `${indent.pop().get()}}\n\n`;
856
+ content += `${indent.get()}return resp, nil\n`;
744
857
  return content;
745
858
  }
746
859
  /**
@@ -750,33 +863,41 @@ function dispatchForLROBody(pkg, receiverName, method, imports) {
750
863
  * @param receiverName the name of the receiver for the dispatch method
751
864
  * @param method the pageable method for which to emit the dispatch logic
752
865
  * @param imports the import manager currently in scope
866
+ * @param indent the indentation helper currently in scope
753
867
  * @returns the text for the pageable dispatch logic
754
868
  */
755
- function dispatchForPagerBody(pkg, receiverName, method, imports) {
869
+ function dispatchForPagerBody(pkg, receiverName, method, imports, indent) {
756
870
  const operationName = fixUpMethodName(method);
757
871
  const localVarName = naming.uncapitalize(operationName);
758
872
  const operationStateMachine = `${receiverName}.${naming.uncapitalize(operationName)}`;
759
- let content = `\t${localVarName} := ${operationStateMachine}.get(req)\n`;
760
- content += `\tif ${localVarName} == nil {\n`;
761
- content += dispatchForOperationBody(pkg, receiverName, method, imports);
762
- content += `\t\t${localVarName} = &resp\n`;
763
- content += `\t\t${operationStateMachine}.add(req, ${localVarName})\n`;
764
- if (method.nextLinkName) {
873
+ let content = `${indent.get()}${localVarName} := ${operationStateMachine}.get(req)\n`;
874
+ content += `${indent.get()}if ${localVarName} == nil {\n`;
875
+ content += dispatchForOperationBody(pkg, receiverName, method, imports, indent);
876
+ indent.push();
877
+ content += `${indent.get()}${localVarName} = &resp\n`;
878
+ content += `${indent.get()}${operationStateMachine}.add(req, ${localVarName})\n`;
879
+ if (method.strategy?.kind === 'nextLink') {
765
880
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/to');
766
- content += `\t\tserver.PagerResponderInjectNextLinks(${localVarName}, req, func(page *${go.getTypeDeclaration(method.returns, pkg)}, createLink func() string) {\n`;
767
- content += `\t\t\tpage.${method.nextLinkName} = to.Ptr(createLink())\n`;
768
- content += '\t\t})\n';
881
+ content += `${indent.get()}server.PagerResponderInjectNextLinks(${localVarName}, req, func(page *${go.getTypeDeclaration(method.returns, pkg)}, createLink func() string) {\n`;
882
+ content += `${indent.push().get()}page.${helpers.buildNextLinkPath(method.strategy)} = to.Ptr(createLink())\n`;
883
+ content += `${indent.pop().get()}})\n`;
769
884
  }
770
- content += '\t}\n'; // end if
771
- content += `\tresp, err := server.PagerResponderNext(${localVarName}, req)\n`;
772
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
885
+ indent.pop();
886
+ content += `${indent.get()}}\n`; // end if
887
+ content += `${indent.get()}resp, err := server.PagerResponderNext(${localVarName}, req)\n`;
888
+ content += `${indent.get()}if err != nil {\n`;
889
+ content += `${indent.push().get()}return nil, err\n`;
890
+ content += `${indent.pop().get()}}\n`;
773
891
  const formattedStatusCodes = helpers.formatStatusCodes(method.httpStatusCodes);
774
- content += `\tif !slices.Contains([]int{${formattedStatusCodes}}, resp.StatusCode) {\n`;
775
- content += `\t\t${operationStateMachine}.remove(req)\n`;
776
- content += `\t\treturn nil, &nonRetriableError{fmt.Errorf("unexpected status code %d. acceptable values are ${formattedStatusCodes}", resp.StatusCode)}\n\t}\n`;
777
- content += `\tif !server.PagerResponderMore(${localVarName}) {\n`;
778
- content += `\t\t${operationStateMachine}.remove(req)\n\t}\n`;
779
- content += '\treturn resp, nil\n';
892
+ content += `${indent.get()}if !slices.Contains([]int{${formattedStatusCodes}}, resp.StatusCode) {\n`;
893
+ indent.push();
894
+ content += `${indent.get()}${operationStateMachine}.remove(req)\n`;
895
+ content += `${indent.get()}return nil, &nonRetriableError{fmt.Errorf("unexpected status code %d. acceptable values are ${formattedStatusCodes}", resp.StatusCode)}\n`;
896
+ content += `${indent.pop().get()}}\n`;
897
+ content += `${indent.get()}if !server.PagerResponderMore(${localVarName}) {\n`;
898
+ content += `${indent.push().get()}${operationStateMachine}.remove(req)\n`;
899
+ content += `${indent.pop().get()}}\n`;
900
+ content += `${indent.get()}return resp, nil\n`;
780
901
  return content;
781
902
  }
782
903
  function sanitizeRegexpCaptureGroupName(name) {
@@ -808,9 +929,10 @@ function createPathParamsRegex(method, pathParams) {
808
929
  * @param pkg contains the package contents
809
930
  * @param method the method for which to emit parameter parsing logic
810
931
  * @param imports the import manager currently in scope
932
+ * @param indent the indentation helper currently in scope
811
933
  * @returns the parsing code and the params that contain the parsed values
812
934
  */
813
- function parseHeaderPathQueryParams(pkg, method, imports) {
935
+ function parseHeaderPathQueryParams(pkg, method, imports, indent) {
814
936
  let content = '';
815
937
  const paramValues = new Map();
816
938
  const createLocalVariableName = function (param, suffix) {
@@ -877,10 +999,10 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
877
999
  // for string-based enums, we perform the conversion as part of unescaping
878
1000
  requiredHelpers.parseWithCast = true;
879
1001
  paramVar = createLocalVariableName(param, 'Param');
880
- content += `\t${paramVar}, err := parseWithCast(${paramValue}, func (v string) (${go.getTypeDeclaration(param.type, pkg)}, error) {\n`;
881
- content += `\t\tp, unescapeErr := url.PathUnescape(v)\n`;
882
- content += '\t\tif unescapeErr != nil {\n\t\t\treturn "", unescapeErr\n\t\t}\n';
883
- content += `\t\treturn ${go.getTypeDeclaration(param.type, pkg)}(p), nil\n\t})\n`;
1002
+ content += `${indent.get()}${paramVar}, err := parseWithCast(${paramValue}, func (v string) (${go.getTypeDeclaration(param.type, pkg)}, error) {\n`;
1003
+ content += `${indent.push().get()}p, unescapeErr := url.PathUnescape(v)\n`;
1004
+ content += `${indent.get()}if unescapeErr != nil {\n${indent.push().get()}return "", unescapeErr\n${indent.pop().get()}}\n`;
1005
+ content += `${indent.get()}return ${go.getTypeDeclaration(param.type, pkg)}(p), nil\n${indent.pop().get()}})\n`;
884
1006
  }
885
1007
  else {
886
1008
  if (go.isRequiredParameter(param.style) && (param.type.kind === 'string' || (param.type.kind === 'slice' && param.type.elementType.kind === 'string'))) {
@@ -889,9 +1011,9 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
889
1011
  // else requires some amount of parsing/conversion.
890
1012
  paramVar = createLocalVariableName(param, 'Param');
891
1013
  }
892
- content += `\t${paramVar}, err := url.PathUnescape(${paramValue})\n`;
1014
+ content += `${indent.get()}${paramVar}, err := url.PathUnescape(${paramValue})\n`;
893
1015
  }
894
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
1016
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
895
1017
  paramValue = paramVar;
896
1018
  }
897
1019
  // parse params as required
@@ -901,7 +1023,7 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
901
1023
  if (param.collectionFormat !== 'multi') {
902
1024
  requiredHelpers.splitHelper = true;
903
1025
  const elementsParam = createLocalVariableName(param, 'Elements');
904
- content += `\t${elementsParam} := splitHelper(${paramValue}, "${helpers.getDelimiterForCollectionFormat(param.collectionFormat)}")\n`;
1026
+ content += `${indent.get()}${elementsParam} := splitHelper(${paramValue}, "${helpers.getDelimiterForCollectionFormat(param.collectionFormat)}")\n`;
905
1027
  paramValue = elementsParam;
906
1028
  }
907
1029
  const paramVar = createLocalVariableName(param, 'Param');
@@ -921,20 +1043,21 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
921
1043
  throw new CodegenError('InternalError', `unhandled element kind ${param.type.elementType.kind}`);
922
1044
  }
923
1045
  const toType = go.getTypeDeclaration(param.type.elementType, pkg);
924
- content += `\t${paramVar} := make([]${toType}, len(${paramValue}))\n`;
925
- content += `\tfor i := 0; i < len(${paramValue}); i++ {\n`;
1046
+ content += `${indent.get()}${paramVar} := make([]${toType}, len(${paramValue}))\n`;
1047
+ content += `${indent.get()}for i := 0; i < len(${paramValue}); i++ {\n`;
1048
+ indent.push();
926
1049
  let fromVar;
927
1050
  // TODO: consolidate with non-collection parsing code
928
1051
  if (elementFormat === 'bool') {
929
1052
  imports.add('strconv');
930
1053
  fromVar = 'parsedBool';
931
- content += `\t\t${fromVar}, parseErr := strconv.ParseBool(${paramValue}[i])\n`;
932
- content += '\t\tif parseErr != nil {\n\t\t\treturn nil, parseErr\n\t\t}\n';
1054
+ content += `${indent.get()}${fromVar}, parseErr := strconv.ParseBool(${paramValue}[i])\n`;
1055
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return nil, parseErr\n${indent.pop().get()}}\n`;
933
1056
  }
934
1057
  else if (elementFormat === 'float32' || elementFormat === 'float64' || elementFormat === 'int32' || elementFormat === 'int64') {
935
1058
  fromVar = `parsed${naming.capitalize(elementFormat)}`;
936
- content += `\t\t${fromVar}, parseErr := ${emitNumericConversion(`${paramValue}[i]`, elementFormat)}\n`;
937
- content += '\t\tif parseErr != nil {\n\t\t\treturn nil, parseErr\n\t\t}\n';
1059
+ content += `${indent.get()}${fromVar}, parseErr := ${emitNumericConversion(`${paramValue}[i]`, elementFormat)}\n`;
1060
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return nil, parseErr\n${indent.pop().get()}}\n`;
938
1061
  }
939
1062
  else if (elementFormat === 'string') {
940
1063
  // we're casting an enum string value to its const type
@@ -944,39 +1067,39 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
944
1067
  else if (elementFormat === 'Std' || elementFormat === 'URL') {
945
1068
  imports.add('encoding/base64');
946
1069
  fromVar = `parsed${naming.capitalize(elementFormat)}`;
947
- content += `\t\t${fromVar}, parseErr := base64.${elementFormat}Encoding.DecodeString(${paramValue}[i])\n`;
948
- content += '\t\tif parseErr != nil {\n\t\t\treturn nil, parseErr\n\t\t}\n';
1070
+ content += `${indent.get()}${fromVar}, parseErr := base64.${elementFormat}Encoding.DecodeString(${paramValue}[i])\n`;
1071
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return nil, parseErr\n${indent.pop().get()}}\n`;
949
1072
  }
950
1073
  else if (elementFormat === 'RFC1123' || elementFormat === 'RFC3339' || elementFormat === 'Unix') {
951
1074
  imports.add('time');
952
1075
  fromVar = `parsed${naming.capitalize(elementFormat)}`;
953
1076
  if (elementFormat === 'Unix') {
954
1077
  imports.add('strconv');
955
- content += `\t\tp, parseErr := strconv.ParseInt(${paramValue}[i], 10, 64)\n`;
956
- content += '\t\tif parseErr != nil {\n\t\t\treturn nil, parseErr\n\t\t}\n';
957
- content += `\t\t${fromVar} := time.Unix(p, 0).UTC()\n`;
1078
+ content += `${indent.get()}p, parseErr := strconv.ParseInt(${paramValue}[i], 10, 64)\n`;
1079
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return nil, parseErr\n${indent.pop().get()}}\n`;
1080
+ content += `${indent.get()}${fromVar} := time.Unix(p, 0).UTC()\n`;
958
1081
  }
959
1082
  else {
960
1083
  let format = 'time.RFC3339Nano';
961
1084
  if (elementFormat === 'RFC1123') {
962
1085
  format = 'time.RFC1123';
963
1086
  }
964
- content += `\t\t${fromVar}, parseErr := time.Parse(${format}, ${paramValue}[i])\n`;
965
- content += '\t\tif parseErr != nil {\n\t\t\treturn nil, parseErr\n\t\t}\n';
1087
+ content += `${indent.get()}${fromVar}, parseErr := time.Parse(${format}, ${paramValue}[i])\n`;
1088
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return nil, parseErr\n${indent.pop().get()}}\n`;
966
1089
  }
967
1090
  }
968
1091
  else {
969
1092
  throw new CodegenError('InternalError', `unhandled element format ${elementFormat}`);
970
1093
  }
971
1094
  // TODO: remove cast in some cases
972
- content += `\t\t${paramVar}[i] = ${toType}(${fromVar})\n\t}\n`;
1095
+ content += `${indent.get()}${paramVar}[i] = ${toType}(${fromVar})\n${indent.pop().get()}}\n`;
973
1096
  }
974
1097
  else if (!go.isRequiredParameter(param.style) && param.collectionFormat !== 'multi') {
975
1098
  // for slices of strings that are required, the call to splitHelper(...) is inlined into
976
1099
  // the invocation of the fake e.g. srv.FakeFunc(splitHelper...). but if it's optional, we
977
1100
  // need to create a local first which will later be copied into the optional param group.
978
1101
  requiredHelpers.splitHelper = true;
979
- content += `\t${createLocalVariableName(param, 'Param')} := splitHelper(${paramValue}, "${helpers.getDelimiterForCollectionFormat(param.collectionFormat)}")\n`;
1102
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')} := splitHelper(${paramValue}, "${helpers.getDelimiterForCollectionFormat(param.collectionFormat)}")\n`;
980
1103
  }
981
1104
  }
982
1105
  else if (param.type.kind === 'scalar' && param.type.type === 'bool') {
@@ -986,13 +1109,13 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
986
1109
  requiredHelpers.parseOptional = true;
987
1110
  from = `parseOptional(${paramValue}, strconv.ParseBool)`;
988
1111
  }
989
- content += `\t${createLocalVariableName(param, 'Param')}, err := ${from}\n`;
990
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
1112
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := ${from}\n`;
1113
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
991
1114
  }
992
1115
  else if (param.type.kind === 'encodedBytes') {
993
1116
  imports.add('encoding/base64');
994
- content += `\t${createLocalVariableName(param, 'Param')}, err := base64.${param.type.encoding}Encoding.DecodeString(${paramValue})\n`;
995
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
1117
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := base64.${param.type.encoding}Encoding.DecodeString(${paramValue})\n`;
1118
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
996
1119
  }
997
1120
  else if (param.type.kind === 'time') {
998
1121
  const formatMap = {
@@ -1009,8 +1132,8 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
1009
1132
  requiredHelpers.parseOptional = true;
1010
1133
  from = `parseOptional(${paramValue}, func(v string) (time.Time, error) { return time.Parse(${format}, v) })`;
1011
1134
  }
1012
- content += `\t${createLocalVariableName(param, 'Param')}, err := ${from}\n`;
1013
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
1135
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := ${from}\n`;
1136
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
1014
1137
  }
1015
1138
  else {
1016
1139
  imports.add('strconv');
@@ -1023,11 +1146,11 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
1023
1146
  requiredHelpers.parseWithCast = true;
1024
1147
  parser = 'parseWithCast';
1025
1148
  }
1026
- content += `\t${createLocalVariableName(param, 'Param')}, err := ${parser}(${paramValue}, func (v string) (time.Time, error) {\n`;
1027
- content += '\t\tp, parseErr := strconv.ParseInt(v, 10, 64)\n';
1028
- content += '\t\tif parseErr != nil {\n\t\t\treturn time.Time{}, parseErr\n\t\t}\n';
1029
- content += '\t\treturn time.Unix(p, 0).UTC(), nil\n\t})\n';
1030
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
1149
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := ${parser}(${paramValue}, func (v string) (time.Time, error) {\n`;
1150
+ content += `${indent.push().get()}p, parseErr := strconv.ParseInt(v, 10, 64)\n`;
1151
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return time.Time{}, parseErr\n${indent.pop().get()}}\n`;
1152
+ content += `${indent.get()}return time.Unix(p, 0).UTC(), nil\n${indent.pop().get()}})\n`;
1153
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
1031
1154
  }
1032
1155
  }
1033
1156
  else if (param.type.kind === 'scalar' && (param.type.type === 'float32' || param.type.type === 'float64' || param.type.type === 'int32' || param.type.type === 'int64')) {
@@ -1041,32 +1164,32 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
1041
1164
  parser = 'parseWithCast';
1042
1165
  }
1043
1166
  if (param.type.type === 'float32' || param.type.type === 'int32' || !go.isRequiredParameter(param.style)) {
1044
- content += `\t${createLocalVariableName(param, 'Param')}, err := ${parser}(${paramValue}, func(v string) (${param.type.type}, error) {\n`;
1045
- content += `\t\tp, parseErr := ${emitNumericConversion('v', param.type.type)}\n`;
1046
- content += '\t\tif parseErr != nil {\n\t\t\treturn 0, parseErr\n\t\t}\n';
1167
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := ${parser}(${paramValue}, func(v string) (${param.type.type}, error) {\n`;
1168
+ content += `${indent.push().get()}p, parseErr := ${emitNumericConversion('v', param.type.type)}\n`;
1169
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return 0, parseErr\n${indent.pop().get()}}\n`;
1047
1170
  let result = 'p';
1048
1171
  if (param.type.type === 'float32' || param.type.type === 'int32') {
1049
1172
  result = `${param.type.type}(${result})`;
1050
1173
  }
1051
- content += `\t\treturn ${result}, nil\n\t})\n`;
1174
+ content += `${indent.get()}return ${result}, nil\n${indent.pop().get()}})\n`;
1052
1175
  }
1053
1176
  else {
1054
- content += `\t${createLocalVariableName(param, 'Param')}, err := ${emitNumericConversion(paramValue, param.type.type)}\n`;
1177
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := ${emitNumericConversion(paramValue, param.type.type)}\n`;
1055
1178
  }
1056
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
1179
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
1057
1180
  }
1058
1181
  else if (param.kind === 'headerMapParam') {
1059
1182
  imports.add('strings');
1060
1183
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/to');
1061
1184
  const localVar = createLocalVariableName(param, 'Param');
1062
- content += `\tvar ${localVar} map[string]*string\n`;
1063
- content += `\tfor hh := range ${paramValue} {\n`;
1185
+ content += `${indent.get()}var ${localVar} map[string]*string\n`;
1186
+ content += `${indent.get()}for hh := range ${paramValue} {\n`;
1064
1187
  const headerPrefix = param.headerName;
1065
1188
  requiredHelpers.getHeaderValue = true;
1066
- content += `\t\tif len(hh) > len("${headerPrefix}") && strings.EqualFold(hh[:len("x-ms-meta-")], "${headerPrefix}") {\n`;
1067
- content += `\t\t\tif ${localVar} == nil {\n\t\t\t\t${localVar} = map[string]*string{}\n\t\t\t}\n`;
1068
- content += `\t\t\t${localVar}[hh[len("${headerPrefix}"):]] = to.Ptr(getHeaderValue(req.Header, hh))\n`;
1069
- content += '\t\t}\n\t}\n';
1189
+ content += `${indent.push().get()}if len(hh) > len("${headerPrefix}") && strings.EqualFold(hh[:len("x-ms-meta-")], "${headerPrefix}") {\n`;
1190
+ content += `${indent.push().get()}if ${localVar} == nil {\n${indent.push().get()}${localVar} = map[string]*string{}\n${indent.pop().get()}}\n`;
1191
+ content += `${indent.get()}${localVar}[hh[len("${headerPrefix}"):]] = to.Ptr(getHeaderValue(req.Header, hh))\n`;
1192
+ content += `${indent.pop().get()}}\n${indent.pop().get()}}\n`;
1070
1193
  }
1071
1194
  else if (param.type.kind === 'constant' && param.type.type !== 'string') {
1072
1195
  let parseHelper;
@@ -1091,11 +1214,11 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
1091
1214
  zeroValue = '0';
1092
1215
  }
1093
1216
  const toConstType = go.getTypeDeclaration(param.type, pkg);
1094
- content += `\t${createLocalVariableName(param, 'Param')}, err := ${parseHelper}(${paramValue}, func(v string) (${toConstType}, error) {\n`;
1095
- content += `\t\tp, parseErr := ${parse}\n`;
1096
- content += `\t\tif parseErr != nil {\n\t\t\treturn ${zeroValue}, parseErr\n\t\t}\n`;
1097
- content += `\t\treturn ${toConstType}(p), nil\n\t})\n`;
1098
- content += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
1217
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')}, err := ${parseHelper}(${paramValue}, func(v string) (${toConstType}, error) {\n`;
1218
+ content += `${indent.push().get()}p, parseErr := ${parse}\n`;
1219
+ content += `${indent.get()}if parseErr != nil {\n${indent.push().get()}return ${zeroValue}, parseErr\n${indent.pop().get()}}\n`;
1220
+ content += `${indent.get()}return ${toConstType}(p), nil\n${indent.pop().get()}})\n`;
1221
+ content += `${indent.get()}if err != nil {\n${indent.push().get()}return nil, err\n${indent.pop().get()}}\n`;
1099
1222
  }
1100
1223
  else if (!go.isRequiredParameter(param.style)) {
1101
1224
  // we check this last as it's a superset of the previous conditions
@@ -1104,23 +1227,25 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
1104
1227
  imports.addForType(param.type);
1105
1228
  paramValue = `${go.getTypeDeclaration(param.type, pkg)}(${paramValue})`;
1106
1229
  }
1107
- content += `\t${createLocalVariableName(param, 'Param')} := getOptional(${paramValue})\n`;
1230
+ content += `${indent.get()}${createLocalVariableName(param, 'Param')} := getOptional(${paramValue})\n`;
1108
1231
  }
1109
1232
  }
1110
1233
  // create the param groups and populate their values
1111
1234
  for (const paramGroup of paramGroups.keys()) {
1112
1235
  if (paramGroup.required) {
1113
- content += `\t${naming.uncapitalize(paramGroup.name)} := ${go.getTypeDeclaration(paramGroup, pkg)}{\n`;
1236
+ content += `${indent.get()}${naming.uncapitalize(paramGroup.name)} := ${go.getTypeDeclaration(paramGroup, pkg)}{\n`;
1114
1237
  const params = paramGroups.get(paramGroup);
1115
1238
  if (params) {
1239
+ indent.push();
1116
1240
  for (const param of params) {
1117
- content += `\t\t${naming.capitalize(param.name)}: ${getFinalParamValue(pkg, param, paramValues)},\n`;
1241
+ content += `${indent.get()}${naming.capitalize(param.name)}: ${getFinalParamValue(pkg, param, paramValues)},\n`;
1118
1242
  }
1243
+ indent.pop();
1119
1244
  }
1120
- content += '\t}\n';
1245
+ content += `${indent.get()}}\n`;
1121
1246
  }
1122
1247
  else {
1123
- content += `\tvar ${naming.uncapitalize(paramGroup.name)} *${go.getTypeDeclaration(paramGroup, pkg)}\n`;
1248
+ content += `${indent.get()}var ${naming.uncapitalize(paramGroup.name)} *${go.getTypeDeclaration(paramGroup, pkg)}\n`;
1124
1249
  const params = paramGroups.get(paramGroup);
1125
1250
  const paramNilCheck = new Array();
1126
1251
  if (params) {
@@ -1148,19 +1273,21 @@ function parseHeaderPathQueryParams(pkg, method, imports) {
1148
1273
  }
1149
1274
  }
1150
1275
  }
1151
- content += `\tif ${paramNilCheck.join(' || ')} {\n`;
1152
- content += `\t\t${naming.uncapitalize(paramGroup.name)} = &${go.getTypeDeclaration(paramGroup, pkg)}{\n`;
1276
+ content += `${indent.get()}if ${paramNilCheck.join(' || ')} {\n`;
1277
+ content += `${indent.push().get()}${naming.uncapitalize(paramGroup.name)} = &${go.getTypeDeclaration(paramGroup, pkg)}{\n`;
1153
1278
  if (params) {
1279
+ indent.push();
1154
1280
  for (const param of params) {
1155
1281
  let byRef = '&';
1156
1282
  if (param.byValue || (!go.isRequiredParameter(param.style) && param.kind !== 'bodyParam' && !go.isFormBodyParameter(param) && param.kind !== 'multipartFormBodyParam')) {
1157
1283
  byRef = '';
1158
1284
  }
1159
- content += `\t\t\t${naming.capitalize(param.name)}: ${byRef}${getFinalParamValue(pkg, param, paramValues)},\n`;
1285
+ content += `${indent.get()}${naming.capitalize(param.name)}: ${byRef}${getFinalParamValue(pkg, param, paramValues)},\n`;
1160
1286
  }
1287
+ indent.pop();
1161
1288
  }
1162
- content += '\t\t}\n';
1163
- content += '\t}\n';
1289
+ content += `${indent.get()}}\n`;
1290
+ content += `${indent.pop().get()}}\n`;
1164
1291
  }
1165
1292
  }
1166
1293
  return {