blob: bed0b922c0dcc86d385e8b54f694da1f91e5ff44 [file] [log] [blame]
/*
* 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
}