@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
@@ -23,8 +23,9 @@ export function generateModels(pkg, options) {
23
23
  const modelImports = new ImportManager(pkg);
24
24
  const serdeImports = new ImportManager(pkg);
25
25
  let modelText = helpers.contentPreamble(pkg);
26
+ const indent = new helpers.Indentation();
26
27
  // we do model generation first as it can add imports to the imports list
27
- const modelDefs = generateModelDefs(modelImports, serdeImports, pkg, options);
28
+ const modelDefs = generateModelDefs(modelImports, serdeImports, pkg, options, indent);
28
29
  modelText += modelImports.text();
29
30
  // structs
30
31
  let needsJSONPopulate = false;
@@ -36,7 +37,7 @@ export function generateModels(pkg, options) {
36
37
  let needsJSONPopulateMultipart = false;
37
38
  let serdeTextBody = '';
38
39
  for (const modelDef of modelDefs) {
39
- modelText += modelDef.text();
40
+ modelText += modelDef.text(indent);
40
41
  modelDef.Methods.sort((a, b) => {
41
42
  return helpers.sortAscending(a.name, b.name);
42
43
  });
@@ -81,13 +82,13 @@ export function generateModels(pkg, options) {
81
82
  serdeImports.add('reflect');
82
83
  serdeImports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore');
83
84
  serdeTextBody += 'func populate(m map[string]any, k string, v any) {\n';
84
- serdeTextBody += '\tif v == nil {\n';
85
- serdeTextBody += '\t\treturn\n';
86
- serdeTextBody += '\t} else if azcore.IsNullValue(v) {\n';
87
- serdeTextBody += '\t\tm[k] = nil\n';
88
- serdeTextBody += '\t} else if !reflect.ValueOf(v).IsNil() {\n';
89
- serdeTextBody += '\t\tm[k] = v\n';
90
- serdeTextBody += '\t}\n';
85
+ serdeTextBody += `${indent.get()}if v == nil {\n`;
86
+ serdeTextBody += `${indent.push().get()}return\n`;
87
+ serdeTextBody += `${indent.pop().get()}} else if azcore.IsNullValue(v) {\n`;
88
+ serdeTextBody += `${indent.push().get()}m[k] = nil\n`;
89
+ serdeTextBody += `${indent.pop().get()}} else if !reflect.ValueOf(v).IsNil() {\n`;
90
+ serdeTextBody += `${indent.push().get()}m[k] = v\n`;
91
+ serdeTextBody += `${indent.pop().get()}}\n`;
91
92
  serdeTextBody += '}\n\n';
92
93
  }
93
94
  if (needsJSONPopulateTime) {
@@ -95,80 +96,85 @@ export function generateModels(pkg, options) {
95
96
  serdeImports.add('reflect');
96
97
  serdeImports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore');
97
98
  serdeTextBody += 'func populateTime[T dateTimeConstraints](m map[string]any, k string, t *time.Time) {\n';
98
- serdeTextBody += '\tif t == nil {\n';
99
- serdeTextBody += '\t\treturn\n';
100
- serdeTextBody += '\t} else if azcore.IsNullValue(t) {\n';
101
- serdeTextBody += '\t\tm[k] = nil\n';
102
- serdeTextBody += '\t} else if !reflect.ValueOf(t).IsNil() {\n';
103
- serdeTextBody += '\t\tnewTime := T(*t)\n';
104
- serdeTextBody += '\t\tm[k] = (*T)(&newTime)\n';
105
- serdeTextBody += '\t}\n';
99
+ serdeTextBody += `${indent.get()}if t == nil {\n`;
100
+ serdeTextBody += `${indent.push().get()}return\n`;
101
+ serdeTextBody += `${indent.pop().get()}} else if azcore.IsNullValue(t) {\n`;
102
+ serdeTextBody += `${indent.push().get()}m[k] = nil\n`;
103
+ serdeTextBody += `${indent.pop().get()}} else if !reflect.ValueOf(t).IsNil() {\n`;
104
+ indent.push();
105
+ serdeTextBody += `${indent.get()}newTime := T(*t)\n`;
106
+ serdeTextBody += `${indent.get()}m[k] = (*T)(&newTime)\n`;
107
+ indent.pop();
108
+ serdeTextBody += `${indent.get()}}\n`;
106
109
  serdeTextBody += '}\n\n';
107
110
  }
108
111
  if (needsJSONPopulateAny) {
109
112
  serdeImports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore');
110
113
  serdeTextBody += 'func populateAny(m map[string]any, k string, v any) {\n';
111
- serdeTextBody += '\tif v == nil {\n';
112
- serdeTextBody += '\t\treturn\n';
113
- serdeTextBody += '\t} else if azcore.IsNullValue(v) {\n';
114
- serdeTextBody += '\t\tm[k] = nil\n';
115
- serdeTextBody += '\t} else {\n';
116
- serdeTextBody += '\t\tm[k] = v\n';
117
- serdeTextBody += '\t}\n';
114
+ serdeTextBody += `${indent.get()}if v == nil {\n`;
115
+ serdeTextBody += `${indent.push().get()}return\n`;
116
+ serdeTextBody += `${indent.pop().get()}} else if azcore.IsNullValue(v) {\n`;
117
+ serdeTextBody += `${indent.push().get()}m[k] = nil\n`;
118
+ serdeTextBody += `${indent.pop().get()}} else {\n`;
119
+ serdeTextBody += `${indent.push().get()}m[k] = v\n`;
120
+ serdeTextBody += `${indent.pop().get()}}\n`;
118
121
  serdeTextBody += '}\n\n';
119
122
  }
120
123
  if (needsJSONPopulateByteArray) {
121
124
  serdeImports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore');
122
125
  serdeImports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
123
126
  serdeTextBody += 'func populateByteArray[T any](m map[string]any, k string, b []T, convert func() any) {\n';
124
- serdeTextBody += '\tif azcore.IsNullValue(b) {\n';
125
- serdeTextBody += '\t\tm[k] = nil\n';
126
- serdeTextBody += '\t} else if len(b) == 0 {\n';
127
- serdeTextBody += '\t\treturn\n';
128
- serdeTextBody += '\t} else {\n';
129
- serdeTextBody += '\t\tm[k] = convert()\n';
130
- serdeTextBody += '\t}\n';
127
+ serdeTextBody += `${indent.get()}if azcore.IsNullValue(b) {\n`;
128
+ serdeTextBody += `${indent.push().get()}m[k] = nil\n`;
129
+ serdeTextBody += `${indent.pop().get()}} else if len(b) == 0 {\n`;
130
+ serdeTextBody += `${indent.push().get()}return\n`;
131
+ serdeTextBody += `${indent.pop().get()}} else {\n`;
132
+ serdeTextBody += `${indent.push().get()}m[k] = convert()\n`;
133
+ serdeTextBody += `${indent.pop().get()}}\n`;
131
134
  serdeTextBody += '}\n\n';
132
135
  }
133
136
  if (needsJSONUnpopulate) {
134
137
  serdeImports.add('fmt');
135
138
  serdeTextBody += 'func unpopulate(data json.RawMessage, fn string, v any) error {\n';
136
- serdeTextBody += '\tif data == nil || string(data) == "null" {\n';
137
- serdeTextBody += '\t\treturn nil\n';
138
- serdeTextBody += '\t}\n';
139
- serdeTextBody += '\tif err := json.Unmarshal(data, v); err != nil {\n';
140
- serdeTextBody += '\t\treturn fmt.Errorf("struct field %s: %v", fn, err)\n';
141
- serdeTextBody += '\t}\n';
142
- serdeTextBody += '\treturn nil\n';
139
+ serdeTextBody += `${indent.get()}if data == nil || string(data) == "null" {\n`;
140
+ serdeTextBody += `${indent.push().get()}return nil\n`;
141
+ serdeTextBody += `${indent.pop().get()}}\n`;
142
+ serdeTextBody += `${indent.get()}if err := json.Unmarshal(data, v); err != nil {\n`;
143
+ serdeTextBody += `${indent.push().get()}return fmt.Errorf("struct field %s: %v", fn, err)\n`;
144
+ serdeTextBody += `${indent.pop().get()}}\n`;
145
+ serdeTextBody += `${indent.get()}return nil\n`;
143
146
  serdeTextBody += '}\n\n';
144
147
  }
145
148
  if (needsJSONUnpopulateTime) {
146
149
  serdeImports.add('fmt');
147
150
  serdeImports.add('time');
148
151
  serdeTextBody += 'func unpopulateTime[T dateTimeConstraints](data json.RawMessage, fn string, t **time.Time) error {\n';
149
- serdeTextBody += '\tif data == nil || string(data) == "null" {\n';
150
- serdeTextBody += '\t\treturn nil\n';
151
- serdeTextBody += '\t}\n';
152
- serdeTextBody += '\tvar aux T\n';
153
- serdeTextBody += '\tif err := json.Unmarshal(data, &aux); err != nil {\n';
154
- serdeTextBody += '\t\treturn fmt.Errorf("struct field %s: %v", fn, err)\n';
155
- serdeTextBody += '\t}\n';
156
- serdeTextBody += '\tnewTime := time.Time(aux)\n';
157
- serdeTextBody += '\t*t = &newTime\n';
158
- serdeTextBody += '\treturn nil\n';
152
+ serdeTextBody += `${indent.get()}if data == nil || string(data) == "null" {\n`;
153
+ serdeTextBody += `${indent.push().get()}return nil\n`;
154
+ serdeTextBody += `${indent.pop().get()}}\n`;
155
+ serdeTextBody += `${indent.get()}var aux T\n`;
156
+ serdeTextBody += `${indent.get()}if err := json.Unmarshal(data, &aux); err != nil {\n`;
157
+ serdeTextBody += `${indent.push().get()}return fmt.Errorf("struct field %s: %v", fn, err)\n`;
158
+ serdeTextBody += `${indent.pop().get()}}\n`;
159
+ serdeTextBody += `${indent.get()}newTime := time.Time(aux)\n`;
160
+ serdeTextBody += `${indent.get()}*t = &newTime\n`;
161
+ serdeTextBody += `${indent.get()}return nil\n`;
159
162
  serdeTextBody += '}\n\n';
160
163
  }
161
164
  if (needsJSONPopulateMultipart) {
162
165
  serdeImports.add('encoding/json');
163
166
  serdeTextBody += 'func populateMultipartJSON(m map[string]any, k string, v any) error {\n';
164
- serdeTextBody += '\tdata, err := json.Marshal(v)\n';
165
- serdeTextBody += '\tif err != nil {\n\t\treturn err\n\t}\n';
166
- serdeTextBody += '\tm[k] = data\n\treturn nil\n';
167
+ serdeTextBody += `${indent.get()}data, err := json.Marshal(v)\n`;
168
+ serdeTextBody += `${indent.get()}if err != nil {\n`;
169
+ serdeTextBody += `${indent.push().get()}return err\n`;
170
+ serdeTextBody += `${indent.pop().get()}}\n`;
171
+ serdeTextBody += `${indent.get()}m[k] = data\n`;
172
+ serdeTextBody += `${indent.get()}return nil\n`;
167
173
  serdeTextBody += '}\n\n';
168
174
  }
169
175
  if (needsJSONUnpopulateTime || needsJSONPopulateTime) {
170
176
  serdeTextBody += `type dateTimeConstraints interface {\n`;
171
- serdeTextBody += `\tdatetime.PlainDate | datetime.PlainTime | datetime.RFC1123 | datetime.RFC3339 | datetime.Unix\n`;
177
+ serdeTextBody += `${indent.get()}datetime.PlainDate | datetime.PlainTime | datetime.RFC1123 | datetime.RFC3339 | datetime.Unix\n`;
172
178
  serdeTextBody += '}\n\n';
173
179
  }
174
180
  let serdeText = '';
@@ -191,7 +197,7 @@ export function generateModels(pkg, options) {
191
197
  * @param options the Go emitter options
192
198
  * @returns an array of ModelDefs
193
199
  */
194
- function generateModelDefs(modelImports, serdeImports, pkg, options) {
200
+ function generateModelDefs(modelImports, serdeImports, pkg, options, indent) {
195
201
  const models = pkg.models;
196
202
  const modelDefs = new Array();
197
203
  for (const model of models) {
@@ -252,32 +258,32 @@ function generateModelDefs(modelImports, serdeImports, pkg, options) {
252
258
  }
253
259
  // due to differences in XML marshallers/unmarshallers, we use different codegen than for JSON
254
260
  const needsXMLDictionaryUnmarshalling = needsXMLDictionaryHelper(model);
255
- if (needsDateTimeMarshalling || model.xml?.wrapper || needsXMLArrayMarshalling(model) || byteArrayFormat) {
256
- generateXMLMarshaller(modelDef, serdeImports);
261
+ if (needsDateTimeMarshalling || model.xml?.name || needsXMLArrayMarshalling(model) || byteArrayFormat) {
262
+ generateXMLMarshaller(modelDef, serdeImports, indent);
257
263
  if (needsDateTimeMarshalling || needsXMLDictionaryUnmarshalling || byteArrayFormat) {
258
- generateXMLUnmarshaller(modelDef, serdeImports);
264
+ generateXMLUnmarshaller(modelDef, serdeImports, indent);
259
265
  }
260
266
  }
261
267
  else if (needsXMLDictionaryUnmarshalling) {
262
- generateXMLMarshaller(modelDef, serdeImports);
263
- generateXMLUnmarshaller(modelDef, serdeImports);
268
+ generateXMLMarshaller(modelDef, serdeImports, indent);
269
+ generateXMLUnmarshaller(modelDef, serdeImports, indent);
264
270
  }
265
271
  modelDefs.push(modelDef);
266
272
  continue;
267
273
  }
268
274
  if (model.kind === 'polymorphicModel') {
269
- generateDiscriminatorMarkerMethod(model.interface, modelDef);
275
+ generateDiscriminatorMarkerMethod(model.interface, modelDef, indent);
270
276
  for (let parent = model.interface.parent; parent !== undefined; parent = parent.parent) {
271
- generateDiscriminatorMarkerMethod(parent, modelDef);
277
+ generateDiscriminatorMarkerMethod(parent, modelDef, indent);
272
278
  }
273
279
  }
274
280
  if (model.annotations.multipartFormData) {
275
- generateToMultipartForm(modelDef);
281
+ generateToMultipartForm(modelDef, indent);
276
282
  modelDef.SerDe.needsJSONPopulateMultipart = true;
277
283
  }
278
284
  else if (!model.annotations.omitSerDeMethods) {
279
- generateJSONMarshaller(modelDef, serdeImports);
280
- generateJSONUnmarshaller(modelDef, serdeImports, options);
285
+ generateJSONMarshaller(modelDef, serdeImports, indent);
286
+ generateJSONUnmarshaller(modelDef, options, serdeImports, indent);
281
287
  }
282
288
  modelDefs.push(modelDef);
283
289
  }
@@ -292,6 +298,15 @@ function needsXMLDictionaryHelper(modelType) {
292
298
  }
293
299
  return false;
294
300
  }
301
+ /**
302
+ * returns true if the model contains one or more slices,
303
+ * indicating that a custom marshaler is required.
304
+ * we use a custom marshaler to omit the XML tags for empty
305
+ * slices (the default marshaler will include them).
306
+ *
307
+ * @param modelType the model to check for slice fields
308
+ * @returns true if a custom marshaler is required
309
+ */
295
310
  function needsXMLArrayMarshalling(modelType) {
296
311
  for (const prop of modelType.fields) {
297
312
  if (prop.type.kind === 'slice') {
@@ -301,7 +316,7 @@ function needsXMLArrayMarshalling(modelType) {
301
316
  return false;
302
317
  }
303
318
  // generates discriminator marker method
304
- function generateDiscriminatorMarkerMethod(type, modelDef) {
319
+ function generateDiscriminatorMarkerMethod(type, modelDef, indent) {
305
320
  const typeName = type.rootType.name;
306
321
  const receiver = modelDef.receiverName();
307
322
  const interfaceMethod = `Get${typeName}`;
@@ -313,37 +328,43 @@ function generateDiscriminatorMarkerMethod(type, modelDef) {
313
328
  else {
314
329
  // the marker method is on a child type, so return an instance of the parent
315
330
  // type by copying the parent values into a new instance.
316
- method += `\n\treturn &${type.rootType.name}{\n`;
331
+ method += `\n${indent.get()}return &${type.rootType.name}{\n`;
332
+ indent.push();
317
333
  for (const field of type.rootType.fields) {
318
- method += `\t\t${field.name}: ${modelDef.receiverName()}.${field.name},\n`;
334
+ method += `${indent.get()}${field.name}: ${modelDef.receiverName()}.${field.name},\n`;
319
335
  }
320
- method += '\t}\n}\n\n';
336
+ method += `${indent.pop().get()}}\n}\n\n`;
321
337
  }
322
338
  modelDef.Methods.push({ name: interfaceMethod, desc: `${interfaceMethod} implements the ${type.name} interface for type ${modelDef.Model.name}.`, text: method });
323
339
  }
324
- function generateToMultipartForm(modelDef) {
340
+ function generateToMultipartForm(modelDef, indent) {
325
341
  const receiver = modelDef.receiverName();
326
342
  let method = `func (${receiver} ${modelDef.Model.name}) toMultipartFormData() (map[string]any, error) {\n`;
327
- method += '\tobjectMap := make(map[string]any)\n';
343
+ method += `${indent.get()}objectMap := make(map[string]any)\n`;
328
344
  for (const field of modelDef.Model.fields) {
329
345
  const fieldType = helpers.recursiveUnwrapMapSlice(field.type);
330
- let setField;
331
346
  let star = '';
332
347
  if (!field.byValue) {
333
348
  star = '*';
334
349
  }
350
+ if (!field.byValue) {
351
+ method += `${indent.get()}if ${receiver}.${field.name} != nil {\n`;
352
+ indent.push();
353
+ }
335
354
  if (fieldType.kind === 'model' && !fieldType.annotations.multipartFormData) {
336
- setField = `\tif err := populateMultipartJSON(objectMap, "${field.serializedName}", ${star}${receiver}.${field.name}); err != nil {\n\t\treturn nil, err\n\t}\n`;
355
+ method += `${indent.get()}if err := populateMultipartJSON(objectMap, "${field.serializedName}", ${star}${receiver}.${field.name}); err != nil {\n`;
356
+ method += `${indent.push().get()}return nil, err\n`;
357
+ method += `${indent.pop().get()}}\n`;
337
358
  }
338
359
  else {
339
- setField = `\tobjectMap["${field.serializedName}"] = ${star}${receiver}.${field.name}\n`;
360
+ method += `${indent.get()}objectMap["${field.serializedName}"] = ${star}${receiver}.${field.name}\n`;
340
361
  }
341
362
  if (!field.byValue) {
342
- setField = `\tif ${receiver}.${field.name} != nil {\n\t\t${setField}\t}\n`;
363
+ indent.pop();
364
+ method += `${indent.get()}}\n`;
343
365
  }
344
- method += setField;
345
366
  }
346
- method += '\treturn objectMap, nil\n}\n\n';
367
+ method += `${indent.get()}return objectMap, nil\n}\n\n`;
347
368
  modelDef.SerDe.methods.push({ name: 'toMultipartFormData', desc: `toMultipartFormData converts ${modelDef.Model.name} to multipart/form data.`, text: method });
348
369
  }
349
370
  /**
@@ -352,8 +373,9 @@ function generateToMultipartForm(modelDef) {
352
373
  *
353
374
  * @param modelDef the type for which to emit the method
354
375
  * @param imports the import manager currently in scope
376
+ * @param indent the indentation helper currently in scope
355
377
  */
356
- function generateJSONMarshaller(modelDef, imports) {
378
+ function generateJSONMarshaller(modelDef, imports, indent) {
357
379
  if (modelDef.Model.kind === 'model' && modelDef.Model.fields.length === 0) {
358
380
  // non-discriminated types without content don't need a custom marshaller.
359
381
  // there is a case in network where child is allOf base and child has no properties.
@@ -363,9 +385,9 @@ function generateJSONMarshaller(modelDef, imports) {
363
385
  const typeName = modelDef.Model.name;
364
386
  const receiver = modelDef.receiverName();
365
387
  let marshaller = `func (${receiver} ${typeName}) MarshalJSON() ([]byte, error) {\n`;
366
- marshaller += '\tobjectMap := make(map[string]any)\n';
367
- marshaller += generateJSONMarshallerBody(modelDef, receiver, imports);
368
- marshaller += '\treturn json.Marshal(objectMap)\n';
388
+ marshaller += `${indent.get()}objectMap := make(map[string]any)\n`;
389
+ marshaller += generateJSONMarshallerBody(modelDef, receiver, imports, indent);
390
+ marshaller += `${indent.get()}return json.Marshal(objectMap)\n`;
369
391
  marshaller += '}\n\n';
370
392
  modelDef.SerDe.methods.push({ name: 'MarshalJSON', desc: `MarshalJSON implements the json.Marshaller interface for type ${typeName}.`, text: marshaller });
371
393
  }
@@ -375,9 +397,10 @@ function generateJSONMarshaller(modelDef, imports) {
375
397
  * @param modelDef the type being encoded
376
398
  * @param receiver the name of the receiver in the MarshalJSON method
377
399
  * @param imports the import manager currently in scope
400
+ * @param indent the indentation helper currently in scope
378
401
  * @returns the text for encoding the target type
379
402
  */
380
- function generateJSONMarshallerBody(modelDef, receiver, imports) {
403
+ function generateJSONMarshallerBody(modelDef, receiver, imports, indent) {
381
404
  let marshaller = '';
382
405
  let addlProps;
383
406
  for (const field of modelDef.Model.fields) {
@@ -387,27 +410,30 @@ function generateJSONMarshallerBody(modelDef, receiver, imports) {
387
410
  }
388
411
  if (field.annotations.isDiscriminator) {
389
412
  if (field.defaultValue) {
390
- marshaller += `\tobjectMap["${field.serializedName}"] = ${helpers.formatLiteralValue(field.defaultValue, true)}\n`;
413
+ marshaller += `${indent.get()}objectMap["${field.serializedName}"] = ${helpers.formatLiteralValue(field.defaultValue, true)}\n`;
391
414
  }
392
415
  else {
393
416
  // if there's no discriminator value (e.g. Fish in test server), use the field's value.
394
417
  // this will enable support for custom types that aren't (yet) described in the swagger.
395
- marshaller += `\tobjectMap["${field.serializedName}"] = ${receiver}.${field.name}\n`;
418
+ marshaller += `${indent.get()}objectMap["${field.serializedName}"] = ${receiver}.${field.name}\n`;
396
419
  }
397
420
  }
398
421
  else if (field.type.kind === 'encodedBytes') {
399
422
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
400
- marshaller += `\tpopulateByteArray(objectMap, "${field.serializedName}", ${receiver}.${field.name}, func() any {\n`;
401
- marshaller += `\t\treturn runtime.EncodeByteArray(${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format)\n\t})\n`;
423
+ marshaller += `${indent.get()}populateByteArray(objectMap, "${field.serializedName}", ${receiver}.${field.name}, func() any {\n`;
424
+ marshaller += `${indent.push().get()}return runtime.EncodeByteArray(${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format)\n`;
425
+ marshaller += `${indent.pop().get()}})\n`;
402
426
  modelDef.SerDe.needsJSONPopulateByteArray = true;
403
427
  }
404
428
  else if (field.type.kind === 'slice' && field.type.elementType.kind === 'encodedBytes') {
405
429
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
406
- marshaller += `\tpopulateByteArray(objectMap, "${field.serializedName}", ${receiver}.${field.name}, func() any {\n`;
407
- marshaller += `\t\tencodedValue := make([]string, len(${receiver}.${field.name}))\n`;
408
- marshaller += `\t\tfor i := 0; i < len(${receiver}.${field.name}); i++ {\n`;
409
- marshaller += `\t\t\tencodedValue[i] = runtime.EncodeByteArray(${receiver}.${field.name}[i], runtime.Base64${field.type.elementType.encoding}Format)\n\t\t}\n`;
410
- marshaller += '\t\treturn encodedValue\n\t})\n';
430
+ marshaller += `${indent.get()}populateByteArray(objectMap, "${field.serializedName}", ${receiver}.${field.name}, func() any {\n`;
431
+ marshaller += `${indent.push().get()}encodedValue := make([]string, len(${receiver}.${field.name}))\n`;
432
+ marshaller += `${indent.get()}for i := 0; i < len(${receiver}.${field.name}); i++ {\n`;
433
+ marshaller += `${indent.push().get()}encodedValue[i] = runtime.EncodeByteArray(${receiver}.${field.name}[i], runtime.Base64${field.type.elementType.encoding}Format)\n`;
434
+ marshaller += `${indent.pop().get()}}\n`;
435
+ marshaller += `${indent.get()}return encodedValue\n`;
436
+ marshaller += `${indent.pop().get()}})\n`;
411
437
  modelDef.SerDe.needsJSONPopulateByteArray = true;
412
438
  }
413
439
  else if (field.type.kind === 'slice' && field.type.elementType.kind === 'time') {
@@ -417,30 +443,34 @@ function generateJSONMarshallerBody(modelDef, receiver, imports) {
417
443
  elementPtr = '';
418
444
  }
419
445
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime');
420
- marshaller += `\taux := make([]${elementPtr}datetime.${field.type.elementType.format}, len(${source}), len(${source}))\n`;
421
- marshaller += `\tfor i := 0; i < len(${source}); i++ {\n`;
422
- marshaller += `\t\taux[i] = (${elementPtr}datetime.${field.type.elementType.format})(${source}[i])\n`;
423
- marshaller += '\t}\n';
424
- marshaller += `\tpopulate(objectMap, "${field.serializedName}", aux)\n`;
446
+ marshaller += `${indent.get()}aux := make([]${elementPtr}datetime.${field.type.elementType.format}, len(${source}), len(${source}))\n`;
447
+ marshaller += `${indent.get()}for i := 0; i < len(${source}); i++ {\n`;
448
+ marshaller += `${indent.push().get()}aux[i] = (${elementPtr}datetime.${field.type.elementType.format})(${source}[i])\n`;
449
+ marshaller += `${indent.pop().get()}}\n`;
450
+ marshaller += `${indent.get()}populate(objectMap, "${field.serializedName}", aux)\n`;
425
451
  modelDef.SerDe.needsJSONPopulate = true;
426
452
  }
427
453
  else if (field.type.kind === 'literal') {
428
454
  const setter = `objectMap["${field.serializedName}"] = ${helpers.formatLiteralValue(field.type, true)}`;
429
455
  if (!field.annotations.required) {
430
- marshaller += `\tif ${receiver}.${field.name} != nil {\n\t\t${setter}\n\t}\n`;
456
+ marshaller += `${indent.get()}if ${receiver}.${field.name} != nil {\n`;
457
+ marshaller += `${indent.push().get()}${setter}\n`;
458
+ marshaller += `${indent.pop().get()}}\n`;
431
459
  }
432
460
  else {
433
- marshaller += `\t${setter}\n`;
461
+ marshaller += `${indent.get()}${setter}\n`;
434
462
  }
435
463
  }
436
464
  else if (field.type.kind === 'rawJSON') {
437
- marshaller += `\tpopulate(objectMap, "${field.serializedName}", json.RawMessage(${receiver}.${field.name}))\n`;
465
+ marshaller += `${indent.get()}populate(objectMap, "${field.serializedName}", json.RawMessage(${receiver}.${field.name}))\n`;
438
466
  modelDef.SerDe.needsJSONPopulate = true;
439
467
  }
440
468
  else {
441
469
  if (field.defaultValue) {
442
470
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/to');
443
- marshaller += `\tif ${receiver}.${field.name} == nil {\n\t\t${receiver}.${field.name} = to.Ptr(${helpers.formatLiteralValue(field.defaultValue, true)})\n\t}\n`;
471
+ marshaller += `${indent.get()}if ${receiver}.${field.name} == nil {\n`;
472
+ marshaller += `${indent.push().get()}${receiver}.${field.name} = to.Ptr(${helpers.formatLiteralValue(field.defaultValue, true)})\n`;
473
+ marshaller += `${indent.pop().get()}}\n`;
444
474
  }
445
475
  let populate;
446
476
  if (field.type.kind === 'time') {
@@ -461,27 +491,27 @@ function generateJSONMarshallerBody(modelDef, receiver, imports) {
461
491
  imports.add('strconv');
462
492
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/to');
463
493
  if ((field.type.type.startsWith('uint') && field.type.type !== 'uint64') || (field.type.type.startsWith('int') && field.type.type !== 'int64')) {
464
- marshaller += `\t${populate}(objectMap, "${field.serializedName}", to.Ptr(strconv.${field.type.type.startsWith('int') ? 'FormatInt' : 'FormatUint'}(${field.type.type.startsWith('int') ? 'int64' : 'uint64'}(*${receiver}.${field.name}), 10)))\n`;
494
+ marshaller += `${indent.get()}${populate}(objectMap, "${field.serializedName}", to.Ptr(strconv.${field.type.type.startsWith('int') ? 'FormatInt' : 'FormatUint'}(${field.type.type.startsWith('int') ? 'int64' : 'uint64'}(*${receiver}.${field.name}), 10)))\n`;
465
495
  }
466
496
  else {
467
- marshaller += `\t${populate}(objectMap, "${field.serializedName}", to.Ptr(strconv.${field.type.type.startsWith('int') ? 'FormatInt' : 'FormatUint'}(*${receiver}.${field.name}, 10)))\n`;
497
+ marshaller += `${indent.get()}${populate}(objectMap, "${field.serializedName}", to.Ptr(strconv.${field.type.type.startsWith('int') ? 'FormatInt' : 'FormatUint'}(*${receiver}.${field.name}, 10)))\n`;
468
498
  }
469
499
  }
470
500
  else {
471
- marshaller += `\t${populate}(objectMap, "${field.serializedName}", ${receiver}.${field.name})\n`;
501
+ marshaller += `${indent.get()}${populate}(objectMap, "${field.serializedName}", ${receiver}.${field.name})\n`;
472
502
  }
473
503
  }
474
504
  }
475
505
  if (addlProps) {
476
- marshaller += `\tif ${receiver}.AdditionalProperties != nil {\n`;
477
- marshaller += `\t\tfor key, val := range ${receiver}.AdditionalProperties {\n`;
506
+ marshaller += `${indent.get()}if ${receiver}.AdditionalProperties != nil {\n`;
507
+ marshaller += `${indent.push().get()}for key, val := range ${receiver}.AdditionalProperties {\n`;
478
508
  let assignment = 'val';
479
509
  if (addlProps.valueType.kind === 'time') {
480
510
  assignment = `(*${addlProps.valueType.format})(val)`;
481
511
  }
482
- marshaller += `\t\t\tobjectMap[key] = ${assignment}\n`;
483
- marshaller += '\t\t}\n';
484
- marshaller += '\t}\n';
512
+ marshaller += `${indent.push().get()}objectMap[key] = ${assignment}\n`;
513
+ marshaller += `${indent.pop().get()}}\n`;
514
+ marshaller += `${indent.pop().get()}}\n`;
485
515
  }
486
516
  return marshaller;
487
517
  }
@@ -490,10 +520,11 @@ function generateJSONMarshallerBody(modelDef, receiver, imports) {
490
520
  * the method impl is added to modelDef.SerDe.methods.
491
521
  *
492
522
  * @param modelDef the type for which to emit the method
493
- * @param imports the import manager currently in scope
494
523
  * @param options the Go emitter options
524
+ * @param imports the import manager currently in scope
525
+ * @param indent the indentation helper currently in scope
495
526
  */
496
- function generateJSONUnmarshaller(modelDef, imports, options) {
527
+ function generateJSONUnmarshaller(modelDef, options, imports, indent) {
497
528
  // there's a corner-case where a derived type might not add any new fields (Cookiecuttershark).
498
529
  // in this case skip adding the unmarshaller as it's not necessary and doesn't compile.
499
530
  if (modelDef.Model.fields.length === 0) {
@@ -504,11 +535,11 @@ function generateJSONUnmarshaller(modelDef, imports, options) {
504
535
  const typeName = modelDef.Model.name;
505
536
  const receiver = modelDef.receiverName();
506
537
  let unmarshaller = `func (${receiver} *${typeName}) UnmarshalJSON(data []byte) error {\n`;
507
- unmarshaller += '\tvar rawMsg map[string]json.RawMessage\n';
508
- unmarshaller += '\tif err := json.Unmarshal(data, &rawMsg); err != nil {\n';
509
- unmarshaller += `\t\treturn fmt.Errorf("unmarshalling type %T: %v", ${receiver}, err)\n`;
510
- unmarshaller += '\t}\n';
511
- unmarshaller += generateJSONUnmarshallerBody(modelDef, receiver, imports, options);
538
+ unmarshaller += `${indent.get()}var rawMsg map[string]json.RawMessage\n`;
539
+ unmarshaller += `${indent.get()}if err := json.Unmarshal(data, &rawMsg); err != nil {\n`;
540
+ unmarshaller += `${indent.push().get()}return fmt.Errorf("unmarshalling type %T: %v", ${receiver}, err)\n`;
541
+ unmarshaller += `${indent.pop().get()}}\n`;
542
+ unmarshaller += generateJSONUnmarshallerBody(modelDef, receiver, options, imports, indent);
512
543
  unmarshaller += '}\n\n';
513
544
  modelDef.SerDe.methods.push({ name: 'UnmarshalJSON', desc: `UnmarshalJSON implements the json.Unmarshaller interface for type ${typeName}.`, text: unmarshaller });
514
545
  }
@@ -517,25 +548,27 @@ function generateJSONUnmarshaller(modelDef, imports, options) {
517
548
  *
518
549
  * @param modelDef the type being decoded
519
550
  * @param receiver the receiver for the UnmarshalJSON method
520
- * @param imports the import manager currently in scope
521
551
  * @param options the Go emitter options
552
+ * @param imports the import manager currently in scope
553
+ * @param indent the indentation helper currently in scope
522
554
  * @returns the text for decoding the target type
523
555
  */
524
- function generateJSONUnmarshallerBody(modelDef, receiver, imports, options) {
556
+ function generateJSONUnmarshallerBody(modelDef, receiver, options, imports, indent) {
525
557
  // we almost always need to have an error check when unmarshaling the values.
526
558
  // however, fields that are raw JSON don't require any unmarshaling. so, if all
527
559
  // of the fields in a type are raw JSON, then the error check isn't necessary
528
560
  // and can be elided (the linter complains about it otherwise).
529
561
  let needsErrCheck = false;
530
- const emitAddlProps = function (tab, addlProps) {
531
- let addlPropsText = `${tab}\t\tif ${receiver}.AdditionalProperties == nil {\n`;
562
+ const emitAddlProps = function (addlProps) {
563
+ // indent is at the case body level when called
564
+ let addlPropsText = `${indent.get()}if ${receiver}.AdditionalProperties == nil {\n`;
532
565
  let ref = '';
533
566
  if (!addlProps.valueTypeByValue) {
534
567
  ref = '&';
535
568
  }
536
- addlPropsText += `${tab}\t\t\t${receiver}.AdditionalProperties = ${go.getTypeDeclaration(addlProps, modelDef.Model.pkg)}{}\n`;
537
- addlPropsText += `${tab}\t\t}\n`;
538
- addlPropsText += `${tab}\t\tif val != nil {\n`;
569
+ addlPropsText += `${indent.push().get()}${receiver}.AdditionalProperties = ${go.getTypeDeclaration(addlProps, modelDef.Model.pkg)}{}\n`;
570
+ addlPropsText += `${indent.pop().get()}}\n`;
571
+ addlPropsText += `${indent.get()}if val != nil {\n`;
539
572
  let auxType = go.getTypeDeclaration(addlProps.valueType, modelDef.Model.pkg);
540
573
  let assignment = `${ref}aux`;
541
574
  if (addlProps.valueType.kind === 'time') {
@@ -543,30 +576,32 @@ function generateJSONUnmarshallerBody(modelDef, receiver, imports, options) {
543
576
  auxType = addlProps.valueType.format;
544
577
  assignment = `(*time.Time)(${assignment})`;
545
578
  }
546
- addlPropsText += `${tab}\t\t\tvar aux ${auxType}\n`;
547
- addlPropsText += `${tab}\t\t\terr = json.Unmarshal(val, &aux)\n`;
548
- addlPropsText += `${tab}\t\t\t${receiver}.AdditionalProperties[key] = ${assignment}\n`;
549
- addlPropsText += `${tab}\t\t}\n`;
550
- addlPropsText += `${tab}\t\tdelete(rawMsg, key)\n`;
579
+ addlPropsText += `${indent.push().get()}var aux ${auxType}\n`;
580
+ addlPropsText += `${indent.get()}err = json.Unmarshal(val, &aux)\n`;
581
+ addlPropsText += `${indent.get()}${receiver}.AdditionalProperties[key] = ${assignment}\n`;
582
+ addlPropsText += `${indent.pop().get()}}\n`;
583
+ addlPropsText += `${indent.get()}delete(rawMsg, key)\n`;
551
584
  needsErrCheck = true;
552
585
  return addlPropsText;
553
586
  };
554
587
  const emitSwitchCase = function () {
588
+ // indent is at level 2 (for loop body) when called
555
589
  let unmarshalBody = '';
556
590
  let addlProps;
557
- unmarshalBody += '\t\tswitch key {\n';
591
+ unmarshalBody += `${indent.get()}switch key {\n`;
558
592
  for (const field of modelDef.Model.fields) {
559
593
  if (field.type.kind === 'map' && field.annotations.isAdditionalProperties) {
560
594
  addlProps = field.type;
561
595
  continue;
562
596
  }
563
- unmarshalBody += `\t\tcase "${field.serializedName}":\n`;
597
+ unmarshalBody += `${indent.get()}case "${field.serializedName}":\n`;
598
+ indent.push(); // case body level
564
599
  if (hasDiscriminatorInterface(field.type)) {
565
- unmarshalBody += generateDiscriminatorUnmarshaller(modelDef.Model, field, receiver);
600
+ unmarshalBody += generateDiscriminatorUnmarshaller(modelDef.Model, field, receiver, indent);
566
601
  needsErrCheck = true;
567
602
  }
568
603
  else if (field.type.kind === 'time') {
569
- unmarshalBody += `\t\t\t\terr = unpopulateTime[datetime.${field.type.format}](val, "${field.name}", &${receiver}.${field.name})\n`;
604
+ unmarshalBody += `${indent.get()}err = unpopulateTime[datetime.${field.type.format}](val, "${field.name}", &${receiver}.${field.name})\n`;
570
605
  modelDef.SerDe.needsJSONUnpopulateTime = true;
571
606
  needsErrCheck = true;
572
607
  }
@@ -577,89 +612,111 @@ function generateJSONUnmarshallerBody(modelDef, receiver, imports, options) {
577
612
  if (field.type.elementTypeByValue) {
578
613
  elementPtr = '';
579
614
  }
580
- unmarshalBody += `\t\t\tvar aux []${elementPtr}datetime.${field.type.elementType.format}\n`;
581
- unmarshalBody += `\t\t\terr = unpopulate(val, "${field.name}", &aux)\n`;
582
- unmarshalBody += '\t\t\tfor _, au := range aux {\n';
583
- unmarshalBody += `\t\t\t\t${receiver}.${field.name} = append(${receiver}.${field.name}, (${elementPtr}time.Time)(au))\n`;
584
- unmarshalBody += '\t\t\t}\n';
615
+ unmarshalBody += `${indent.get()}var aux []${elementPtr}datetime.${field.type.elementType.format}\n`;
616
+ unmarshalBody += `${indent.get()}err = unpopulate(val, "${field.name}", &aux)\n`;
617
+ unmarshalBody += `${indent.get()}for _, au := range aux {\n`;
618
+ unmarshalBody += `${indent.push().get()}${receiver}.${field.name} = append(${receiver}.${field.name}, (${elementPtr}time.Time)(au))\n`;
619
+ unmarshalBody += `${indent.pop().get()}}\n`;
585
620
  modelDef.SerDe.needsJSONUnpopulate = true;
586
621
  needsErrCheck = true;
587
622
  }
588
623
  else if (field.type.kind === 'encodedBytes') {
589
624
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
590
- unmarshalBody += '\t\tif val != nil && string(val) != "null" {\n';
591
- unmarshalBody += `\t\t\t\terr = runtime.DecodeByteArray(string(val), &${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format)\n\t\t}\n`;
625
+ unmarshalBody += `${indent.get()}if val != nil && string(val) != "null" {\n`;
626
+ unmarshalBody += `${indent.push().get()}err = runtime.DecodeByteArray(string(val), &${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format)\n`;
627
+ unmarshalBody += `${indent.pop().get()}}\n`;
592
628
  needsErrCheck = true;
593
629
  }
594
630
  else if (field.type.kind === 'slice' && field.type.elementType.kind === 'encodedBytes') {
595
631
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
596
- unmarshalBody += '\t\t\tvar encodedValue []string\n';
597
- unmarshalBody += `\t\t\terr = unpopulate(val, "${field.name}", &encodedValue)\n`;
598
- unmarshalBody += '\t\t\tif err == nil && len(encodedValue) > 0 {\n';
599
- unmarshalBody += `\t\t\t\t${receiver}.${field.name} = make([][]byte, len(encodedValue))\n`;
600
- unmarshalBody += '\t\t\t\tfor i := 0; i < len(encodedValue) && err == nil; i++ {\n';
601
- unmarshalBody += `\t\t\t\t\terr = runtime.DecodeByteArray(encodedValue[i], &${receiver}.${field.name}[i], runtime.Base64${field.type.elementType.encoding}Format)\n`;
602
- unmarshalBody += '\t\t\t\t}\n\t\t\t}\n';
632
+ unmarshalBody += `${indent.get()}var encodedValue []string\n`;
633
+ unmarshalBody += `${indent.get()}err = unpopulate(val, "${field.name}", &encodedValue)\n`;
634
+ unmarshalBody += `${indent.get()}if err == nil && len(encodedValue) > 0 {\n`;
635
+ indent.push();
636
+ unmarshalBody += `${indent.get()}${receiver}.${field.name} = make([][]byte, len(encodedValue))\n`;
637
+ unmarshalBody += `${indent.get()}for i := 0; i < len(encodedValue) && err == nil; i++ {\n`;
638
+ unmarshalBody += `${indent.push().get()}err = runtime.DecodeByteArray(encodedValue[i], &${receiver}.${field.name}[i], runtime.Base64${field.type.elementType.encoding}Format)\n`;
639
+ unmarshalBody += `${indent.pop().get()}}\n`;
640
+ indent.pop();
641
+ unmarshalBody += `${indent.get()}}\n`;
603
642
  modelDef.SerDe.needsJSONUnpopulate = true;
604
643
  needsErrCheck = true;
605
644
  }
606
645
  else if (field.type.kind === 'rawJSON') {
607
- unmarshalBody += '\t\t\tif string(val) != "null" {\n';
608
- unmarshalBody += `\t\t\t\t${receiver}.${field.name} = val\n\t\t\t}\n`;
646
+ unmarshalBody += `${indent.get()}if string(val) != "null" {\n`;
647
+ unmarshalBody += `${indent.push().get()}${receiver}.${field.name} = val\n`;
648
+ unmarshalBody += `${indent.pop().get()}}\n`;
609
649
  }
610
650
  else if (field.type.kind === 'scalar' && (field.type.type.startsWith('uint') || field.type.type.startsWith('int')) && field.type.encodeAsString) {
611
651
  // TODO: need to handle map and slice type with underlying int as string type
612
652
  imports.add('strconv');
613
- unmarshalBody += `\t\t\t\tvar aux string\n`;
614
- unmarshalBody += `\t\t\t\terr = unpopulate(val, "${field.name}", &aux)\n`;
615
- unmarshalBody += `\t\t\t\tif err == nil {\n`;
616
- unmarshalBody += `\t\t\t\t\tvar v ${field.type.type.startsWith('int') ? 'int64' : 'uint64'}\n`;
617
- unmarshalBody += `\t\t\t\t\tv, err = strconv.${field.type.type.startsWith('int') ? 'ParseInt' : 'ParseUint'}(aux, 10, 0)\n`;
618
- unmarshalBody += `\t\t\t\t\tif err == nil {\n`;
653
+ unmarshalBody += `${indent.get()}var aux string\n`;
654
+ unmarshalBody += `${indent.get()}err = unpopulate(val, "${field.name}", &aux)\n`;
655
+ unmarshalBody += `${indent.get()}if err == nil {\n`;
656
+ indent.push();
657
+ unmarshalBody += `${indent.get()}var v ${field.type.type.startsWith('int') ? 'int64' : 'uint64'}\n`;
658
+ unmarshalBody += `${indent.get()}v, err = strconv.${field.type.type.startsWith('int') ? 'ParseInt' : 'ParseUint'}(aux, 10, 0)\n`;
659
+ unmarshalBody += `${indent.get()}if err == nil {\n`;
619
660
  if ((field.type.type.startsWith('uint') && field.type.type !== 'uint64') || (field.type.type.startsWith('int') && field.type.type !== 'int64')) {
620
- unmarshalBody += `\t\t\t\t\t\t${receiver}.${field.name} = to.Ptr(${field.type.type}(v))\n`;
661
+ unmarshalBody += `${indent.push().get()}${receiver}.${field.name} = to.Ptr(${field.type.type}(v))\n`;
621
662
  }
622
663
  else {
623
- unmarshalBody += `\t\t\t\t\t\t${receiver}.${field.name} = to.Ptr(v)\n`;
664
+ unmarshalBody += `${indent.push().get()}${receiver}.${field.name} = to.Ptr(v)\n`;
624
665
  }
625
- unmarshalBody += '\t\t\t\t\t}\n';
626
- unmarshalBody += '\t\t\t\t}\n';
666
+ unmarshalBody += `${indent.pop().get()}}\n`;
667
+ indent.pop();
668
+ unmarshalBody += `${indent.get()}}\n`;
627
669
  modelDef.SerDe.needsJSONUnpopulate = true;
628
670
  needsErrCheck = true;
629
671
  }
630
672
  else {
631
- unmarshalBody += `\t\t\t\terr = unpopulate(val, "${field.name}", &${receiver}.${field.name})\n`;
673
+ const unpopulateField = `err = unpopulate(val, "${field.name}", &${receiver}.${field.name})\n`;
674
+ if (field.type.kind === 'string' && field.annotations.unmarshalEmptyStringAsNil) {
675
+ unmarshalBody += `${indent.get()}${helpers.buildIfBlock(indent, {
676
+ condition: `string(val) != \`""\``,
677
+ body: (indent) => `${indent.get()}${unpopulateField}`,
678
+ })}\n`;
679
+ }
680
+ else {
681
+ unmarshalBody += `${indent.get()}${unpopulateField}`;
682
+ }
632
683
  modelDef.SerDe.needsJSONUnpopulate = true;
633
684
  needsErrCheck = true;
634
685
  }
635
- unmarshalBody += '\t\t\tdelete(rawMsg, key)\n';
686
+ unmarshalBody += `${indent.get()}delete(rawMsg, key)\n`;
687
+ indent.pop(); // back to switch level
636
688
  }
637
689
  if (addlProps) {
638
- unmarshalBody += '\t\tdefault:\n';
639
- unmarshalBody += emitAddlProps('\t', addlProps);
690
+ unmarshalBody += `${indent.get()}default:\n`;
691
+ indent.push(); // case body level
692
+ unmarshalBody += emitAddlProps(addlProps);
693
+ indent.pop();
640
694
  }
641
695
  else if (options.disallowUnknownFields) {
642
- unmarshalBody += '\t\tdefault:\n';
643
- unmarshalBody += `\t\t\terr = fmt.Errorf("unmarshalling type %T, unknown field %q", ${receiver}, key)\n`;
696
+ unmarshalBody += `${indent.get()}default:\n`;
697
+ unmarshalBody += `${indent.push().get()}err = fmt.Errorf("unmarshalling type %T, unknown field %q", ${receiver}, key)\n`;
698
+ indent.pop();
644
699
  needsErrCheck = true;
645
700
  }
646
- unmarshalBody += '\t\t}\n';
701
+ unmarshalBody += `${indent.get()}}\n`;
647
702
  return unmarshalBody;
648
703
  };
649
- let unmarshalBody = '\tfor key, val := range rawMsg {\n';
704
+ let unmarshalBody = `${indent.get()}for key, val := range rawMsg {\n`;
705
+ indent.push(); // level 2 (for loop body)
650
706
  // emitSwitchCase sets needsErrCheck so we must call it first
651
707
  const switchCaseBody = emitSwitchCase();
652
708
  if (needsErrCheck) {
653
- unmarshalBody += '\t\tvar err error\n';
709
+ unmarshalBody += `${indent.get()}var err error\n`;
654
710
  }
655
711
  unmarshalBody += switchCaseBody;
656
712
  if (needsErrCheck) {
657
- unmarshalBody += '\t\tif err != nil {\n';
658
- unmarshalBody += `\t\t\treturn fmt.Errorf("unmarshalling type %T: %v", ${receiver}, err)\n`;
659
- unmarshalBody += '\t\t}\n';
713
+ unmarshalBody += `${indent.get()}if err != nil {\n`;
714
+ unmarshalBody += `${indent.push().get()}return fmt.Errorf("unmarshalling type %T: %v", ${receiver}, err)\n`;
715
+ unmarshalBody += `${indent.pop().get()}}\n`;
660
716
  }
661
- unmarshalBody += '\t}\n'; // end for key, val := range rawMsg
662
- unmarshalBody += '\treturn nil\n';
717
+ indent.pop(); // level 1
718
+ unmarshalBody += `${indent.get()}}\n`; // end for key, val := range rawMsg
719
+ unmarshalBody += `${indent.get()}return nil\n`;
663
720
  return unmarshalBody;
664
721
  }
665
722
  // returns true if item has a discriminator interface.
@@ -677,25 +734,25 @@ function hasDiscriminatorInterface(item) {
677
734
  }
678
735
  }
679
736
  // returns the text for unmarshalling a discriminated type
680
- function generateDiscriminatorUnmarshaller(modelType, field, receiver) {
681
- const startingIndentation = '\t\t\t';
737
+ function generateDiscriminatorUnmarshaller(modelType, field, receiver, indent) {
682
738
  const propertyName = field.name;
683
739
  // these are the simple, non-nested cases (e.g. IterfaceType, []InterfaceType, map[string]InterfaceType)
684
740
  if (field.type.kind === 'interface') {
685
- return `${startingIndentation}${receiver}.${propertyName}, err = unmarshal${field.type.name}(val)\n`;
741
+ return `${indent.get()}${receiver}.${propertyName}, err = unmarshal${field.type.name}(val)\n`;
686
742
  }
687
743
  else if (field.type.kind === 'slice' && field.type.elementType.kind === 'interface') {
688
- return `${startingIndentation}${receiver}.${propertyName}, err = unmarshal${field.type.elementType.name}Array(val)\n`;
744
+ return `${indent.get()}${receiver}.${propertyName}, err = unmarshal${field.type.elementType.name}Array(val)\n`;
689
745
  }
690
746
  else if (field.type.kind === 'map' && field.type.valueType.kind === 'interface') {
691
- return `${startingIndentation}${receiver}.${propertyName}, err = unmarshal${field.type.valueType.name}Map(val)\n`;
747
+ return `${indent.get()}${receiver}.${propertyName}, err = unmarshal${field.type.valueType.name}Map(val)\n`;
692
748
  }
693
749
  // nested case (e.g. [][]InterfaceType, map[string]map[string]InterfaceType etc)
694
750
  // first, unmarshal the raw data
695
751
  const rawTargetVar = `${field.serializedName}Raw`;
696
- let text = `${startingIndentation}var ${rawTargetVar} ${recursiveGetDiscriminatorTypeName(modelType, field.type, true)}\n`;
697
- text += `${startingIndentation}if err = json.Unmarshal(val, &${rawTargetVar}); err != nil {\n`;
698
- text += `${startingIndentation}\treturn err\n${startingIndentation}}\n`;
752
+ let text = `${indent.get()}var ${rawTargetVar} ${recursiveGetDiscriminatorTypeName(modelType, field.type, true)}\n`;
753
+ text += `${indent.get()}if err = json.Unmarshal(val, &${rawTargetVar}); err != nil {\n`;
754
+ text += `${indent.push().get()}return err\n`;
755
+ text += `${indent.pop().get()}}\n`;
699
756
  // create a local instantiation of the final type
700
757
  const finalTargetVar = field.serializedName;
701
758
  let finalTargetCtor = recursiveGetDiscriminatorTypeName(modelType, field.type, false);
@@ -706,11 +763,11 @@ function generateDiscriminatorUnmarshaller(modelType, field, receiver) {
706
763
  // must be a dictionary
707
764
  finalTargetCtor = `${finalTargetCtor}{}`;
708
765
  }
709
- text += `${startingIndentation}${finalTargetVar} := ${finalTargetCtor}\n`;
766
+ text += `${indent.get()}${finalTargetVar} := ${finalTargetCtor}\n`;
710
767
  // now populate the final type
711
- text += recursivePopulateDiscriminator(modelType, field.type, receiver, rawTargetVar, finalTargetVar, startingIndentation, 1);
768
+ text += recursivePopulateDiscriminator(modelType, field.type, receiver, rawTargetVar, finalTargetVar, indent, 1);
712
769
  // finally, assign the final target to the property
713
- text += `${startingIndentation}${receiver}.${propertyName} = ${finalTargetVar}\n`;
770
+ text += `${indent.get()}${receiver}.${propertyName} = ${finalTargetVar}\n`;
714
771
  return text;
715
772
  }
716
773
  // constructs the type name for a nested discriminated type
@@ -741,7 +798,7 @@ function recursiveGetDiscriminatorTypeName(modelType, item, raw) {
741
798
  * @param receiver the name of the receiver for the method to contain the expression
742
799
  * @param rawSrc contains the raw unmarshaled JSON source
743
800
  * @param dest the variable that will contain the result of the expression
744
- * @param indent the current level of indentation (increases with each recursive call)
801
+ * @param indent the current indentation helper (level increases with each recursive call)
745
802
  * @param nesting the current level of nesting (increments with each recursive call)
746
803
  * @returns the text populating the discriminator
747
804
  */
@@ -753,13 +810,15 @@ function recursivePopulateDiscriminator(modelType, item, receiver, rawSrc, dest,
753
810
  if (item.elementType.kind !== 'interface') {
754
811
  if (nesting > 1) {
755
812
  // at nestling level 1, the destination var was already created in generateDiscriminatorUnmarshaller()
756
- text += `${indent}${dest} = make(${recursiveGetDiscriminatorTypeName(modelType, item, false)}, len(${rawSrc}))\n`;
813
+ text += `${indent.get()}${dest} = make(${recursiveGetDiscriminatorTypeName(modelType, item, false)}, len(${rawSrc}))\n`;
757
814
  }
758
- text += `${indent}for i${nesting} := range ${rawSrc} {\n`;
815
+ text += `${indent.get()}for i${nesting} := range ${rawSrc} {\n`;
759
816
  rawSrc = `${rawSrc}[i${nesting}]`; // source becomes each element in the source slice
760
817
  dest = `${dest}[i${nesting}]`; // update destination to each element in the destination slice
761
- text += recursivePopulateDiscriminator(modelType, item.elementType, receiver, rawSrc, dest, indent + '\t', nesting + 1);
762
- text += `${indent}}\n`;
818
+ indent.push();
819
+ text += recursivePopulateDiscriminator(modelType, item.elementType, receiver, rawSrc, dest, indent, nesting + 1);
820
+ indent.pop();
821
+ text += `${indent.get()}}\n`;
763
822
  return text;
764
823
  }
765
824
  // we're at leaf node - 1, so get the interface from the element's type
@@ -770,21 +829,25 @@ function recursivePopulateDiscriminator(modelType, item, receiver, rawSrc, dest,
770
829
  if (item.valueType.kind !== 'interface') {
771
830
  if (nesting > 1) {
772
831
  // at nestling level 1, the destination var was already created in generateDiscriminatorUnmarshaller()
773
- text += `${indent}${dest} = ${recursiveGetDiscriminatorTypeName(modelType, item, false)}{}\n`;
832
+ text += `${indent.get()}${dest} = ${recursiveGetDiscriminatorTypeName(modelType, item, false)}{}\n`;
774
833
  }
775
- text += `${indent}for k${nesting}, v${nesting} := range ${rawSrc} {\n`;
834
+ text += `${indent.get()}for k${nesting}, v${nesting} := range ${rawSrc} {\n`;
776
835
  rawSrc = `v${nesting}`; // source becomes the current value in the source map
777
836
  dest = `${dest}[k${nesting}]`; // update destination to the destination map's value for the current key
778
- text += recursivePopulateDiscriminator(modelType, item.valueType, receiver, rawSrc, dest, indent + '\t', nesting + 1);
779
- text += `${indent}}\n`;
837
+ indent.push();
838
+ text += recursivePopulateDiscriminator(modelType, item.valueType, receiver, rawSrc, dest, indent, nesting + 1);
839
+ indent.pop();
840
+ text += `${indent.get()}}\n`;
780
841
  return text;
781
842
  }
782
843
  // we're at leaf node - 1, so get the interface from the element's type
783
844
  interfaceName = go.getTypeDeclaration(item.valueType, modelType.pkg);
784
845
  targetType = 'Map';
785
846
  }
786
- text += `${indent}${dest}, err = unmarshal${interfaceName}${targetType}(${rawSrc})\n`;
787
- text += `${indent}if err != nil {\n${indent}\treturn fmt.Errorf("unmarshalling type %T: %v", ${receiver}, err)\n${indent}}\n`;
847
+ text += `${indent.get()}${dest}, err = unmarshal${interfaceName}${targetType}(${rawSrc})\n`;
848
+ text += `${indent.get()}if err != nil {\n`;
849
+ text += `${indent.push().get()}return fmt.Errorf("unmarshalling type %T: %v", ${receiver}, err)\n`;
850
+ text += `${indent.pop().get()}}\n`;
788
851
  return text;
789
852
  }
790
853
  /**
@@ -794,33 +857,35 @@ function recursivePopulateDiscriminator(modelType, item, receiver, rawSrc, dest,
794
857
  * @param modelDef the type for which to implement MarshalXML
795
858
  * @param imports the import manager currently in scope
796
859
  */
797
- function generateXMLMarshaller(modelDef, imports) {
860
+ function generateXMLMarshaller(modelDef, imports, indent) {
798
861
  // only needed for types with time.Time, maps, or where the XML name doesn't match the type name
799
862
  const receiver = modelDef.receiverName();
800
863
  const desc = `MarshalXML implements the xml.Marshaller interface for type ${modelDef.Model.name}.`;
801
864
  let text = `func (${receiver} ${modelDef.Model.name}) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {\n`;
802
- if (modelDef.Model.xml?.wrapper) {
803
- text += `\tstart.Name.Local = "${modelDef.Model.xml.wrapper}"\n`;
865
+ if (modelDef.Model.xml?.name) {
866
+ text += `${indent.get()}start.Name.Local = "${modelDef.Model.xml.name}"\n`;
804
867
  }
805
- text += generateAliasType(modelDef.Model, receiver, true, imports);
868
+ text += generateAliasType(modelDef.Model, receiver, true, imports, indent);
806
869
  for (const field of modelDef.Model.fields) {
807
870
  if (field.type.kind === 'slice') {
808
- text += `\tif ${receiver}.${field.name} != nil {\n`;
809
- text += `\t\taux.${field.name} = &${receiver}.${field.name}\n`;
810
- text += '\t}\n';
871
+ text += `${indent.get()}if ${receiver}.${field.name} != nil {\n`;
872
+ text += `${indent.push().get()}aux.${field.name} = &${receiver}.${field.name}\n`;
873
+ text += `${indent.pop().get()}}\n`;
811
874
  }
812
875
  else if (field.annotations.isAdditionalProperties || field.type.kind === 'map') {
813
- text += `\taux.${field.name} = (additionalProperties)(${receiver}.${field.name})\n`;
876
+ text += `${indent.get()}aux.${field.name} = (additionalProperties)(${receiver}.${field.name})\n`;
814
877
  }
815
878
  else if (field.type.kind === 'encodedBytes') {
816
879
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
817
- text += `\tif ${receiver}.${field.name} != nil {\n`;
818
- text += `\t\tencoded${field.name} := runtime.EncodeByteArray(${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format)\n`;
819
- text += `\t\taux.${field.name} = &encoded${field.name}\n`;
820
- text += '\t}\n';
880
+ text += `${indent.get()}if ${receiver}.${field.name} != nil {\n`;
881
+ indent.push();
882
+ text += `${indent.get()}encoded${field.name} := runtime.EncodeByteArray(${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format)\n`;
883
+ text += `${indent.get()}aux.${field.name} = &encoded${field.name}\n`;
884
+ indent.pop();
885
+ text += `${indent.get()}}\n`;
821
886
  }
822
887
  }
823
- text += '\treturn enc.EncodeElement(aux, start)\n';
888
+ text += `${indent.get()}return enc.EncodeElement(aux, start)\n`;
824
889
  text += '}\n\n';
825
890
  modelDef.SerDe.methods.push({ name: 'MarshalXML', desc: desc, text: text });
826
891
  }
@@ -831,33 +896,36 @@ function generateXMLMarshaller(modelDef, imports) {
831
896
  * @param modelDef the type for which to implement UnmarshalXML
832
897
  * @param imports the import manager currently in scope
833
898
  */
834
- function generateXMLUnmarshaller(modelDef, imports) {
899
+ function generateXMLUnmarshaller(modelDef, imports, indent) {
835
900
  // non-polymorphic case, must be something with time.Time
836
901
  const receiver = modelDef.receiverName();
837
902
  const desc = `UnmarshalXML implements the xml.Unmarshaller interface for type ${modelDef.Model.name}.`;
838
903
  let text = `func (${receiver} *${modelDef.Model.name}) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) error {\n`;
839
- text += generateAliasType(modelDef.Model, receiver, false, imports);
840
- text += '\tif err := dec.DecodeElement(aux, &start); err != nil {\n';
841
- text += '\t\treturn err\n';
842
- text += '\t}\n';
904
+ text += generateAliasType(modelDef.Model, receiver, false, imports, indent);
905
+ text += `${indent.get()}if err := dec.DecodeElement(aux, &start); err != nil {\n`;
906
+ text += `${indent.push().get()}return err\n`;
907
+ text += `${indent.pop().get()}}\n`;
843
908
  for (const field of modelDef.Model.fields) {
844
909
  if (field.type.kind === 'time') {
845
- text += `\tif aux.${field.name} != nil && !(*time.Time)(aux.${field.name}).IsZero() {\n`;
846
- text += `\t\t${receiver}.${field.name} = (*time.Time)(aux.${field.name})\n\t}\n`;
910
+ text += `${indent.get()}if aux.${field.name} != nil && !(*time.Time)(aux.${field.name}).IsZero() {\n`;
911
+ text += `${indent.push().get()}${receiver}.${field.name} = (*time.Time)(aux.${field.name})\n`;
912
+ text += `${indent.pop().get()}}\n`;
847
913
  }
848
914
  else if (field.annotations.isAdditionalProperties || field.type.kind === 'map') {
849
- text += `\t${receiver}.${field.name} = (map[string]*string)(aux.${field.name})\n`;
915
+ text += `${indent.get()}${receiver}.${field.name} = (map[string]*string)(aux.${field.name})\n`;
850
916
  }
851
917
  else if (field.type.kind === 'encodedBytes') {
852
918
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
853
- text += `\tif aux.${field.name} != nil {\n`;
854
- text += `\t\tif err := runtime.DecodeByteArray(*aux.${field.name}, &${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format); err != nil {\n`;
855
- text += '\t\t\treturn err\n';
856
- text += '\t\t}\n';
857
- text += '\t}\n';
919
+ text += `${indent.get()}if aux.${field.name} != nil {\n`;
920
+ indent.push();
921
+ text += `${indent.get()}if err := runtime.DecodeByteArray(*aux.${field.name}, &${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format); err != nil {\n`;
922
+ text += `${indent.push().get()}return err\n`;
923
+ text += `${indent.pop().get()}}\n`;
924
+ indent.pop();
925
+ text += `${indent.get()}}\n`;
858
926
  }
859
927
  }
860
- text += '\treturn nil\n';
928
+ text += `${indent.get()}return nil\n`;
861
929
  text += '}\n\n';
862
930
  modelDef.SerDe.methods.push({ name: 'UnmarshalXML', desc: desc, text: text });
863
931
  }
@@ -869,32 +937,32 @@ function generateXMLUnmarshaller(modelDef, imports) {
869
937
  * @param forMarshal when true, indicates type is to be used in a marshaller (else an unmarshaller)
870
938
  * @returns the text for an initialized type alias
871
939
  */
872
- function generateAliasType(modelType, receiver, forMarshal, imports) {
873
- let text = `\ttype alias ${modelType.name}\n`;
874
- text += '\taux := &struct {\n';
875
- text += '\t\t*alias\n';
940
+ function generateAliasType(modelType, receiver, forMarshal, imports, indent) {
941
+ let text = `${indent.get()}type alias ${modelType.name}\n`;
942
+ text += `${indent.get()}aux := &struct {\n`;
943
+ text += `${indent.push().get()}*alias\n`;
876
944
  for (const field of modelType.fields) {
877
- const sn = getXMLSerialization(modelType, field);
945
+ const sn = getXMLSerialization(field);
878
946
  if (field.type.kind === 'time') {
879
947
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime');
880
- text += `\t\t${field.name} *datetime.${field.type.format} \`xml:"${sn}"\`\n`;
948
+ text += `${indent.get()}${field.name} *datetime.${field.type.format} \`xml:"${sn}"\`\n`;
881
949
  }
882
950
  else if (field.annotations.isAdditionalProperties || field.type.kind === 'map') {
883
- text += `\t\t${field.name} additionalProperties \`xml:"${sn}"\`\n`;
951
+ text += `${indent.get()}${field.name} additionalProperties \`xml:"${sn}"\`\n`;
884
952
  }
885
953
  else if (field.type.kind === 'slice') {
886
- text += `\t\t${field.name} *${go.getTypeDeclaration(field.type, modelType.pkg)} \`xml:"${sn}"\`\n`;
954
+ text += `${indent.get()}${field.name} *${go.getTypeDeclaration(field.type, modelType.pkg)} \`xml:"${sn}"\`\n`;
887
955
  }
888
956
  else if (field.type.kind === 'encodedBytes') {
889
- text += `\t\t${field.name} *string \`xml:"${sn}"\`\n`;
957
+ text += `${indent.get()}${field.name} *string \`xml:"${sn}"\`\n`;
890
958
  }
891
959
  }
892
- text += '\t}{\n';
960
+ text += `${indent.pop().get()}}{\n`;
893
961
  let rec = receiver;
894
962
  if (forMarshal) {
895
963
  rec = '&' + rec;
896
964
  }
897
- text += `\t\talias: (*alias)(${rec}),\n`;
965
+ text += `${indent.push().get()}alias: (*alias)(${rec}),\n`;
898
966
  if (forMarshal) {
899
967
  // emit code to initialize time fields
900
968
  for (const field of modelType.fields) {
@@ -902,10 +970,10 @@ function generateAliasType(modelType, receiver, forMarshal, imports) {
902
970
  continue;
903
971
  }
904
972
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime');
905
- text += `\t\t${field.name}: (*datetime.${field.type.format})(${receiver}.${field.name}),\n`;
973
+ text += `${indent.get()}${field.name}: (*datetime.${field.type.format})(${receiver}.${field.name}),\n`;
906
974
  }
907
975
  }
908
- text += '\t}\n';
976
+ text += `${indent.pop().get()}}\n`;
909
977
  return text;
910
978
  }
911
979
  /** used to track which serde helpers and methods are required for a struct */
@@ -942,7 +1010,7 @@ class ModelDef {
942
1010
  this.Methods = new Array();
943
1011
  }
944
1012
  /** returns the text for the struct definition */
945
- text() {
1013
+ text(indent) {
946
1014
  let text = helpers.formatDocComment(this.Model.docs);
947
1015
  text += `type ${this.Model.name} struct {\n`;
948
1016
  // group fields by required/optional/read-only in that order
@@ -978,14 +1046,14 @@ class ModelDef {
978
1046
  serialization += ',omitempty';
979
1047
  }
980
1048
  else if (this.Format === 'XML') {
981
- serialization = getXMLSerialization(this.Model, field);
1049
+ serialization = getXMLSerialization(field);
982
1050
  }
983
1051
  let tag = '';
984
1052
  // only emit tags for XML; JSON uses custom marshallers/unmarshallers
985
1053
  if (this.Format === 'XML' && !field.annotations.isAdditionalProperties) {
986
1054
  tag = ` \`xml:"${serialization}"\``;
987
1055
  }
988
- text += `\t${field.name} ${helpers.star(field.byValue)}${typeName}${tag}\n`;
1056
+ text += `${indent.get()}${field.name} ${helpers.star(field.byValue)}${typeName}${tag}\n`;
989
1057
  first = false;
990
1058
  }
991
1059
  text += '}\n\n';
@@ -1000,11 +1068,10 @@ class ModelDef {
1000
1068
  /**
1001
1069
  * returns the serialization options to use in the XML tag on a model field
1002
1070
  *
1003
- * @param modelType the type that contains the field
1004
1071
  * @param field the field for which to construct the tag's contents
1005
1072
  * @returns the contents for the XML tag
1006
1073
  */
1007
- function getXMLSerialization(modelType, field) {
1074
+ function getXMLSerialization(field) {
1008
1075
  let serialization = field.serializedName;
1009
1076
  // default to using the serialization name
1010
1077
  if (field.xml?.name) {
@@ -1022,7 +1089,7 @@ function getXMLSerialization(modelType, field) {
1022
1089
  }
1023
1090
  else if (field.type.kind === 'slice') {
1024
1091
  // start with the serialized name of the element, preferring xml name if available
1025
- let inner = go.getTypeDeclaration(field.type.elementType, modelType.pkg);
1092
+ let inner = field.serializedName;
1026
1093
  if (field.xml?.name) {
1027
1094
  inner = field.xml.name;
1028
1095
  }