If you are using JavaScript, there may not be a good solution. Ironically, the JavaScript implementation of protos does not support the canonical JSON representation for protobuf types (which would be needed to convert arbitrary JSON into a
google.protobuf.Value).
Most other languages, though, should work fine. Here's a sketch in Go:
example.proto
syntax = "proto3";
import "google/protobuf/struct.proto";
message SomeMessage {
google.protobuf.Value arbitrary_json = 1;
}
example.go
package example
func example(json string) (*SomeMessage, error) {
msg := &SomeMessage{ArbitraryJson: &structpb.Value{}}
jsm := jsonpb.Marshaler{}
if err := jsm.Unmarshal(json, msg.ArbitraryJson); err != nil {
return nil, err
}
return msg, nil
}
You could also use the "encoding/json" package to then convert any kind of Go value into a google.protobuf.Value: you just have to marshal to JSON first, and from there into the protobuf. While using JSON as intermediate format is not efficient, you do get the benefit that a google.protobuf.Value created this way is guaranteed to be well-formed, whereas just using a string or bytes field could be garbage that is not proper JSON.