@azure-tools/typespec-go 0.17.4-dev.6 → 0.17.5-dev.10

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 (64) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/src/codegen/core/example.js +20 -20
  3. package/dist/src/codegen/core/example.js.map +1 -1
  4. package/dist/src/codegen/core/helpers.d.ts +3 -9
  5. package/dist/src/codegen/core/helpers.d.ts.map +1 -1
  6. package/dist/src/codegen/core/helpers.js +33 -74
  7. package/dist/src/codegen/core/helpers.js.map +1 -1
  8. package/dist/src/codegen/core/imports.d.ts.map +1 -1
  9. package/dist/src/codegen/core/imports.js +4 -3
  10. package/dist/src/codegen/core/imports.js.map +1 -1
  11. package/dist/src/codegen/core/models.d.ts.map +1 -1
  12. package/dist/src/codegen/core/models.js +193 -143
  13. package/dist/src/codegen/core/models.js.map +1 -1
  14. package/dist/src/codegen/core/operations.js +11 -17
  15. package/dist/src/codegen/core/operations.js.map +1 -1
  16. package/dist/src/codegen/core/options.js +1 -5
  17. package/dist/src/codegen/core/options.js.map +1 -1
  18. package/dist/src/codegen/core/polymorphics.d.ts.map +1 -1
  19. package/dist/src/codegen/core/polymorphics.js +3 -5
  20. package/dist/src/codegen/core/polymorphics.js.map +1 -1
  21. package/dist/src/codegen/core/request-handler.d.ts.map +1 -1
  22. package/dist/src/codegen/core/request-handler.js +29 -22
  23. package/dist/src/codegen/core/request-handler.js.map +1 -1
  24. package/dist/src/codegen/core/response-handler.js +17 -15
  25. package/dist/src/codegen/core/response-handler.js.map +1 -1
  26. package/dist/src/codegen/core/responses.js +8 -22
  27. package/dist/src/codegen/core/responses.js.map +1 -1
  28. package/dist/src/codegen/core/unions.js +21 -16
  29. package/dist/src/codegen/core/unions.js.map +1 -1
  30. package/dist/src/codegen/fake/servers.js +105 -98
  31. package/dist/src/codegen/fake/servers.js.map +1 -1
  32. package/dist/src/codemodel/client.d.ts +8 -3
  33. package/dist/src/codemodel/client.d.ts.map +1 -1
  34. package/dist/src/codemodel/client.js +3 -3
  35. package/dist/src/codemodel/client.js.map +1 -1
  36. package/dist/src/codemodel/method.d.ts +1 -3
  37. package/dist/src/codemodel/method.d.ts.map +1 -1
  38. package/dist/src/codemodel/method.js +1 -2
  39. package/dist/src/codemodel/method.js.map +1 -1
  40. package/dist/src/codemodel/param.d.ts +41 -29
  41. package/dist/src/codemodel/param.d.ts.map +1 -1
  42. package/dist/src/codemodel/param.js +33 -33
  43. package/dist/src/codemodel/param.js.map +1 -1
  44. package/dist/src/codemodel/result.d.ts +21 -15
  45. package/dist/src/codemodel/result.d.ts.map +1 -1
  46. package/dist/src/codemodel/result.js +8 -24
  47. package/dist/src/codemodel/result.js.map +1 -1
  48. package/dist/src/codemodel/type.d.ts +83 -54
  49. package/dist/src/codemodel/type.d.ts.map +1 -1
  50. package/dist/src/codemodel/type.js +68 -30
  51. package/dist/src/codemodel/type.js.map +1 -1
  52. package/dist/src/tcgcadapter/clients.d.ts +2 -1
  53. package/dist/src/tcgcadapter/clients.d.ts.map +1 -1
  54. package/dist/src/tcgcadapter/clients.js +99 -107
  55. package/dist/src/tcgcadapter/clients.js.map +1 -1
  56. package/dist/src/tcgcadapter/helpers.d.ts +8 -27
  57. package/dist/src/tcgcadapter/helpers.d.ts.map +1 -1
  58. package/dist/src/tcgcadapter/helpers.js +32 -87
  59. package/dist/src/tcgcadapter/helpers.js.map +1 -1
  60. package/dist/src/tcgcadapter/types.d.ts +5 -3
  61. package/dist/src/tcgcadapter/types.d.ts.map +1 -1
  62. package/dist/src/tcgcadapter/types.js +113 -45
  63. package/dist/src/tcgcadapter/types.js.map +1 -1
  64. package/package.json +40 -40
@@ -3,6 +3,7 @@
3
3
  * Licensed under the MIT License. See License.txt in the project root for license information.
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as go from "../../codemodel/index.js";
6
+ import * as naming from "../../naming/index.js";
6
7
  import * as helpers from "./helpers.js";
7
8
  import { ImportManager } from "./imports.js";
8
9
  /**
@@ -333,21 +334,22 @@ function generateModelDefs(modelImports, serdeImports, pkg, options, indent) {
333
334
  const modelDefs = new Array();
334
335
  for (const model of models) {
335
336
  for (const field of model.fields) {
337
+ const fieldType = go.unwrapPtr(field.type);
336
338
  const descriptionMods = new Array();
337
339
  if (field.annotations.readOnly) {
338
340
  descriptionMods.push("READ-ONLY");
339
341
  }
340
342
  else if (field.annotations.required &&
341
- (field.type.kind !== "literal" || model.usage === go.UsageFlags.Output)) {
343
+ (fieldType.kind !== "literal" || model.usage === go.UsageFlags.Output)) {
342
344
  descriptionMods.push("REQUIRED");
343
345
  }
344
- else if (field.type.kind === "literal") {
346
+ else if (fieldType.kind === "literal" || go.isSlice(fieldType, "literal")) {
345
347
  if (!field.annotations.required) {
346
348
  descriptionMods.push("FLAG");
347
349
  }
348
350
  descriptionMods.push("CONSTANT");
349
351
  }
350
- if (field.type.kind === "literal" && model.usage !== go.UsageFlags.Output) {
352
+ if ((fieldType.kind === "literal" || go.isSlice(fieldType, "literal")) && model.usage !== go.UsageFlags.Output) {
351
353
  // add a comment with the const value for const properties that are sent over the wire
352
354
  if (field.docs.description) {
353
355
  field.docs.description += "\n";
@@ -355,9 +357,9 @@ function generateModelDefs(modelImports, serdeImports, pkg, options, indent) {
355
357
  else {
356
358
  field.docs.description = "";
357
359
  }
358
- field.docs.description += `Field has constant value ${helpers.formatLiteralValue(field.type, false)}, any specified value is ignored.`;
360
+ field.docs.description += `Field has constant value ${formatLiteralValue(fieldType, model.pkg, false)}, any specified value is ignored.`;
359
361
  }
360
- else if (field.type.kind === "rawJSON") {
362
+ else if (fieldType.kind === "rawJSON") {
361
363
  // raw JSON is emitted as []byte, so document that the field contains raw
362
364
  // JSON and that the caller is responsible for marshaling their data structure.
363
365
  if (field.docs.description) {
@@ -392,24 +394,26 @@ function generateModelDefs(modelImports, serdeImports, pkg, options, indent) {
392
394
  let needsDateTimeMarshalling = false;
393
395
  let byteArrayFormat = false;
394
396
  for (const field of model.fields) {
395
- if (field.type.kind !== "etag") {
397
+ const fieldType = go.unwrapPtr(field.type);
398
+ if (fieldType.kind !== "etag") {
396
399
  // azcore.ETag un/marshals on its own so no need to
397
400
  // import azcore as we don't explicitly reference the type
398
- serdeImports.addForType(field.type);
401
+ serdeImports.addForType(fieldType);
399
402
  }
400
- if (field.type.kind === "time") {
403
+ if (fieldType.kind === "time") {
401
404
  needsDateTimeMarshalling = true;
402
405
  }
403
- else if (field.type.kind === "encodedBytes") {
406
+ else if (fieldType.kind === "encodedBytes") {
404
407
  byteArrayFormat = true;
405
408
  }
406
409
  }
407
410
  // due to differences in XML marshallers/unmarshallers, we use different codegen than for JSON
408
411
  const needsXMLDictionaryUnmarshalling = needsXMLDictionaryHelper(model);
409
412
  if (needsDateTimeMarshalling ||
410
- model.xml?.name ||
413
+ model.xmlName ||
411
414
  needsXMLArrayMarshalling(model) ||
412
- byteArrayFormat) {
415
+ byteArrayFormat ||
416
+ needsXMLNestedModelMarshalling(model)) {
413
417
  generateXMLMarshaller(modelDef, serdeImports, indent);
414
418
  if (needsDateTimeMarshalling || needsXMLDictionaryUnmarshalling || byteArrayFormat) {
415
419
  generateXMLUnmarshaller(modelDef, serdeImports, indent);
@@ -466,6 +470,34 @@ function needsXMLArrayMarshalling(modelType) {
466
470
  }
467
471
  return false;
468
472
  }
473
+ /**
474
+ * returns true if the model contains one or more nested models
475
+ * where the field's serialized name is different from the model's
476
+ * XML name. the field's serialized name takes precedence.
477
+ *
478
+ * @param modelType the model to inspect
479
+ * @returns true if a custom marshaller is required
480
+ */
481
+ function needsXMLNestedModelMarshalling(modelType) {
482
+ for (const field of modelType.fields) {
483
+ if (fieldNeedsXMLNestedModelMarshalling(field)) {
484
+ return true;
485
+ }
486
+ }
487
+ return false;
488
+ }
489
+ /**
490
+ * narrows field to a Model or Ptr<Model> type that requires custom
491
+ * marshalling due to the field's serialized name being different from
492
+ * the model's XML name.
493
+ *
494
+ * @param field the field to inspect
495
+ * @returns a Model or Ptr<Model> that requires custom marshalling
496
+ */
497
+ function fieldNeedsXMLNestedModelMarshalling(field) {
498
+ const fieldType = go.unwrapPtr(field.type);
499
+ return fieldType.kind === "model" && !!fieldType.xmlName && field.serializedName !== fieldType.xmlName;
500
+ }
469
501
  // generates discriminator marker method
470
502
  function generateDiscriminatorMarkerMethod(type, modelDef, indent) {
471
503
  const typeName = type.rootType.name;
@@ -497,15 +529,12 @@ function generateToMultipartForm(modelDef, indent) {
497
529
  let method = `func (${receiver} ${modelDef.Model.name}) toMultipartFormData() (map[string]any, error) {\n`;
498
530
  method += `${indent.get()}objectMap := make(map[string]any)\n`;
499
531
  for (const field of modelDef.Model.fields) {
500
- const fieldType = helpers.recursiveUnwrapMapSlice(field.type);
501
- let star = "";
502
- if (!field.byValue) {
503
- star = "*";
504
- }
505
- if (!field.byValue) {
532
+ const star = helpers.deref(field.type);
533
+ if (field.type.kind === "ptr") {
506
534
  method += `${indent.get()}if ${receiver}.${field.name} != nil {\n`;
507
535
  indent.push();
508
536
  }
537
+ const fieldType = helpers.recursiveUnwrapMapSlice(field.type);
509
538
  if (fieldType.kind === "model" && !fieldType.annotations.multipartFormData) {
510
539
  method += `${indent.get()}if err := populateMultipartJSON(objectMap, "${field.serializedName}", ${star}${receiver}.${field.name}); err != nil {\n`;
511
540
  method += `${indent.push().get()}return nil, err\n`;
@@ -514,7 +543,7 @@ function generateToMultipartForm(modelDef, indent) {
514
543
  else {
515
544
  method += `${indent.get()}objectMap["${field.serializedName}"] = ${star}${receiver}.${field.name}\n`;
516
545
  }
517
- if (!field.byValue) {
546
+ if (field.type.kind === "ptr") {
518
547
  indent.pop();
519
548
  method += `${indent.get()}}\n`;
520
549
  }
@@ -571,6 +600,10 @@ function generateJSONMarshallerBody(modelDef, receiver, imports, indent) {
571
600
  addlProps = field.type;
572
601
  continue;
573
602
  }
603
+ // pointer-ness is captured in the code model, so dispatch on the unwrapped
604
+ // type and read isPtr to decide pointer-to-type emission.
605
+ const fieldType = go.unwrapPtr(field.type);
606
+ const deref = helpers.deref(field.type);
574
607
  if (field.annotations.isDiscriminator) {
575
608
  if (field.defaultValue) {
576
609
  marshaller += `${indent.get()}objectMap["${field.serializedName}"] = ${helpers.formatLiteralValue(field.defaultValue, true)}\n`;
@@ -581,31 +614,28 @@ function generateJSONMarshallerBody(modelDef, receiver, imports, indent) {
581
614
  marshaller += `${indent.get()}objectMap["${field.serializedName}"] = ${receiver}.${field.name}\n`;
582
615
  }
583
616
  }
584
- else if (field.type.kind === "encodedBytes") {
617
+ else if (fieldType.kind === "encodedBytes") {
585
618
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime");
586
619
  marshaller += `${indent.get()}populateByteArray(objectMap, "${field.serializedName}", ${receiver}.${field.name}, func() any {\n`;
587
- marshaller += `${indent.push().get()}return runtime.EncodeByteArray(${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format)\n`;
620
+ marshaller += `${indent.push().get()}return runtime.EncodeByteArray(${receiver}.${field.name}, runtime.Base64${fieldType.encoding}Format)\n`;
588
621
  marshaller += `${indent.pop().get()}})\n`;
589
622
  modelDef.SerDe.needsJSONPopulateByteArray = true;
590
623
  }
591
- else if (go.isSlice(field.type, "encodedBytes")) {
624
+ else if (go.isSlice(fieldType, "encodedBytes")) {
592
625
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime");
593
626
  marshaller += `${indent.get()}populateByteArray(objectMap, "${field.serializedName}", ${receiver}.${field.name}, func() any {\n`;
594
627
  marshaller += `${indent.push().get()}encodedValue := make([]string, len(${receiver}.${field.name}))\n`;
595
628
  marshaller += `${indent.get()}for i := 0; i < len(${receiver}.${field.name}); i++ {\n`;
596
- marshaller += `${indent.push().get()}encodedValue[i] = runtime.EncodeByteArray(${receiver}.${field.name}[i], runtime.Base64${field.type.elementType.encoding}Format)\n`;
629
+ marshaller += `${indent.push().get()}encodedValue[i] = runtime.EncodeByteArray(${receiver}.${field.name}[i], runtime.Base64${fieldType.itemType.encoding}Format)\n`;
597
630
  marshaller += `${indent.pop().get()}}\n`;
598
631
  marshaller += `${indent.get()}return encodedValue\n`;
599
632
  marshaller += `${indent.pop().get()}})\n`;
600
633
  modelDef.SerDe.needsJSONPopulateByteArray = true;
601
634
  }
602
- else if (go.isSlice(field.type, "time")) {
635
+ else if (go.isSlice(fieldType, "time")) {
603
636
  const source = `${receiver}.${field.name}`;
604
- const elementType = field.type.elementType;
605
- let elementPtr = "*";
606
- if (field.type.elementTypeByValue) {
607
- elementPtr = "";
608
- }
637
+ const elementType = go.unwrapPtr(fieldType.itemType);
638
+ const elementPtr = helpers.deref(fieldType.itemType);
609
639
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime");
610
640
  marshaller += `${indent.get()}aux := make([]${elementPtr}datetime.${elementType.format}, len(${source}), len(${source}))\n`;
611
641
  marshaller += `${indent.get()}for i := 0; i < len(${source}); i++ {\n`;
@@ -626,8 +656,8 @@ function generateJSONMarshallerBody(modelDef, receiver, imports, indent) {
626
656
  marshaller += `${indent.get()}populate(objectMap, "${field.serializedName}", aux)\n`;
627
657
  modelDef.SerDe.needsJSONPopulate = true;
628
658
  }
629
- else if (field.type.kind === "literal") {
630
- const setter = `objectMap["${field.serializedName}"] = ${helpers.formatLiteralValue(field.type, true)}`;
659
+ else if (fieldType.kind === "literal" || go.isSlice(fieldType, "literal")) {
660
+ const setter = `objectMap["${field.serializedName}"] = ${formatLiteralValue(fieldType, modelDef.Model.pkg, true)}`;
631
661
  if (!field.annotations.required) {
632
662
  marshaller += `${indent.get()}if ${receiver}.${field.name} != nil {\n`;
633
663
  marshaller += `${indent.push().get()}${setter}\n`;
@@ -637,7 +667,7 @@ function generateJSONMarshallerBody(modelDef, receiver, imports, indent) {
637
667
  marshaller += `${indent.get()}${setter}\n`;
638
668
  }
639
669
  }
640
- else if (field.type.kind === "rawJSON") {
670
+ else if (fieldType.kind === "rawJSON") {
641
671
  marshaller += `${indent.get()}populate(objectMap, "${field.serializedName}", json.RawMessage(${receiver}.${field.name}))\n`;
642
672
  modelDef.SerDe.needsJSONPopulate = true;
643
673
  }
@@ -648,24 +678,24 @@ function generateJSONMarshallerBody(modelDef, receiver, imports, indent) {
648
678
  marshaller += `${indent.push().get()}${receiver}.${field.name} = to.Ptr(${helpers.formatLiteralValue(field.defaultValue, true)})\n`;
649
679
  marshaller += `${indent.pop().get()}}\n`;
650
680
  }
651
- if (go.isScalar(field.type, "uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64") &&
652
- field.type.encodeAsString) {
681
+ if (go.isScalar(fieldType, "uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64") &&
682
+ fieldType.encodeAsString) {
653
683
  imports.add("strconv");
654
684
  marshaller += `${indent.get()}populateAsString(objectMap, "${field.serializedName}", ${receiver}.${field.name}, func() string {\n`;
655
- const isSigned = field.type.type.startsWith("int");
656
- let fieldExpr = `*${receiver}.${field.name}`;
657
- if ((field.type.type.startsWith("uint") && field.type.type !== "uint64") ||
658
- (field.type.type.startsWith("int") && field.type.type !== "int64")) {
685
+ const isSigned = fieldType.type.startsWith("int");
686
+ let fieldExpr = `${deref}${receiver}.${field.name}`;
687
+ if ((fieldType.type.startsWith("uint") && fieldType.type !== "uint64") ||
688
+ (fieldType.type.startsWith("int") && fieldType.type !== "int64")) {
659
689
  fieldExpr = `${isSigned ? "int64" : "uint64"}(${fieldExpr})`;
660
690
  }
661
691
  marshaller += `${indent.push().get()}return strconv.${isSigned ? "FormatInt" : "FormatUint"}(${fieldExpr}, 10)\n`;
662
692
  marshaller += `${indent.pop().get()}})\n`;
663
693
  modelDef.SerDe.needsJSONPopulateAsString = true;
664
694
  }
665
- else if (go.isScalar(field.type, "bool") && field.type.encodeAsString) {
695
+ else if (go.isScalar(fieldType, "bool") && fieldType.encodeAsString) {
666
696
  imports.add("strconv");
667
697
  marshaller += `${indent.get()}populateAsString(objectMap, "${field.serializedName}", ${receiver}.${field.name}, func() string {\n`;
668
- marshaller += `${indent.push().get()}return strconv.FormatBool(*${receiver}.${field.name})\n`;
698
+ marshaller += `${indent.push().get()}return strconv.FormatBool(${deref}${receiver}.${field.name})\n`;
669
699
  marshaller += `${indent.pop().get()}})\n`;
670
700
  modelDef.SerDe.needsJSONPopulateAsString = true;
671
701
  }
@@ -673,19 +703,19 @@ function generateJSONMarshallerBody(modelDef, receiver, imports, indent) {
673
703
  let populate;
674
704
  // some helpers require extra args after the common ones
675
705
  let populateArgs = "";
676
- if (field.type.kind === "time") {
706
+ if (fieldType.kind === "time") {
677
707
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime");
678
- populate = `populateTime[datetime.${field.type.format}]`;
679
- populateArgs = `, ${field.type.utc}`;
708
+ populate = `populateTime[datetime.${fieldType.format}]`;
709
+ populateArgs = `, ${fieldType.utc}`;
680
710
  modelDef.SerDe.needsJSONPopulateTime = true;
681
711
  }
682
- else if (field.type.kind === "any") {
712
+ else if (fieldType.kind === "any") {
683
713
  populate = "populateAny";
684
714
  modelDef.SerDe.needsJSONPopulateAny = true;
685
715
  }
686
- else if (field.type.kind === "sliceArray") {
716
+ else if (fieldType.kind === "sliceArray") {
687
717
  populate = "populateStringArray";
688
- populateArgs = `, "${getSliceArrayDelimiter(field.type.delimiter)}"`;
718
+ populateArgs = `, "${getSliceArrayDelimiter(fieldType.delimiter)}"`;
689
719
  modelDef.SerDe.needsJSONPopulateStringArray = true;
690
720
  }
691
721
  else {
@@ -699,20 +729,20 @@ function generateJSONMarshallerBody(modelDef, receiver, imports, indent) {
699
729
  if (addlProps) {
700
730
  marshaller += `${indent.get()}if ${receiver}.AdditionalProperties != nil {\n`;
701
731
  marshaller += `${indent.push().get()}for key, val := range ${receiver}.AdditionalProperties {\n`;
702
- if (addlProps.valueType.kind === "time" && addlProps.valueType.utc) {
732
+ if (go.isPtr(addlProps.itemType, "time") && addlProps.itemType.ptrType.utc) {
703
733
  // normalize utc datetimes before casting the (pointer) map value
704
734
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime");
705
735
  marshaller += `${indent.push().get()}if val != nil {\n`;
706
736
  marshaller += `${indent.push().get()}utcTime := val.UTC()\n`;
707
- marshaller += `${indent.get()}objectMap[key] = (*datetime.${addlProps.valueType.format})(&utcTime)\n`;
737
+ marshaller += `${indent.get()}objectMap[key] = (*datetime.${addlProps.itemType.ptrType.format})(&utcTime)\n`;
708
738
  marshaller += `${indent.pop().get()}} else {\n`;
709
739
  marshaller += `${indent.push().get()}objectMap[key] = nil\n`;
710
740
  marshaller += `${indent.pop().get()}}\n`;
711
741
  }
712
742
  else {
713
743
  let assignment = "val";
714
- if (addlProps.valueType.kind === "time") {
715
- assignment = `(*${addlProps.valueType.format})(val)`;
744
+ if (go.isPtr(addlProps.itemType, "time")) {
745
+ assignment = `(*${addlProps.itemType.ptrType.format})(val)`;
716
746
  }
717
747
  marshaller += `${indent.push().get()}objectMap[key] = ${assignment}\n`;
718
748
  }
@@ -772,18 +802,15 @@ function generateJSONUnmarshallerBody(modelDef, receiver, options, imports, inde
772
802
  const emitAddlProps = function (addlProps) {
773
803
  // indent is at the case body level when called
774
804
  let addlPropsText = `${indent.get()}if ${receiver}.AdditionalProperties == nil {\n`;
775
- let ref = "";
776
- if (!addlProps.valueTypeByValue) {
777
- ref = "&";
778
- }
805
+ const ref = addlProps.itemType.kind === "ptr" ? "&" : "";
779
806
  addlPropsText += `${indent.push().get()}${receiver}.AdditionalProperties = ${go.getTypeDeclaration(addlProps, modelDef.Model.pkg)}{}\n`;
780
807
  addlPropsText += `${indent.pop().get()}}\n`;
781
808
  addlPropsText += `${indent.get()}if val != nil {\n`;
782
- let auxType = go.getTypeDeclaration(addlProps.valueType, modelDef.Model.pkg);
809
+ let auxType = go.getTypeDeclaration(go.unwrapPtr(addlProps.itemType), modelDef.Model.pkg);
783
810
  let assignment = `${ref}aux`;
784
- if (addlProps.valueType.kind === "time") {
811
+ if (go.isPtr(addlProps.itemType, "time")) {
785
812
  imports.add("time");
786
- auxType = addlProps.valueType.format;
813
+ auxType = addlProps.itemType.ptrType.format;
787
814
  assignment = `(*time.Time)(${assignment})`;
788
815
  }
789
816
  addlPropsText += `${indent.push().get()}var aux ${auxType}\n`;
@@ -804,30 +831,30 @@ function generateJSONUnmarshallerBody(modelDef, receiver, options, imports, inde
804
831
  addlProps = field.type;
805
832
  continue;
806
833
  }
834
+ // dispatch on the unwrapped type; pointer-ness is captured in the code model.
835
+ const fieldType = go.unwrapPtr(field.type);
807
836
  unmarshalBody += `${indent.get()}case "${field.serializedName}":\n`;
808
837
  indent.push(); // case body level
809
- if (hasDiscriminatorInterface(field.type)) {
838
+ if (hasDiscriminatorInterface(fieldType)) {
810
839
  unmarshalBody += generateDiscriminatorUnmarshaller(modelDef.Model, field, receiver, indent);
811
840
  needsErrCheck = true;
812
841
  }
813
- else if (field.type.kind === "sliceArray") {
814
- unmarshalBody += `${indent.get()}err = unpopulateStringArray(val, "${field.name}", &${receiver}.${field.name}, "${getSliceArrayDelimiter(field.type.delimiter)}")\n`;
842
+ else if (fieldType.kind === "sliceArray") {
843
+ unmarshalBody += `${indent.get()}err = unpopulateStringArray(val, "${field.name}", &${receiver}.${field.name}, "${getSliceArrayDelimiter(fieldType.delimiter)}")\n`;
815
844
  modelDef.SerDe.needsJSONUnpopulateStringArray = true;
816
845
  needsErrCheck = true;
817
846
  }
818
- else if (field.type.kind === "time") {
819
- unmarshalBody += `${indent.get()}err = unpopulateTime[datetime.${field.type.format}](val, "${field.name}", &${receiver}.${field.name})\n`;
847
+ else if (fieldType.kind === "time") {
848
+ unmarshalBody += `${indent.get()}err = unpopulateTime[datetime.${fieldType.format}](val, "${field.name}", &${receiver}.${field.name})\n`;
820
849
  modelDef.SerDe.needsJSONUnpopulateTime = true;
821
850
  needsErrCheck = true;
822
851
  }
823
- else if (go.isSlice(field.type, "time")) {
852
+ else if (go.isSlice(fieldType, "time")) {
824
853
  imports.add("time");
825
854
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime");
826
- let elementPtr = "*";
827
- if (field.type.elementTypeByValue) {
828
- elementPtr = "";
829
- }
830
- unmarshalBody += `${indent.get()}var aux []${elementPtr}datetime.${field.type.elementType.format}\n`;
855
+ const elementType = go.unwrapPtr(fieldType.itemType);
856
+ const elementPtr = helpers.deref(fieldType.itemType);
857
+ unmarshalBody += `${indent.get()}var aux []${elementPtr}datetime.${elementType.format}\n`;
831
858
  unmarshalBody += `${indent.get()}err = unpopulate(val, "${field.name}", &aux)\n`;
832
859
  unmarshalBody += `${indent.get()}for _, au := range aux {\n`;
833
860
  unmarshalBody += `${indent.push().get()}${receiver}.${field.name} = append(${receiver}.${field.name}, (${elementPtr}time.Time)(au))\n`;
@@ -835,14 +862,14 @@ function generateJSONUnmarshallerBody(modelDef, receiver, options, imports, inde
835
862
  modelDef.SerDe.needsJSONUnpopulate = true;
836
863
  needsErrCheck = true;
837
864
  }
838
- else if (field.type.kind === "encodedBytes") {
865
+ else if (fieldType.kind === "encodedBytes") {
839
866
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime");
840
867
  unmarshalBody += `${indent.get()}if val != nil && string(val) != "null" {\n`;
841
- unmarshalBody += `${indent.push().get()}err = runtime.DecodeByteArray(string(val), &${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format)\n`;
868
+ unmarshalBody += `${indent.push().get()}err = runtime.DecodeByteArray(string(val), &${receiver}.${field.name}, runtime.Base64${fieldType.encoding}Format)\n`;
842
869
  unmarshalBody += `${indent.pop().get()}}\n`;
843
870
  needsErrCheck = true;
844
871
  }
845
- else if (go.isSlice(field.type, "encodedBytes")) {
872
+ else if (go.isSlice(fieldType, "encodedBytes")) {
846
873
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime");
847
874
  unmarshalBody += `${indent.get()}var encodedValue []string\n`;
848
875
  unmarshalBody += `${indent.get()}err = unpopulate(val, "${field.name}", &encodedValue)\n`;
@@ -850,19 +877,19 @@ function generateJSONUnmarshallerBody(modelDef, receiver, options, imports, inde
850
877
  indent.push();
851
878
  unmarshalBody += `${indent.get()}${receiver}.${field.name} = make([][]byte, len(encodedValue))\n`;
852
879
  unmarshalBody += `${indent.get()}for i := 0; i < len(encodedValue) && err == nil; i++ {\n`;
853
- unmarshalBody += `${indent.push().get()}err = runtime.DecodeByteArray(encodedValue[i], &${receiver}.${field.name}[i], runtime.Base64${field.type.elementType.encoding}Format)\n`;
880
+ unmarshalBody += `${indent.push().get()}err = runtime.DecodeByteArray(encodedValue[i], &${receiver}.${field.name}[i], runtime.Base64${fieldType.itemType.encoding}Format)\n`;
854
881
  unmarshalBody += `${indent.pop().get()}}\n`;
855
882
  indent.pop();
856
883
  unmarshalBody += `${indent.get()}}\n`;
857
884
  modelDef.SerDe.needsJSONUnpopulate = true;
858
885
  needsErrCheck = true;
859
886
  }
860
- else if (field.type.kind === "rawJSON") {
887
+ else if (fieldType.kind === "rawJSON") {
861
888
  unmarshalBody += `${indent.get()}if string(val) != "null" {\n`;
862
889
  unmarshalBody += `${indent.push().get()}${receiver}.${field.name} = val\n`;
863
890
  unmarshalBody += `${indent.pop().get()}}\n`;
864
891
  }
865
- else if (go.isScalar(field.type, "bool") && field.type.encodeAsString) {
892
+ else if (go.isScalar(fieldType, "bool") && fieldType.encodeAsString) {
866
893
  imports.add("strconv");
867
894
  imports.add("strings");
868
895
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/to");
@@ -877,13 +904,13 @@ function generateJSONUnmarshallerBody(modelDef, receiver, options, imports, inde
877
904
  modelDef.SerDe.needsJSONUnpopulateFromString = true;
878
905
  needsErrCheck = true;
879
906
  }
880
- else if (go.isScalar(field.type, "uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64") &&
881
- field.type.encodeAsString) {
882
- const scalarType = field.type.type;
907
+ else if (go.isScalar(fieldType, "uint8", "uint16", "uint32", "uint64", "int8", "int16", "int32", "int64") &&
908
+ fieldType.encodeAsString) {
909
+ const scalarType = fieldType.type;
883
910
  imports.add("strconv");
884
911
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/to");
885
912
  unmarshalBody += `${indent.get()}err = unpopulateFromString(val, "${field.name}", func(encodedValue string) error {\n`;
886
- unmarshalBody += `${indent.push().get()}v, parseErr := strconv.${field.type.type.startsWith("int") ? "ParseInt" : "ParseUint"}(encodedValue, 10, 0)\n`;
913
+ unmarshalBody += `${indent.push().get()}v, parseErr := strconv.${fieldType.type.startsWith("int") ? "ParseInt" : "ParseUint"}(encodedValue, 10, 0)\n`;
887
914
  unmarshalBody += `${indent.get()}${helpers.buildIfBlock(indent, {
888
915
  condition: "parseErr == nil",
889
916
  body: (indent) => {
@@ -902,7 +929,7 @@ function generateJSONUnmarshallerBody(modelDef, receiver, options, imports, inde
902
929
  }
903
930
  else {
904
931
  const unpopulateField = `err = unpopulate(val, "${field.name}", &${receiver}.${field.name})\n`;
905
- if (field.type.kind === "string" && field.annotations.unmarshalEmptyStringAsNil) {
932
+ if (fieldType.kind === "string" && field.annotations.unmarshalEmptyStringAsNil) {
906
933
  unmarshalBody += `${indent.get()}${helpers.buildIfBlock(indent, {
907
934
  condition: `string(val) != \`""\``,
908
935
  body: (indent) => `${indent.get()}${unpopulateField}`,
@@ -975,9 +1002,8 @@ function hasDiscriminatorInterface(item) {
975
1002
  case "interface":
976
1003
  return true;
977
1004
  case "map":
978
- return hasDiscriminatorInterface(item.valueType);
979
1005
  case "slice":
980
- return hasDiscriminatorInterface(item.elementType);
1006
+ return hasDiscriminatorInterface(item.itemType);
981
1007
  default:
982
1008
  return false;
983
1009
  }
@@ -990,10 +1016,10 @@ function generateDiscriminatorUnmarshaller(modelType, field, receiver, indent) {
990
1016
  return `${indent.get()}${receiver}.${propertyName}, err = unmarshal${field.type.name}(val)\n`;
991
1017
  }
992
1018
  else if (go.isSlice(field.type, "interface")) {
993
- return `${indent.get()}${receiver}.${propertyName}, err = unmarshal${field.type.elementType.name}Array(val)\n`;
1019
+ return `${indent.get()}${receiver}.${propertyName}, err = unmarshal${field.type.itemType.name}Array(val)\n`;
994
1020
  }
995
1021
  else if (go.isMap(field.type, "interface")) {
996
- return `${indent.get()}${receiver}.${propertyName}, err = unmarshal${field.type.valueType.name}Map(val)\n`;
1022
+ return `${indent.get()}${receiver}.${propertyName}, err = unmarshal${field.type.itemType.name}Map(val)\n`;
997
1023
  }
998
1024
  // nested case (e.g. [][]InterfaceType, map[string]map[string]InterfaceType etc)
999
1025
  // first, unmarshal the raw data
@@ -1025,13 +1051,13 @@ function generateDiscriminatorUnmarshaller(modelType, field, receiver, indent) {
1025
1051
  function recursiveGetDiscriminatorTypeName(modelType, item, raw) {
1026
1052
  // when raw is true, stop recursing at the level before the leaf schema
1027
1053
  if (item.kind === "slice") {
1028
- if (!raw || item.elementType.kind !== "interface") {
1029
- return `[]${recursiveGetDiscriminatorTypeName(modelType, item.elementType, raw)}`;
1054
+ if (!raw || item.itemType.kind !== "interface") {
1055
+ return `[]${recursiveGetDiscriminatorTypeName(modelType, item.itemType, raw)}`;
1030
1056
  }
1031
1057
  }
1032
1058
  else if (item.kind === "map") {
1033
- if (!raw || item.valueType.kind !== "interface") {
1034
- return `map[string]${recursiveGetDiscriminatorTypeName(modelType, item.valueType, raw)}`;
1059
+ if (!raw || item.itemType.kind !== "interface") {
1060
+ return `map[string]${recursiveGetDiscriminatorTypeName(modelType, item.itemType, raw)}`;
1035
1061
  }
1036
1062
  }
1037
1063
  if (raw) {
@@ -1056,7 +1082,7 @@ function recursivePopulateDiscriminator(modelType, item, receiver, rawSrc, dest,
1056
1082
  let interfaceName = "";
1057
1083
  let targetType = "";
1058
1084
  if (item.kind === "slice") {
1059
- if (item.elementType.kind !== "interface") {
1085
+ if (item.itemType.kind !== "interface") {
1060
1086
  if (nesting > 1) {
1061
1087
  // at nestling level 1, the destination var was already created in generateDiscriminatorUnmarshaller()
1062
1088
  text += `${indent.get()}${dest} = make(${recursiveGetDiscriminatorTypeName(modelType, item, false)}, len(${rawSrc}))\n`;
@@ -1065,17 +1091,17 @@ function recursivePopulateDiscriminator(modelType, item, receiver, rawSrc, dest,
1065
1091
  rawSrc = `${rawSrc}[i${nesting}]`; // source becomes each element in the source slice
1066
1092
  dest = `${dest}[i${nesting}]`; // update destination to each element in the destination slice
1067
1093
  indent.push();
1068
- text += recursivePopulateDiscriminator(modelType, item.elementType, receiver, rawSrc, dest, indent, nesting + 1);
1094
+ text += recursivePopulateDiscriminator(modelType, item.itemType, receiver, rawSrc, dest, indent, nesting + 1);
1069
1095
  indent.pop();
1070
1096
  text += `${indent.get()}}\n`;
1071
1097
  return text;
1072
1098
  }
1073
1099
  // we're at leaf node - 1, so get the interface from the element's type
1074
- interfaceName = go.getTypeDeclaration(item.elementType, modelType.pkg);
1100
+ interfaceName = go.getTypeDeclaration(item.itemType, modelType.pkg);
1075
1101
  targetType = "Array";
1076
1102
  }
1077
1103
  else if (item.kind === "map") {
1078
- if (item.valueType.kind !== "interface") {
1104
+ if (item.itemType.kind !== "interface") {
1079
1105
  if (nesting > 1) {
1080
1106
  // at nestling level 1, the destination var was already created in generateDiscriminatorUnmarshaller()
1081
1107
  text += `${indent.get()}${dest} = ${recursiveGetDiscriminatorTypeName(modelType, item, false)}{}\n`;
@@ -1084,13 +1110,13 @@ function recursivePopulateDiscriminator(modelType, item, receiver, rawSrc, dest,
1084
1110
  rawSrc = `v${nesting}`; // source becomes the current value in the source map
1085
1111
  dest = `${dest}[k${nesting}]`; // update destination to the destination map's value for the current key
1086
1112
  indent.push();
1087
- text += recursivePopulateDiscriminator(modelType, item.valueType, receiver, rawSrc, dest, indent, nesting + 1);
1113
+ text += recursivePopulateDiscriminator(modelType, item.itemType, receiver, rawSrc, dest, indent, nesting + 1);
1088
1114
  indent.pop();
1089
1115
  text += `${indent.get()}}\n`;
1090
1116
  return text;
1091
1117
  }
1092
1118
  // we're at leaf node - 1, so get the interface from the element's type
1093
- interfaceName = go.getTypeDeclaration(item.valueType, modelType.pkg);
1119
+ interfaceName = go.getTypeDeclaration(item.itemType, modelType.pkg);
1094
1120
  targetType = "Map";
1095
1121
  }
1096
1122
  text += `${indent.get()}${dest}, err = unmarshal${interfaceName}${targetType}(${rawSrc})\n`;
@@ -1099,6 +1125,11 @@ function recursivePopulateDiscriminator(modelType, item, receiver, rawSrc, dest,
1099
1125
  text += `${indent.pop().get()}}\n`;
1100
1126
  return text;
1101
1127
  }
1128
+ /** returns the alias type name to use when aliasing a model type */
1129
+ function getXMLNestedModelAliasTypeName(type) {
1130
+ const fieldType = go.unwrapPtr(type);
1131
+ return naming.uncapitalize(fieldType.name);
1132
+ }
1102
1133
  /**
1103
1134
  * generates an implementation of MarshalXML for the provided type.
1104
1135
  * the method impl is added to modelDef.SerDe.methods.
@@ -1111,28 +1142,43 @@ function generateXMLMarshaller(modelDef, imports, indent) {
1111
1142
  const receiver = modelDef.receiverName();
1112
1143
  const desc = `MarshalXML implements the xml.Marshaller interface for type ${modelDef.Model.name}.`;
1113
1144
  let text = `func (${receiver} ${modelDef.Model.name}) MarshalXML(enc *xml.Encoder, start xml.StartElement) error {\n`;
1114
- if (modelDef.Model.xml?.name) {
1115
- text += `${indent.get()}start.Name.Local = "${modelDef.Model.xml.name}"\n`;
1145
+ if (modelDef.Model.xmlName) {
1146
+ text += `${indent.get()}start.Name.Local = "${modelDef.Model.xmlName}"\n`;
1147
+ }
1148
+ // declare the type aliases for custom marshalling first
1149
+ // as the containing type's alias type depends on them
1150
+ for (const field of modelDef.Model.fields) {
1151
+ if (fieldNeedsXMLNestedModelMarshalling(field)) {
1152
+ const fieldType = go.unwrapPtr(field.type);
1153
+ text += `${indent.get()}type ${getXMLNestedModelAliasTypeName(field.type)} ${fieldType.name}\n`;
1154
+ }
1116
1155
  }
1117
1156
  text += generateAliasType(modelDef.Model, receiver, true, imports, indent);
1118
1157
  for (const field of modelDef.Model.fields) {
1119
- if (field.type.kind === "slice") {
1158
+ const fieldType = go.unwrapPtr(field.type);
1159
+ if (fieldType.kind === "slice") {
1120
1160
  text += `${indent.get()}if ${receiver}.${field.name} != nil {\n`;
1121
1161
  text += `${indent.push().get()}aux.${field.name} = &${receiver}.${field.name}\n`;
1122
1162
  text += `${indent.pop().get()}}\n`;
1123
1163
  }
1124
- else if (go.isAdditionalProperties(field) || field.type.kind === "map") {
1164
+ else if (go.isAdditionalProperties(field) || fieldType.kind === "map") {
1125
1165
  text += `${indent.get()}aux.${field.name} = (additionalProperties)(${receiver}.${field.name})\n`;
1126
1166
  }
1127
- else if (field.type.kind === "encodedBytes") {
1167
+ else if (fieldType.kind === "encodedBytes") {
1128
1168
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime");
1129
1169
  text += `${indent.get()}if ${receiver}.${field.name} != nil {\n`;
1130
1170
  indent.push();
1131
- text += `${indent.get()}encoded${field.name} := runtime.EncodeByteArray(${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format)\n`;
1171
+ text += `${indent.get()}encoded${field.name} := runtime.EncodeByteArray(${receiver}.${field.name}, runtime.Base64${fieldType.encoding}Format)\n`;
1132
1172
  text += `${indent.get()}aux.${field.name} = &encoded${field.name}\n`;
1133
1173
  indent.pop();
1134
1174
  text += `${indent.get()}}\n`;
1135
1175
  }
1176
+ else if (fieldNeedsXMLNestedModelMarshalling(field)) {
1177
+ text += `${indent.get()}${helpers.buildIfBlock(indent, {
1178
+ condition: `${receiver}.${field.name} != nil`,
1179
+ body: (indent) => `${indent.get()}aux.${field.name} = (*${getXMLNestedModelAliasTypeName(field.type)})(${receiver}.${field.name})\n`,
1180
+ })}\n`;
1181
+ }
1136
1182
  }
1137
1183
  text += `${indent.get()}return enc.EncodeElement(aux, start)\n`;
1138
1184
  text += "}\n\n";
@@ -1155,19 +1201,20 @@ function generateXMLUnmarshaller(modelDef, imports, indent) {
1155
1201
  text += `${indent.push().get()}return err\n`;
1156
1202
  text += `${indent.pop().get()}}\n`;
1157
1203
  for (const field of modelDef.Model.fields) {
1158
- if (field.type.kind === "time") {
1204
+ const fieldType = go.unwrapPtr(field.type);
1205
+ if (fieldType.kind === "time") {
1159
1206
  text += `${indent.get()}if aux.${field.name} != nil && !(*time.Time)(aux.${field.name}).IsZero() {\n`;
1160
1207
  text += `${indent.push().get()}${receiver}.${field.name} = (*time.Time)(aux.${field.name})\n`;
1161
1208
  text += `${indent.pop().get()}}\n`;
1162
1209
  }
1163
- else if (go.isAdditionalProperties(field) || field.type.kind === "map") {
1210
+ else if (go.isAdditionalProperties(field) || fieldType.kind === "map") {
1164
1211
  text += `${indent.get()}${receiver}.${field.name} = (map[string]*string)(aux.${field.name})\n`;
1165
1212
  }
1166
- else if (field.type.kind === "encodedBytes") {
1213
+ else if (fieldType.kind === "encodedBytes") {
1167
1214
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime");
1168
1215
  text += `${indent.get()}if aux.${field.name} != nil {\n`;
1169
1216
  indent.push();
1170
- text += `${indent.get()}if err := runtime.DecodeByteArray(*aux.${field.name}, &${receiver}.${field.name}, runtime.Base64${field.type.encoding}Format); err != nil {\n`;
1217
+ text += `${indent.get()}if err := runtime.DecodeByteArray(*aux.${field.name}, &${receiver}.${field.name}, runtime.Base64${fieldType.encoding}Format); err != nil {\n`;
1171
1218
  text += `${indent.push().get()}return err\n`;
1172
1219
  text += `${indent.pop().get()}}\n`;
1173
1220
  indent.pop();
@@ -1191,20 +1238,24 @@ function generateAliasType(modelType, receiver, forMarshal, imports, indent) {
1191
1238
  text += `${indent.get()}aux := &struct {\n`;
1192
1239
  text += `${indent.push().get()}*alias\n`;
1193
1240
  for (const field of modelType.fields) {
1194
- const sn = getXMLSerialization(field);
1195
- if (field.type.kind === "time") {
1241
+ const fieldType = go.unwrapPtr(field.type);
1242
+ const sn = getXMLSerialization(field, modelType.pkg);
1243
+ if (fieldType.kind === "time") {
1196
1244
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime");
1197
- text += `${indent.get()}${field.name} *datetime.${field.type.format} \`xml:"${sn}"\`\n`;
1245
+ text += `${indent.get()}${field.name} *datetime.${fieldType.format} \`xml:"${sn}"\`\n`;
1198
1246
  }
1199
- else if (go.isAdditionalProperties(field) || field.type.kind === "map") {
1247
+ else if (go.isAdditionalProperties(field) || fieldType.kind === "map") {
1200
1248
  text += `${indent.get()}${field.name} additionalProperties \`xml:"${sn}"\`\n`;
1201
1249
  }
1202
- else if (field.type.kind === "slice") {
1203
- text += `${indent.get()}${field.name} *${go.getTypeDeclaration(field.type, modelType.pkg)} \`xml:"${sn}"\`\n`;
1250
+ else if (fieldType.kind === "slice") {
1251
+ text += `${indent.get()}${field.name} *${go.getTypeDeclaration(fieldType, modelType.pkg)} \`xml:"${sn}"\`\n`;
1204
1252
  }
1205
- else if (field.type.kind === "encodedBytes") {
1253
+ else if (fieldType.kind === "encodedBytes") {
1206
1254
  text += `${indent.get()}${field.name} *string \`xml:"${sn}"\`\n`;
1207
1255
  }
1256
+ else if (fieldNeedsXMLNestedModelMarshalling(field)) {
1257
+ text += `${indent.get()}${field.name} *${getXMLNestedModelAliasTypeName(field.type)} \`xml:"${field.serializedName}"\`\n`;
1258
+ }
1208
1259
  }
1209
1260
  text += `${indent.pop().get()}}{\n`;
1210
1261
  let rec = receiver;
@@ -1215,11 +1266,12 @@ function generateAliasType(modelType, receiver, forMarshal, imports, indent) {
1215
1266
  if (forMarshal) {
1216
1267
  // emit code to initialize time fields
1217
1268
  for (const field of modelType.fields) {
1218
- if (field.type.kind !== "time") {
1269
+ const fieldType = go.unwrapPtr(field.type);
1270
+ if (fieldType.kind !== "time") {
1219
1271
  continue;
1220
1272
  }
1221
1273
  imports.add("github.com/Azure/azure-sdk-for-go/sdk/azcore/runtime/datetime");
1222
- text += `${indent.get()}${field.name}: (*datetime.${field.type.format})(${receiver}.${field.name}),\n`;
1274
+ text += `${indent.get()}${field.name}: (*datetime.${fieldType.format})(${receiver}.${field.name}),\n`;
1223
1275
  }
1224
1276
  }
1225
1277
  text += `${indent.pop().get()}}\n`;
@@ -1296,23 +1348,24 @@ class ModelDef {
1296
1348
  text += helpers.formatDocComment(field.docs);
1297
1349
  }
1298
1350
  let typeName = go.getTypeDeclaration(field.type, this.Model.pkg);
1299
- if (field.type.kind === "literal") {
1300
- // for constants we use the underlying type name
1301
- typeName = go.getLiteralTypeDeclaration(field.type.type);
1351
+ const fieldType = go.unwrapPtr(field.type);
1352
+ if (fieldType.kind === "literal") {
1353
+ // for constants we use the underlying type name; getTypeDeclaration above emits the pointer.
1354
+ typeName = `${helpers.deref(field.type)}${go.getLiteralTypeDeclaration(fieldType.type)}`;
1302
1355
  }
1303
1356
  let serialization = field.serializedName;
1304
1357
  if (this.Format === "JSON") {
1305
1358
  serialization += ",omitempty";
1306
1359
  }
1307
1360
  else if (this.Format === "XML") {
1308
- serialization = getXMLSerialization(field);
1361
+ serialization = getXMLSerialization(field, this.Model.pkg);
1309
1362
  }
1310
1363
  let tag = "";
1311
1364
  // only emit tags for XML; JSON uses custom marshallers/unmarshallers
1312
1365
  if (this.Format === "XML" && !go.isAdditionalProperties(field)) {
1313
1366
  tag = ` \`xml:"${serialization}"\``;
1314
1367
  }
1315
- text += `${indent.get()}${field.name} ${helpers.star(field.byValue)}${typeName}${tag}\n`;
1368
+ text += `${indent.get()}${field.name} ${typeName}${tag}\n`;
1316
1369
  first = false;
1317
1370
  }
1318
1371
  text += "}\n\n";
@@ -1330,28 +1383,17 @@ class ModelDef {
1330
1383
  * @param field the field for which to construct the tag's contents
1331
1384
  * @returns the contents for the XML tag
1332
1385
  */
1333
- function getXMLSerialization(field) {
1386
+ function getXMLSerialization(field, pkg) {
1334
1387
  let serialization = field.serializedName;
1335
- // default to using the serialization name
1336
- if (field.xml?.name) {
1337
- // xml can specify its own name, prefer that if available
1338
- serialization = field.xml.name;
1339
- }
1340
- else if (field.xml?.text) {
1341
- // type has the x-ms-text attribute applied so it should be character data, not a node (https://github.com/Azure/autorest/tree/main/docs/extensions#x-ms-text)
1342
- // see https://pkg.go.dev/encoding/xml#Unmarshal for what ,chardata actually means
1343
- serialization = ",chardata";
1388
+ switch (field.xmlKind) {
1389
+ case "attribute":
1390
+ serialization += ",attr";
1391
+ return serialization;
1392
+ case "text":
1393
+ serialization = ",chardata";
1394
+ return serialization;
1344
1395
  }
1345
- if (field.xml?.attribute) {
1346
- // value comes from an xml attribute
1347
- serialization += ",attr";
1348
- }
1349
- else if (field.type.kind === "slice") {
1350
- // start with the serialized name of the element, preferring xml name if available
1351
- let inner = field.serializedName;
1352
- if (field.xml?.name) {
1353
- inner = field.xml.name;
1354
- }
1396
+ if (field.type.kind === "slice") {
1355
1397
  // arrays can be wrapped or unwrapped. here's a wrapped example
1356
1398
  // note how the array of apple objects is "wrapped" in GoodApples
1357
1399
  // <AppleBarrel>
@@ -1370,15 +1412,23 @@ function getXMLSerialization(field) {
1370
1412
  // <title>Overview</title>
1371
1413
  // </slide>
1372
1414
  // </slideshow>
1373
- // arrays in the response type are handled slightly different as we
1374
- // unmarshal directly into them so no need to add the unwrapping.
1375
- if (field.xml?.wraps) {
1376
- serialization += `>${field.xml.wraps}`;
1377
- }
1378
- else {
1379
- serialization = inner;
1415
+ // for unwrapped lists we use the serialized name on the field
1416
+ if (field.xmlKind !== "unwrappedList") {
1417
+ // start with the serialized name of the element, preferring xml name if available
1418
+ const unwrappedPtrType = go.unwrapPtr(field.type.itemType);
1419
+ const inner = field.type.xmlName ? field.type.xmlName : go.hasXMLName(unwrappedPtrType) ?? go.getTypeDeclaration(unwrappedPtrType, pkg);
1420
+ serialization += `>${inner}`;
1380
1421
  }
1381
1422
  }
1382
1423
  return serialization;
1383
1424
  }
1425
+ /** expanded version of helpers.formatLiteralValue than handles slices */
1426
+ function formatLiteralValue(type, pkg, withCast) {
1427
+ switch (type.kind) {
1428
+ case "literal":
1429
+ return helpers.formatLiteralValue(type, withCast);
1430
+ case "slice":
1431
+ return `[]${go.getTypeDeclaration(type.itemType.type, pkg)}{${helpers.formatLiteralValue(type.itemType, withCast)}}`;
1432
+ }
1433
+ }
1384
1434
  //# sourceMappingURL=models.js.map