Remove BPA from Makefile
[icn.git] / cmd / bpa-operator / vendor / github.com / grpc-ecosystem / grpc-gateway / runtime / fieldmask.go
1 package runtime
2
3 import (
4         "encoding/json"
5         "io"
6         "strings"
7
8         "github.com/golang/protobuf/protoc-gen-go/generator"
9         "google.golang.org/genproto/protobuf/field_mask"
10 )
11
12 // FieldMaskFromRequestBody creates a FieldMask printing all complete paths from the JSON body.
13 func FieldMaskFromRequestBody(r io.Reader) (*field_mask.FieldMask, error) {
14         fm := &field_mask.FieldMask{}
15         var root interface{}
16         if err := json.NewDecoder(r).Decode(&root); err != nil {
17                 if err == io.EOF {
18                         return fm, nil
19                 }
20                 return nil, err
21         }
22
23         queue := []fieldMaskPathItem{{node: root}}
24         for len(queue) > 0 {
25                 // dequeue an item
26                 item := queue[0]
27                 queue = queue[1:]
28
29                 if m, ok := item.node.(map[string]interface{}); ok {
30                         // if the item is an object, then enqueue all of its children
31                         for k, v := range m {
32                                 queue = append(queue, fieldMaskPathItem{path: append(item.path, generator.CamelCase(k)), node: v})
33                         }
34                 } else if len(item.path) > 0 {
35                         // otherwise, it's a leaf node so print its path
36                         fm.Paths = append(fm.Paths, strings.Join(item.path, "."))
37                 }
38         }
39
40         return fm, nil
41 }
42
43 // fieldMaskPathItem stores a in-progress deconstruction of a path for a fieldmask
44 type fieldMaskPathItem struct {
45         // the list of prior fields leading up to node
46         path []string
47
48         // a generic decoded json object the current item to inspect for further path extraction
49         node interface{}
50 }
51
52 // CamelCaseFieldMask updates the given FieldMask by converting all of its paths to CamelCase, using the same heuristic
53 // that's used for naming protobuf fields in Go.
54 func CamelCaseFieldMask(mask *field_mask.FieldMask) {
55         if mask == nil || mask.Paths == nil {
56                 return
57         }
58
59         var newPaths []string
60         for _, path := range mask.Paths {
61                 lowerCasedParts := strings.Split(path, ".")
62                 var camelCasedParts []string
63                 for _, part := range lowerCasedParts {
64                         camelCasedParts = append(camelCasedParts, generator.CamelCase(part))
65                 }
66                 newPaths = append(newPaths, strings.Join(camelCasedParts, "."))
67         }
68
69         mask.Paths = newPaths
70 }