github.com/qiniu/go-sdk/v7@v7.27.0/internal/api-generator/client.go (about)

     1  package main
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/dave/jennifer/jen"
     7  	"github.com/iancoleman/strcase"
     8  )
     9  
    10  type (
    11  	ApiDetailedDescription struct {
    12  		CamelCaseName string                 `yaml:"camel_case_name,omitempty"`
    13  		SnakeCaseName string                 `yaml:"snake_case_name,omitempty"`
    14  		Method        MethodName             `yaml:"method,omitempty"`
    15  		ServiceNames  []ServiceName          `yaml:"service_names,omitempty"`
    16  		Documentation string                 `yaml:"documentation,omitempty"`
    17  		Command       string                 `yaml:"command,omitempty"`
    18  		BasePath      string                 `yaml:"base_path,omitempty"`
    19  		PathSuffix    string                 `yaml:"path_suffix,omitempty"`
    20  		Request       ApiRequestDescription  `yaml:"request,omitempty"`
    21  		Response      ApiResponseDescription `yaml:"response,omitempty"`
    22  	}
    23  
    24  	CodeGeneratorOptions struct {
    25  		Name, Documentation          string
    26  		CamelCaseName, SnakeCaseName string
    27  		apiDetailedDescription       *ApiDetailedDescription
    28  	}
    29  )
    30  
    31  func (options *CodeGeneratorOptions) camelCaseName() string {
    32  	if options.CamelCaseName != "" {
    33  		return options.CamelCaseName
    34  	}
    35  	return strcase.ToCamel(options.Name)
    36  }
    37  
    38  func (description *ApiDetailedDescription) generateSubPackages(group *jen.Group, _ CodeGeneratorOptions) (err error) {
    39  	if body := description.Response.Body; body != nil {
    40  		if bodyJson := body.Json; bodyJson != nil && bodyJson.Any {
    41  			description.Request.responseTypeRequired = true
    42  		}
    43  	}
    44  	if err = description.Request.generate(group, CodeGeneratorOptions{
    45  		Name:                   "Request",
    46  		Documentation:          "调用 API 所用的请求",
    47  		apiDetailedDescription: description,
    48  	}); err != nil {
    49  		return
    50  	}
    51  	if err = description.Response.generate(group, CodeGeneratorOptions{
    52  		Name:                   "Response",
    53  		Documentation:          "获取 API 所用的响应",
    54  		apiDetailedDescription: description,
    55  	}); err != nil {
    56  		return
    57  	}
    58  	return
    59  }
    60  
    61  func (description *ApiDetailedDescription) generatePackage(group *jen.Group, options CodeGeneratorOptions) (err error) {
    62  	packageName := flags.ApiPackagePath + "/" + options.Name
    63  	innerStructName := "inner" + options.camelCaseName() + "Request"
    64  	reexportedRequestStructName := options.camelCaseName() + "Request"
    65  	reexportedResponseStructName := options.camelCaseName() + "Response"
    66  	group.Add(jen.Type().Id(innerStructName).Qual(packageName, "Request"))
    67  	var getBucketNameGenerated, getObjectNameGenerated bool
    68  	if getBucketNameGenerated, err = description.generateGetBucketNameFunc(group, innerStructName); err != nil {
    69  		return
    70  	} else if getObjectNameGenerated, err = description.generateGetObjectNameFunc(group, innerStructName); err != nil {
    71  		return
    72  	} else if err = description.generateBuildFunc(group, innerStructName); err != nil {
    73  		return
    74  	}
    75  	if body := description.Request.Body; body != nil && body.Json != nil {
    76  		if err = description.addJsonMarshalerUnmarshaler(group, innerStructName, packageName, "Request"); err != nil {
    77  			return
    78  		}
    79  	}
    80  	if isStorageAPIs() && !description.isBucketService() {
    81  		if err = description.Request.generateGetAccessKeyFunc(group, innerStructName); err != nil {
    82  			return
    83  		}
    84  	}
    85  	group.Add(jen.Type().Id(reexportedRequestStructName).Op("=").Qual(packageName, "Request"))
    86  	group.Add(jen.Type().Id(reexportedResponseStructName).Op("=").Qual(packageName, "Response"))
    87  	if options.Documentation != "" {
    88  		group.Add(jen.Comment(options.Documentation))
    89  	}
    90  
    91  	structName := strcase.ToCamel(flags.StructName)
    92  	fieldName := strcase.ToLowerCamel(structName)
    93  
    94  	group.Add(
    95  		jen.Func().
    96  			Params(jen.Id(fieldName).Op("*").Id(structName)).
    97  			Id(options.camelCaseName()).
    98  			Params(
    99  				jen.Id("ctx").Qual("context", "Context"),
   100  				jen.Id("request").Op("*").Id(reexportedRequestStructName),
   101  				jen.Id("options").Op("*").Id("Options"),
   102  			).
   103  			Params(
   104  				jen.Op("*").Id(reexportedResponseStructName),
   105  				jen.Error(),
   106  			).
   107  			BlockFunc(func(group *jen.Group) {
   108  				group.Add(jen.If(jen.Id("options").Op("==").Nil()).BlockFunc(func(group *jen.Group) {
   109  					group.Id("options").Op("=").Op("&").Id("Options").Values()
   110  				}))
   111  				group.Add(jen.Id("innerRequest").Op(":=").Parens(jen.Op("*").Id(innerStructName)).Parens(jen.Id("request")))
   112  				group.Add(
   113  					jen.Id("serviceNames").
   114  						Op(":=").
   115  						Index().
   116  						Qual(PackageNameRegion, "ServiceName").
   117  						ValuesFunc(func(group *jen.Group) {
   118  							for _, serviceName := range description.ServiceNames {
   119  								if code, e := serviceName.ToServiceName(); e != nil {
   120  									err = e
   121  									return
   122  								} else {
   123  									group.Add(code)
   124  								}
   125  							}
   126  						}),
   127  				)
   128  				switch description.Request.Authorization.ToAuthorization() {
   129  				case AuthorizationQbox, AuthorizationQiniu:
   130  					group.Add(jen.If(
   131  						jen.Id("innerRequest").Dot("Credentials").Op("==").Nil().Op("&&").
   132  							Id(fieldName).Dot("client").Dot("GetCredentials").Call().Op("==").Nil()).
   133  						BlockFunc(func(group *jen.Group) {
   134  							group.Add(jen.Return(
   135  								jen.Nil(),
   136  								jen.Qual(PackageNameErrors, "MissingRequiredFieldError").
   137  									ValuesFunc(func(group *jen.Group) {
   138  										group.Add(jen.Id("Name").Op(":").Lit("Credentials"))
   139  									}),
   140  							))
   141  						}))
   142  				case AuthorizationUpToken:
   143  					group.Add(jen.If(jen.Id("innerRequest").Dot("UpToken").Op("==").Nil()).
   144  						BlockFunc(func(group *jen.Group) {
   145  							group.Add(jen.Return(
   146  								jen.Nil(),
   147  								jen.Qual(PackageNameErrors, "MissingRequiredFieldError").
   148  									ValuesFunc(func(group *jen.Group) {
   149  										group.Add(jen.Id("Name").Op(":").Lit("UpToken"))
   150  									}),
   151  							))
   152  						}))
   153  				}
   154  				guessPathSegmentsCount := 0
   155  				if description.BasePath != "" {
   156  					guessPathSegmentsCount += len(description.getBasePathSegments())
   157  				}
   158  				if description.PathSuffix != "" {
   159  					guessPathSegmentsCount += len(description.getPathSuffixSegments())
   160  				}
   161  				if pp := description.Request.PathParams; pp != nil {
   162  					for _, namedPathParam := range pp.Named {
   163  						guessPathSegmentsCount += 1
   164  						if namedPathParam.PathSegment != "" {
   165  							guessPathSegmentsCount += 1
   166  						}
   167  					}
   168  				}
   169  				if guessPathSegmentsCount > 0 {
   170  					group.Add(jen.Id("pathSegments").Op(":=").Make(jen.Index().String(), jen.Lit(0), jen.Lit(guessPathSegmentsCount)))
   171  				} else {
   172  					group.Add(jen.Id("pathSegments").Op(":=").Make(jen.Index().String(), jen.Lit(0)))
   173  				}
   174  				if description.BasePath != "" {
   175  					if basePathSegments := description.getBasePathSegments(); len(basePathSegments) > 0 {
   176  						group.Add(jen.Id("pathSegments").Op("=").AppendFunc(func(group *jen.Group) {
   177  							group.Add(jen.Id("pathSegments"))
   178  							for _, pathSegment := range basePathSegments {
   179  								group.Add(jen.Lit(pathSegment))
   180  							}
   181  						}))
   182  					}
   183  				}
   184  				if description.Request.PathParams != nil {
   185  					group.Add(
   186  						jen.If(
   187  							jen.List(jen.Id("segments"), jen.Err()).
   188  								Op(":=").
   189  								Id("innerRequest").
   190  								Dot("buildPath").
   191  								Call(),
   192  							jen.Err().Op("!=").Nil(),
   193  						).BlockFunc(func(group *jen.Group) {
   194  							group.Add(jen.Return(jen.Nil(), jen.Err()))
   195  						}).Else().BlockFunc(func(group *jen.Group) {
   196  							group.Add(jen.Id("pathSegments").Op("=").Append(
   197  								jen.Id("pathSegments"),
   198  								jen.Id("segments").Op("..."),
   199  							))
   200  						}),
   201  					)
   202  				}
   203  				if description.PathSuffix != "" {
   204  					if suffixSegments := description.getPathSuffixSegments(); len(suffixSegments) > 0 {
   205  						group.Add(jen.Id("pathSegments").Op("=").AppendFunc(func(group *jen.Group) {
   206  							group.Add(jen.Id("pathSegments"))
   207  							for _, pathSegment := range suffixSegments {
   208  								group.Add(jen.Lit(pathSegment))
   209  							}
   210  						}))
   211  					}
   212  				}
   213  				group.Add(jen.Id("path").Op(":=").Lit("/").Op("+").Qual("strings", "Join").Call(jen.Id("pathSegments"), jen.Lit("/")))
   214  				if description.PathSuffix == "/" {
   215  					group.Add(jen.Id("path").Op("+=").Lit("/"))
   216  				}
   217  				if description.Command != "" {
   218  					group.Add(jen.Id("rawQuery").Op(":=").Lit(description.Command + "&"))
   219  				} else {
   220  					group.Add(jen.Var().Id("rawQuery").String())
   221  				}
   222  				if description.Request.QueryNames != nil {
   223  					group.Add(
   224  						jen.If(
   225  							jen.List(jen.Id("query"), jen.Err()).Op(":=").Id("innerRequest").Dot("buildQuery").Call(),
   226  							jen.Err().Op("!=").Nil(),
   227  						).BlockFunc(func(group *jen.Group) {
   228  							group.Add(jen.Return(jen.Nil(), jen.Err()))
   229  						}).Else().BlockFunc(func(group *jen.Group) {
   230  							group.Id("rawQuery").Op("+=").Id("query").Dot("Encode").Call()
   231  						}),
   232  					)
   233  				}
   234  				if description.Request.HeaderNames != nil {
   235  					group.Add(
   236  						jen.List(jen.Id("headers"), jen.Err()).Op(":=").Id("innerRequest").Dot("buildHeaders").Call(),
   237  					)
   238  					group.Add(
   239  						jen.If(
   240  							jen.Err().Op("!=").Nil(),
   241  						).BlockFunc(func(group *jen.Group) {
   242  							group.Add(jen.Return(jen.Nil(), jen.Err()))
   243  						}),
   244  					)
   245  				} else {
   246  					group.Add(
   247  						jen.Id("headers").Op(":=").Qual("net/http", "Header").Values(jen.Dict{}),
   248  					)
   249  				}
   250  				if requestBody := description.Request.Body; requestBody != nil {
   251  					if json := requestBody.Json; json != nil {
   252  						group.Add(
   253  							jen.List(jen.Id("body"), jen.Err()).
   254  								Op(":=").
   255  								Qual(PackageNameHTTPClient, "GetJsonRequestBody").
   256  								Call(jen.Op("&").Id("innerRequest")),
   257  						)
   258  						group.Add(
   259  							jen.If(jen.Err().Op("!=").Nil()).
   260  								BlockFunc(func(group *jen.Group) {
   261  									group.Add(jen.Return(jen.Nil(), jen.Err()))
   262  								}),
   263  						)
   264  					} else if multipartForm := requestBody.MultipartFormData; multipartForm != nil {
   265  						group.Add(
   266  							jen.List(jen.Id("body"), jen.Err()).
   267  								Op(":=").
   268  								Id("innerRequest").
   269  								Dot("build").
   270  								Call(jen.Id("ctx")),
   271  						)
   272  						group.Add(
   273  							jen.If(jen.Err().Op("!=").Nil()).
   274  								BlockFunc(func(group *jen.Group) {
   275  									group.Add(jen.Return(jen.Nil(), jen.Err()))
   276  								}),
   277  						)
   278  					} else if form := requestBody.FormUrlencoded; form != nil {
   279  						group.Add(
   280  							jen.List(jen.Id("body"), jen.Err()).
   281  								Op(":=").
   282  								Id("innerRequest").
   283  								Dot("build").
   284  								Call(),
   285  						)
   286  						group.Add(
   287  							jen.If(jen.Err().Op("!=").Nil()).
   288  								BlockFunc(func(group *jen.Group) {
   289  									group.Add(jen.Return(jen.Nil(), jen.Err()))
   290  								}),
   291  						)
   292  					} else if requestBody.BinaryData {
   293  						group.Add(
   294  							jen.Id("body").Op(":=").Id("innerRequest").Dot("Body"),
   295  						)
   296  						group.Add(
   297  							jen.If(jen.Id("body").Op("==").Nil()).
   298  								BlockFunc(func(group *jen.Group) {
   299  									group.Add(jen.Return(
   300  										jen.Nil(),
   301  										jen.Qual(PackageNameErrors, "MissingRequiredFieldError").
   302  											ValuesFunc(func(group *jen.Group) {
   303  												group.Add(jen.Id("Name").Op(":").Lit("Body"))
   304  											}),
   305  									))
   306  								}),
   307  						)
   308  						group.Add(
   309  							jen.Id("hErr").Op(":=").Qual(PackageNameUtils, "HttpHeadAddContentLength").Call(jen.Id("headers"), jen.Id("body")),
   310  						)
   311  						group.Add(
   312  							jen.If(
   313  								jen.Id("hErr").Op("!=").Nil(),
   314  							).Block(
   315  								jen.Return(jen.Nil(), jen.Id("hErr")),
   316  							),
   317  						)
   318  					}
   319  				}
   320  				if isStorageAPIs() {
   321  					group.Add(jen.Id("bucketName").Op(":=").Id("options").Dot("OverwrittenBucketName"))
   322  					if getBucketNameGenerated {
   323  						group.Add(
   324  							jen.If(jen.Id("bucketName").Op("==").Lit("")).BlockFunc(func(group *jen.Group) {
   325  								group.Add(jen.Var().Id("err").Error())
   326  								group.Add(
   327  									jen.If(
   328  										jen.List(jen.Id("bucketName"), jen.Err()).Op("=").Id("innerRequest").Dot("getBucketName").Call(jen.Id("ctx")),
   329  										jen.Err().Op("!=").Nil(),
   330  									).BlockFunc(func(group *jen.Group) {
   331  										group.Return(jen.Nil(), jen.Err())
   332  									}),
   333  								)
   334  							}),
   335  						)
   336  					}
   337  				}
   338  				if isStorageAPIs() && getObjectNameGenerated {
   339  					group.Add(jen.Id("objectName").Op(":=").Id("innerRequest").Dot("getObjectName").Call())
   340  				}
   341  
   342  				var (
   343  					bucketNameVar jen.Code = jen.Lit("")
   344  					objectNameVar jen.Code = jen.Lit("")
   345  				)
   346  				if isStorageAPIs() {
   347  					bucketNameVar = jen.Id("bucketName")
   348  					if getObjectNameGenerated {
   349  						objectNameVar = jen.Id("objectName")
   350  					}
   351  				}
   352  
   353  				var getUpTokenFunc jen.Code
   354  				switch description.Request.Authorization.ToAuthorization() {
   355  				case AuthorizationQbox, AuthorizationQiniu:
   356  					getUpTokenFunc = jen.Func().Params().Params(jen.String(), jen.Error()).BlockFunc(func(group *jen.Group) {
   357  						group.Add(
   358  							jen.Id("credentials").
   359  								Op(":=").
   360  								Id("innerRequest").
   361  								Dot("Credentials"))
   362  						group.Add(jen.If(jen.Id("credentials").Op("==").Nil()).BlockFunc(func(group *jen.Group) {
   363  							group.Add(
   364  								jen.Id("credentials").
   365  									Op("=").
   366  									Id(fieldName).
   367  									Dot("client").
   368  									Dot("GetCredentials").
   369  									Call())
   370  						}))
   371  						group.Add(
   372  							jen.List(jen.Id("putPolicy"), jen.Err()).
   373  								Op(":=").
   374  								Qual(PackageNameUpToken, "NewPutPolicy").
   375  								Call(bucketNameVar, jen.Qual("time", "Now").Call().Dot("Add").Call(jen.Qual("time", "Hour"))))
   376  						group.Add(jen.If(jen.Err().Op("!=").Nil()).BlockFunc(func(group *jen.Group) {
   377  							group.Return(jen.List(jen.Lit(""), jen.Err()))
   378  						}))
   379  						group.Add(
   380  							jen.Return(
   381  								jen.Qual(PackageNameUpToken, "NewSigner").Call(jen.Id("putPolicy"), jen.Id("credentials")).Dot("GetUpToken").Call(jen.Id("ctx"))))
   382  					})
   383  				case AuthorizationUpToken:
   384  					getUpTokenFunc = jen.Func().Params().Params(jen.String(), jen.Error()).BlockFunc(func(group *jen.Group) {
   385  						group.Return(jen.Id("innerRequest").Dot("UpToken").Dot("GetUpToken").Call(jen.Id("ctx")))
   386  					})
   387  				case AuthorizationNone:
   388  					getUpTokenFunc = jen.Nil()
   389  				}
   390  
   391  				group.Add(
   392  					jen.List(jen.Id("uplogInterceptor"), jen.Err()).
   393  						Op(":=").
   394  						Qual(PackageNameUplog, "NewRequestUplog").Call(
   395  						jen.Lit(strcase.ToLowerCamel(options.camelCaseName())),
   396  						bucketNameVar,
   397  						objectNameVar,
   398  						getUpTokenFunc,
   399  					),
   400  				)
   401  				group.Add(jen.If(jen.Err().Op("!=").Nil()).BlockFunc(func(group *jen.Group) {
   402  					group.Return(jen.Nil(), jen.Err())
   403  				}))
   404  
   405  				var method string
   406  				method, err = description.Method.ToString()
   407  				if err != nil {
   408  					return
   409  				}
   410  				group.Add(
   411  					jen.Id("req").
   412  						Op(":=").
   413  						Qual(PackageNameHTTPClient, "Request").
   414  						ValuesFunc(func(group *jen.Group) {
   415  							group.Add(jen.Id("Method").Op(":").Lit(method))
   416  							group.Add(jen.Id("ServiceNames").Op(":").Id("serviceNames"))
   417  							group.Add(jen.Id("Path").Op(":").Id("path"))
   418  							group.Add(jen.Id("RawQuery").Op(":").Id("rawQuery"))
   419  							group.Add(jen.Id("Endpoints").Op(":").Id("options").Dot("OverwrittenEndpoints"))
   420  							group.Add(jen.Id("Region").Op(":").Id("options").Dot("OverwrittenRegion"))
   421  							group.Add(jen.Id("Interceptors").Op(":").Index().Qual(PackageNameHTTPClient, "Interceptor").Values(jen.Id("uplogInterceptor")))
   422  							group.Add(jen.Id("Header").Op(":").Id("headers"))
   423  							switch description.Request.Authorization.ToAuthorization() {
   424  							case AuthorizationQbox:
   425  								group.Add(jen.Id("AuthType").Op(":").Qual(PackageNameAuth, "TokenQBox"))
   426  								group.Add(jen.Id("Credentials").Op(":").Id("innerRequest").Dot("Credentials"))
   427  							case AuthorizationQiniu:
   428  								group.Add(jen.Id("AuthType").Op(":").Qual(PackageNameAuth, "TokenQiniu"))
   429  								group.Add(jen.Id("Credentials").Op(":").Id("innerRequest").Dot("Credentials"))
   430  							case AuthorizationUpToken:
   431  								group.Add(jen.Id("UpToken").Op(":").Id("innerRequest").Dot("UpToken"))
   432  							}
   433  							if body := description.Response.Body; body != nil {
   434  								if json := body.Json; json != nil {
   435  									group.Add(jen.Id("BufferResponse").Op(":").True())
   436  								}
   437  							}
   438  							if requestBody := description.Request.Body; requestBody != nil {
   439  								if json := requestBody.Json; json != nil {
   440  									group.Add(jen.Id("RequestBody").Op(":").Id("body"))
   441  								} else if formUrlencoded := requestBody.FormUrlencoded; formUrlencoded != nil {
   442  									group.Add(
   443  										jen.Id("RequestBody").
   444  											Op(":").
   445  											Qual(PackageNameHTTPClient, "GetFormRequestBody").
   446  											Call(jen.Id("body")),
   447  									)
   448  								} else if multipartFormData := requestBody.MultipartFormData; multipartFormData != nil {
   449  									group.Add(
   450  										jen.Id("RequestBody").
   451  											Op(":").
   452  											Qual(PackageNameHTTPClient, "GetMultipartFormRequestBody").
   453  											Call(jen.Id("body")),
   454  									)
   455  								} else if requestBody.BinaryData {
   456  									group.Add(
   457  										jen.Id("RequestBody").
   458  											Op(":").
   459  											Qual(PackageNameHTTPClient, "GetRequestBodyFromReadSeekCloser").
   460  											Call(jen.Id("body")),
   461  									)
   462  								}
   463  							}
   464  							group.Add(jen.Id("OnRequestProgress").Op(":").Id("options").Dot("OnRequestProgress"))
   465  						}),
   466  				)
   467  				group.Add(
   468  					jen.If(
   469  						jen.Id("options").Dot("OverwrittenEndpoints").Op("==").Nil().Op("&&").
   470  							Id("options").Dot("OverwrittenRegion").Op("==").Nil().Op("&&").
   471  							Id(fieldName).Dot("client").Dot("GetRegions").Call().Op("==").Nil()).
   472  						BlockFunc(func(group *jen.Group) {
   473  							group.Add(jen.Id("bucketHosts").Op(":=").Qual(PackageNameHTTPClient, "DefaultBucketHosts").Call())
   474  							if description.isBucketService() {
   475  								group.Add(
   476  									jen.If(jen.Id("options").Dot("OverwrittenBucketHosts").Op("!=").Nil()).
   477  										BlockFunc(func(group *jen.Group) {
   478  											group.Add(jen.Id("req").Dot("Endpoints").Op("=").Id("options").Dot("OverwrittenBucketHosts"))
   479  										}).
   480  										Else().
   481  										BlockFunc(func(group *jen.Group) {
   482  											group.Add(jen.Id("req").Dot("Endpoints").Op("=").Id("bucketHosts"))
   483  										}),
   484  								)
   485  							} else {
   486  								ifBucketIsNotEmptyStmt := jen.If(jen.Id("bucketName").Op("!=").Lit("")).BlockFunc(func(group *jen.Group) {
   487  									group.Add(jen.Id("query").Op(":=").Id(fieldName).Dot("client").Dot("GetBucketQuery").Call())
   488  									group.Add(
   489  										jen.If(jen.Id("query").Op("==").Nil()).BlockFunc(func(group *jen.Group) {
   490  											group.Add(
   491  												jen.If(jen.Id("options").Dot("OverwrittenBucketHosts").Op("!=").Nil()).BlockFunc(func(group *jen.Group) {
   492  													group.Add(
   493  														jen.If(
   494  															jen.List(jen.Id("bucketHosts"), jen.Err()).
   495  																Op("=").
   496  																Id("options").
   497  																Dot("OverwrittenBucketHosts").
   498  																Dot("GetEndpoints").
   499  																Call(jen.Id("ctx")),
   500  															jen.Err().Op("!=").Nil(),
   501  														).BlockFunc(func(group *jen.Group) {
   502  															group.Add(jen.Return(jen.Nil(), jen.Err()))
   503  														}),
   504  													)
   505  												}),
   506  											)
   507  											group.Add(
   508  												jen.Id("queryOptions").
   509  													Op(":=").
   510  													Qual(PackageNameRegion, "BucketRegionsQueryOptions").
   511  													ValuesFunc(func(group *jen.Group) {
   512  														group.Add(jen.Id("UseInsecureProtocol").Op(":").Id(fieldName).Dot("client").Dot("UseInsecureProtocol").Call())
   513  														group.Add(jen.Id("AccelerateUploading").Op(":").Id(fieldName).Dot("client").Dot("AccelerateUploadingEnabled").Call())
   514  														group.Add(jen.Id("HostFreezeDuration").Op(":").Id(fieldName).Dot("client").Dot("GetHostFreezeDuration").Call())
   515  														group.Add(jen.Id("Resolver").Op(":").Id(fieldName).Dot("client").Dot("GetResolver").Call())
   516  														group.Add(jen.Id("Chooser").Op(":").Id(fieldName).Dot("client").Dot("GetChooser").Call())
   517  														group.Add(jen.Id("BeforeResolve").Op(":").Id(fieldName).Dot("client").Dot("GetBeforeResolveCallback").Call())
   518  														group.Add(jen.Id("AfterResolve").Op(":").Id(fieldName).Dot("client").Dot("GetAfterResolveCallback").Call())
   519  														group.Add(jen.Id("ResolveError").Op(":").Id(fieldName).Dot("client").Dot("GetResolveErrorCallback").Call())
   520  														group.Add(jen.Id("BeforeBackoff").Op(":").Id(fieldName).Dot("client").Dot("GetBeforeBackoffCallback").Call())
   521  														group.Add(jen.Id("AfterBackoff").Op(":").Id(fieldName).Dot("client").Dot("GetAfterBackoffCallback").Call())
   522  														group.Add(jen.Id("BeforeRequest").Op(":").Id(fieldName).Dot("client").Dot("GetBeforeRequestCallback").Call())
   523  														group.Add(jen.Id("AfterResponse").Op(":").Id(fieldName).Dot("client").Dot("GetAfterResponseCallback").Call())
   524  													}),
   525  											)
   526  											group.Add(
   527  												jen.If(
   528  													jen.Id("hostRetryConfig").Op(":=").Id(fieldName).Dot("client").Dot("GetHostRetryConfig").Call(),
   529  													jen.Id("hostRetryConfig").Op("!=").Nil(),
   530  												).BlockFunc(func(group *jen.Group) {
   531  													group.Id("queryOptions").Dot("RetryMax").Op("=").Id("hostRetryConfig").Dot("RetryMax")
   532  													group.Id("queryOptions").Dot("Backoff").Op("=").Id("hostRetryConfig").Dot("Backoff")
   533  												}),
   534  											)
   535  											group.Add(
   536  												jen.If(
   537  													jen.List(jen.Id("query"), jen.Err()).
   538  														Op("=").
   539  														Qual(PackageNameRegion, "NewBucketRegionsQuery").
   540  														Call(jen.Id("bucketHosts"), jen.Op("&").Id("queryOptions")),
   541  													jen.Err().Op("!=").Nil(),
   542  												).BlockFunc(func(group *jen.Group) {
   543  													group.Add(jen.Return(jen.Nil(), jen.Err()))
   544  												}),
   545  											)
   546  										}),
   547  									)
   548  									group.Add(
   549  										jen.If(jen.Id("query").Op("!=").Nil()).BlockFunc(func(group *jen.Group) {
   550  											group.Add(jen.Var().Id("accessKey").String())
   551  											group.Add(jen.Var().Err().Error())
   552  											group.Add(
   553  												jen.If(
   554  													jen.List(jen.Id("accessKey"), jen.Err()).Op("=").Id("innerRequest").Dot("getAccessKey").Call(jen.Id("ctx")),
   555  													jen.Err().Op("!=").Nil(),
   556  												).BlockFunc(func(group *jen.Group) {
   557  													group.Return(jen.Nil(), jen.Err())
   558  												}),
   559  											)
   560  											group.Add(
   561  												jen.If(jen.Id("accessKey").Op("==").Lit("")).
   562  													BlockFunc(func(group *jen.Group) {
   563  														group.Add(jen.If(
   564  															jen.Id("credentialsProvider").Op(":=").Id(fieldName).Dot("client").Dot("GetCredentials").Call(),
   565  															jen.Id("credentialsProvider").Op("!=").Nil(),
   566  														).BlockFunc(func(group *jen.Group) {
   567  															group.If(
   568  																jen.List(jen.Id("creds"), jen.Err()).
   569  																	Op(":=").
   570  																	Id("credentialsProvider").
   571  																	Dot("Get").
   572  																	Call(jen.Id("ctx")),
   573  																jen.Err().Op("!=").Nil(),
   574  															).BlockFunc(func(group *jen.Group) {
   575  																group.Return(jen.Nil(), jen.Err())
   576  															}).Else().
   577  																If(jen.Id("creds").Op("!=").Nil()).
   578  																BlockFunc(func(group *jen.Group) {
   579  																	group.Id("accessKey").Op("=").Id("creds").Dot("AccessKey")
   580  																})
   581  														}))
   582  													}),
   583  											)
   584  											group.Add(
   585  												jen.If(jen.Id("accessKey").Op("!=").Lit("")).
   586  													BlockFunc(func(group *jen.Group) {
   587  														group.Id("req").Dot("Region").Op("=").Id("query").Dot("Query").Call(jen.Id("accessKey"), jen.Id("bucketName"))
   588  													}),
   589  											)
   590  										}),
   591  									)
   592  								})
   593  								ifBucketIsEmptyStmt := jen.CustomFunc(jen.Options{Multi: true}, func(group *jen.Group) {
   594  									group.Add(jen.Id("req").Dot("Region").Op("=").Id(fieldName).Dot("client").Dot("GetAllRegions").Call())
   595  									group.Add(
   596  										jen.If(jen.Id("req").Dot("Region").Op("==").Nil()).BlockFunc(func(group *jen.Group) {
   597  											group.Add(
   598  												jen.If(jen.Id("options").Dot("OverwrittenBucketHosts").Op("!=").Nil()).BlockFunc(func(group *jen.Group) {
   599  													group.Add(
   600  														jen.If(
   601  															jen.List(jen.Id("bucketHosts"), jen.Err()).
   602  																Op("=").
   603  																Id("options").
   604  																Dot("OverwrittenBucketHosts").
   605  																Dot("GetEndpoints").
   606  																Call(jen.Id("ctx")),
   607  															jen.Err().Op("!=").Nil(),
   608  														).BlockFunc(func(group *jen.Group) {
   609  															group.Add(jen.Return(jen.Nil(), jen.Err()))
   610  														}),
   611  													)
   612  												}),
   613  											)
   614  											group.Add(
   615  												jen.Id("allRegionsOptions").
   616  													Op(":=").
   617  													Qual(PackageNameRegion, "AllRegionsProviderOptions").
   618  													ValuesFunc(func(group *jen.Group) {
   619  														group.Add(jen.Id("UseInsecureProtocol").Op(":").Id(fieldName).Dot("client").Dot("UseInsecureProtocol").Call())
   620  														group.Add(jen.Id("HostFreezeDuration").Op(":").Id(fieldName).Dot("client").Dot("GetHostFreezeDuration").Call())
   621  														group.Add(jen.Id("Resolver").Op(":").Id(fieldName).Dot("client").Dot("GetResolver").Call())
   622  														group.Add(jen.Id("Chooser").Op(":").Id(fieldName).Dot("client").Dot("GetChooser").Call())
   623  														group.Add(jen.Id("BeforeSign").Op(":").Id(fieldName).Dot("client").Dot("GetBeforeSignCallback").Call())
   624  														group.Add(jen.Id("AfterSign").Op(":").Id(fieldName).Dot("client").Dot("GetAfterSignCallback").Call())
   625  														group.Add(jen.Id("SignError").Op(":").Id(fieldName).Dot("client").Dot("GetSignErrorCallback").Call())
   626  														group.Add(jen.Id("BeforeResolve").Op(":").Id(fieldName).Dot("client").Dot("GetBeforeResolveCallback").Call())
   627  														group.Add(jen.Id("AfterResolve").Op(":").Id(fieldName).Dot("client").Dot("GetAfterResolveCallback").Call())
   628  														group.Add(jen.Id("ResolveError").Op(":").Id(fieldName).Dot("client").Dot("GetResolveErrorCallback").Call())
   629  														group.Add(jen.Id("BeforeBackoff").Op(":").Id(fieldName).Dot("client").Dot("GetBeforeBackoffCallback").Call())
   630  														group.Add(jen.Id("AfterBackoff").Op(":").Id(fieldName).Dot("client").Dot("GetAfterBackoffCallback").Call())
   631  														group.Add(jen.Id("BeforeRequest").Op(":").Id(fieldName).Dot("client").Dot("GetBeforeRequestCallback").Call())
   632  														group.Add(jen.Id("AfterResponse").Op(":").Id(fieldName).Dot("client").Dot("GetAfterResponseCallback").Call())
   633  													}),
   634  											)
   635  											group.Add(
   636  												jen.If(
   637  													jen.Id("hostRetryConfig").Op(":=").Id(fieldName).Dot("client").Dot("GetHostRetryConfig").Call(),
   638  													jen.Id("hostRetryConfig").Op("!=").Nil(),
   639  												).BlockFunc(func(group *jen.Group) {
   640  													group.Id("allRegionsOptions").Dot("RetryMax").Op("=").Id("hostRetryConfig").Dot("RetryMax")
   641  													group.Id("allRegionsOptions").Dot("Backoff").Op("=").Id("hostRetryConfig").Dot("Backoff")
   642  												}),
   643  											)
   644  											group.Add(jen.Id("credentials").Op(":=").Id("innerRequest").Dot("Credentials"))
   645  											group.Add(jen.If(jen.Id("credentials").Op("==").Nil()).BlockFunc(func(group *jen.Group) {
   646  												group.Add(jen.Id("credentials").Op("=").Id(fieldName).Dot("client").Dot("GetCredentials").Call())
   647  											}))
   648  											group.Add(
   649  												jen.If(
   650  													jen.List(jen.Id("req").Dot("Region"), jen.Err()).
   651  														Op("=").
   652  														Qual(PackageNameRegion, "NewAllRegionsProvider").
   653  														Call(jen.Id("credentials"), jen.Id("bucketHosts"), jen.Op("&").Id("allRegionsOptions")),
   654  													jen.Err().Op("!=").Nil(),
   655  												).BlockFunc(func(group *jen.Group) {
   656  													group.Add(jen.Return(jen.Nil(), jen.Err()))
   657  												}),
   658  											)
   659  										}),
   660  									)
   661  								})
   662  								if !isStorageAPIs() {
   663  									group.Add(ifBucketIsEmptyStmt)
   664  								} else if description.isApiService() {
   665  									group.Add(ifBucketIsNotEmptyStmt).Else().Block(ifBucketIsEmptyStmt)
   666  								} else {
   667  									group.Add(ifBucketIsNotEmptyStmt)
   668  								}
   669  							}
   670  						}),
   671  				)
   672  				if description.Request.Authorization.ToAuthorization() == AuthorizationNone {
   673  					group.Add(jen.Id("ctx").Op("=").Qual(PackageNameHTTPClient, "WithoutSignature").Call(jen.Id("ctx")))
   674  				}
   675  				if body := description.Response.Body; body != nil {
   676  					if json := body.Json; json != nil {
   677  						if description.Request.responseTypeRequired {
   678  							group.Add(jen.Id("respBody").Op(":=").Id(reexportedResponseStructName).Values(jen.Id("Body").Op(":").Id("innerRequest").Dot("ResponseBody")))
   679  						} else {
   680  							group.Add(jen.Var().Id("respBody").Id(reexportedResponseStructName))
   681  						}
   682  						group.Add(
   683  							jen.If(
   684  								jen.Err().
   685  									Op(":=").
   686  									Id(fieldName).
   687  									Dot("client").
   688  									Dot("DoAndAcceptJSON").
   689  									Call(
   690  										jen.Id("ctx"),
   691  										jen.Op("&").Id("req"),
   692  										jen.Op("&").Id("respBody"),
   693  									),
   694  								jen.Err().Op("!=").Nil(),
   695  							).BlockFunc(func(group *jen.Group) {
   696  								group.Return(jen.Nil(), jen.Err())
   697  							}),
   698  						)
   699  						group.Add(jen.Return(jen.Op("&").Id("respBody"), jen.Nil()))
   700  					} else if body.BinaryDataStream {
   701  						group.Add(
   702  							jen.List(jen.Id("resp"), jen.Err()).
   703  								Op(":=").
   704  								Id(fieldName).
   705  								Dot("client").
   706  								Dot("Do").
   707  								Call(
   708  									jen.Id("ctx"),
   709  									jen.Op("&").Id("req"),
   710  								),
   711  						)
   712  						group.Add(
   713  							jen.If(jen.Err().Op("!=").Nil()).
   714  								BlockFunc(func(group *jen.Group) {
   715  									group.Return(jen.Nil(), jen.Err())
   716  								}),
   717  						)
   718  						group.Add(
   719  							jen.Return(
   720  								jen.Op("&").
   721  									Id(reexportedResponseStructName).
   722  									Values(jen.Id("Body").
   723  										Op(":").
   724  										Id("resp").
   725  										Dot("Body")), jen.Nil(),
   726  							),
   727  						)
   728  					}
   729  				} else {
   730  					group.Add(
   731  						jen.List(jen.Id("resp"), jen.Err()).
   732  							Op(":=").
   733  							Id(fieldName).
   734  							Dot("client").
   735  							Dot("Do").
   736  							Call(
   737  								jen.Id("ctx"),
   738  								jen.Op("&").Id("req"),
   739  							),
   740  					)
   741  					group.Add(
   742  						jen.If(jen.Err().Op("!=").Nil()).
   743  							BlockFunc(func(group *jen.Group) {
   744  								group.Return(jen.Nil(), jen.Err())
   745  							}),
   746  					)
   747  					group.Add(jen.Return(jen.Op("&").Id(reexportedResponseStructName).Values(), jen.Id("resp").Dot("Body").Dot("Close").Call()))
   748  				}
   749  			}),
   750  	)
   751  	return
   752  }
   753  
   754  func (description *ApiDetailedDescription) generateGetBucketNameFunc(group *jen.Group, structName string) (ok bool, err error) {
   755  	if pp := description.Request.PathParams; pp != nil {
   756  		if ok, err = pp.addGetBucketNameFunc(group, structName); err != nil || ok {
   757  			return
   758  		}
   759  	}
   760  	if queryNames := description.Request.QueryNames; queryNames != nil {
   761  		if ok, err = queryNames.addGetBucketNameFunc(group, structName); err != nil || ok {
   762  			return
   763  		}
   764  	}
   765  	if headerNames := description.Request.HeaderNames; headerNames != nil {
   766  		if ok, err = headerNames.addGetBucketNameFunc(group, structName); err != nil || ok {
   767  			return
   768  		}
   769  	}
   770  	if authorization := description.Request.Authorization; authorization != nil {
   771  		if ok, err = authorization.addGetBucketNameFunc(group, structName); err != nil || ok {
   772  			return
   773  		}
   774  	}
   775  	if body := description.Request.Body; body != nil {
   776  		if json := body.Json; json != nil {
   777  			if jsonStruct := json.Struct; jsonStruct != nil {
   778  				if ok, err = jsonStruct.addGetBucketNameFunc(group, structName); err != nil || ok {
   779  					return
   780  				}
   781  			}
   782  		} else if formUrlencoded := body.FormUrlencoded; formUrlencoded != nil {
   783  			if ok, err = formUrlencoded.addGetBucketNameFunc(group, structName); err != nil || ok {
   784  				return
   785  			}
   786  		} else if multipartFormData := body.MultipartFormData; multipartFormData != nil {
   787  			if ok, err = multipartFormData.addGetBucketNameFunc(group, structName); err != nil || ok {
   788  				return
   789  			}
   790  		}
   791  	}
   792  	return
   793  }
   794  
   795  func (description *ApiDetailedDescription) generateGetObjectNameFunc(group *jen.Group, structName string) (ok bool, err error) {
   796  	if pp := description.Request.PathParams; pp != nil {
   797  		if ok, err = pp.addGetObjectNameFunc(group, structName); err != nil || ok {
   798  			return
   799  		}
   800  	}
   801  	if queryNames := description.Request.QueryNames; queryNames != nil {
   802  		if ok, err = queryNames.addGetObjectNameFunc(group, structName); err != nil || ok {
   803  			return
   804  		}
   805  	}
   806  	if headerNames := description.Request.HeaderNames; headerNames != nil {
   807  		if ok, err = headerNames.addGetObjectNameFunc(group, structName); err != nil || ok {
   808  			return
   809  		}
   810  	}
   811  	if authorization := description.Request.Authorization; authorization != nil {
   812  		if ok, err = authorization.addGetObjectNameFunc(group, structName); err != nil || ok {
   813  			return
   814  		}
   815  	}
   816  	if body := description.Request.Body; body != nil {
   817  		if json := body.Json; json != nil {
   818  			if jsonStruct := json.Struct; jsonStruct != nil {
   819  				if ok, err = jsonStruct.addGetObjectNameFunc(group, structName); err != nil || ok {
   820  					return
   821  				}
   822  			}
   823  		} else if formUrlencoded := body.FormUrlencoded; formUrlencoded != nil {
   824  			if ok, err = formUrlencoded.addGetObjectNameFunc(group, structName); err != nil || ok {
   825  				return
   826  			}
   827  		} else if multipartFormData := body.MultipartFormData; multipartFormData != nil {
   828  			if ok, err = multipartFormData.addGetObjectNameFunc(group, structName); err != nil || ok {
   829  				return
   830  			}
   831  		}
   832  	}
   833  	return
   834  }
   835  
   836  func (description *ApiDetailedDescription) generateBuildFunc(group *jen.Group, structName string) (err error) {
   837  	if pp := description.Request.PathParams; pp != nil {
   838  		if err = pp.addBuildFunc(group, structName); err != nil {
   839  			return
   840  		}
   841  	}
   842  	if queryNames := description.Request.QueryNames; queryNames != nil {
   843  		if err = queryNames.addBuildFunc(group, structName); err != nil {
   844  			return
   845  		}
   846  	}
   847  	if headerNames := description.Request.HeaderNames; headerNames != nil {
   848  		if err = headerNames.addBuildFunc(group, structName); err != nil {
   849  			return
   850  		}
   851  	}
   852  	if body := description.Request.Body; body != nil {
   853  		if formUrlencoded := body.FormUrlencoded; formUrlencoded != nil {
   854  			if err = formUrlencoded.addBuildFunc(group, structName); err != nil {
   855  				return
   856  			}
   857  		} else if multipartFormData := body.MultipartFormData; multipartFormData != nil {
   858  			if err = multipartFormData.addBuildFunc(group, structName); err != nil {
   859  				return
   860  			}
   861  		}
   862  	}
   863  	return
   864  }
   865  
   866  func (description *ApiDetailedDescription) addJsonMarshalerUnmarshaler(group *jen.Group, structName, actualPackageName, actualStructName string) (err error) {
   867  	group.Add(
   868  		jen.Func().
   869  			Params(jen.Id("j").Op("*").Id(structName)).
   870  			Id("MarshalJSON").
   871  			Params().
   872  			Params(jen.Index().Byte(), jen.Error()).
   873  			BlockFunc(func(group *jen.Group) {
   874  				group.Return(jen.Qual("encoding/json", "Marshal").Call(jen.Parens(jen.Op("*").Qual(actualPackageName, actualStructName)).Parens(jen.Id("j"))))
   875  			}),
   876  	)
   877  	group.Add(
   878  		jen.Func().
   879  			Params(jen.Id("j").Op("*").Id(structName)).
   880  			Id("UnmarshalJSON").
   881  			Params(jen.Id("data").Index().Byte()).
   882  			Params(jen.Error()).
   883  			BlockFunc(func(group *jen.Group) {
   884  				group.Return(jen.Qual("encoding/json", "Unmarshal").Call(jen.Id("data"), jen.Parens(jen.Op("*").Qual(actualPackageName, actualStructName)).Parens(jen.Id("j"))))
   885  			}),
   886  	)
   887  	return
   888  }
   889  
   890  func (description *ApiDetailedDescription) getBasePathSegments() []string {
   891  	basePath := strings.TrimPrefix(description.BasePath, "/")
   892  	basePath = strings.TrimSuffix(basePath, "/")
   893  	segments := strings.Split(basePath, "/")
   894  	newSegments := make([]string, 0, len(segments))
   895  	for _, segment := range segments {
   896  		if segment != "" {
   897  			newSegments = append(newSegments, segment)
   898  		}
   899  	}
   900  	return newSegments
   901  }
   902  
   903  func (description *ApiDetailedDescription) getPathSuffixSegments() []string {
   904  	pathSuffix := strings.TrimPrefix(description.PathSuffix, "/")
   905  	pathSuffix = strings.TrimSuffix(pathSuffix, "/")
   906  	segments := strings.Split(pathSuffix, "/")
   907  	newSegments := make([]string, 0, len(segments))
   908  	for _, segment := range segments {
   909  		if segment != "" {
   910  			newSegments = append(newSegments, segment)
   911  		}
   912  	}
   913  	return newSegments
   914  }
   915  
   916  func (description *ApiDetailedDescription) isBucketService() bool {
   917  	for _, service := range description.ServiceNames {
   918  		if service == ServiceNameBucket {
   919  			return true
   920  		}
   921  	}
   922  	return false
   923  }
   924  
   925  func (description *ApiDetailedDescription) isApiService() bool {
   926  	for _, service := range description.ServiceNames {
   927  		if service == ServiceNameApi {
   928  			return true
   929  		}
   930  	}
   931  	return false
   932  }