12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- package runtime
- import (
- "encoding/json"
- "io"
- "strings"
- "github.com/golang/protobuf/protoc-gen-go/generator"
- "google.golang.org/genproto/protobuf/field_mask"
- )
- // FieldMaskFromRequestBody creates a FieldMask printing all complete paths from the JSON body.
- func FieldMaskFromRequestBody(r io.Reader) (*field_mask.FieldMask, error) {
- fm := &field_mask.FieldMask{}
- var root interface{}
- if err := json.NewDecoder(r).Decode(&root); err != nil {
- if err == io.EOF {
- return fm, nil
- }
- return nil, err
- }
- queue := []fieldMaskPathItem{{node: root}}
- for len(queue) > 0 {
- // dequeue an item
- item := queue[0]
- queue = queue[1:]
- if m, ok := item.node.(map[string]interface{}); ok {
- // if the item is an object, then enqueue all of its children
- for k, v := range m {
- queue = append(queue, fieldMaskPathItem{path: append(item.path, generator.CamelCase(k)), node: v})
- }
- } else if len(item.path) > 0 {
- // otherwise, it's a leaf node so print its path
- fm.Paths = append(fm.Paths, strings.Join(item.path, "."))
- }
- }
- return fm, nil
- }
- // fieldMaskPathItem stores a in-progress deconstruction of a path for a fieldmask
- type fieldMaskPathItem struct {
- // the list of prior fields leading up to node
- path []string
- // a generic decoded json object the current item to inspect for further path extraction
- node interface{}
- }
- // CamelCaseFieldMask updates the given FieldMask by converting all of its paths to CamelCase, using the same heuristic
- // that's used for naming protobuf fields in Go.
- func CamelCaseFieldMask(mask *field_mask.FieldMask) {
- if mask == nil || mask.Paths == nil {
- return
- }
- var newPaths []string
- for _, path := range mask.Paths {
- lowerCasedParts := strings.Split(path, ".")
- var camelCasedParts []string
- for _, part := range lowerCasedParts {
- camelCasedParts = append(camelCasedParts, generator.CamelCase(part))
- }
- newPaths = append(newPaths, strings.Join(camelCasedParts, "."))
- }
- mask.Paths = newPaths
- }
|