internal/mcp/protocol: make type name more convenient
You can now write "*" for a name in a config to use the original name. Also, fix a bug in dealing with initialisms. Change-Id: I4d5d0acb1200fff6500644457ec34c5026d63f9f Reviewed-on: https://go-review.googlesource.com/c/tools/+/671361 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Robert Findley <rfindley@google.com> Reviewed-by: Sam Thanawalla <samthanawalla@google.com>
This commit is contained in:
parent
5004d3e1bb
commit
51ea6a4a72
1 changed files with 56 additions and 36 deletions
|
|
@ -46,53 +46,61 @@ type config map[string]*typeConfig
|
||||||
|
|
||||||
// declarations configures the set of declarations to write.
|
// declarations configures the set of declarations to write.
|
||||||
//
|
//
|
||||||
// Top level declarations are only created if they are configured with a
|
// Top level declarations are created unless configured with Name=="-",
|
||||||
// non-empty Name. Otherwise, they are discarded, though their fields may be
|
// in which case they are discarded, though their fields may be
|
||||||
// extracted to types if they have a nested field configuration.
|
// extracted to types if they have a nested field configuration.
|
||||||
|
// If Name == "", the map key is used as the type name.
|
||||||
var declarations = config{
|
var declarations = config{
|
||||||
"Annotations": {Name: "Annotations"},
|
"Annotations": {},
|
||||||
"CallToolRequest": {
|
"CallToolRequest": {
|
||||||
|
Name: "-",
|
||||||
Fields: config{"Params": {Name: "CallToolParams"}},
|
Fields: config{"Params": {Name: "CallToolParams"}},
|
||||||
},
|
},
|
||||||
"CallToolResult": {Name: "CallToolResult"},
|
"CallToolResult": {},
|
||||||
"CancelledNotification": {
|
"CancelledNotification": {
|
||||||
|
Name: "-",
|
||||||
Fields: config{"Params": {Name: "CancelledParams"}},
|
Fields: config{"Params": {Name: "CancelledParams"}},
|
||||||
},
|
},
|
||||||
"ClientCapabilities": {Name: "ClientCapabilities"},
|
"ClientCapabilities": {},
|
||||||
"GetPromptRequest": {
|
"GetPromptRequest": {
|
||||||
|
Name: "-",
|
||||||
Fields: config{"Params": {Name: "GetPromptParams"}},
|
Fields: config{"Params": {Name: "GetPromptParams"}},
|
||||||
},
|
},
|
||||||
"GetPromptResult": {Name: "GetPromptResult"},
|
"GetPromptResult": {},
|
||||||
"Implementation": {Name: "Implementation"},
|
"Implementation": {},
|
||||||
"InitializeRequest": {
|
"InitializeRequest": {
|
||||||
|
Name: "-",
|
||||||
Fields: config{"Params": {Name: "InitializeParams"}},
|
Fields: config{"Params": {Name: "InitializeParams"}},
|
||||||
},
|
},
|
||||||
"InitializeResult": {Name: "InitializeResult"},
|
"InitializeResult": {},
|
||||||
"InitializedNotification": {
|
"InitializedNotification": {
|
||||||
|
Name: "-",
|
||||||
Fields: config{"Params": {Name: "InitializedParams"}},
|
Fields: config{"Params": {Name: "InitializedParams"}},
|
||||||
},
|
},
|
||||||
"ListPromptsRequest": {
|
"ListPromptsRequest": {
|
||||||
|
Name: "-",
|
||||||
Fields: config{"Params": {Name: "ListPromptsParams"}},
|
Fields: config{"Params": {Name: "ListPromptsParams"}},
|
||||||
},
|
},
|
||||||
"ListPromptsResult": {Name: "ListPromptsResult"},
|
"ListPromptsResult": {},
|
||||||
"ListRootsRequest": {
|
"ListRootsRequest": {
|
||||||
|
Name: "-",
|
||||||
Fields: config{"Params": {Name: "ListRootsParams"}},
|
Fields: config{"Params": {Name: "ListRootsParams"}},
|
||||||
},
|
},
|
||||||
"ListRootsResult": {Name: "ListRootsResult"},
|
"ListRootsResult": {},
|
||||||
"ListToolsRequest": {
|
"ListToolsRequest": {
|
||||||
|
Name: "-",
|
||||||
Fields: config{"Params": {Name: "ListToolsParams"}},
|
Fields: config{"Params": {Name: "ListToolsParams"}},
|
||||||
},
|
},
|
||||||
"ListToolsResult": {Name: "ListToolsResult"},
|
"ListToolsResult": {},
|
||||||
"Prompt": {Name: "Prompt"},
|
"Prompt": {},
|
||||||
"PromptMessage": {Name: "PromptMessage"},
|
"PromptMessage": {},
|
||||||
"PromptArgument": {Name: "PromptArgument"},
|
"PromptArgument": {},
|
||||||
"ProgressToken": {Substitute: "any"}, // null|number|string
|
"ProgressToken": {Name: "-", Substitute: "any"}, // null|number|string
|
||||||
"RequestId": {Substitute: "any"}, // null|number|string
|
"RequestId": {Name: "-", Substitute: "any"}, // null|number|string
|
||||||
"Role": {Name: "Role"},
|
"Role": {},
|
||||||
"Root": {Name: "Root"},
|
"Root": {},
|
||||||
|
|
||||||
"ServerCapabilities": {
|
"ServerCapabilities": {
|
||||||
Name: "ServerCapabilities",
|
|
||||||
Fields: config{
|
Fields: config{
|
||||||
"Prompts": {Name: "PromptCapabilities"},
|
"Prompts": {Name: "PromptCapabilities"},
|
||||||
"Resources": {Name: "ResourceCapabilities"},
|
"Resources": {Name: "ResourceCapabilities"},
|
||||||
|
|
@ -100,10 +108,9 @@ var declarations = config{
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"Tool": {
|
"Tool": {
|
||||||
Name: "Tool",
|
|
||||||
Fields: config{"InputSchema": {Substitute: "*jsonschema.Schema"}},
|
Fields: config{"InputSchema": {Substitute: "*jsonschema.Schema"}},
|
||||||
},
|
},
|
||||||
"ToolAnnotations": {Name: "ToolAnnotations"},
|
"ToolAnnotations": {},
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
@ -128,7 +135,7 @@ func main() {
|
||||||
if config == nil {
|
if config == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := writeDecl(*config, def, named); err != nil {
|
if err := writeDecl(name, *config, def, named); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -199,19 +206,22 @@ func loadSchema(schemaFile string) (data []byte, err error) {
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeDecl(config typeConfig, def *jsonschema.Schema, named map[string]*bytes.Buffer) error {
|
func writeDecl(configName string, config typeConfig, def *jsonschema.Schema, named map[string]*bytes.Buffer) error {
|
||||||
var w io.Writer = io.Discard
|
var w io.Writer = io.Discard
|
||||||
if name := config.Name; name != "" {
|
if typeName := config.Name; typeName != "-" {
|
||||||
if _, ok := named[name]; ok {
|
if typeName == "" {
|
||||||
|
typeName = configName
|
||||||
|
}
|
||||||
|
if _, ok := named[typeName]; ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
buf := new(bytes.Buffer)
|
buf := new(bytes.Buffer)
|
||||||
w = buf
|
w = buf
|
||||||
named[name] = buf
|
named[typeName] = buf
|
||||||
if def.Description != "" {
|
if def.Description != "" {
|
||||||
fmt.Fprintf(buf, "%s\n", toComment(def.Description))
|
fmt.Fprintf(buf, "%s\n", toComment(def.Description))
|
||||||
}
|
}
|
||||||
fmt.Fprintf(buf, "type %s ", name)
|
fmt.Fprintf(buf, "type %s ", typeName)
|
||||||
}
|
}
|
||||||
if err := writeType(w, &config, def, named); err != nil {
|
if err := writeType(w, &config, def, named); err != nil {
|
||||||
return err // Better error here?
|
return err // Better error here?
|
||||||
|
|
@ -234,12 +244,12 @@ func writeType(w io.Writer, config *typeConfig, def *jsonschema.Schema, named ma
|
||||||
// definition is missing, *but only if w is not io.Discard*. That's not a
|
// definition is missing, *but only if w is not io.Discard*. That's not a
|
||||||
// great API: see if we can do something more explicit than io.Discard.
|
// great API: see if we can do something more explicit than io.Discard.
|
||||||
if cfg, ok := declarations[name]; ok {
|
if cfg, ok := declarations[name]; ok {
|
||||||
if cfg.Name == "" && cfg.Substitute == "" {
|
if cfg.Name == "-" && cfg.Substitute == "" {
|
||||||
panic(fmt.Sprintf("referenced type %q cannot be referred to (no name or substitution)", name))
|
panic(fmt.Sprintf("referenced type %q cannot be referred to (no name or substitution)", name))
|
||||||
}
|
}
|
||||||
if cfg.Substitute != "" {
|
if cfg.Substitute != "" {
|
||||||
name = cfg.Substitute
|
name = cfg.Substitute
|
||||||
} else {
|
} else if cfg.Name != "" {
|
||||||
name = cfg.Name
|
name = cfg.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -311,14 +321,18 @@ func writeType(w io.Writer, config *typeConfig, def *jsonschema.Schema, named ma
|
||||||
if r.Substitute != "" {
|
if r.Substitute != "" {
|
||||||
fmt.Fprintf(w, r.Substitute)
|
fmt.Fprintf(w, r.Substitute)
|
||||||
} else {
|
} else {
|
||||||
assert(r.Name != "", "missing ExtractTo")
|
assert(r.Name != "-", "missing ExtractTo")
|
||||||
if err := writeDecl(*r, fieldDef, named); err != nil {
|
typename := export
|
||||||
|
if r.Name != "" {
|
||||||
|
typename = r.Name
|
||||||
|
}
|
||||||
|
if err := writeDecl(typename, *r, fieldDef, named); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if needPointer {
|
if needPointer {
|
||||||
fmt.Fprintf(w, "*")
|
fmt.Fprintf(w, "*")
|
||||||
}
|
}
|
||||||
fmt.Fprintf(w, r.Name)
|
fmt.Fprintf(w, typename)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if needPointer {
|
if needPointer {
|
||||||
|
|
@ -410,7 +424,12 @@ func exportName(s string) string {
|
||||||
// at once, because the replacement will change the indices.)
|
// at once, because the replacement will change the indices.)
|
||||||
for {
|
for {
|
||||||
if loc := re.FindStringIndex(s); loc != nil {
|
if loc := re.FindStringIndex(s); loc != nil {
|
||||||
s = s[:loc[0]] + replacement + s[loc[1]:]
|
// Don't replace the rune after the initialism, if any.
|
||||||
|
end := loc[1]
|
||||||
|
if end < len(s) {
|
||||||
|
end--
|
||||||
|
}
|
||||||
|
s = s[:loc[0]] + replacement + s[end:]
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -421,9 +440,10 @@ func exportName(s string) string {
|
||||||
|
|
||||||
// Map from initialism to the regexp that matches it.
|
// Map from initialism to the regexp that matches it.
|
||||||
var initialisms = map[string]*regexp.Regexp{
|
var initialisms = map[string]*regexp.Regexp{
|
||||||
"Id": nil,
|
"Id": nil,
|
||||||
"Url": nil,
|
"Url": nil,
|
||||||
"Uri": nil,
|
"Uri": nil,
|
||||||
|
"Mime": nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue