@@ -47,6 +47,7 @@ type ResourceDeprecation struct {
4747type Versioning interface {
4848 ShouldInclude (provider string , version string , typeName , token string ) bool
4949 GetDeprecation (token string ) (ResourceDeprecation , bool )
50+ GetAllVersions (openapi.ProviderName , openapi.ResourceName ) []openapi.ApiVersion
5051}
5152
5253type GenerationResult struct {
@@ -227,15 +228,17 @@ func PulumiSchema(rootDir string, providerMap openapi.AzureProviders, versioning
227228 gen := packageGenerator {
228229 pkg : & pkg ,
229230 metadata : & metadata ,
231+ provider : providerName ,
230232 apiVersion : version ,
233+ allApiVersions : versions ,
231234 examples : exampleMap ,
232235 versioning : versioning ,
233236 caseSensitiveTypes : caseSensitiveTypes ,
234237 rootDir : rootDir ,
235238 }
236239
237240 // Populate C#, Java, Python and Go module mapping.
238- module := gen .providerToModule ( providerName )
241+ module := gen .moduleName ( )
239242 csharpNamespaces [strings .ToLower (providerName )] = providerName
240243 javaPackages [module ] = strings .ToLower (providerName )
241244 if version != "" {
@@ -257,7 +260,7 @@ func PulumiSchema(rootDir string, providerMap openapi.AzureProviders, versioning
257260 for _ , typeName := range resources {
258261 resource := items .Resources [typeName ]
259262 nestedResourceBodyRefs := findNestedResourceBodyRefs (resource , items .Resources )
260- err := gen .genResources (providerName , typeName , resource , nestedResourceBodyRefs )
263+ err := gen .genResources (typeName , resource , nestedResourceBodyRefs )
261264 if err != nil {
262265 return nil , err
263266 }
@@ -272,7 +275,7 @@ func PulumiSchema(rootDir string, providerMap openapi.AzureProviders, versioning
272275
273276 for _ , typeName := range invokes {
274277 invoke := items .Invokes [typeName ]
275- gen .genPostFunctions (providerName , typeName , invoke .Path , invoke .PathItem , invoke .Swagger )
278+ gen .genPostFunctions (typeName , invoke .Path , invoke .PathItem , invoke .Swagger )
276279 }
277280 warnings = append (warnings , gen .warnings ... )
278281 }
@@ -490,16 +493,18 @@ const (
490493type packageGenerator struct {
491494 pkg * pschema.PackageSpec
492495 metadata * resources.AzureAPIMetadata
496+ provider string
493497 examples map [string ][]resources.AzureAPIExample
494498 apiVersion string
499+ allApiVersions []openapi.ApiVersion
495500 versioning Versioning
496501 caseSensitiveTypes caseSensitiveTokens
497502 warnings []string
498503 // rootDir is used to resolve relative paths in the examples.
499504 rootDir string
500505}
501506
502- func (g * packageGenerator ) genResources (prov , typeName string , resource * openapi.ResourceSpec , nestedResourceBodyRefs []string ) error {
507+ func (g * packageGenerator ) genResources (typeName string , resource * openapi.ResourceSpec , nestedResourceBodyRefs []string ) error {
503508 // Resource names should consistently start with upper case.
504509 // We need to alias the previous, lowercase name so users can upgrade to v2 without replacement.
505510 // These aliases will not be required anymore with v3; their removal is tracked by #2411.
@@ -515,11 +520,11 @@ func (g *packageGenerator) genResources(prov, typeName string, resource *openapi
515520 // per each union case. We call them "variants" in the code below.
516521 variants , err := g .findResourceVariants (resource )
517522 if err != nil {
518- return errors .Wrapf (err , "resource %s.%s" , prov , titleCasedTypeName )
523+ return errors .Wrapf (err , "resource %s.%s" , g . provider , titleCasedTypeName )
519524 }
520525
521526 for _ , v := range variants {
522- err = g .genResourceVariant (prov , resource , v , nestedResourceBodyRefs , typeNameAliases ... )
527+ err = g .genResourceVariant (resource , v , nestedResourceBodyRefs , typeNameAliases ... )
523528 if err != nil {
524529 return err
525530 }
@@ -537,7 +542,7 @@ func (g *packageGenerator) genResources(prov, typeName string, resource *openapi
537542 if resource .DeprecationMessage != "" {
538543 mainResource .deprecationMessage = resource .DeprecationMessage
539544 }
540- return g .genResourceVariant (prov , resource , mainResource , nestedResourceBodyRefs , typeNameAliases ... )
545+ return g .genResourceVariant (resource , mainResource , nestedResourceBodyRefs , typeNameAliases ... )
541546}
542547
543548// resourceVariant points to request body's and response's schemas of a resource which is one of the variants
@@ -626,18 +631,18 @@ func (g *packageGenerator) findResourceVariants(resource *openapi.ResourceSpec)
626631 return result , nil
627632}
628633
629- func (g * packageGenerator ) makeTypeAlias (prov , alias , apiVersion string ) pschema.AliasSpec {
630- fqAlias := fmt .Sprintf ("%s:%s:%s" , g .pkg .Name , providerApiToModule (prov , apiVersion ), alias )
634+ func (g * packageGenerator ) makeTypeAlias (alias , apiVersion string ) pschema.AliasSpec {
635+ fqAlias := fmt .Sprintf ("%s:%s:%s" , g .pkg .Name , g . providerApiToModule (apiVersion ), alias )
631636 return pschema.AliasSpec {Type : & fqAlias }
632637}
633638
634- func (g * packageGenerator ) genResourceVariant (prov string , apiSpec * openapi.ResourceSpec , resource * resourceVariant , nestedResourceBodyRefs []string , typeNameAliases ... string ) error {
635- module := g .providerToModule ( prov )
639+ func (g * packageGenerator ) genResourceVariant (apiSpec * openapi.ResourceSpec , resource * resourceVariant , nestedResourceBodyRefs []string , typeNameAliases ... string ) error {
640+ module := g .moduleName ( )
636641 swagger := resource .Swagger
637642 path := resource .PathItem
638643
639644 resourceTok := fmt .Sprintf (`%s:%s:%s` , g .pkg .Name , module , resource .typeName )
640- if ! g .versioning .ShouldInclude (prov , g .apiVersion , resource .typeName , resourceTok ) {
645+ if ! g .versioning .ShouldInclude (g . provider , g .apiVersion , resource .typeName , resourceTok ) {
641646 return nil
642647 }
643648
@@ -646,7 +651,7 @@ func (g *packageGenerator) genResourceVariant(prov string, apiSpec *openapi.Reso
646651 pkg : g .pkg ,
647652 metadata : g .metadata ,
648653 module : module ,
649- prov : prov ,
654+ prov : g . provider ,
650655 resourceName : resource .typeName ,
651656 resourceToken : resourceTok ,
652657 visitedTypes : make (map [string ]bool ),
@@ -702,21 +707,21 @@ func (g *packageGenerator) genResourceVariant(prov string, apiSpec *openapi.Reso
702707
703708 resourceSpec := pschema.ResourceSpec {
704709 ObjectTypeSpec : pschema.ObjectTypeSpec {
705- Description : g .formatDescription (resourceResponse .description , swagger .Info , apiSpec , additionalDocs ),
710+ Description : g .formatDescription (resourceResponse .description , resource . typeName , swagger .Info . Version , apiSpec . PreviousVersion , additionalDocs ),
706711 Type : "object" ,
707712 Properties : resourceResponse .specs ,
708713 Required : resourceResponse .requiredSpecs .SortedValues (),
709714 },
710715 InputProperties : resourceRequest .specs ,
711716 RequiredInputs : resourceRequest .requiredSpecs .SortedValues (),
712- Aliases : g .generateAliases (prov , resource , typeNameAliases ... ),
717+ Aliases : g .generateAliases (resource , typeNameAliases ... ),
713718 DeprecationMessage : resource .deprecationMessage ,
714719 }
715720 g .pkg .Resources [resourceTok ] = resourceSpec
716721
717722 // Generate the function to get this resource.
718723 functionTok := fmt .Sprintf (`%s:%s:get%s` , g .pkg .Name , module , resource .typeName )
719- if g .versioning .ShouldInclude (prov , g .apiVersion , resource .typeName , functionTok ) {
724+ if g .versioning .ShouldInclude (g . provider , g .apiVersion , resource .typeName , functionTok ) {
720725 var readOp * spec.Operation
721726 switch {
722727 case resource .PathItemList != nil :
@@ -743,7 +748,7 @@ func (g *packageGenerator) genResourceVariant(prov string, apiSpec *openapi.Reso
743748
744749 if path .Get != nil && responseFunction != nil {
745750 functionSpec := pschema.FunctionSpec {
746- Description : g .formatFunctionDescription (readOp , resourceResponse , swagger .Info ),
751+ Description : g .formatFunctionDescription (readOp , resource . typeName , resourceResponse , swagger .Info ),
747752 DeprecationMessage : resource .deprecationMessage ,
748753 Inputs : & pschema.ObjectTypeSpec {
749754 Description : requestFunction .description ,
@@ -801,19 +806,19 @@ func (g *packageGenerator) genResourceVariant(prov string, apiSpec *openapi.Reso
801806 return nil
802807}
803808
804- func (g * packageGenerator ) generateAliases (prov string , resource * resourceVariant , typeNameAliases ... string ) []pschema.AliasSpec {
809+ func (g * packageGenerator ) generateAliases (resource * resourceVariant , typeNameAliases ... string ) []pschema.AliasSpec {
805810 var aliases []pschema.AliasSpec
806811
807812 for _ , alias := range typeNameAliases {
808- aliases = append (aliases , g .makeTypeAlias (prov , alias , g .apiVersion ))
813+ aliases = append (aliases , g .makeTypeAlias (alias , g .apiVersion ))
809814 }
810815
811816 // Add an alias for each API version that has the same path in it.
812817 for _ , version := range resource .CompatibleVersions {
813- aliases = append (aliases , g .makeTypeAlias (prov , resource .typeName , version ))
818+ aliases = append (aliases , g .makeTypeAlias (resource .typeName , version ))
814819
815820 for _ , alias := range typeNameAliases {
816- aliases = append (aliases , g .makeTypeAlias (prov , alias , version ))
821+ aliases = append (aliases , g .makeTypeAlias (alias , version ))
817822 }
818823 }
819824
@@ -877,23 +882,23 @@ func (g *packageGenerator) generateExampleReferences(resourceTok string, path *s
877882
878883// genPostFunctions defines functions for list* (listKeys, listSecrets, etc.)
879884// and get* (getFullUrl, getBastionShareableLink, etc.) POST endpoints.
880- func (g * packageGenerator ) genPostFunctions (prov , typeName , path string , pathItem * spec.PathItem , swagger * openapi.Spec ) {
881- module := g .providerToModule ( prov )
885+ func (g * packageGenerator ) genPostFunctions (typeName , path string , pathItem * spec.PathItem , swagger * openapi.Spec ) {
886+ module := g .moduleName ( )
882887 gen := moduleGenerator {
883888 pkg : g .pkg ,
884889 metadata : g .metadata ,
885890 module : module ,
886891 resourceToken : fmt .Sprintf (`%s:%s:%s` , g .pkg .Name , module , typeName ),
887- prov : prov ,
892+ prov : g . provider ,
888893 resourceName : typeName ,
889894 visitedTypes : make (map [string ]bool ),
890895 caseSensitiveTypes : g .caseSensitiveTypes ,
891896 inlineTypes : map [* openapi.ReferenceContext ]codegen.StringSet {},
892897 }
893898
894899 // Generate the function to get this resource.
895- functionTok := fmt . Sprintf ( `%s:%s:%s` , g .pkg . Name , module , typeName )
896- if ! g .versioning . ShouldInclude ( prov , g .apiVersion , typeName , functionTok ) {
900+ functionTok := g . generateTok ( typeName , g .apiVersion )
901+ if ! g .shouldInclude ( typeName , functionTok , g .apiVersion ) {
897902 return
898903 }
899904
@@ -915,7 +920,7 @@ func (g *packageGenerator) genPostFunctions(prov, typeName, path string, pathIte
915920 }
916921
917922 functionSpec := pschema.FunctionSpec {
918- Description : g .formatFunctionDescription (pathItem .Post , response , swagger .Info ),
923+ Description : g .formatFunctionDescription (pathItem .Post , typeName , response , swagger .Info ),
919924 Inputs : & pschema.ObjectTypeSpec {
920925 Description : request .description ,
921926 Type : "object" ,
@@ -940,37 +945,68 @@ func (g *packageGenerator) genPostFunctions(prov, typeName, path string, pathIte
940945 g .metadata .Invokes [functionTok ] = f
941946}
942947
943- // providerToModule produces the module name from the provider name and the API version (e.g. (`Compute`, `2020-07-01` => `compute/v20200701`).
944- func (g * packageGenerator ) providerToModule ( prov string ) string {
945- return providerApiToModule (prov , g .apiVersion )
948+ // moduleName produces the module name from the provider name and the API version (e.g. (`Compute`, `2020-07-01` => `compute/v20200701`).
949+ func (g * packageGenerator ) moduleName ( ) string {
950+ return g . providerApiToModule (g .apiVersion )
946951}
947- func providerApiToModule (prov , apiVersion string ) string {
952+
953+ func (g * packageGenerator ) providerApiToModule (apiVersion string ) string {
948954 if apiVersion == "" {
949- return strings .ToLower (prov )
955+ return strings .ToLower (g . provider )
950956 }
951- return fmt .Sprintf ("%s/%s" , strings .ToLower (prov ), apiVersion )
957+ return fmt .Sprintf ("%s/%s" , strings .ToLower (g .provider ), apiVersion )
958+ }
959+
960+ func (g * packageGenerator ) generateTok (typeName string , apiVersion string ) string {
961+ return fmt .Sprintf (`%s:%s:%s` , g .pkg .Name , g .providerApiToModule (apiVersion ), typeName )
962+ }
963+
964+ func (g * packageGenerator ) shouldInclude (typeName , tok , version string ) bool {
965+ return g .versioning .ShouldInclude (g .provider , version , typeName , tok )
952966}
953967
954- func (g * packageGenerator ) formatFunctionDescription (op * spec.Operation , response * propertyBag , info * spec.Info ) string {
968+ func (g * packageGenerator ) formatFunctionDescription (op * spec.Operation , typeName string , response * propertyBag , info * spec.Info ) string {
955969 desc := response .description
956970 if op .Description != "" {
957971 desc = op .Description
958972 }
959- return g .formatDescription (desc , info , nil , nil )
973+ return g .formatDescription (desc , typeName , info . Version , "" , nil )
960974}
961975
962- func (g * packageGenerator ) formatDescription (desc string , info * spec.Info , resourceSpec * openapi.ResourceSpec , additionalDocs * string ) string {
963- description := desc
976+ func (g * packageGenerator ) formatDescription (desc string , typeName string , defaultVersion , previousDefaultVersion string , additionalDocs * string ) string {
977+ var b strings.Builder
978+ b .WriteString (desc )
979+
964980 if g .apiVersion == "" {
965- description = fmt .Sprintf ("%s\n Azure REST API version: %s." , description , info .Version )
966- }
967- if resourceSpec != nil && resourceSpec .PreviousVersion != "" {
968- description = fmt .Sprintf ("%s Prior API version in Azure Native 1.x: %s" , description , resourceSpec .PreviousVersion )
981+ fmt .Fprintf (& b , "\n Azure REST API version: %s." , defaultVersion )
982+ if previousDefaultVersion != "" {
983+ fmt .Fprintf (& b , " Prior API version in Azure Native 1.x: %s." , previousDefaultVersion )
984+ }
985+
986+ // List other available API versions, if any.
987+ allVersions := g .versioning .GetAllVersions (g .provider , typeName )
988+ includedVersions := []openapi.ApiVersion {}
989+ for _ , v := range allVersions {
990+ // Don't list the default version twice.
991+ if v == defaultVersion {
992+ continue
993+ }
994+ tok := g .generateTok (typeName , openapi .ApiToSdkVersion (v ))
995+ if g .shouldInclude (typeName , tok , v ) {
996+ includedVersions = append (includedVersions , v )
997+ }
998+ }
999+
1000+ if len (includedVersions ) > 0 {
1001+ fmt .Fprintf (& b , "\n \n Other available API versions: %s." , strings .Join (includedVersions , ", " ))
1002+ }
9691003 }
1004+
9701005 if additionalDocs != nil {
971- description = fmt .Sprintf ( "%s \n \n %s", description , * additionalDocs )
1006+ fmt .Fprintf ( & b , " \n \n %s" , * additionalDocs )
9721007 }
973- return description
1008+
1009+ return b .String ()
9741010}
9751011
9761012func (g * packageGenerator ) getAsyncStyle (op * spec.Operation ) string {
0 commit comments