@@ -21,32 +21,57 @@ import (
2121 "github.com/googleapis/librarian/internal/sidekick/internal/api"
2222)
2323
24- func makeServiceMethods (model * api.API , serviceID string , doc * document , resource * resource ) ([]* api.Method , error ) {
25- var methods []* api.Method
24+ func makeServiceMethods (model * api.API , service * api.Service , doc * document , resource * resource ) error {
25+ // It is Okay to reuse the ID, sidekick uses different the namespaces
26+ // for messages vs. services.
27+ parent := & api.Message {
28+ Name : service .Name ,
29+ ID : service .ID ,
30+ Package : service .Package ,
31+ Documentation : fmt .Sprintf ("Synthetic messages for the [%s][%s] service" , service .Name , service .ID [1 :]),
32+ ChildrenOnly : true ,
33+ }
34+ model .State .MessageByID [parent .ID ] = parent
35+ model .Messages = append (model .Messages , parent )
2636 for _ , input := range resource .Methods {
27- method , err := makeMethod (model , serviceID , doc , input )
37+ method , err := makeMethod (model , parent , doc , input )
2838 if err != nil {
29- return nil , err
39+ return err
3040 }
31- methods = append (methods , method )
41+ model .State .MethodByID [method .ID ] = method
42+ service .Methods = append (service .Methods , method )
3243 }
3344
34- return methods , nil
45+ return nil
3546}
3647
37- func makeMethod (model * api.API , serviceID string , doc * document , input * method ) (* api.Method , error ) {
38- id := fmt .Sprintf ("%s.%s" , serviceID , input .Name )
48+ func makeMethod (model * api.API , parent * api. Message , doc * document , input * method ) (* api.Method , error ) {
49+ id := fmt .Sprintf ("%s.%s" , parent . ID , input .Name )
3950 if input .MediaUpload != nil {
4051 return nil , fmt .Errorf ("media upload methods are not supported, id=%s" , id )
4152 }
42- inputID , err := getMethodType (model , id , "request type" , input .Request )
53+ bodyID , err := getMethodType (model , id , "request type" , input .Request )
4354 if err != nil {
4455 return nil , err
4556 }
4657 outputID , err := getMethodType (model , id , "response type" , input .Response )
4758 if err != nil {
4859 return nil , err
4960 }
61+
62+ // Discovery doc methods get a synthetic request message.
63+ requestMessage := & api.Message {
64+ Name : fmt .Sprintf ("%sRequest" , input .Name ),
65+ ID : fmt .Sprintf ("%s.%sRequest" , parent .ID , input .Name ),
66+ Package : model .PackageName ,
67+ SyntheticRequest : true ,
68+ Documentation : fmt .Sprintf ("Synthetic request message for the [%s()][%s] method." , input .Name , id [1 :]),
69+ Parent : parent ,
70+ // TODO(#2268) - deprecated if method is deprecated.
71+ }
72+ model .State .MessageByID [requestMessage .ID ] = requestMessage
73+ parent .Messages = append (parent .Messages , requestMessage )
74+
5075 var uriTemplate string
5176 if strings .HasSuffix (doc .ServicePath , "/" ) {
5277 uriTemplate = fmt .Sprintf ("%s%s" , doc .ServicePath , input .Path )
@@ -58,33 +83,73 @@ func makeMethod(model *api.API, serviceID string, doc *document, input *method)
5883 if err != nil {
5984 return nil , err
6085 }
86+
6187 binding := & api.PathBinding {
6288 Verb : input .HTTPMethod ,
6389 PathTemplate : path ,
6490 QueryParameters : map [string ]bool {},
6591 }
92+ fieldNames := map [string ]bool {}
6693 for _ , p := range input .Parameters {
6794 if p .Location != "path" {
6895 binding .QueryParameters [p .Name ] = true
6996 }
97+ prop := & property {
98+ Name : p .Name ,
99+ Schema : & p .schema ,
100+ }
101+ field , err := makeField (fmt .Sprintf (requestMessage .ID , id ), prop )
102+ if err != nil {
103+ return nil , err
104+ }
105+ field .Synthetic = true
106+ field .Optional = ! p .Required
107+ requestMessage .Fields = append (requestMessage .Fields , field )
108+ fieldNames [field .Name ] = true
70109 }
110+
111+ bodyPathField := ""
112+ if bodyID != ".google.protobuf.Empty" {
113+ name , err := bodyFieldName (fieldNames )
114+ if err != nil {
115+ return nil , err
116+ }
117+ body := & api.Field {
118+ Documentation : fmt .Sprintf ("Synthetic request body field for the [%s()][%s] method." , input .Name , id [1 :]),
119+ Name : name ,
120+ JSONName : name ,
121+ ID : fmt .Sprintf ("%s.%s" , requestMessage .ID , name ),
122+ Typez : api .MESSAGE_TYPE ,
123+ TypezID : bodyID ,
124+ Optional : true ,
125+ }
126+ requestMessage .Fields = append (requestMessage .Fields , body )
127+ bodyPathField = name
128+ }
129+
71130 method := & api.Method {
72131 ID : id ,
73132 Name : input .Name ,
74133 Documentation : input .Description ,
75- // TODO(#1850 ) - handle deprecated methods
134+ // TODO(#2268 ) - handle deprecated methods
76135 // Deprecated: ...,
77- InputTypeID : inputID ,
136+ InputTypeID : requestMessage . ID ,
78137 OutputTypeID : outputID ,
79138 PathInfo : & api.PathInfo {
80139 Bindings : []* api.PathBinding {binding },
81- BodyFieldPath : "*" ,
140+ BodyFieldPath : bodyPathField ,
82141 },
83142 }
84- model .State .MethodByID [id ] = method
85143 return method , nil
86144}
87145
146+ func bodyFieldName (fieldNames map [string ]bool ) (string , error ) {
147+ if _ , ok := fieldNames ["body" ]; ok {
148+ return "" , fmt .Errorf ("body is a request or path parameter" )
149+ }
150+ return "body" , nil
151+ }
152+
88153func getMethodType (model * api.API , methodID , name string , typez * schema ) (string , error ) {
89154 if typez == nil {
90155 return ".google.protobuf.Empty" , nil
0 commit comments