...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package compiler
16
17 import (
18 "bytes"
19 "fmt"
20 "os/exec"
21 "strings"
22
23 "google.golang.org/protobuf/proto"
24 "google.golang.org/protobuf/types/known/anypb"
25 yaml "gopkg.in/yaml.v3"
26
27 extensions "github.com/google/gnostic-models/extensions"
28 )
29
30
31 type ExtensionHandler struct {
32 Name string
33 }
34
35
36 func CallExtension(context *Context, in *yaml.Node, extensionName string) (handled bool, response *anypb.Any, err error) {
37 if context == nil || context.ExtensionHandlers == nil {
38 return false, nil, nil
39 }
40 handled = false
41 for _, handler := range *(context.ExtensionHandlers) {
42 response, err = handler.handle(in, extensionName)
43 if response == nil {
44 continue
45 } else {
46 handled = true
47 break
48 }
49 }
50 return handled, response, err
51 }
52
53 func (extensionHandlers *ExtensionHandler) handle(in *yaml.Node, extensionName string) (*anypb.Any, error) {
54 if extensionHandlers.Name != "" {
55 yamlData, _ := yaml.Marshal(in)
56 request := &extensions.ExtensionHandlerRequest{
57 CompilerVersion: &extensions.Version{
58 Major: 0,
59 Minor: 1,
60 Patch: 0,
61 },
62 Wrapper: &extensions.Wrapper{
63 Version: "unknown",
64 Yaml: string(yamlData),
65 ExtensionName: extensionName,
66 },
67 }
68 requestBytes, _ := proto.Marshal(request)
69 cmd := exec.Command(extensionHandlers.Name)
70 cmd.Stdin = bytes.NewReader(requestBytes)
71 output, err := cmd.Output()
72 if err != nil {
73 return nil, err
74 }
75 response := &extensions.ExtensionHandlerResponse{}
76 err = proto.Unmarshal(output, response)
77 if err != nil || !response.Handled {
78 return nil, err
79 }
80 if len(response.Errors) != 0 {
81 return nil, fmt.Errorf("Errors when parsing: %+v for field %s by vendor extension handler %s. Details %+v", in, extensionName, extensionHandlers.Name, strings.Join(response.Errors, ","))
82 }
83 return response.Value, nil
84 }
85 return nil, nil
86 }
87
View as plain text