@@ -43,7 +43,6 @@ type goEncoder struct {
43
43
// types cache
44
44
stypes map [string ]* wsdl.SimpleType
45
45
ctypes map [string ]* wsdl.ComplexType
46
- rtypes map [string ]string // renamed ctypes old->new
47
46
48
47
// funcs cache
49
48
funcs map [string ]* wsdl.Operation
@@ -59,7 +58,7 @@ type goEncoder struct {
59
58
needsTimeType bool
60
59
needsDateTimeType bool
61
60
needsDurationType bool
62
- needsNSTag map [string ]string
61
+ needsTag map [string ]bool
63
62
needsStdPkg map [string ]bool
64
63
needsExtPkg map [string ]bool
65
64
}
@@ -71,11 +70,10 @@ func NewEncoder(w io.Writer) Encoder {
71
70
http : http .DefaultClient ,
72
71
stypes : make (map [string ]* wsdl.SimpleType ),
73
72
ctypes : make (map [string ]* wsdl.ComplexType ),
74
- rtypes : make (map [string ]string ),
75
73
funcs : make (map [string ]* wsdl.Operation ),
76
74
messages : make (map [string ]* wsdl.Message ),
77
75
soapOps : make (map [string ]* wsdl.BindingOperation ),
78
- needsNSTag : make (map [string ]string ),
76
+ needsTag : make (map [string ]bool ),
79
77
needsStdPkg : make (map [string ]bool ),
80
78
needsExtPkg : make (map [string ]bool ),
81
79
}
@@ -133,6 +131,10 @@ func (ge *goEncoder) encode(w io.Writer, d *wsdl.Definitions) error {
133
131
pkg = "internal"
134
132
}
135
133
var b bytes.Buffer
134
+ if len (ge .soapOps ) > 0 {
135
+ // TODO: rpc? meh.
136
+ ge .writePortType (& b , d )
137
+ }
136
138
err = ge .writeGoFuncs (& b , d ) // functions first, for clarity
137
139
if err != nil {
138
140
return err
@@ -242,6 +244,25 @@ func (ge *goEncoder) cacheSOAPOperations(d *wsdl.Definitions) {
242
244
}
243
245
}
244
246
247
+ var portTypeT = template .Must (template .New ("portType" ).Parse (`
248
+ // {{.}} was auto-generated from WSDL.
249
+ type {{.}} struct {
250
+ cli *soap.Client
251
+ }
252
+
253
+ // New{{.}} creates an initializes a {{.}}.
254
+ func New{{.}}(cli *soap.Client) *{{.}} {
255
+ return &{{.}}{cli}
256
+ }
257
+ ` ))
258
+
259
+ func (ge * goEncoder ) writePortType (w io.Writer , d * wsdl.Definitions ) error {
260
+ if d .PortType .Operations == nil || len (d .PortType .Operations ) == 0 {
261
+ return nil
262
+ }
263
+ return portTypeT .Execute (w , strings .Title (d .PortType .Name ))
264
+ }
265
+
245
266
// writeGoFuncs writes Go function definitions from WSDL types to w.
246
267
// Functions are written in the same order of the WSDL document.
247
268
func (ge * goEncoder ) writeGoFuncs (w io.Writer , d * wsdl.Definitions ) error {
@@ -257,7 +278,6 @@ func (ge *goEncoder) writeGoFuncs(w io.Writer, d *wsdl.Definitions) error {
257
278
return nil
258
279
}
259
280
for _ , op := range d .PortType .Operations {
260
- // TODO: really rename input to have Request suffix?
261
281
ge .writeComments (w , op .Name , op .Doc )
262
282
in , err := ge .inputParams (op )
263
283
if err != nil {
@@ -274,7 +294,7 @@ func (ge *goEncoder) writeGoFuncs(w io.Writer, d *wsdl.Definitions) error {
274
294
ret [i ] = ge .wsdl2goDefault (parts [1 ])
275
295
}
276
296
}
277
- ok := ge .writeSOAPFunc (w , op , in , out , ret )
297
+ ok := ge .writeSOAPFunc (w , d , op , in , out , ret )
278
298
if ! ok {
279
299
ge .needsStdPkg ["errors" ] = true
280
300
ge .needsExtPkg ["golang.org/x/net/context" ] = true
@@ -291,22 +311,22 @@ func (ge *goEncoder) writeGoFuncs(w io.Writer, d *wsdl.Definitions) error {
291
311
return nil
292
312
}
293
313
294
- var soapFuncT = template .Must (template .New ("soapFunc" ).
295
- Parse ( `func {{.Name}}(cli soap.RoundTripper, {{.Input}}) ({{.Output}}) {
314
+ var soapFuncT = template .Must (template .New ("soapFunc" ).Parse (
315
+ `func (p * {{.PortType}}) {{.Name}}( {{.Input}}) ({{.Output}}) {
296
316
γ := struct {
297
317
XMLName xml.Name ` + "`xml:\" Envelope\" `" + `
298
318
Body struct {
299
319
M {{.OutputType}} ` + "`xml:\" {{.OutputType}}\" `" + `
300
320
}
301
321
}{}
302
- if err = cli.RoundTrip(α, &γ); err != nil {
322
+ if err = p. cli.RoundTrip(α, &γ); err != nil {
303
323
return {{.RetDef}}, err
304
324
}
305
325
return {{if .RetPtr}}&{{end}}γ.Body.M, nil
306
326
}
307
327
` ))
308
328
309
- func (ge * goEncoder ) writeSOAPFunc (w io.Writer , op * wsdl.Operation , in , out , ret []string ) bool {
329
+ func (ge * goEncoder ) writeSOAPFunc (w io.Writer , d * wsdl. Definitions , op * wsdl.Operation , in , out , ret []string ) bool {
310
330
if _ , exists := ge .soapOps [op .Name ]; ! exists {
311
331
return false
312
332
}
@@ -322,13 +342,15 @@ func (ge *goEncoder) writeSOAPFunc(w io.Writer, op *wsdl.Operation, in, out, ret
322
342
ret [0 ] = "nil"
323
343
}
324
344
soapFuncT .Execute (w , & struct {
345
+ PortType string
325
346
Name string
326
347
Input string
327
348
Output string
328
349
OutputType string
329
350
RetPtr bool
330
351
RetDef string
331
352
}{
353
+ strings .Title (d .PortType .Name ),
332
354
strings .Title (op .Name ),
333
355
strings .Join (in , "," ),
334
356
strings .Join (out , "," ),
@@ -357,7 +379,7 @@ func (ge *goEncoder) inputParams(op *wsdl.Operation) ([]string, error) {
357
379
if ! ok {
358
380
return nil , fmt .Errorf ("operation %q wants input message %q but it's not defined" , op .Name , im )
359
381
}
360
- return ge .genParams (req , "Request" ), nil
382
+ return ge .genParams (req , true ), nil
361
383
}
362
384
363
385
// returns list of function output parameters plus error.
@@ -371,20 +393,23 @@ func (ge *goEncoder) outputParams(op *wsdl.Operation) ([]string, error) {
371
393
if ! ok {
372
394
return nil , fmt .Errorf ("operation %q wants output message %q but it's not defined" , op .Name , om )
373
395
}
374
- return append (ge .genParams (resp , "Response" ), out [0 ]), nil
396
+ return append (ge .genParams (resp , false ), out [0 ]), nil
375
397
}
376
398
377
- func (ge * goEncoder ) genParams (m * wsdl.Message , suffix string ) []string {
399
+ func (ge * goEncoder ) genParams (m * wsdl.Message , needsTag bool ) []string {
378
400
params := make ([]string , len (m .Parts ))
379
401
for i , param := range m .Parts {
380
402
var t string
381
403
switch {
382
404
case param .Type != "" :
383
- t = ge .wsdl2goType (param .Type , suffix )
405
+ t = ge .wsdl2goType (param .Type )
384
406
case param .Element != "" :
385
- t = ge .wsdl2goType (param .Element , suffix )
407
+ t = ge .wsdl2goType (param .Element )
386
408
}
387
409
params [i ] = param .Name + " " + t
410
+ if needsTag {
411
+ ge .needsTag [strings .TrimPrefix (t , "*" )] = true
412
+ }
388
413
}
389
414
return params
390
415
}
@@ -408,13 +433,8 @@ func (ge *goEncoder) fixParamConflicts(req, resp []string) {
408
433
}
409
434
}
410
435
411
- // Converts types from wsdl type to Go type. If t is a complex type
412
- // (a struct, as opposed to int or string) and a suffix is provided,
413
- // we look for the suffix in its name and add if needed. When we do
414
- // that, we also update the list of cached ctypes to match this new
415
- // type name, with the suffix (e.g. ping -> pingRequest). This is
416
- // to avoid ambiguous parameter and function names.
417
- func (ge * goEncoder ) wsdl2goType (t , suffix string ) string {
436
+ // Converts types from wsdl type to Go type.
437
+ func (ge * goEncoder ) wsdl2goType (t string ) string {
418
438
// TODO: support other types.
419
439
v := ge .trimns (t )
420
440
if _ , exists := ge .stypes [v ]; exists {
@@ -446,28 +466,7 @@ func (ge *goEncoder) wsdl2goType(t, suffix string) string {
446
466
ge .needsDurationType = true
447
467
return "Duration"
448
468
default :
449
- if newname , exists := ge .rtypes [t ]; exists {
450
- t = newname
451
- } else if suffix != "" {
452
- // These types are parameters to functions. Since
453
- // they are structs, we set their names to have
454
- // suffixes Request and Response based on how
455
- // they're used.
456
- if strings .HasSuffix (t , suffix ) {
457
- t = v
458
- } else {
459
- ge .renameType (t , t + suffix )
460
- t = v + suffix
461
- }
462
- // Request types need a special xml tag to enable
463
- // encoding them correct. Responses cannot have it.
464
- if suffix == "Request" {
465
- ge .needsNSTag [t ] = v
466
- }
467
- } else {
468
- t = v
469
- }
470
- return "*" + strings .Title (t )
469
+ return "*" + strings .Title (v )
471
470
}
472
471
}
473
472
@@ -510,7 +509,6 @@ func (ge *goEncoder) renameType(old, name string) {
510
509
if ! exists {
511
510
return
512
511
}
513
- ge .rtypes [old ] = name
514
512
name = ge .trimns (name )
515
513
}
516
514
ct .Name = name
@@ -530,13 +528,13 @@ func (ge *goEncoder) writeGoTypes(w io.Writer, d *wsdl.Definitions) error {
530
528
continue
531
529
}
532
530
ge .writeComments (& b , st .Name , "" )
533
- fmt .Fprintf (& b , "type %s %s\n \n " , st .Name , ge .wsdl2goType (st .Restriction .Base , "" ))
531
+ fmt .Fprintf (& b , "type %s %s\n \n " , st .Name , ge .wsdl2goType (st .Restriction .Base ))
534
532
ge .genValidator (& b , st .Name , st .Restriction )
535
533
}
536
534
var err error
537
535
for _ , name := range ge .sortedComplexTypes () {
538
536
ct := ge .ctypes [name ]
539
- err = ge .genGoStruct (& b , ct )
537
+ err = ge .genGoStruct (& b , d , ct )
540
538
if err != nil {
541
539
return err
542
540
}
@@ -623,7 +621,7 @@ func (ge *goEncoder) genValidator(w io.Writer, typeName string, r *wsdl.Restrict
623
621
return
624
622
}
625
623
args := make ([]string , len (r .Enum ))
626
- t := ge .wsdl2goType (r .Base , "" )
624
+ t := ge .wsdl2goType (r .Base )
627
625
for i , v := range r .Enum {
628
626
if t == "string" {
629
627
args [i ] = strconv .Quote (v .Value )
@@ -643,7 +641,7 @@ func (ge *goEncoder) genValidator(w io.Writer, typeName string, r *wsdl.Restrict
643
641
})
644
642
}
645
643
646
- func (ge * goEncoder ) genGoStruct (w io.Writer , ct * wsdl.ComplexType ) error {
644
+ func (ge * goEncoder ) genGoStruct (w io.Writer , d * wsdl. Definitions , ct * wsdl.ComplexType ) error {
647
645
if ct .Abstract {
648
646
return nil
649
647
}
@@ -663,36 +661,38 @@ func (ge *goEncoder) genGoStruct(w io.Writer, ct *wsdl.ComplexType) error {
663
661
// dont generate empty structs
664
662
return nil
665
663
}
666
- ge .writeComments (w , ct .Name , ct .Doc )
667
- fmt .Fprintf (w , "type %s struct {\n " , strings .Title (ct .Name ))
668
- if tag , exists := ge .needsNSTag [ct .Name ]; exists {
669
- fmt .Fprintf (w , "XMLName xml.Name `xml:\" ns:%s\" json:\" -\" yaml:\" -\" `\n " , tag )
664
+ name := strings .Title (ct .Name )
665
+ ge .writeComments (w , name , ct .Doc )
666
+ fmt .Fprintf (w , "type %s struct {\n " , name )
667
+ if ge .needsTag [name ] {
668
+ fmt .Fprintf (w , "XMLName xml.Name `xml:\" %s %s\" json:\" -\" yaml:\" -\" `\n " ,
669
+ d .TargetNamespace , name )
670
670
}
671
- err := ge .genStructFields (w , ct )
671
+ err := ge .genStructFields (w , d , ct )
672
672
if err != nil {
673
673
return err
674
674
}
675
675
fmt .Fprintf (w , "}\n \n " )
676
676
return nil
677
677
}
678
678
679
- func (ge * goEncoder ) genStructFields (w io.Writer , ct * wsdl.ComplexType ) error {
680
- err := ge .genComplexContent (w , ct )
679
+ func (ge * goEncoder ) genStructFields (w io.Writer , d * wsdl. Definitions , ct * wsdl.ComplexType ) error {
680
+ err := ge .genComplexContent (w , d , ct )
681
681
if err != nil {
682
682
return err
683
683
}
684
684
return ge .genElements (w , ct )
685
685
}
686
686
687
- func (ge * goEncoder ) genComplexContent (w io.Writer , ct * wsdl.ComplexType ) error {
687
+ func (ge * goEncoder ) genComplexContent (w io.Writer , d * wsdl. Definitions , ct * wsdl.ComplexType ) error {
688
688
if ct .ComplexContent == nil || ct .ComplexContent .Extension == nil {
689
689
return nil
690
690
}
691
691
ext := ct .ComplexContent .Extension
692
692
if ext .Base != "" {
693
693
base , exists := ge .ctypes [ge .trimns (ext .Base )]
694
694
if exists {
695
- err := ge .genStructFields (w , base )
695
+ err := ge .genStructFields (w , d , base )
696
696
if err != nil {
697
697
return err
698
698
}
@@ -746,7 +746,7 @@ func (ge *goEncoder) genElementField(w io.Writer, el *wsdl.Element) {
746
746
tag = el .Name + ">" + slicetype
747
747
}
748
748
}
749
- typ := ge .wsdl2goType (el .Type , "" )
749
+ typ := ge .wsdl2goType (el .Type )
750
750
if el .Nillable || el .Min == 0 {
751
751
tag += ",omitempty"
752
752
}
0 commit comments