@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
@@ -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) {
@@ -253,31 +259,31 @@ function generateModelDefs(modelImports, serdeImports, pkg, options) {
253
259
  // due to differences in XML marshallers/unmarshallers, we use different codegen than for JSON
254
260
  const needsXMLDictionaryUnmarshalling = needsXMLDictionaryHelper(model);
255
261
  if (needsDateTimeMarshalling || model.xml?.name || needsXMLArrayMarshalling(model) || byteArrayFormat) {
256
- generateXMLMarshaller(modelDef, serdeImports);
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
  }
@@ -310,7 +316,7 @@ function needsXMLArrayMarshalling(modelType) {
310
316
  return false;
311
317
  }
312
318
  // generates discriminator marker method
313
- function generateDiscriminatorMarkerMethod(type, modelDef) {
319
+ function generateDiscriminatorMarkerMethod(type, modelDef, indent) {
314
320
  const typeName = type.rootType.name;
315
321
  const receiver = modelDef.receiverName();
316
322
  const interfaceMethod = `Get${typeName}`;
@@ -322,37 +328,43 @@ function generateDiscriminatorMarkerMethod(type, modelDef) {
322
328
  else {
323
329
  // the marker method is on a child type, so return an instance of the parent
324
330
  // type by copying the parent values into a new instance.
325
- method += `\n\treturn &${type.rootType.name}{\n`;
331
+ method += `\n${indent.get()}return &${type.rootType.name}{\n`;
332
+ indent.push();
326
333
  for (const field of type.rootType.fields) {
327
- method += `\t\t${field.name}: ${modelDef.receiverName()}.${field.name},\n`;
334
+ method += `${indent.get()}${field.name}: ${modelDef.receiverName()}.${field.name},\n`;
328
335
  }
329
- method += '\t}\n}\n\n';
336
+ method += `${indent.pop().get()}}\n}\n\n`;
330
337
  }
331
338
  modelDef.Methods.push({ name: interfaceMethod, desc: `${interfaceMethod} implements the ${type.name} interface for type ${modelDef.Model.name}.`, text: method });
332
339
  }
333
- function generateToMultipartForm(modelDef) {
340
+ function generateToMultipartForm(modelDef, indent) {
334
341
  const receiver = modelDef.receiverName();
335
342
  let method = `func (${receiver} ${modelDef.Model.name}) toMultipartFormData() (map[string]any, error) {\n`;
336
- method += '\tobjectMap := make(map[string]any)\n';
343
+ method += `${indent.get()}objectMap := make(map[string]any)\n`;
337
344
  for (const field of modelDef.Model.fields) {
338
345
  const fieldType = helpers.recursiveUnwrapMapSlice(field.type);
339
- let setField;
340
346
  let star = '';
341
347
  if (!field.byValue) {
342
348
  star = '*';
343
349
  }
350
+ if (!field.byValue) {
351
+ method += `${indent.get()}if ${receiver}.${field.name} != nil {\n`;
352
+ indent.push();
353
+ }
344
354
  if (fieldType.kind === 'model' && !fieldType.annotations.multipartFormData) {
345
- 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`;
346
358
  }
347
359
  else {
348
- setField = `\tobjectMap["${field.serializedName}"] = ${star}${receiver}.${field.name}\n`;
360
+ method += `${indent.get()}objectMap["${field.serializedName}"] = ${star}${receiver}.${field.name}\n`;
349
361
  }
350
362
  if (!field.byValue) {
351
- setField = `\tif ${receiver}.${field.name} != nil {\n\t\t${setField}\t}\n`;
363
+ indent.pop();
364
+ method += `${indent.get()}}\n`;
352
365
  }
353
- method += setField;
354
366
  }
355
- method += '\treturn objectMap, nil\n}\n\n';
367
+ method += `${indent.get()}return objectMap, nil\n}\n\n`;
356
368
  modelDef.SerDe.methods.push({ name: 'toMultipartFormData', desc: `toMultipartFormData converts ${modelDef.Model.name} to multipart/form data.`, text: method });
357
369
  }
358
370
  /**
@@ -361,8 +373,9 @@ function generateToMultipartForm(modelDef) {
361
373
  *
362
374
  * @param modelDef the type for which to emit the method
363
375
  * @param imports the import manager currently in scope
376
+ * @param indent the indentation helper currently in scope
364
377
  */
365
- function generateJSONMarshaller(modelDef, imports) {
378
+ function generateJSONMarshaller(modelDef, imports, indent) {
366
379
  if (modelDef.Model.kind === 'model' && modelDef.Model.fields.length === 0) {
367
380
  // non-discriminated types without content don't need a custom marshaller.
368
381
  // there is a case in network where child is allOf base and child has no properties.
@@ -372,9 +385,9 @@ function generateJSONMarshaller(modelDef, imports) {
372
385
  const typeName = modelDef.Model.name;
373
386
  const receiver = modelDef.receiverName();
374
387
  let marshaller = `func (${receiver} ${typeName}) MarshalJSON() ([]byte, error) {\n`;
375
- marshaller += '\tobjectMap := make(map[string]any)\n';
376
- marshaller += generateJSONMarshallerBody(modelDef, receiver, imports);
377
- 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`;
378
391
  marshaller += '}\n\n';
379
392
  modelDef.SerDe.methods.push({ name: 'MarshalJSON', desc: `MarshalJSON implements the json.Marshaller interface for type ${typeName}.`, text: marshaller });
380
393
  }
@@ -384,9 +397,10 @@ function generateJSONMarshaller(modelDef, imports) {
384
397
  * @param modelDef the type being encoded
385
398
  * @param receiver the name of the receiver in the MarshalJSON method
386
399
  * @param imports the import manager currently in scope
400
+ * @param indent the indentation helper currently in scope
387
401
  * @returns the text for encoding the target type
388
402
  */
389
- function generateJSONMarshallerBody(modelDef, receiver, imports) {
403
+ function generateJSONMarshallerBody(modelDef, receiver, imports, indent) {
390
404
  let marshaller = '';
391
405
  let addlProps;
392
406
  for (const field of modelDef.Model.fields) {
@@ -396,27 +410,30 @@ function generateJSONMarshallerBody(modelDef, receiver, imports) {
396
410
  }
397
411
  if (field.annotations.isDiscriminator) {
398
412
  if (field.defaultValue) {
399
- marshaller += `\tobjectMap["${field.serializedName}"] = ${helpers.formatLiteralValue(field.defaultValue, true)}\n`;
413
+ marshaller += `${indent.get()}objectMap["${field.serializedName}"] = ${helpers.formatLiteralValue(field.defaultValue, true)}\n`;
400
414
  }
401
415
  else {
402
416
  // if there's no discriminator value (e.g. Fish in test server), use the field's value.
403
417
  // this will enable support for custom types that aren't (yet) described in the swagger.
404
- marshaller += `\tobjectMap["${field.serializedName}"] = ${receiver}.${field.name}\n`;
418
+ marshaller += `${indent.get()}objectMap["${field.serializedName}"] = ${receiver}.${field.name}\n`;
405
419
  }
406
420
  }
407
421
  else if (field.type.kind === 'encodedBytes') {
408
422
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
409
- marshaller += `\tpopulateByteArray(objectMap, "${field.serializedName}", ${receiver}.${field.name}, func() any {\n`;
410
- 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`;
411
426
  modelDef.SerDe.needsJSONPopulateByteArray = true;
412
427
  }
413
428
  else if (field.type.kind === 'slice' && field.type.elementType.kind === 'encodedBytes') {
414
429
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
415
- marshaller += `\tpopulateByteArray(objectMap, "${field.serializedName}", ${receiver}.${field.name}, func() any {\n`;
416
- marshaller += `\t\tencodedValue := make([]string, len(${receiver}.${field.name}))\n`;
417
- marshaller += `\t\tfor i := 0; i < len(${receiver}.${field.name}); i++ {\n`;
418
- marshaller += `\t\t\tencodedValue[i] = runtime.EncodeByteArray(${receiver}.${field.name}[i], runtime.Base64${field.type.elementType.encoding}Format)\n\t\t}\n`;
419
- 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`;
420
437
  modelDef.SerDe.needsJSONPopulateByteArray = true;
421
438
  }
422
439
  else if (field.type.kind === 'slice' && field.type.elementType.kind === 'time') {
@@ -426,30 +443,34 @@ function generateJSONMarshallerBody(modelDef, receiver, imports) {
426
443
  elementPtr = '';
427
444
  }
428
445
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime');
429
- marshaller += `\taux := make([]${elementPtr}datetime.${field.type.elementType.format}, len(${source}), len(${source}))\n`;
430
- marshaller += `\tfor i := 0; i < len(${source}); i++ {\n`;
431
- marshaller += `\t\taux[i] = (${elementPtr}datetime.${field.type.elementType.format})(${source}[i])\n`;
432
- marshaller += '\t}\n';
433
- 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`;
434
451
  modelDef.SerDe.needsJSONPopulate = true;
435
452
  }
436
453
  else if (field.type.kind === 'literal') {
437
454
  const setter = `objectMap["${field.serializedName}"] = ${helpers.formatLiteralValue(field.type, true)}`;
438
455
  if (!field.annotations.required) {
439
- 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`;
440
459
  }
441
460
  else {
442
- marshaller += `\t${setter}\n`;
461
+ marshaller += `${indent.get()}${setter}\n`;
443
462
  }
444
463
  }
445
464
  else if (field.type.kind === 'rawJSON') {
446
- 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`;
447
466
  modelDef.SerDe.needsJSONPopulate = true;
448
467
  }
449
468
  else {
450
469
  if (field.defaultValue) {
451
470
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/to');
452
- 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`;
453
474
  }
454
475
  let populate;
455
476
  if (field.type.kind === 'time') {
@@ -470,27 +491,27 @@ function generateJSONMarshallerBody(modelDef, receiver, imports) {
470
491
  imports.add('strconv');
471
492
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/to');
472
493
  if ((field.type.type.startsWith('uint') && field.type.type !== 'uint64') || (field.type.type.startsWith('int') && field.type.type !== 'int64')) {
473
- 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`;
474
495
  }
475
496
  else {
476
- 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`;
477
498
  }
478
499
  }
479
500
  else {
480
- marshaller += `\t${populate}(objectMap, "${field.serializedName}", ${receiver}.${field.name})\n`;
501
+ marshaller += `${indent.get()}${populate}(objectMap, "${field.serializedName}", ${receiver}.${field.name})\n`;
481
502
  }
482
503
  }
483
504
  }
484
505
  if (addlProps) {
485
- marshaller += `\tif ${receiver}.AdditionalProperties != nil {\n`;
486
- 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`;
487
508
  let assignment = 'val';
488
509
  if (addlProps.valueType.kind === 'time') {
489
510
  assignment = `(*${addlProps.valueType.format})(val)`;
490
511
  }
491
- marshaller += `\t\t\tobjectMap[key] = ${assignment}\n`;
492
- marshaller += '\t\t}\n';
493
- marshaller += '\t}\n';
512
+ marshaller += `${indent.push().get()}objectMap[key] = ${assignment}\n`;
513
+ marshaller += `${indent.pop().get()}}\n`;
514
+ marshaller += `${indent.pop().get()}}\n`;
494
515
  }
495
516
  return marshaller;
496
517
  }
@@ -499,10 +520,11 @@ function generateJSONMarshallerBody(modelDef, receiver, imports) {
499
520
  * the method impl is added to modelDef.SerDe.methods.
500
521
  *
501
522
  * @param modelDef the type for which to emit the method
502
- * @param imports the import manager currently in scope
503
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
504
526
  */
505
- function generateJSONUnmarshaller(modelDef, imports, options) {
527
+ function generateJSONUnmarshaller(modelDef, options, imports, indent) {
506
528
  // there's a corner-case where a derived type might not add any new fields (Cookiecuttershark).
507
529
  // in this case skip adding the unmarshaller as it's not necessary and doesn't compile.
508
530
  if (modelDef.Model.fields.length === 0) {
@@ -513,11 +535,11 @@ function generateJSONUnmarshaller(modelDef, imports, options) {
513
535
  const typeName = modelDef.Model.name;
514
536
  const receiver = modelDef.receiverName();
515
537
  let unmarshaller = `func (${receiver} *${typeName}) UnmarshalJSON(data []byte) error {\n`;
516
- unmarshaller += '\tvar rawMsg map[string]json.RawMessage\n';
517
- unmarshaller += '\tif err := json.Unmarshal(data, &rawMsg); err != nil {\n';
518
- unmarshaller += `\t\treturn fmt.Errorf("unmarshalling type %T: %v", ${receiver}, err)\n`;
519
- unmarshaller += '\t}\n';
520
- 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);
521
543
  unmarshaller += '}\n\n';
522
544
  modelDef.SerDe.methods.push({ name: 'UnmarshalJSON', desc: `UnmarshalJSON implements the json.Unmarshaller interface for type ${typeName}.`, text: unmarshaller });
523
545
  }
@@ -526,25 +548,27 @@ function generateJSONUnmarshaller(modelDef, imports, options) {
526
548
  *
527
549
  * @param modelDef the type being decoded
528
550
  * @param receiver the receiver for the UnmarshalJSON method
529
- * @param imports the import manager currently in scope
530
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
531
554
  * @returns the text for decoding the target type
532
555
  */
533
- function generateJSONUnmarshallerBody(modelDef, receiver, imports, options) {
556
+ function generateJSONUnmarshallerBody(modelDef, receiver, options, imports, indent) {
534
557
  // we almost always need to have an error check when unmarshaling the values.
535
558
  // however, fields that are raw JSON don't require any unmarshaling. so, if all
536
559
  // of the fields in a type are raw JSON, then the error check isn't necessary
537
560
  // and can be elided (the linter complains about it otherwise).
538
561
  let needsErrCheck = false;
539
- const emitAddlProps = function (tab, addlProps) {
540
- 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`;
541
565
  let ref = '';
542
566
  if (!addlProps.valueTypeByValue) {
543
567
  ref = '&';
544
568
  }
545
- addlPropsText += `${tab}\t\t\t${receiver}.AdditionalProperties = ${go.getTypeDeclaration(addlProps, modelDef.Model.pkg)}{}\n`;
546
- addlPropsText += `${tab}\t\t}\n`;
547
- 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`;
548
572
  let auxType = go.getTypeDeclaration(addlProps.valueType, modelDef.Model.pkg);
549
573
  let assignment = `${ref}aux`;
550
574
  if (addlProps.valueType.kind === 'time') {
@@ -552,30 +576,32 @@ function generateJSONUnmarshallerBody(modelDef, receiver, imports, options) {
552
576
  auxType = addlProps.valueType.format;
553
577
  assignment = `(*time.Time)(${assignment})`;
554
578
  }
555
- addlPropsText += `${tab}\t\t\tvar aux ${auxType}\n`;
556
- addlPropsText += `${tab}\t\t\terr = json.Unmarshal(val, &aux)\n`;
557
- addlPropsText += `${tab}\t\t\t${receiver}.AdditionalProperties[key] = ${assignment}\n`;
558
- addlPropsText += `${tab}\t\t}\n`;
559
- 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`;
560
584
  needsErrCheck = true;
561
585
  return addlPropsText;
562
586
  };
563
587
  const emitSwitchCase = function () {
588
+ // indent is at level 2 (for loop body) when called
564
589
  let unmarshalBody = '';
565
590
  let addlProps;
566
- unmarshalBody += '\t\tswitch key {\n';
591
+ unmarshalBody += `${indent.get()}switch key {\n`;
567
592
  for (const field of modelDef.Model.fields) {
568
593
  if (field.type.kind === 'map' && field.annotations.isAdditionalProperties) {
569
594
  addlProps = field.type;
570
595
  continue;
571
596
  }
572
- unmarshalBody += `\t\tcase "${field.serializedName}":\n`;
597
+ unmarshalBody += `${indent.get()}case "${field.serializedName}":\n`;
598
+ indent.push(); // case body level
573
599
  if (hasDiscriminatorInterface(field.type)) {
574
- unmarshalBody += generateDiscriminatorUnmarshaller(modelDef.Model, field, receiver);
600
+ unmarshalBody += generateDiscriminatorUnmarshaller(modelDef.Model, field, receiver, indent);
575
601
  needsErrCheck = true;
576
602
  }
577
603
  else if (field.type.kind === 'time') {
578
- 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`;
579
605
  modelDef.SerDe.needsJSONUnpopulateTime = true;
580
606
  needsErrCheck = true;
581
607
  }
@@ -586,89 +612,111 @@ function generateJSONUnmarshallerBody(modelDef, receiver, imports, options) {
586
612
  if (field.type.elementTypeByValue) {
587
613
  elementPtr = '';
588
614
  }
589
- unmarshalBody += `\t\t\tvar aux []${elementPtr}datetime.${field.type.elementType.format}\n`;
590
- unmarshalBody += `\t\t\terr = unpopulate(val, "${field.name}", &aux)\n`;
591
- unmarshalBody += '\t\t\tfor _, au := range aux {\n';
592
- unmarshalBody += `\t\t\t\t${receiver}.${field.name} = append(${receiver}.${field.name}, (${elementPtr}time.Time)(au))\n`;
593
- 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`;
594
620
  modelDef.SerDe.needsJSONUnpopulate = true;
595
621
  needsErrCheck = true;
596
622
  }
597
623
  else if (field.type.kind === 'encodedBytes') {
598
624
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
599
- unmarshalBody += '\t\tif val != nil && string(val) != "null" {\n';
600
- 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`;
601
628
  needsErrCheck = true;
602
629
  }
603
630
  else if (field.type.kind === 'slice' && field.type.elementType.kind === 'encodedBytes') {
604
631
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
605
- unmarshalBody += '\t\t\tvar encodedValue []string\n';
606
- unmarshalBody += `\t\t\terr = unpopulate(val, "${field.name}", &encodedValue)\n`;
607
- unmarshalBody += '\t\t\tif err == nil && len(encodedValue) > 0 {\n';
608
- unmarshalBody += `\t\t\t\t${receiver}.${field.name} = make([][]byte, len(encodedValue))\n`;
609
- unmarshalBody += '\t\t\t\tfor i := 0; i < len(encodedValue) && err == nil; i++ {\n';
610
- unmarshalBody += `\t\t\t\t\terr = runtime.DecodeByteArray(encodedValue[i], &${receiver}.${field.name}[i], runtime.Base64${field.type.elementType.encoding}Format)\n`;
611
- 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`;
612
642
  modelDef.SerDe.needsJSONUnpopulate = true;
613
643
  needsErrCheck = true;
614
644
  }
615
645
  else if (field.type.kind === 'rawJSON') {
616
- unmarshalBody += '\t\t\tif string(val) != "null" {\n';
617
- 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`;
618
649
  }
619
650
  else if (field.type.kind === 'scalar' && (field.type.type.startsWith('uint') || field.type.type.startsWith('int')) && field.type.encodeAsString) {
620
651
  // TODO: need to handle map and slice type with underlying int as string type
621
652
  imports.add('strconv');
622
- unmarshalBody += `\t\t\t\tvar aux string\n`;
623
- unmarshalBody += `\t\t\t\terr = unpopulate(val, "${field.name}", &aux)\n`;
624
- unmarshalBody += `\t\t\t\tif err == nil {\n`;
625
- unmarshalBody += `\t\t\t\t\tvar v ${field.type.type.startsWith('int') ? 'int64' : 'uint64'}\n`;
626
- unmarshalBody += `\t\t\t\t\tv, err = strconv.${field.type.type.startsWith('int') ? 'ParseInt' : 'ParseUint'}(aux, 10, 0)\n`;
627
- 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`;
628
660
  if ((field.type.type.startsWith('uint') && field.type.type !== 'uint64') || (field.type.type.startsWith('int') && field.type.type !== 'int64')) {
629
- 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`;
630
662
  }
631
663
  else {
632
- 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`;
633
665
  }
634
- unmarshalBody += '\t\t\t\t\t}\n';
635
- unmarshalBody += '\t\t\t\t}\n';
666
+ unmarshalBody += `${indent.pop().get()}}\n`;
667
+ indent.pop();
668
+ unmarshalBody += `${indent.get()}}\n`;
636
669
  modelDef.SerDe.needsJSONUnpopulate = true;
637
670
  needsErrCheck = true;
638
671
  }
639
672
  else {
640
- 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
+ }
641
683
  modelDef.SerDe.needsJSONUnpopulate = true;
642
684
  needsErrCheck = true;
643
685
  }
644
- unmarshalBody += '\t\t\tdelete(rawMsg, key)\n';
686
+ unmarshalBody += `${indent.get()}delete(rawMsg, key)\n`;
687
+ indent.pop(); // back to switch level
645
688
  }
646
689
  if (addlProps) {
647
- unmarshalBody += '\t\tdefault:\n';
648
- unmarshalBody += emitAddlProps('\t', addlProps);
690
+ unmarshalBody += `${indent.get()}default:\n`;
691
+ indent.push(); // case body level
692
+ unmarshalBody += emitAddlProps(addlProps);
693
+ indent.pop();
649
694
  }
650
695
  else if (options.disallowUnknownFields) {
651
- unmarshalBody += '\t\tdefault:\n';
652
- 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();
653
699
  needsErrCheck = true;
654
700
  }
655
- unmarshalBody += '\t\t}\n';
701
+ unmarshalBody += `${indent.get()}}\n`;
656
702
  return unmarshalBody;
657
703
  };
658
- 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)
659
706
  // emitSwitchCase sets needsErrCheck so we must call it first
660
707
  const switchCaseBody = emitSwitchCase();
661
708
  if (needsErrCheck) {
662
- unmarshalBody += '\t\tvar err error\n';
709
+ unmarshalBody += `${indent.get()}var err error\n`;
663
710
  }
664
711
  unmarshalBody += switchCaseBody;
665
712
  if (needsErrCheck) {
666
- unmarshalBody += '\t\tif err != nil {\n';
667
- unmarshalBody += `\t\t\treturn fmt.Errorf("unmarshalling type %T: %v", ${receiver}, err)\n`;
668
- 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`;
669
716
  }
670
- unmarshalBody += '\t}\n'; // end for key, val := range rawMsg
671
- 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`;
672
720
  return unmarshalBody;
673
721
  }
674
722
  // returns true if item has a discriminator interface.
@@ -686,25 +734,25 @@ function hasDiscriminatorInterface(item) {
686
734
  }
687
735
  }
688
736
  // returns the text for unmarshalling a discriminated type
689
- function generateDiscriminatorUnmarshaller(modelType, field, receiver) {
690
- const startingIndentation = '\t\t\t';
737
+ function generateDiscriminatorUnmarshaller(modelType, field, receiver, indent) {
691
738
  const propertyName = field.name;
692
739
  // these are the simple, non-nested cases (e.g. IterfaceType, []InterfaceType, map[string]InterfaceType)
693
740
  if (field.type.kind === 'interface') {
694
- return `${startingIndentation}${receiver}.${propertyName}, err = unmarshal${field.type.name}(val)\n`;
741
+ return `${indent.get()}${receiver}.${propertyName}, err = unmarshal${field.type.name}(val)\n`;
695
742
  }
696
743
  else if (field.type.kind === 'slice' && field.type.elementType.kind === 'interface') {
697
- 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`;
698
745
  }
699
746
  else if (field.type.kind === 'map' && field.type.valueType.kind === 'interface') {
700
- 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`;
701
748
  }
702
749
  // nested case (e.g. [][]InterfaceType, map[string]map[string]InterfaceType etc)
703
750
  // first, unmarshal the raw data
704
751
  const rawTargetVar = `${field.serializedName}Raw`;
705
- let text = `${startingIndentation}var ${rawTargetVar} ${recursiveGetDiscriminatorTypeName(modelType, field.type, true)}\n`;
706
- text += `${startingIndentation}if err = json.Unmarshal(val, &${rawTargetVar}); err != nil {\n`;
707
- 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`;
708
756
  // create a local instantiation of the final type
709
757
  const finalTargetVar = field.serializedName;
710
758
  let finalTargetCtor = recursiveGetDiscriminatorTypeName(modelType, field.type, false);
@@ -715,11 +763,11 @@ function generateDiscriminatorUnmarshaller(modelType, field, receiver) {
715
763
  // must be a dictionary
716
764
  finalTargetCtor = `${finalTargetCtor}{}`;
717
765
  }
718
- text += `${startingIndentation}${finalTargetVar} := ${finalTargetCtor}\n`;
766
+ text += `${indent.get()}${finalTargetVar} := ${finalTargetCtor}\n`;
719
767
  // now populate the final type
720
- text += recursivePopulateDiscriminator(modelType, field.type, receiver, rawTargetVar, finalTargetVar, startingIndentation, 1);
768
+ text += recursivePopulateDiscriminator(modelType, field.type, receiver, rawTargetVar, finalTargetVar, indent, 1);
721
769
  // finally, assign the final target to the property
722
- text += `${startingIndentation}${receiver}.${propertyName} = ${finalTargetVar}\n`;
770
+ text += `${indent.get()}${receiver}.${propertyName} = ${finalTargetVar}\n`;
723
771
  return text;
724
772
  }
725
773
  // constructs the type name for a nested discriminated type
@@ -750,7 +798,7 @@ function recursiveGetDiscriminatorTypeName(modelType, item, raw) {
750
798
  * @param receiver the name of the receiver for the method to contain the expression
751
799
  * @param rawSrc contains the raw unmarshaled JSON source
752
800
  * @param dest the variable that will contain the result of the expression
753
- * @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)
754
802
  * @param nesting the current level of nesting (increments with each recursive call)
755
803
  * @returns the text populating the discriminator
756
804
  */
@@ -762,13 +810,15 @@ function recursivePopulateDiscriminator(modelType, item, receiver, rawSrc, dest,
762
810
  if (item.elementType.kind !== 'interface') {
763
811
  if (nesting > 1) {
764
812
  // at nestling level 1, the destination var was already created in generateDiscriminatorUnmarshaller()
765
- text += `${indent}${dest} = make(${recursiveGetDiscriminatorTypeName(modelType, item, false)}, len(${rawSrc}))\n`;
813
+ text += `${indent.get()}${dest} = make(${recursiveGetDiscriminatorTypeName(modelType, item, false)}, len(${rawSrc}))\n`;
766
814
  }
767
- text += `${indent}for i${nesting} := range ${rawSrc} {\n`;
815
+ text += `${indent.get()}for i${nesting} := range ${rawSrc} {\n`;
768
816
  rawSrc = `${rawSrc}[i${nesting}]`; // source becomes each element in the source slice
769
817
  dest = `${dest}[i${nesting}]`; // update destination to each element in the destination slice
770
- text += recursivePopulateDiscriminator(modelType, item.elementType, receiver, rawSrc, dest, indent + '\t', nesting + 1);
771
- 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`;
772
822
  return text;
773
823
  }
774
824
  // we're at leaf node - 1, so get the interface from the element's type
@@ -779,21 +829,25 @@ function recursivePopulateDiscriminator(modelType, item, receiver, rawSrc, dest,
779
829
  if (item.valueType.kind !== 'interface') {
780
830
  if (nesting > 1) {
781
831
  // at nestling level 1, the destination var was already created in generateDiscriminatorUnmarshaller()
782
- text += `${indent}${dest} = ${recursiveGetDiscriminatorTypeName(modelType, item, false)}{}\n`;
832
+ text += `${indent.get()}${dest} = ${recursiveGetDiscriminatorTypeName(modelType, item, false)}{}\n`;
783
833
  }
784
- text += `${indent}for k${nesting}, v${nesting} := range ${rawSrc} {\n`;
834
+ text += `${indent.get()}for k${nesting}, v${nesting} := range ${rawSrc} {\n`;
785
835
  rawSrc = `v${nesting}`; // source becomes the current value in the source map
786
836
  dest = `${dest}[k${nesting}]`; // update destination to the destination map's value for the current key
787
- text += recursivePopulateDiscriminator(modelType, item.valueType, receiver, rawSrc, dest, indent + '\t', nesting + 1);
788
- 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`;
789
841
  return text;
790
842
  }
791
843
  // we're at leaf node - 1, so get the interface from the element's type
792
844
  interfaceName = go.getTypeDeclaration(item.valueType, modelType.pkg);
793
845
  targetType = 'Map';
794
846
  }
795
- text += `${indent}${dest}, err = unmarshal${interfaceName}${targetType}(${rawSrc})\n`;
796
- 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`;
797
851
  return text;
798
852
  }
799
853
  /**
@@ -803,33 +857,35 @@ function recursivePopulateDiscriminator(modelType, item, receiver, rawSrc, dest,
803
857
  * @param modelDef the type for which to implement MarshalXML
804
858
  * @param imports the import manager currently in scope
805
859
  */
806
- function generateXMLMarshaller(modelDef, imports) {
860
+ function generateXMLMarshaller(modelDef, imports, indent) {
807
861
  // only needed for types with time.Time, maps, or where the XML name doesn't match the type name
808
862
  const receiver = modelDef.receiverName();
809
863
  const desc = `MarshalXML implements the xml.Marshaller interface for type ${modelDef.Model.name}.`;
810
864
  let text = `func (${receiver} ${modelDef.Model.name}) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {\n`;
811
865
  if (modelDef.Model.xml?.name) {
812
- text += `\tstart.Name.Local = "${modelDef.Model.xml.name}"\n`;
866
+ text += `${indent.get()}start.Name.Local = "${modelDef.Model.xml.name}"\n`;
813
867
  }
814
- text += generateAliasType(modelDef.Model, receiver, true, imports);
868
+ text += generateAliasType(modelDef.Model, receiver, true, imports, indent);
815
869
  for (const field of modelDef.Model.fields) {
816
870
  if (field.type.kind === 'slice') {
817
- text += `\tif ${receiver}.${field.name} != nil {\n`;
818
- text += `\t\taux.${field.name} = &${receiver}.${field.name}\n`;
819
- 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`;
820
874
  }
821
875
  else if (field.annotations.isAdditionalProperties || field.type.kind === 'map') {
822
- text += `\taux.${field.name} = (additionalProperties)(${receiver}.${field.name})\n`;
876
+ text += `${indent.get()}aux.${field.name} = (additionalProperties)(${receiver}.${field.name})\n`;
823
877
  }
824
878
  else if (field.type.kind === 'encodedBytes') {
825
879
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
826
- text += `\tif ${receiver}.${field.name} != nil {\n`;
827
- text += `\t\tencoded${field.name} := runtime.EncodeByteArray(${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format)\n`;
828
- text += `\t\taux.${field.name} = &encoded${field.name}\n`;
829
- 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`;
830
886
  }
831
887
  }
832
- text += '\treturn enc.EncodeElement(aux, start)\n';
888
+ text += `${indent.get()}return enc.EncodeElement(aux, start)\n`;
833
889
  text += '}\n\n';
834
890
  modelDef.SerDe.methods.push({ name: 'MarshalXML', desc: desc, text: text });
835
891
  }
@@ -840,33 +896,36 @@ function generateXMLMarshaller(modelDef, imports) {
840
896
  * @param modelDef the type for which to implement UnmarshalXML
841
897
  * @param imports the import manager currently in scope
842
898
  */
843
- function generateXMLUnmarshaller(modelDef, imports) {
899
+ function generateXMLUnmarshaller(modelDef, imports, indent) {
844
900
  // non-polymorphic case, must be something with time.Time
845
901
  const receiver = modelDef.receiverName();
846
902
  const desc = `UnmarshalXML implements the xml.Unmarshaller interface for type ${modelDef.Model.name}.`;
847
903
  let text = `func (${receiver} *${modelDef.Model.name}) UnmarshalXML(dec *xml.Decoder, start xml.StartElement) error {\n`;
848
- text += generateAliasType(modelDef.Model, receiver, false, imports);
849
- text += '\tif err := dec.DecodeElement(aux, &start); err != nil {\n';
850
- text += '\t\treturn err\n';
851
- 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`;
852
908
  for (const field of modelDef.Model.fields) {
853
909
  if (field.type.kind === 'time') {
854
- text += `\tif aux.${field.name} != nil && !(*time.Time)(aux.${field.name}).IsZero() {\n`;
855
- 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`;
856
913
  }
857
914
  else if (field.annotations.isAdditionalProperties || field.type.kind === 'map') {
858
- 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`;
859
916
  }
860
917
  else if (field.type.kind === 'encodedBytes') {
861
918
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime');
862
- text += `\tif aux.${field.name} != nil {\n`;
863
- text += `\t\tif err := runtime.DecodeByteArray(*aux.${field.name}, &${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format); err != nil {\n`;
864
- text += '\t\t\treturn err\n';
865
- text += '\t\t}\n';
866
- 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`;
867
926
  }
868
927
  }
869
- text += '\treturn nil\n';
928
+ text += `${indent.get()}return nil\n`;
870
929
  text += '}\n\n';
871
930
  modelDef.SerDe.methods.push({ name: 'UnmarshalXML', desc: desc, text: text });
872
931
  }
@@ -878,32 +937,32 @@ function generateXMLUnmarshaller(modelDef, imports) {
878
937
  * @param forMarshal when true, indicates type is to be used in a marshaller (else an unmarshaller)
879
938
  * @returns the text for an initialized type alias
880
939
  */
881
- function generateAliasType(modelType, receiver, forMarshal, imports) {
882
- let text = `\ttype alias ${modelType.name}\n`;
883
- text += '\taux := &struct {\n';
884
- 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`;
885
944
  for (const field of modelType.fields) {
886
945
  const sn = getXMLSerialization(field);
887
946
  if (field.type.kind === 'time') {
888
947
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime');
889
- 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`;
890
949
  }
891
950
  else if (field.annotations.isAdditionalProperties || field.type.kind === 'map') {
892
- text += `\t\t${field.name} additionalProperties \`xml:"${sn}"\`\n`;
951
+ text += `${indent.get()}${field.name} additionalProperties \`xml:"${sn}"\`\n`;
893
952
  }
894
953
  else if (field.type.kind === 'slice') {
895
- 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`;
896
955
  }
897
956
  else if (field.type.kind === 'encodedBytes') {
898
- text += `\t\t${field.name} *string \`xml:"${sn}"\`\n`;
957
+ text += `${indent.get()}${field.name} *string \`xml:"${sn}"\`\n`;
899
958
  }
900
959
  }
901
- text += '\t}{\n';
960
+ text += `${indent.pop().get()}}{\n`;
902
961
  let rec = receiver;
903
962
  if (forMarshal) {
904
963
  rec = '&' + rec;
905
964
  }
906
- text += `\t\talias: (*alias)(${rec}),\n`;
965
+ text += `${indent.push().get()}alias: (*alias)(${rec}),\n`;
907
966
  if (forMarshal) {
908
967
  // emit code to initialize time fields
909
968
  for (const field of modelType.fields) {
@@ -911,10 +970,10 @@ function generateAliasType(modelType, receiver, forMarshal, imports) {
911
970
  continue;
912
971
  }
913
972
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime');
914
- 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`;
915
974
  }
916
975
  }
917
- text += '\t}\n';
976
+ text += `${indent.pop().get()}}\n`;
918
977
  return text;
919
978
  }
920
979
  /** used to track which serde helpers and methods are required for a struct */
@@ -951,7 +1010,7 @@ class ModelDef {
951
1010
  this.Methods = new Array();
952
1011
  }
953
1012
  /** returns the text for the struct definition */
954
- text() {
1013
+ text(indent) {
955
1014
  let text = helpers.formatDocComment(this.Model.docs);
956
1015
  text += `type ${this.Model.name} struct {\n`;
957
1016
  // group fields by required/optional/read-only in that order
@@ -994,7 +1053,7 @@ class ModelDef {
994
1053
  if (this.Format === 'XML' && !field.annotations.isAdditionalProperties) {
995
1054
  tag = ` \`xml:"${serialization}"\``;
996
1055
  }
997
- text += `\t${field.name} ${helpers.star(field.byValue)}${typeName}${tag}\n`;
1056
+ text += `${indent.get()}${field.name} ${helpers.star(field.byValue)}${typeName}${tag}\n`;
998
1057
  first = false;
999
1058
  }
1000
1059
  text += '}\n\n';