@azure-tools/typespec-go 0.4.12 → 0.5.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 (43) hide show
  1. package/dist/codegen.go/src/clientFactory.js.map +1 -1
  2. package/dist/codegen.go/src/example.d.ts.map +1 -1
  3. package/dist/codegen.go/src/example.js +25 -20
  4. package/dist/codegen.go/src/example.js.map +1 -1
  5. package/dist/codegen.go/src/fake/servers.d.ts.map +1 -1
  6. package/dist/codegen.go/src/fake/servers.js +290 -272
  7. package/dist/codegen.go/src/fake/servers.js.map +1 -1
  8. package/dist/codegen.go/src/helpers.d.ts +42 -15
  9. package/dist/codegen.go/src/helpers.d.ts.map +1 -1
  10. package/dist/codegen.go/src/helpers.js +170 -98
  11. package/dist/codegen.go/src/helpers.js.map +1 -1
  12. package/dist/codegen.go/src/operations.d.ts +1 -1
  13. package/dist/codegen.go/src/operations.d.ts.map +1 -1
  14. package/dist/codegen.go/src/operations.js +266 -275
  15. package/dist/codegen.go/src/operations.js.map +1 -1
  16. package/dist/codegen.go/src/polymorphics.d.ts.map +1 -1
  17. package/dist/codegen.go/src/polymorphics.js +12 -13
  18. package/dist/codegen.go/src/polymorphics.js.map +1 -1
  19. package/dist/codegen.go/src/responses.js +17 -9
  20. package/dist/codegen.go/src/responses.js.map +1 -1
  21. package/dist/codegen.go/src/time.js +4 -4
  22. package/dist/codegen.go/src/time.js.map +1 -1
  23. package/dist/codemodel.go/src/client.d.ts +104 -32
  24. package/dist/codemodel.go/src/client.d.ts.map +1 -1
  25. package/dist/codemodel.go/src/client.js +19 -17
  26. package/dist/codemodel.go/src/client.js.map +1 -1
  27. package/dist/codemodel.go/src/examples.d.ts +5 -4
  28. package/dist/codemodel.go/src/examples.d.ts.map +1 -1
  29. package/dist/codemodel.go/src/examples.js.map +1 -1
  30. package/dist/codemodel.go/src/package.js.map +1 -1
  31. package/dist/codemodel.go/src/param.d.ts +196 -83
  32. package/dist/codemodel.go/src/param.d.ts.map +1 -1
  33. package/dist/codemodel.go/src/param.js +81 -89
  34. package/dist/codemodel.go/src/param.js.map +1 -1
  35. package/dist/codemodel.go/src/result.d.ts +93 -28
  36. package/dist/codemodel.go/src/result.d.ts.map +1 -1
  37. package/dist/codemodel.go/src/result.js +26 -53
  38. package/dist/codemodel.go/src/result.js.map +1 -1
  39. package/dist/typespec-go/src/tcgcadapter/clients.d.ts +4 -4
  40. package/dist/typespec-go/src/tcgcadapter/clients.d.ts.map +1 -1
  41. package/dist/typespec-go/src/tcgcadapter/clients.js +81 -75
  42. package/dist/typespec-go/src/tcgcadapter/clients.js.map +1 -1
  43. package/package.json +3 -3
@@ -73,7 +73,7 @@ export async function generateOperations(codeModel) {
73
73
  const optionalParams = new Array();
74
74
  const isParamPointer = function (param) {
75
75
  // for client params, only optional and flag types are passed by pointer
76
- return param.kind === 'flag' || param.kind === 'optional';
76
+ return param.style === 'flag' || param.style === 'optional';
77
77
  };
78
78
  // now emit any client params (non parameterized host params case)
79
79
  if (client.parameters.length > 0) {
@@ -131,11 +131,11 @@ export async function generateOperations(codeModel) {
131
131
  }
132
132
  opText += generateOperation(client, method, imports, codeModel.options.injectSpans, codeModel.options.generateFakes);
133
133
  opText += createProtocolRequest(azureARM, client, method, imports);
134
- if (!go.isLROMethod(method) || go.isPageableMethod(method)) {
134
+ if (method.kind !== 'lroMethod') {
135
135
  // LRO responses are handled elsewhere, with the exception of pageable LROs
136
136
  opText += createProtocolResponse(client, method, imports);
137
137
  }
138
- if (go.isPageableMethod(method) && method.nextPageMethod && !nextPageMethods.includes(method.nextPageMethod)) {
138
+ if ((method.kind === 'lroPageableMethod' || method.kind === 'pageableMethod') && method.nextPageMethod && !nextPageMethods.includes(method.nextPageMethod)) {
139
139
  // track the next page methods to generate as multiple operations can use the same next page operation
140
140
  nextPageMethods.push(method.nextPageMethod);
141
141
  }
@@ -214,10 +214,10 @@ function createARMClientConstructor(client, imports) {
214
214
  // use this to generate the code that will help process values returned in response headers
215
215
  function formatHeaderResponseValue(headerResp, imports, respObj, zeroResp) {
216
216
  // dictionaries are handled slightly different so we do that first
217
- if (go.isHeaderMapResponse(headerResp)) {
217
+ if (headerResp.kind === 'headerMapResponse') {
218
218
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/to');
219
219
  imports.add('strings');
220
- const headerPrefix = headerResp.collectionPrefix;
220
+ const headerPrefix = headerResp.headerName;
221
221
  let text = '\tfor hh := range resp.Header {\n';
222
222
  text += `\t\tif len(hh) > len("${headerPrefix}") && strings.EqualFold(hh[:len("${headerPrefix}")], "${headerPrefix}") {\n`;
223
223
  text += `\t\t\tif ${respObj}.${headerResp.fieldName} == nil {\n`;
@@ -345,7 +345,7 @@ function emitPagerDefinition(client, method, imports, injectSpans, generateFakes
345
345
  }
346
346
  if (method.nextLinkName) {
347
347
  let nextLinkVar;
348
- if (!go.isLROMethod(method)) {
348
+ if (method.kind === 'pageableMethod') {
349
349
  text += '\t\t\tnextLink := ""\n';
350
350
  nextLinkVar = 'nextLink';
351
351
  text += '\t\t\tif page != nil {\n';
@@ -410,7 +410,7 @@ function genApiVersionDoc(apiVersions) {
410
410
  return `//\n// Generated from API version ${apiVersions.join(', ')}\n`;
411
411
  }
412
412
  function genRespErrorDoc(method) {
413
- if (!(method.responseEnvelope.result && go.isHeadAsBooleanResult(method.responseEnvelope.result)) && !go.isPageableMethod(method)) {
413
+ if (!(method.responseEnvelope.result?.kind === 'headAsBooleanResult') && !go.isPageableMethod(method)) {
414
414
  // when head-as-boolean is enabled, no error is returned for 4xx status codes.
415
415
  // pager constructors don't return an error
416
416
  return '// If the operation fails it returns an *azcore.ResponseError type.\n';
@@ -421,7 +421,7 @@ function generateOperation(client, method, imports, injectSpans, generateFakes)
421
421
  const params = getAPIParametersSig(method, imports);
422
422
  const returns = generateReturnsInfo(method, 'op');
423
423
  let methodName = method.name;
424
- if (go.isPageableMethod(method) && !go.isLROMethod(method)) {
424
+ if (method.kind === 'pageableMethod') {
425
425
  methodName = fixUpMethodName(method);
426
426
  }
427
427
  let text = '';
@@ -448,7 +448,7 @@ function generateOperation(client, method, imports, injectSpans, generateFakes)
448
448
  }
449
449
  text += `func (client *${client.name}) ${methodName}(${params}) (${returns.join(', ')}) {\n`;
450
450
  const reqParams = helpers.getCreateRequestParameters(method);
451
- if (go.isPageableMethod(method) && !go.isLROMethod(method)) {
451
+ if (method.kind === 'pageableMethod') {
452
452
  text += '\treturn ';
453
453
  text += emitPagerDefinition(client, method, imports, injectSpans, generateFakes);
454
454
  text += '}\n\n';
@@ -481,7 +481,7 @@ function generateOperation(client, method, imports, injectSpans, generateFakes)
481
481
  text += `\t\treturn ${zeroResp}, err\n`;
482
482
  text += '\t}\n';
483
483
  // HAB with headers response is handled in protocol responder
484
- if (method.responseEnvelope.result && go.isHeadAsBooleanResult(method.responseEnvelope.result) && method.responseEnvelope.headers.length === 0) {
484
+ if (method.responseEnvelope.result?.kind === 'headAsBooleanResult' && method.responseEnvelope.headers.length === 0) {
485
485
  text += `\treturn ${method.responseEnvelope.name}{${method.responseEnvelope.result.fieldName}: httpResp.StatusCode >= 200 && httpResp.StatusCode < 300}, nil\n`;
486
486
  }
487
487
  else {
@@ -493,7 +493,7 @@ function generateOperation(client, method, imports, injectSpans, generateFakes)
493
493
  text += `\tresp, err := client.${method.naming.responseMethod}(httpResp)\n`;
494
494
  text += '\treturn resp, err\n';
495
495
  }
496
- else if (method.responseEnvelope.result && go.isBinaryResult(method.responseEnvelope.result)) {
496
+ else if (method.responseEnvelope.result?.kind === 'binaryResult') {
497
497
  text += `\treturn ${method.responseEnvelope.name}{${method.responseEnvelope.result.fieldName}: httpResp.Body}, nil\n`;
498
498
  }
499
499
  else {
@@ -505,7 +505,7 @@ function generateOperation(client, method, imports, injectSpans, generateFakes)
505
505
  }
506
506
  function createProtocolRequest(azureARM, client, method, imports) {
507
507
  let name = method.name;
508
- if (go.isMethod(method)) {
508
+ if (method.kind !== 'nextPageMethod') {
509
509
  name = method.naming.requestMethod;
510
510
  }
511
511
  for (const param of values(method.parameters)) {
@@ -519,7 +519,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
519
519
  text += `func (client *${client.name}) ${name}(${helpers.getCreateRequestParametersSig(method)}) (${returns.join(', ')}) {\n`;
520
520
  const hostParams = new Array();
521
521
  for (const parameter of client.parameters) {
522
- if (go.isURIParameter(parameter)) {
522
+ if (parameter.kind === 'uriParam') {
523
523
  hostParams.push(parameter);
524
524
  }
525
525
  }
@@ -537,7 +537,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
537
537
  }
538
538
  // check for any method local host params
539
539
  for (const param of values(method.parameters)) {
540
- if (param.location === 'method' && go.isURIParameter(param)) {
540
+ if (param.location === 'method' && param.kind === 'uriParam') {
541
541
  text += `\thost = strings.ReplaceAll(host, "{${param.uriPathSegment}}", ${helpers.formatValue(helpers.getParamName(param), param.type, imports)})\n`;
542
542
  }
543
543
  }
@@ -554,7 +554,8 @@ function createProtocolRequest(azureARM, client, method, imports) {
554
554
  else {
555
555
  throw new CodegenError('InternalError', `no host or endpoint defined for method ${client.name}.${method.name}`);
556
556
  }
557
- const hasPathParams = values(method.parameters).where((each) => { return go.isPathParameter(each); }).any();
557
+ const methodParamGroups = helpers.getMethodParamGroups(method);
558
+ const hasPathParams = methodParamGroups.pathParams.length > 0;
558
559
  // storage needs the client.u to be the source-of-truth for the full path.
559
560
  // however, swagger requires that all operations specify a path, which is at odds with storage.
560
561
  // to work around this, storage specifies x-ms-path paths with path params but doesn't
@@ -571,10 +572,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
571
572
  // swagger defines path params, emit path and replace tokens
572
573
  imports.add('strings');
573
574
  // replace path parameters
574
- for (const pp of values(method.parameters)) {
575
- if (!go.isPathParameter(pp)) {
576
- continue;
577
- }
575
+ for (const pp of methodParamGroups.pathParams) {
578
576
  // emit check to ensure path param isn't an empty string. we only need
579
577
  // to do this for params that have an underlying type of string.
580
578
  const choiceIsString = function (type) {
@@ -583,7 +581,8 @@ function createProtocolRequest(azureARM, client, method, imports) {
583
581
  }
584
582
  return type.type === 'string';
585
583
  };
586
- if (((go.isPrimitiveType(pp.type) && pp.type.typeName === 'string') || choiceIsString(pp.type)) && pp.isEncoded) {
584
+ // TODO: https://github.com/Azure/autorest.go/issues/1593
585
+ if (pp.kind === 'pathScalarParam' && ((go.isPrimitiveType(pp.type) && pp.type.typeName === 'string' || choiceIsString(pp.type)) && pp.isEncoded)) {
587
586
  const paramName = helpers.getParamName(pp);
588
587
  imports.add('errors');
589
588
  text += `\tif ${paramName} == "" {\n`;
@@ -619,25 +618,14 @@ function createProtocolRequest(azureARM, client, method, imports) {
619
618
  return `\tif ${optionalParamGroupCheck}${client}${paramGroupName}.${capitalize(param.name)} != nil {\n`;
620
619
  };
621
620
  // add query parameters
622
- const encodedParams = new Array();
623
- const unencodedParams = new Array();
624
- for (const qp of values(method.parameters)) {
625
- if (!go.isQueryParameter(qp)) {
626
- continue;
627
- }
628
- if (qp.isEncoded) {
629
- encodedParams.push(qp);
630
- }
631
- else {
632
- unencodedParams.push(qp);
633
- }
634
- }
621
+ const encodedParams = methodParamGroups.encodedQueryParams;
622
+ const unencodedParams = methodParamGroups.unencodedQueryParams;
635
623
  const emitQueryParam = function (qp, setter) {
636
624
  let qpText = '';
637
- if (qp.location === 'method' && go.isClientSideDefault(qp.kind)) {
638
- qpText = emitClientSideDefault(qp, qp.kind, (name, val) => { return `\treqQP.Set(${name}, ${val})`; }, imports);
625
+ if (qp.location === 'method' && go.isClientSideDefault(qp.style)) {
626
+ qpText = emitClientSideDefault(qp, qp.style, (name, val) => { return `\treqQP.Set(${name}, ${val})`; }, imports);
639
627
  }
640
- else if (go.isRequiredParameter(qp) || go.isLiteralParameter(qp) || (qp.location === 'client' && go.isClientSideDefault(qp.kind))) {
628
+ else if (go.isRequiredParameter(qp) || go.isLiteralParameter(qp) || (qp.location === 'client' && go.isClientSideDefault(qp.style))) {
641
629
  qpText = `\t${setter}\n`;
642
630
  }
643
631
  else if (qp.location === 'client' && !qp.group) {
@@ -658,7 +646,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
658
646
  text += '\treqQP := req.Raw().URL.Query()\n';
659
647
  for (const qp of values(encodedParams.sort((a, b) => { return helpers.sortAscending(a.queryParameter, b.queryParameter); }))) {
660
648
  let setter;
661
- if (go.isQueryCollectionParameter(qp) && qp.collectionFormat === 'multi') {
649
+ if (qp.kind === 'queryCollectionParam' && qp.collectionFormat === 'multi') {
662
650
  setter = `\tfor _, qv := range ${helpers.getParamName(qp)} {\n`;
663
651
  // emit a type conversion for the qv based on the array's element type
664
652
  let queryVal;
@@ -702,7 +690,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
702
690
  }
703
691
  for (const qp of values(unencodedParams.sort((a, b) => { return helpers.sortAscending(a.queryParameter, b.queryParameter); }))) {
704
692
  let setter;
705
- if (go.isQueryCollectionParameter(qp) && qp.collectionFormat === 'multi') {
693
+ if (qp.kind === 'queryCollectionParam' && qp.collectionFormat === 'multi') {
706
694
  setter = `\tfor _, qv := range ${helpers.getParamName(qp)} {\n`;
707
695
  setter += `\t\tunencodedParams = append(unencodedParams, "${qp.queryParameter}="+qv)\n`;
708
696
  setter += '\t}';
@@ -715,49 +703,43 @@ function createProtocolRequest(azureARM, client, method, imports) {
715
703
  imports.add('strings');
716
704
  text += '\treq.Raw().URL.RawQuery = strings.Join(unencodedParams, "&")\n';
717
705
  }
718
- if (go.isMethod(method) && method.responseEnvelope.result && go.isBinaryResult(method.responseEnvelope.result)) {
706
+ if (method.kind !== 'nextPageMethod' && method.responseEnvelope.result?.kind === 'binaryResult') {
719
707
  // skip auto-body downloading for binary stream responses
720
708
  text += '\truntime.SkipBodyDownload(req)\n';
721
709
  }
722
710
  // add specific request headers
723
711
  const emitHeaderSet = function (headerParam, prefix) {
724
- if (headerParam.location === 'method' && go.isClientSideDefault(headerParam.kind)) {
725
- return emitClientSideDefault(headerParam, headerParam.kind, (name, val) => {
726
- return `${prefix}req.Raw().Header[${name}] = []string{${val}}`;
727
- }, imports);
728
- }
729
- else if (go.isHeaderMapParameter(headerParam)) {
712
+ if (headerParam.kind === 'headerMapParam') {
730
713
  let headerText = `${prefix}for k, v := range ${helpers.getParamName(headerParam)} {\n`;
731
714
  headerText += `${prefix}\tif v != nil {\n`;
732
- headerText += `${prefix}\t\treq.Raw().Header["${headerParam.collectionPrefix}"+k] = []string{*v}\n`;
715
+ headerText += `${prefix}\t\treq.Raw().Header["${headerParam.headerName}"+k] = []string{*v}\n`;
733
716
  headerText += `${prefix}}\n`;
734
717
  headerText += `${prefix}}\n`;
735
718
  return headerText;
736
719
  }
720
+ else if (headerParam.location === 'method' && go.isClientSideDefault(headerParam.style)) {
721
+ return emitClientSideDefault(headerParam, headerParam.style, (name, val) => {
722
+ return `${prefix}req.Raw().Header[${name}] = []string{${val}}`;
723
+ }, imports);
724
+ }
737
725
  else {
738
726
  return `${prefix}req.Raw().Header["${headerParam.headerName}"] = []string{${helpers.formatParamValue(headerParam, imports)}}\n`;
739
727
  }
740
728
  };
741
- const headerParams = new Array();
742
- for (const param of values(method.parameters)) {
743
- if (go.isHeaderParameter(param)) {
744
- headerParams.push(param);
745
- }
746
- }
747
729
  let contentType;
748
- for (const param of headerParams.sort((a, b) => { return helpers.sortAscending(a.headerName, b.headerName); })) {
730
+ for (const param of methodParamGroups.headerParams.sort((a, b) => { return helpers.sortAscending(a.headerName, b.headerName); })) {
749
731
  if (param.headerName.match(/^content-type$/)) {
750
732
  // canonicalize content-type as req.SetBody checks for it via its canonicalized name :(
751
733
  param.headerName = 'Content-Type';
752
734
  }
753
- if (param.headerName === 'Content-Type' && param.kind === 'literal') {
735
+ if (param.headerName === 'Content-Type' && param.style === 'literal') {
754
736
  // the content-type header will be set as part of emitSetBodyWithErrCheck
755
737
  // to handle cases where the body param is optional. we don't want to set
756
738
  // the content-type if the body is nil.
757
739
  // we do it like this as tsp specifies content-type while swagger does not.
758
740
  contentType = helpers.formatParamValue(param, imports);
759
741
  }
760
- else if (go.isRequiredParameter(param) || go.isLiteralParameter(param) || go.isClientSideDefault(param.kind)) {
742
+ else if (go.isRequiredParameter(param) || go.isLiteralParameter(param) || go.isClientSideDefault(param.style)) {
761
743
  text += emitHeaderSet(param, '\t');
762
744
  }
763
745
  else if (param.location === 'client' && !param.group) {
@@ -772,8 +754,11 @@ function createProtocolRequest(azureARM, client, method, imports) {
772
754
  text += '\t}\n';
773
755
  }
774
756
  }
775
- const partialBodyParams = values(method.parameters).where((param) => { return go.isPartialBodyParameter(param); }).toArray();
776
- const bodyParam = values(method.parameters).where((each) => { return go.isBodyParameter(each) || go.isFormBodyParameter(each) || go.isMultipartFormBodyParameter(each); }).first();
757
+ // note that these are mutually exclusive
758
+ const bodyParam = methodParamGroups.bodyParam;
759
+ const formBodyParams = methodParamGroups.formBodyParams;
760
+ const multipartBodyParams = methodParamGroups.multipartBodyParams;
761
+ const partialBodyParams = methodParamGroups.partialBodyParams;
777
762
  const emitSetBodyWithErrCheck = function (setBodyParam, contentType) {
778
763
  let content = `if err := ${setBodyParam}; err != nil {\n\treturn nil, err\n}\n;`;
779
764
  if (contentType) {
@@ -781,7 +766,111 @@ function createProtocolRequest(azureARM, client, method, imports) {
781
766
  }
782
767
  return content;
783
768
  };
784
- if (partialBodyParams.length > 0) {
769
+ if (bodyParam) {
770
+ if (bodyParam.bodyFormat === 'JSON' || bodyParam.bodyFormat === 'XML') {
771
+ // default to the body param name
772
+ let body = helpers.getParamName(bodyParam);
773
+ if (go.isLiteralValue(bodyParam.type)) {
774
+ // if the value is constant, embed it directly
775
+ body = helpers.formatLiteralValue(bodyParam.type, true);
776
+ }
777
+ else if (bodyParam.bodyFormat === 'XML' && go.isSliceType(bodyParam.type)) {
778
+ // for XML payloads, create a wrapper type if the payload is an array
779
+ imports.add('encoding/xml');
780
+ text += '\ttype wrapper struct {\n';
781
+ let tagName = go.getTypeDeclaration(bodyParam.type);
782
+ if (bodyParam.xml?.name) {
783
+ tagName = bodyParam.xml.name;
784
+ }
785
+ text += `\t\tXMLName xml.Name \`xml:"${tagName}"\`\n`;
786
+ const fieldName = capitalize(bodyParam.name);
787
+ let tag = go.getTypeDeclaration(bodyParam.type.elementType);
788
+ if (go.isModelType(bodyParam.type.elementType) && bodyParam.type.elementType.xml?.name) {
789
+ tag = bodyParam.type.elementType.xml.name;
790
+ }
791
+ text += `\t\t${fieldName} *${go.getTypeDeclaration(bodyParam.type)} \`xml:"${tag}"\`\n`;
792
+ text += '\t}\n';
793
+ let addr = '&';
794
+ if (!go.isRequiredParameter(bodyParam) && !bodyParam.byValue) {
795
+ addr = '';
796
+ }
797
+ body = `wrapper{${fieldName}: ${addr}${body}}`;
798
+ }
799
+ else if (go.isTimeType(bodyParam.type) && bodyParam.type.dateTimeFormat !== 'dateTimeRFC3339') {
800
+ // wrap the body in the internal time type
801
+ // no need for dateTimeRFC3339 as the JSON marshaler defaults to that.
802
+ body = `${bodyParam.type.dateTimeFormat}(${body})`;
803
+ }
804
+ else if (isArrayOfDateTimeForMarshalling(bodyParam.type)) {
805
+ const timeInfo = isArrayOfDateTimeForMarshalling(bodyParam.type);
806
+ let elementPtr = '*';
807
+ if (timeInfo?.elemByVal) {
808
+ elementPtr = '';
809
+ }
810
+ text += `\taux := make([]${elementPtr}${timeInfo?.format}, len(${body}))\n`;
811
+ text += `\tfor i := 0; i < len(${body}); i++ {\n`;
812
+ text += `\t\taux[i] = (${elementPtr}${timeInfo?.format})(${body}[i])\n`;
813
+ text += '\t}\n';
814
+ body = 'aux';
815
+ }
816
+ else if (isMapOfDateTime(bodyParam.type)) {
817
+ const timeType = isMapOfDateTime(bodyParam.type);
818
+ text += `\taux := map[string]*${timeType}{}\n`;
819
+ text += `\tfor k, v := range ${body} {\n`;
820
+ text += `\t\taux[k] = (*${timeType})(v)\n`;
821
+ text += '\t}\n';
822
+ body = 'aux';
823
+ }
824
+ let setBody = `runtime.MarshalAs${getMediaFormat(bodyParam.type, bodyParam.bodyFormat, `req, ${body}`)}`;
825
+ if (go.isSliceType(bodyParam.type) && bodyParam.type.rawJSONAsBytes) {
826
+ imports.add('bytes');
827
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming');
828
+ setBody = `req.SetBody(streaming.NopCloser(bytes.NewReader(${body})), "application/${bodyParam.bodyFormat.toLowerCase()}")`;
829
+ }
830
+ if (go.isRequiredParameter(bodyParam) || go.isLiteralParameter(bodyParam)) {
831
+ text += `\t${emitSetBodyWithErrCheck(setBody, contentType)}`;
832
+ text += '\treturn req, nil\n';
833
+ }
834
+ else {
835
+ text += emitParamGroupCheck(bodyParam);
836
+ text += `\t${emitSetBodyWithErrCheck(setBody, contentType)}`;
837
+ text += '\t\treturn req, nil\n';
838
+ text += '\t}\n';
839
+ text += '\treturn req, nil\n';
840
+ }
841
+ }
842
+ else if (bodyParam.bodyFormat === 'binary') {
843
+ if (go.isRequiredParameter(bodyParam)) {
844
+ text += `\t${emitSetBodyWithErrCheck(`req.SetBody(${bodyParam.name}, ${bodyParam.contentType})`, contentType)}`;
845
+ text += '\treturn req, nil\n';
846
+ }
847
+ else {
848
+ text += emitParamGroupCheck(bodyParam);
849
+ text += `\t${emitSetBodyWithErrCheck(`req.SetBody(${helpers.getParamName(bodyParam)}, ${bodyParam.contentType})`, contentType)}`;
850
+ text += '\treturn req, nil\n';
851
+ text += '\t}\n';
852
+ text += '\treturn req, nil\n';
853
+ }
854
+ }
855
+ else if (bodyParam.bodyFormat === 'Text') {
856
+ imports.add('strings');
857
+ imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming');
858
+ if (go.isRequiredParameter(bodyParam)) {
859
+ text += `\tbody := streaming.NopCloser(strings.NewReader(${bodyParam.name}))\n`;
860
+ text += `\t${emitSetBodyWithErrCheck(`req.SetBody(body, ${bodyParam.contentType})`, contentType)}`;
861
+ text += '\treturn req, nil\n';
862
+ }
863
+ else {
864
+ text += emitParamGroupCheck(bodyParam);
865
+ text += `\tbody := streaming.NopCloser(strings.NewReader(${helpers.getParamName(bodyParam)}))\n`;
866
+ text += `\t${emitSetBodyWithErrCheck(`req.SetBody(body, ${bodyParam.contentType})`, contentType)}`;
867
+ text += '\treturn req, nil\n';
868
+ text += '\t}\n';
869
+ text += '\treturn req, nil\n';
870
+ }
871
+ }
872
+ }
873
+ else if (partialBodyParams.length > 0) {
785
874
  // partial body params are discrete params that are all fields within an internal struct.
786
875
  // define and instantiate an instance of the wire type, using the values from each param.
787
876
  text += '\tbody := struct {\n';
@@ -808,123 +897,14 @@ function createProtocolRequest(azureARM, client, method, imports) {
808
897
  text += '\tif err := runtime.MarshalAsJSON(req, body); err != nil {\n\t\treturn nil, err\n\t}\n';
809
898
  text += '\treturn req, nil\n';
810
899
  }
811
- else if (!bodyParam) {
812
- text += '\treturn req, nil\n';
813
- }
814
- else if (bodyParam.bodyFormat === 'JSON' || bodyParam.bodyFormat === 'XML') {
815
- // default to the body param name
816
- let body = helpers.getParamName(bodyParam);
817
- if (go.isLiteralValue(bodyParam.type)) {
818
- // if the value is constant, embed it directly
819
- body = helpers.formatLiteralValue(bodyParam.type, true);
820
- }
821
- else if (bodyParam.bodyFormat === 'XML' && go.isSliceType(bodyParam.type)) {
822
- // for XML payloads, create a wrapper type if the payload is an array
823
- imports.add('encoding/xml');
824
- text += '\ttype wrapper struct {\n';
825
- let tagName = go.getTypeDeclaration(bodyParam.type);
826
- if (bodyParam.xml?.name) {
827
- tagName = bodyParam.xml.name;
828
- }
829
- text += `\t\tXMLName xml.Name \`xml:"${tagName}"\`\n`;
830
- const fieldName = capitalize(bodyParam.name);
831
- let tag = go.getTypeDeclaration(bodyParam.type.elementType);
832
- if (go.isModelType(bodyParam.type.elementType) && bodyParam.type.elementType.xml?.name) {
833
- tag = bodyParam.type.elementType.xml.name;
834
- }
835
- text += `\t\t${fieldName} *${go.getTypeDeclaration(bodyParam.type)} \`xml:"${tag}"\`\n`;
836
- text += '\t}\n';
837
- let addr = '&';
838
- if (!go.isRequiredParameter(bodyParam) && !bodyParam.byValue) {
839
- addr = '';
840
- }
841
- body = `wrapper{${fieldName}: ${addr}${body}}`;
842
- }
843
- else if (go.isTimeType(bodyParam.type) && bodyParam.type.dateTimeFormat !== 'dateTimeRFC3339') {
844
- // wrap the body in the internal time type
845
- // no need for dateTimeRFC3339 as the JSON marshaler defaults to that.
846
- body = `${bodyParam.type.dateTimeFormat}(${body})`;
847
- }
848
- else if (isArrayOfDateTimeForMarshalling(bodyParam.type)) {
849
- const timeInfo = isArrayOfDateTimeForMarshalling(bodyParam.type);
850
- let elementPtr = '*';
851
- if (timeInfo?.elemByVal) {
852
- elementPtr = '';
853
- }
854
- text += `\taux := make([]${elementPtr}${timeInfo?.format}, len(${body}))\n`;
855
- text += `\tfor i := 0; i < len(${body}); i++ {\n`;
856
- text += `\t\taux[i] = (${elementPtr}${timeInfo?.format})(${body}[i])\n`;
857
- text += '\t}\n';
858
- body = 'aux';
859
- }
860
- else if (isMapOfDateTime(bodyParam.type)) {
861
- const timeType = isMapOfDateTime(bodyParam.type);
862
- text += `\taux := map[string]*${timeType}{}\n`;
863
- text += `\tfor k, v := range ${body} {\n`;
864
- text += `\t\taux[k] = (*${timeType})(v)\n`;
865
- text += '\t}\n';
866
- body = 'aux';
867
- }
868
- let setBody = `runtime.MarshalAs${getMediaFormat(bodyParam.type, bodyParam.bodyFormat, `req, ${body}`)}`;
869
- if (go.isSliceType(bodyParam.type) && bodyParam.type.rawJSONAsBytes) {
870
- imports.add('bytes');
871
- imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming');
872
- setBody = `req.SetBody(streaming.NopCloser(bytes.NewReader(${body})), "application/${bodyParam.bodyFormat.toLowerCase()}")`;
873
- }
874
- if (go.isRequiredParameter(bodyParam) || go.isLiteralParameter(bodyParam)) {
875
- text += `\t${emitSetBodyWithErrCheck(setBody, contentType)}`;
876
- text += '\treturn req, nil\n';
877
- }
878
- else {
879
- text += emitParamGroupCheck(bodyParam);
880
- text += `\t${emitSetBodyWithErrCheck(setBody, contentType)}`;
881
- text += '\t\treturn req, nil\n';
882
- text += '\t}\n';
883
- text += '\treturn req, nil\n';
884
- }
885
- }
886
- else if (bodyParam.bodyFormat === 'binary') {
887
- if (go.isRequiredParameter(bodyParam)) {
888
- text += `\t${emitSetBodyWithErrCheck(`req.SetBody(${bodyParam.name}, ${bodyParam.contentType})`, contentType)}`;
889
- text += '\treturn req, nil\n';
890
- }
891
- else {
892
- text += emitParamGroupCheck(bodyParam);
893
- text += `\t${emitSetBodyWithErrCheck(`req.SetBody(${helpers.getParamName(bodyParam)}, ${bodyParam.contentType})`, contentType)}`;
894
- text += '\treturn req, nil\n';
895
- text += '\t}\n';
896
- text += '\treturn req, nil\n';
897
- }
898
- }
899
- else if (bodyParam.bodyFormat === 'Text') {
900
- imports.add('strings');
901
- imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming');
902
- const bodyParam = values(method.parameters).where((each) => { return go.isBodyParameter(each); }).first();
903
- if (go.isRequiredParameter(bodyParam)) {
904
- text += `\tbody := streaming.NopCloser(strings.NewReader(${bodyParam.name}))\n`;
905
- text += `\t${emitSetBodyWithErrCheck(`req.SetBody(body, ${bodyParam.contentType})`, contentType)}`;
906
- text += '\treturn req, nil\n';
907
- }
908
- else {
909
- text += emitParamGroupCheck(bodyParam);
910
- text += `\tbody := streaming.NopCloser(strings.NewReader(${helpers.getParamName(bodyParam)}))\n`;
911
- text += `\t${emitSetBodyWithErrCheck(`req.SetBody(body, ${bodyParam.contentType})`, contentType)}`;
912
- text += '\treturn req, nil\n';
913
- text += '\t}\n';
914
- text += '\treturn req, nil\n';
915
- }
916
- }
917
- else if (go.isMultipartFormBodyParameter(bodyParam)) {
918
- if (go.isModelType(bodyParam.type) && bodyParam.type.annotations.multipartFormData) {
919
- text += `\tformData, err := ${bodyParam.name}.toMultipartFormData()\n`;
900
+ else if (multipartBodyParams.length > 0) {
901
+ if (multipartBodyParams.length === 1 && go.isModelType(multipartBodyParams[0].type) && multipartBodyParams[0].type.annotations.multipartFormData) {
902
+ text += `\tformData, err := ${multipartBodyParams[0].name}.toMultipartFormData()\n`;
920
903
  text += '\tif err != nil {\n\t\treturn nil, err\n\t}\n';
921
904
  }
922
905
  else {
923
906
  text += '\tformData := map[string]any{}\n';
924
- for (const param of values(method.parameters)) {
925
- if (!go.isMultipartFormBodyParameter(param)) {
926
- continue;
927
- }
907
+ for (const param of multipartBodyParams) {
928
908
  const setter = `formData["${param.name}"] = ${helpers.getParamName(param)}`;
929
909
  if (go.isRequiredParameter(param)) {
930
910
  text += `\t${setter}\n`;
@@ -938,7 +918,7 @@ function createProtocolRequest(azureARM, client, method, imports) {
938
918
  text += '\tif err := runtime.SetMultipartFormData(req, formData); err != nil {\n\t\treturn nil, err\n\t}\n';
939
919
  text += '\treturn req, nil\n';
940
920
  }
941
- else if (go.isFormBodyParameter(bodyParam)) {
921
+ else if (formBodyParams.length > 0) {
942
922
  const emitFormData = function (param, setter) {
943
923
  let formDataText = '';
944
924
  if (go.isRequiredParameter(param)) {
@@ -956,11 +936,9 @@ function createProtocolRequest(azureARM, client, method, imports) {
956
936
  imports.add('github.com/Azure/azure-sdk-for-go/sdk/azcore/streaming');
957
937
  text += '\tformData := url.Values{}\n';
958
938
  // find all the form body params
959
- for (const param of values(method.parameters)) {
960
- if (go.isFormBodyParameter(param)) {
961
- const setter = `formData.Set("${param.formDataName}", ${helpers.formatParamValue(param, imports)})`;
962
- text += emitFormData(param, setter);
963
- }
939
+ for (const param of formBodyParams) {
940
+ const setter = `formData.Set("${param.formDataName}", ${helpers.formatParamValue(param, imports)})`;
941
+ text += emitFormData(param, setter);
964
942
  }
965
943
  text += '\tbody := streaming.NopCloser(strings.NewReader(formData.Encode()))\n';
966
944
  text += `\t${emitSetBodyWithErrCheck('req.SetBody(body, "application/x-www-form-urlencoded")')}`;
@@ -979,11 +957,15 @@ function emitClientSideDefault(param, csd, setterFormat, imports) {
979
957
  text += `\t\t${defaultVar} = *options.${capitalize(param.name)}\n`;
980
958
  text += '}\n';
981
959
  let serializedName;
982
- if (go.isHeaderParameter(param)) {
983
- serializedName = param.headerName;
984
- }
985
- else {
986
- serializedName = param.queryParameter;
960
+ switch (param.kind) {
961
+ case 'headerCollectionParam':
962
+ case 'headerScalarParam':
963
+ serializedName = param.headerName;
964
+ break;
965
+ case 'queryCollectionParam':
966
+ case 'queryScalarParam':
967
+ serializedName = param.queryParameter;
968
+ break;
987
969
  }
988
970
  text += setterFormat(`"${serializedName}"`, helpers.formatValue(defaultVar, param.type, imports)) + '\n';
989
971
  return text;
@@ -1111,56 +1093,59 @@ function createProtocolResponse(client, method, imports) {
1111
1093
  text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1112
1094
  addHeaders(method.responseEnvelope.headers);
1113
1095
  }
1114
- else if (go.isAnyResult(result)) {
1115
- imports.add('fmt');
1116
- text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1117
- addHeaders(method.responseEnvelope.headers);
1118
- text += '\tswitch resp.StatusCode {\n';
1119
- for (const statusCode of method.httpStatusCodes) {
1120
- text += `\tcase ${helpers.formatStatusCodes([statusCode])}:\n`;
1121
- const resultType = result.httpStatusCodeType[statusCode];
1122
- if (!resultType) {
1123
- // the operation contains a mix of schemas and non-schema responses
1124
- continue;
1125
- }
1126
- text += `\tvar val ${go.getTypeDeclaration(resultType)}\n`;
1127
- text += generateResponseUnmarshaller(method, resultType, result.format, 'val');
1128
- text += '\tresult.Value = val\n';
1129
- }
1130
- text += '\tdefault:\n';
1131
- text += `\t\treturn ${getZeroReturnValue(method, 'handler')}, fmt.Errorf("unhandled HTTP status code %d", resp.StatusCode)\n`;
1132
- text += '\t}\n';
1133
- }
1134
- else if (go.isBinaryResult(result)) {
1135
- text += `\tresult := ${method.responseEnvelope.name}{${result.fieldName}: resp.Body}\n`;
1136
- addHeaders(method.responseEnvelope.headers);
1137
- }
1138
- else if (go.isHeadAsBooleanResult(result)) {
1139
- text += `\tresult := ${method.responseEnvelope.name}{${result.fieldName}: resp.StatusCode >= 200 && resp.StatusCode < 300}\n`;
1140
- addHeaders(method.responseEnvelope.headers);
1141
- }
1142
- else if (go.isMonomorphicResult(result)) {
1143
- text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1144
- addHeaders(method.responseEnvelope.headers);
1145
- let target = `result.${helpers.getResultFieldName(method)}`;
1146
- // when unmarshalling a wrapped XML array, unmarshal into the response envelope
1147
- if (result.format === 'XML' && go.isSliceType(result.monomorphicType)) {
1148
- target = 'result';
1149
- }
1150
- text += generateResponseUnmarshaller(method, result.monomorphicType, result.format, target);
1151
- }
1152
- else if (go.isPolymorphicResult(result)) {
1153
- text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1154
- addHeaders(method.responseEnvelope.headers);
1155
- text += generateResponseUnmarshaller(method, result.interfaceType, result.format, 'result');
1156
- }
1157
- else if (go.isModelResult(result)) {
1158
- text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1159
- addHeaders(method.responseEnvelope.headers);
1160
- text += generateResponseUnmarshaller(method, result.modelType, result.format, `result.${helpers.getResultFieldName(method)}`);
1161
- }
1162
1096
  else {
1163
- throw new CodegenError('InternalError', `unhandled result type for ${client.name}.${method.name}`);
1097
+ switch (result.kind) {
1098
+ case 'anyResult':
1099
+ imports.add('fmt');
1100
+ text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1101
+ addHeaders(method.responseEnvelope.headers);
1102
+ text += '\tswitch resp.StatusCode {\n';
1103
+ for (const statusCode of method.httpStatusCodes) {
1104
+ text += `\tcase ${helpers.formatStatusCodes([statusCode])}:\n`;
1105
+ const resultType = result.httpStatusCodeType[statusCode];
1106
+ if (!resultType) {
1107
+ // the operation contains a mix of schemas and non-schema responses
1108
+ continue;
1109
+ }
1110
+ text += `\tvar val ${go.getTypeDeclaration(resultType)}\n`;
1111
+ text += generateResponseUnmarshaller(method, resultType, result.format, 'val');
1112
+ text += '\tresult.Value = val\n';
1113
+ }
1114
+ text += '\tdefault:\n';
1115
+ text += `\t\treturn ${getZeroReturnValue(method, 'handler')}, fmt.Errorf("unhandled HTTP status code %d", resp.StatusCode)\n`;
1116
+ text += '\t}\n';
1117
+ break;
1118
+ case 'binaryResult':
1119
+ text += `\tresult := ${method.responseEnvelope.name}{${result.fieldName}: resp.Body}\n`;
1120
+ addHeaders(method.responseEnvelope.headers);
1121
+ break;
1122
+ case 'headAsBooleanResult':
1123
+ text += `\tresult := ${method.responseEnvelope.name}{${result.fieldName}: resp.StatusCode >= 200 && resp.StatusCode < 300}\n`;
1124
+ addHeaders(method.responseEnvelope.headers);
1125
+ break;
1126
+ case 'modelResult':
1127
+ text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1128
+ addHeaders(method.responseEnvelope.headers);
1129
+ text += generateResponseUnmarshaller(method, result.modelType, result.format, `result.${helpers.getResultFieldName(method)}`);
1130
+ break;
1131
+ case 'monomorphicResult':
1132
+ text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1133
+ addHeaders(method.responseEnvelope.headers);
1134
+ let target = `result.${helpers.getResultFieldName(method)}`;
1135
+ // when unmarshalling a wrapped XML array, unmarshal into the response envelope
1136
+ if (result.format === 'XML' && go.isSliceType(result.monomorphicType)) {
1137
+ target = 'result';
1138
+ }
1139
+ text += generateResponseUnmarshaller(method, result.monomorphicType, result.format, target);
1140
+ break;
1141
+ case 'polymorphicResult':
1142
+ text += `\tresult := ${method.responseEnvelope.name}{}\n`;
1143
+ addHeaders(method.responseEnvelope.headers);
1144
+ text += generateResponseUnmarshaller(method, result.interfaceType, result.format, 'result');
1145
+ break;
1146
+ default:
1147
+ result;
1148
+ }
1164
1149
  }
1165
1150
  text += '\treturn result, nil\n';
1166
1151
  text += '}\n\n';
@@ -1192,7 +1177,7 @@ function isMapOfDateTime(paramType) {
1192
1177
  function getAPIParametersSig(method, imports, pkgName) {
1193
1178
  const methodParams = helpers.getMethodParameters(method);
1194
1179
  const params = new Array();
1195
- if (!go.isPageableMethod(method) || go.isLROMethod(method)) {
1180
+ if (method.kind !== 'pageableMethod') {
1196
1181
  imports.add('context');
1197
1182
  params.push('ctx context.Context');
1198
1183
  }
@@ -1209,34 +1194,37 @@ function getAPIParametersSig(method, imports, pkgName) {
1209
1194
  // handler - for the response handler
1210
1195
  function generateReturnsInfo(method, apiType) {
1211
1196
  let returnType = method.responseEnvelope.name;
1212
- if (go.isLROMethod(method)) {
1213
- switch (apiType) {
1214
- case 'api':
1215
- if (go.isPageableMethod(method)) {
1216
- returnType = `*runtime.Poller[*runtime.Pager[${returnType}]]`;
1217
- }
1218
- else {
1219
- returnType = `*runtime.Poller[${returnType}]`;
1220
- }
1221
- break;
1222
- case 'handler':
1223
- // we only have a handler for operations that return a schema
1224
- if (!go.isPageableMethod(method)) {
1225
- throw new CodegenError('InternalError', `handler being generated for non-pageable LRO ${method.name} which is unexpected`);
1226
- }
1227
- break;
1228
- case 'op':
1229
- returnType = '*http.Response';
1230
- break;
1231
- }
1232
- }
1233
- else if (go.isPageableMethod(method)) {
1234
- switch (apiType) {
1235
- case 'api':
1236
- case 'op':
1237
- // pager operations don't return an error
1238
- return [`*runtime.Pager[${returnType}]`];
1239
- }
1197
+ switch (method.kind) {
1198
+ case 'lroMethod':
1199
+ case 'lroPageableMethod':
1200
+ switch (apiType) {
1201
+ case 'api':
1202
+ if (method.kind === 'lroPageableMethod') {
1203
+ returnType = `*runtime.Poller[*runtime.Pager[${returnType}]]`;
1204
+ }
1205
+ else {
1206
+ returnType = `*runtime.Poller[${returnType}]`;
1207
+ }
1208
+ break;
1209
+ case 'handler':
1210
+ // we only have a handler for operations that return a schema
1211
+ if (method.kind !== 'lroPageableMethod') {
1212
+ throw new CodegenError('InternalError', `handler being generated for non-pageable LRO ${method.name} which is unexpected`);
1213
+ }
1214
+ break;
1215
+ case 'op':
1216
+ returnType = '*http.Response';
1217
+ break;
1218
+ }
1219
+ break;
1220
+ case 'pageableMethod':
1221
+ switch (apiType) {
1222
+ case 'api':
1223
+ case 'op':
1224
+ // pager operations don't return an error
1225
+ return [`*runtime.Pager[${returnType}]`];
1226
+ }
1227
+ break;
1240
1228
  }
1241
1229
  return [returnType, 'error'];
1242
1230
  }
@@ -1258,7 +1246,7 @@ function generateLROBeginMethod(client, method, imports, injectSpans, generateFa
1258
1246
  text += `func (client *${client.name}) ${fixUpMethodName(method)}(${params}) (${returns.join(', ')}) {\n`;
1259
1247
  let pollerType = 'nil';
1260
1248
  let pollerTypeParam = `[${method.responseEnvelope.name}]`;
1261
- if (go.isPageableMethod(method)) {
1249
+ if (method.kind === 'lroPageableMethod') {
1262
1250
  // for paged LROs, we construct a pager and pass it to the LRO ctor.
1263
1251
  pollerTypeParam = `[*runtime.Pager${pollerTypeParam}]`;
1264
1252
  pollerType = '&pager';
@@ -1347,21 +1335,24 @@ function generateLROBeginMethod(client, method, imports, injectSpans, generateFa
1347
1335
  return text;
1348
1336
  }
1349
1337
  export function fixUpMethodName(method) {
1350
- if (go.isLROMethod(method)) {
1351
- return `Begin${method.name}`;
1352
- }
1353
- if (go.isPageableMethod(method)) {
1354
- let N = 'N';
1355
- let name = method.name;
1356
- if (method.name[0] !== method.name[0].toUpperCase()) {
1357
- // the method isn't exported; don't export the pager ctor
1358
- N = 'n';
1359
- // ensure correct casing of the emitted function name e.g.,
1360
- // "listThings" -> "newListThingsPager"
1361
- name = name[0].toUpperCase() + name.substring(1);
1338
+ switch (method.kind) {
1339
+ case 'lroMethod':
1340
+ case 'lroPageableMethod':
1341
+ return `Begin${method.name}`;
1342
+ case 'pageableMethod': {
1343
+ let N = 'N';
1344
+ let name = method.name;
1345
+ if (method.name[0] !== method.name[0].toUpperCase()) {
1346
+ // the method isn't exported; don't export the pager ctor
1347
+ N = 'n';
1348
+ // ensure correct casing of the emitted function name e.g.,
1349
+ // "listThings" -> "newListThingsPager"
1350
+ name = name[0].toUpperCase() + name.substring(1);
1351
+ }
1352
+ return `${N}ew${name}Pager`;
1362
1353
  }
1363
- return `${N}ew${name}Pager`;
1354
+ case 'method':
1355
+ return method.name;
1364
1356
  }
1365
- return method.name;
1366
1357
  }
1367
1358
  //# sourceMappingURL=operations.js.map