Giant blob of minor changes
[dotfiles/.git] / .config / coc / extensions / coc-go-data / tools / pkg / mod / golang.org / x / tools / gopls@v0.5.2 / doc / generate.go
1 // Copyright 2020 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 // Command generate updates settings.md from the UserOptions struct.
6 package main
7
8 import (
9         "bytes"
10         "encoding/json"
11         "fmt"
12         "io/ioutil"
13         "os"
14         "path/filepath"
15         "regexp"
16         "strings"
17
18         "golang.org/x/tools/internal/lsp/source"
19 )
20
21 func main() {
22         if _, err := doMain(".", true); err != nil {
23                 fmt.Fprintf(os.Stderr, "Generation failed: %v\n", err)
24                 os.Exit(1)
25         }
26 }
27
28 func doMain(baseDir string, write bool) (bool, error) {
29         api := &source.APIJSON{}
30         if err := json.Unmarshal([]byte(source.GeneratedAPIJSON), api); err != nil {
31                 return false, err
32         }
33
34         if ok, err := rewriteFile(filepath.Join(baseDir, "gopls/doc/settings.md"), api, write, rewriteSettings); !ok || err != nil {
35                 return ok, err
36         }
37         if ok, err := rewriteFile(filepath.Join(baseDir, "gopls/doc/commands.md"), api, write, rewriteCommands); !ok || err != nil {
38                 return ok, err
39         }
40
41         return true, nil
42 }
43
44 func rewriteFile(file string, api *source.APIJSON, write bool, rewrite func([]byte, *source.APIJSON) ([]byte, error)) (bool, error) {
45         doc, err := ioutil.ReadFile(file)
46         if err != nil {
47                 return false, err
48         }
49
50         content, err := rewrite(doc, api)
51         if err != nil {
52                 return false, fmt.Errorf("rewriting %q: %v", file, err)
53         }
54
55         if !bytes.Equal(doc, content) && !write {
56                 return false, nil
57         }
58
59         if err := ioutil.WriteFile(file, content, 0); err != nil {
60                 return false, err
61         }
62
63         return true, nil
64 }
65
66 var parBreakRE = regexp.MustCompile("\n{2,}")
67
68 func rewriteSettings(doc []byte, api *source.APIJSON) ([]byte, error) {
69         result := doc
70         for category, opts := range api.Options {
71                 section := bytes.NewBuffer(nil)
72                 for _, opt := range opts {
73                         var enumValues strings.Builder
74                         if len(opt.EnumValues) > 0 {
75                                 enumValues.WriteString("Must be one of:\n\n")
76                                 for _, val := range opt.EnumValues {
77                                         if val.Doc != "" {
78                                                 // Don't break the list item by starting a new paragraph.
79                                                 unbroken := parBreakRE.ReplaceAllString(val.Doc, "\\\n")
80                                                 fmt.Fprintf(&enumValues, " * %s\n", unbroken)
81                                         } else {
82                                                 fmt.Fprintf(&enumValues, " * `%s`\n", val.Value)
83                                         }
84                                 }
85                         }
86                         fmt.Fprintf(section, "### **%v** *%v*\n%v%v\n\nDefault: `%v`.\n", opt.Name, opt.Type, opt.Doc, enumValues.String(), opt.Default)
87                 }
88                 var err error
89                 result, err = replaceSection(result, category, section.Bytes())
90                 if err != nil {
91                         return nil, err
92                 }
93         }
94
95         section := bytes.NewBuffer(nil)
96         for _, lens := range api.Lenses {
97                 fmt.Fprintf(section, "### **%v**\nIdentifier: `%v`\n\n%v\n\n", lens.Title, lens.Lens, lens.Doc)
98         }
99         return replaceSection(result, "Lenses", section.Bytes())
100 }
101
102 func rewriteCommands(doc []byte, api *source.APIJSON) ([]byte, error) {
103         section := bytes.NewBuffer(nil)
104         for _, command := range api.Commands {
105                 fmt.Fprintf(section, "### **%v**\nIdentifier: `%v`\n\n%v\n\n", command.Title, command.Command, command.Doc)
106         }
107         return replaceSection(doc, "Commands", section.Bytes())
108 }
109
110 func replaceSection(doc []byte, sectionName string, replacement []byte) ([]byte, error) {
111         re := regexp.MustCompile(fmt.Sprintf(`(?s)<!-- BEGIN %v.* -->\n(.*?)<!-- END %v.* -->`, sectionName, sectionName))
112         idx := re.FindSubmatchIndex(doc)
113         if idx == nil {
114                 return nil, fmt.Errorf("could not find section %q", sectionName)
115         }
116         result := append([]byte(nil), doc[:idx[2]]...)
117         result = append(result, replacement...)
118         result = append(result, doc[idx[3]:]...)
119         return result, nil
120 }