From 60fee6e5059dc8a85c32356193192a79f5082ea4 Mon Sep 17 00:00:00 2001 From: Ben Clayton Date: Fri, 9 Jun 2023 12:09:47 +0100 Subject: [PATCH] Remove accidental commit --- tools/protocol_gen/protocol_gen.bkp.go | 725 ------------------------- 1 file changed, 725 deletions(-) delete mode 100644 tools/protocol_gen/protocol_gen.bkp.go diff --git a/tools/protocol_gen/protocol_gen.bkp.go b/tools/protocol_gen/protocol_gen.bkp.go deleted file mode 100644 index a2f6270..0000000 --- a/tools/protocol_gen/protocol_gen.bkp.go +++ /dev/null @@ -1,725 +0,0 @@ -// Copyright 2019 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// protocol_gen (re)generates the cppdap .h and .cpp files that describe the -// DAP protocol. -package main - -import ( - "bytes" - "encoding/json" - "flag" - "fmt" - "io" - "io/ioutil" - "net/http" - "os" - "os/exec" - "path" - "reflect" - "runtime" - "sort" - "strings" -) - -const ( - protocolURL = "https://raw.githubusercontent.com/microsoft/vscode-debugadapter-node/master/debugProtocol.json" - packageURL = "https://raw.githubusercontent.com/microsoft/vscode-debugadapter-node/master/protocol/package.json" - - versionTag = "${version}" - commonPrologue = `// Copyright 2019 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// Generated with protocol_gen.go -- do not edit this file. -// go run scripts/protocol_gen/protocol_gen.go -// -// DAP version ${version} -` - - headerPrologue = commonPrologue + ` -#ifndef dap_protocol_h -#define dap_protocol_h - -#include "optional.h" -#include "typeinfo.h" -#include "typeof.h" -#include "variant.h" - -#include -#include -#include - -namespace dap { - -struct Request {}; -struct Response {}; -struct Event {}; - -` - - headerEpilogue = `} // namespace dap - -#endif // dap_protocol_h -` - - cppPrologue = commonPrologue + ` - -#include "dap/protocol.h" - -namespace dap { - -` - - cppEpilogue = `} // namespace dap -` -) - -func main() { - flag.Parse() - if err := run(); err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - os.Exit(1) - } -} - -type root struct { - Schema string `json:"$schema"` - Title string `json:"title"` - Description string `json:"description"` - Ty string `json:"type"` - Definitions map[string]definition `json:"definitions"` -} - -func (r *root) definitions() []namedDefinition { - sortedDefinitions := make([]namedDefinition, 0, len(r.Definitions)) - for name, def := range r.Definitions { - sortedDefinitions = append(sortedDefinitions, namedDefinition{name, def}) - } - sort.Slice(sortedDefinitions, func(i, j int) bool { return sortedDefinitions[i].name < sortedDefinitions[j].name }) - return sortedDefinitions -} - -func (r *root) getRef(ref string) (namedDefinition, error) { - if !strings.HasPrefix(ref, "#/definitions/") { - return namedDefinition{}, fmt.Errorf("Unknown $ref '%s'", ref) - } - name := strings.TrimPrefix(ref, "#/definitions/") - def, ok := r.Definitions[name] - if !ok { - return namedDefinition{}, fmt.Errorf("Unknown $ref '%s'", ref) - } - return namedDefinition{name, def}, nil -} - -type namedDefinition struct { - name string - def definition -} - -type definition struct { - Ty string `json:"type"` - Title string `json:"title"` - Description string `json:"description"` - Properties properties `json:"properties"` - Required []string `json:"required"` - AllOf []definition `json:"allOf"` - Ref string `json:"$ref"` - ClosedEnum []string `json:"enum"` -} - -type properties map[string]property - -func (p *properties) foreach(cb func(string, property) error) error { - type namedProperty struct { - name string - property property - } - sorted := make([]namedProperty, 0, len(*p)) - for name, property := range *p { - sorted = append(sorted, namedProperty{name, property}) - } - sort.Slice(sorted, func(i, j int) bool { return sorted[i].name < sorted[j].name }) - for _, entry := range sorted { - if err := cb(entry.name, entry.property); err != nil { - return err - } - } - return nil -} - -type property struct { - typed - Description string `json:"description"` -} - -func (p *property) properties(r *root) (properties, []string, error) { - if p.Ref == "" { - return p.Properties, p.Required, nil - } - - d, err := r.getRef(p.Ref) - if err != nil { - return nil, nil, err - } - return d.def.Properties, d.def.Required, nil -} - -type typed struct { - Ty interface{} `json:"type"` - Items *typed `json:"items"` - Ref string `json:"$ref"` - Properties properties `json:"properties"` - Required []string `json:"required"` - ClosedEnum []string `json:"enum"` - OpenEnum []string `json:"_enum"` -} - -func (t typed) typename(r *root, refs *[]string) (string, error) { - if t.Ref != "" { - d, err := r.getRef(t.Ref) - if err != nil { - return "", err - } - *refs = append(*refs, d.name) - return d.name, nil - } - - if t.Ty == nil { - return "", fmt.Errorf("No type specified") - } - - var typeof func(v reflect.Value) (string, error) - typeof = func(v reflect.Value) (string, error) { - if v.Kind() == reflect.Interface { - v = v.Elem() - } - switch v.Kind() { - case reflect.String: - ty := v.Interface().(string) - switch ty { - case "boolean", "string", "integer", "number", "object", "null": - return ty, nil - case "array": - if t.Items != nil { - el, err := t.Items.typename(r, refs) - if err != nil { - return "", err - } - return fmt.Sprintf("array<%s>", el), nil - } - return "array", nil - default: - return "", fmt.Errorf("Unhandled property type '%v'", ty) - } - - case reflect.Slice, reflect.Array: - ty := "variant<" - for i := 0; i < v.Len(); i++ { - if i > 0 { - ty += ", " - } - el, err := typeof(v.Index(i)) - if err != nil { - return "", err - } - ty += el - } - ty += ">" - return ty, nil - } - - return "", fmt.Errorf("Unsupported type '%v' kind: %v", v.Interface(), v.Kind()) - } - - return typeof(reflect.ValueOf(t.Ty)) -} - -type cppField struct { - desc string - ty string - name string - defaultValue string - optional bool -} - -type cppType interface { - Name() string - Dependencies() []string - File() cppFile - DefaultValue() string - WriteHeader(w io.Writer) - WriteCPP(w io.Writer) -} - -type cppStruct struct { - desc string - name string - typename string - base string - fields []cppField - deps []string - emit bool - typedefs []cppTypedef - file cppFile -} - -func (s *cppStruct) Name() string { - return s.name -} - -func (s *cppStruct) Dependencies() []string { - return s.deps -} - -func (s *cppStruct) File() cppFile { - return s.file -} - -func (s *cppStruct) DefaultValue() string { return "" } - -func (s *cppStruct) WriteHeader(w io.Writer) { - if s.desc != "" { - io.WriteString(w, "// ") - io.WriteString(w, strings.ReplaceAll(s.desc, "\n", "\n// ")) - io.WriteString(w, "\n") - } - io.WriteString(w, "struct ") - io.WriteString(w, s.name) - if s.base != "" { - io.WriteString(w, " : public ") - io.WriteString(w, s.base) - } - io.WriteString(w, " {") - - // typedefs - for _, t := range s.typedefs { - io.WriteString(w, "\n using ") - io.WriteString(w, t.from) - io.WriteString(w, " = ") - io.WriteString(w, t.to) - io.WriteString(w, ";") - } - - for _, f := range s.fields { - if f.desc != "" { - io.WriteString(w, "\n // ") - io.WriteString(w, strings.ReplaceAll(f.desc, "\n", "\n // ")) - } - io.WriteString(w, "\n ") - if f.optional { - io.WriteString(w, "optional<") - io.WriteString(w, f.ty) - io.WriteString(w, ">") - } else { - io.WriteString(w, f.ty) - } - io.WriteString(w, " ") - io.WriteString(w, sanitize(f.name)) - if !f.optional && f.defaultValue != "" { - io.WriteString(w, " = ") - io.WriteString(w, f.defaultValue) - } - io.WriteString(w, ";") - } - - io.WriteString(w, "\n};\n\n") - - io.WriteString(w, "DAP_DECLARE_STRUCT_TYPEINFO(") - io.WriteString(w, s.name) - io.WriteString(w, ");\n\n") -} - -func (s *cppStruct) WriteCPP(w io.Writer) { - // typeinfo - io.WriteString(w, "DAP_IMPLEMENT_STRUCT_TYPEINFO(") - io.WriteString(w, s.name) - io.WriteString(w, ",\n \"") - io.WriteString(w, s.typename) - io.WriteString(w, "\"") - for _, f := range s.fields { - io.WriteString(w, ",\n ") - io.WriteString(w, "DAP_FIELD(") - io.WriteString(w, sanitize(f.name)) - io.WriteString(w, ", \"") - io.WriteString(w, f.name) - io.WriteString(w, "\")") - } - io.WriteString(w, ");\n\n") -} - -type cppTypedef struct { - from string - to string - deps []string - desc string - defaultValue string -} - -func (ty *cppTypedef) Name() string { - return ty.from -} - -func (ty *cppTypedef) Dependencies() []string { - return ty.deps -} - -func (ty *cppTypedef) File() cppFile { - return types -} - -func (ty *cppTypedef) DefaultValue() string { return ty.defaultValue } - -func (ty *cppTypedef) WriteHeader(w io.Writer) { - if ty.desc != "" { - io.WriteString(w, "// ") - io.WriteString(w, strings.ReplaceAll(ty.desc, "\n", "\n// ")) - io.WriteString(w, "\n") - } - - io.WriteString(w, "using ") - io.WriteString(w, ty.from) - io.WriteString(w, " = ") - io.WriteString(w, ty.to) - io.WriteString(w, ";\n\n") -} - -func (ty *cppTypedef) WriteCPP(w io.Writer) { -} - -func sanitize(s string) string { - s = strings.Trim(s, "_") - switch s { - case "default": - return "def" - default: - return s - } -} - -func appendEnumDetails(desc string, openEnum []string, closedEnum []string) string { - if len(closedEnum) > 0 { - desc += "\n\nMust be one of the following enumeration values:\n" - for i, enum := range closedEnum { - if i > 0 { - desc += ", " - } - desc += "'" + enum + "'" - } - } - - if len(openEnum) > 0 { - desc += "\n\nMay be one of the following enumeration values:\n" - for i, enum := range openEnum { - if i > 0 { - desc += ", " - } - desc += "'" + enum + "'" - } - } - return desc -} - -func (r *root) buildObject(entry namedDefinition) (*cppStruct, error) { - defName := entry.name - def := entry.def - - base := "" - if len(def.AllOf) > 1 && def.AllOf[0].Ref != "" { - ref, err := r.getRef(def.AllOf[0].Ref) - if err != nil { - return nil, err - } - base = ref.name - if len(def.AllOf) > 2 { - return nil, fmt.Errorf("Cannot handle allOf with more than 2 entries") - } - def = def.AllOf[1] - } - - s := &cppStruct{ - desc: def.Description, - name: defName, - base: base, - } - - var props properties - var required []string - var err error - switch base { - case "Request": - if arguments, ok := def.Properties["arguments"]; ok { - props, required, err = arguments.properties(r) - } - if command, ok := def.Properties["command"]; ok { - s.typename = command.ClosedEnum[0] - } - response := strings.TrimSuffix(s.name, "Request") + "Response" - s.deps = append(s.deps, response) - s.typedefs = append(s.typedefs, cppTypedef{from: "Response", to: response}) - s.emit = true - s.file = request - case "Response": - if body, ok := def.Properties["body"]; ok { - props, required, err = body.properties(r) - } - s.emit = true - s.file = response - case "Event": - if body, ok := def.Properties["body"]; ok { - props, required, err = body.properties(r) - } - if command, ok := def.Properties["event"]; ok { - s.typename = command.ClosedEnum[0] - } - s.emit = true - s.file = event - default: - props = def.Properties - required = def.Required - s.file = types - } - if err != nil { - return nil, err - } - - if err = props.foreach(func(propName string, property property) error { - ty, err := property.typename(r, &s.deps) - if err != nil { - return fmt.Errorf("While processing %v.%v: %v", defName, propName, err) - } - - optional := true - for _, r := range required { - if propName == r { - optional = false - } - } - - desc := appendEnumDetails(property.Description, property.OpenEnum, property.ClosedEnum) - - defaultValue := "" - if len(property.ClosedEnum) > 0 { - defaultValue = `"` + property.ClosedEnum[0] + `"` - } - - s.fields = append(s.fields, cppField{ - desc: desc, - defaultValue: defaultValue, - ty: ty, - name: propName, - optional: optional, - }) - - return nil - }); err != nil { - return nil, err - } - - return s, nil -} - -func (r *root) buildTypes() ([]cppType, error) { - ignore := map[string]bool{ - // These are handled internally. - "ProtocolMessage": true, - "Request": true, - "Event": true, - "Response": true, - } - - out := []cppType{} - for _, entry := range r.definitions() { - if ignore[entry.name] { - continue - } - switch entry.def.Ty { - case "", "object": - ty, err := r.buildObject(entry) - if err != nil { - return nil, err - } - out = append(out, ty) - case "string": - desc := appendEnumDetails(entry.def.Description, nil, entry.def.ClosedEnum) - defaultValue := "" - if len(entry.def.ClosedEnum) > 0 { - defaultValue = entry.def.ClosedEnum[0] - } - ty := &cppTypedef{from: entry.name, to: "std::string", desc: desc, defaultValue: defaultValue} - out = append(out, ty) - default: - return nil, fmt.Errorf("Unhandled type '%v' for '%v'", entry.def.Ty, entry.name) - } - } - - return out, nil -} - -type cppFile string - -const ( - request = cppFile("request") - response = cppFile("response") - event = cppFile("event") - types = cppFile("types") -) - -type cppFilePaths map[cppFile]string - -type cppFiles map[cppFile]*os.File - -func run() error { - pkg := struct { - Version string `json:"version"` - }{} - if err := loadJSONFile(packageURL, &pkg); err != nil { - return fmt.Errorf("Failed to load JSON file from '%v': %w", packageURL, err) - } - - protocol := root{} - if err := loadJSONFile(protocolURL, &protocol); err != nil { - return fmt.Errorf("Failed to load JSON file from '%v': %w", protocolURL, err) - } - - hPath, cppPaths := outputPaths() - if err := emitFiles(&protocol, hPath, cppPaths, pkg.Version); err != nil { - return fmt.Errorf("Failed to emit files: %w", err) - } - - if clangfmt, err := exec.LookPath("clang-format"); err == nil { - if out, err := exec.Command(clangfmt, "-i", hPath).CombinedOutput(); err != nil { - return fmt.Errorf("Failed to run clang-format on '%v':\n%v\n%w", hPath, string(out), err) - } - for _, p := range cppPaths { - if out, err := exec.Command(clangfmt, "-i", p).CombinedOutput(); err != nil { - return fmt.Errorf("Failed to run clang-format on '%v':\n%v\n%w", p, string(out), err) - } - } - } else { - fmt.Printf("clang-format not found on PATH. Please format before committing.") - } - - return nil -} - -func emitFiles(r *root, hPath string, cppPaths map[cppFile]string, version string) error { - h, err := os.Create(hPath) - if err != nil { - return err - } - defer h.Close() - cppFiles := map[cppFile]*os.File{} - for ty, p := range cppPaths { - f, err := os.Create(p) - if err != nil { - return err - } - cppFiles[ty] = f - defer f.Close() - } - - h.WriteString(strings.ReplaceAll(headerPrologue, versionTag, version)) - for _, f := range cppFiles { - f.WriteString(strings.ReplaceAll(cppPrologue, versionTag, version)) - } - - types, err := r.buildTypes() - if err != nil { - return err - } - - typesByName := map[string]cppType{} - for _, s := range types { - typesByName[s.Name()] = s - } - - seen := map[string]bool{} - var emit func(cppType) error - emit = func(ty cppType) error { - name := ty.Name() - if seen[name] { - return nil - } - seen[name] = true - for _, depName := range ty.Dependencies() { - dep, ok := typesByName[depName] - if !ok { - return fmt.Errorf("'%v' depends on unknown type '%v'", name, depName) - } - if err := emit(dep); err != nil { - return err - } - } - ty.WriteHeader(h) - ty.WriteCPP(cppFiles[ty.File()]) - return nil - } - - // emit message types. - // Referenced types will be transitively emitted. - for _, s := range types { - switch s.File() { - case request, response, event: - if err := emit(s); err != nil { - return err - } - } - } - - h.WriteString(headerEpilogue) - for _, f := range cppFiles { - f.WriteString(cppEpilogue) - } - - return nil -} - -func loadJSONFile(url string, obj interface{}) error { - resp, err := http.Get(url) - if err != nil { - return err - } - data, err := ioutil.ReadAll(resp.Body) - if err != nil { - return err - } - if err := json.NewDecoder(bytes.NewReader(data)).Decode(obj); err != nil { - return err - } - return nil -} - -func outputPaths() (string, cppFilePaths) { - _, thisFile, _, _ := runtime.Caller(1) - thisDir := path.Dir(thisFile) - h := path.Join(thisDir, "../../include/dap/protocol.h") - cpp := cppFilePaths{ - request: path.Join(thisDir, "../../src/protocol_requests.cpp"), - response: path.Join(thisDir, "../../src/protocol_response.cpp"), - event: path.Join(thisDir, "../../src/protocol_events.cpp"), - types: path.Join(thisDir, "../../src/protocol_types.cpp"), - } - return h, cpp -}