-
Notifications
You must be signed in to change notification settings - Fork 75
/
proto.go
124 lines (108 loc) · 3.19 KB
/
proto.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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
*
* http://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.
*/
package proto
import (
"bytes"
"fmt"
)
import (
"github.com/golang/protobuf/jsonpb"
protov1 "github.com/golang/protobuf/proto"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/structpb"
"sigs.k8s.io/yaml"
)
// Note: we continue to use github.com/golang/protobuf/jsonpb because it
// unmarshals types the way we expect in go.
// See https://github.com/golang/protobuf/issues/1374
func FromYAML(content []byte, pb proto.Message) error {
json, err := yaml.YAMLToJSON(content)
if err != nil {
return err
}
return FromJSON(json, pb)
}
func ToYAML(pb proto.Message) ([]byte, error) {
marshaler := &jsonpb.Marshaler{}
json, err := marshaler.MarshalToString(protov1.MessageV1(pb))
if err != nil {
return nil, err
}
return yaml.JSONToYAML([]byte(json))
}
func ToJSON(pb proto.Message) ([]byte, error) {
var buf bytes.Buffer
marshaler := &jsonpb.Marshaler{}
if err := marshaler.Marshal(&buf, protov1.MessageV1(pb)); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func ToJSONIndent(pb proto.Message, indent string) ([]byte, error) {
var buf bytes.Buffer
marshaler := &jsonpb.Marshaler{
Indent: indent,
}
if err := marshaler.Marshal(&buf, protov1.MessageV1(pb)); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func MustMarshalJSON(in proto.Message) []byte {
content, err := ToJSON(in)
if err != nil {
panic(fmt.Sprintf("failed to marshal %T: %s", in, err))
}
return content
}
func FromJSON(content []byte, out proto.Message) error {
unmarshaler := &jsonpb.Unmarshaler{AllowUnknownFields: true}
return unmarshaler.Unmarshal(bytes.NewReader(content), protov1.MessageV1(out))
}
// Converts loosely typed Struct to strongly typed Message
func ToTyped(protoStruct *structpb.Struct, message proto.Message) error {
if protoStruct == nil {
return nil
}
configBytes, err := ToJSON(protoStruct)
if err != nil {
return err
}
if err := FromJSON(configBytes, message); err != nil {
return err
}
return nil
}
// Converts loosely typed Struct to strongly typed Message
func ToStruct(message proto.Message) (*structpb.Struct, error) {
configBytes, err := ToJSON(message)
if err != nil {
return nil, err
}
str := &structpb.Struct{}
if err := FromJSON(configBytes, str); err != nil {
return nil, err
}
return str, nil
}
func MustToStruct(message proto.Message) *structpb.Struct {
str, err := ToStruct(message)
if err != nil {
panic(err)
}
return str
}