| /* |
| * 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 |
| } |