Closed Patrick0308 closed 1 year ago
I need to look at this in a bit more detail to see if this is an appropriate solution, but let's first take a step back: why are you writing your own protojson marshaller? What is missing from package protojson?
@aktau Thanks, for your reply. We want to add some protojson decode rules to support the ways we use. Now our grpc service unmarshal the json requests from http gateway to protobuf parameter by jsonproto. Http gateway will transfer request's url parameter to json. This an transfer example:
http://github.com/golang/protobuf/issues/1497?p1=true
Http gateway know 1497 is issueId. So gateway will generate the json requests
{
"issueId": "1497",
"p1":"true"
}
We want to protojson can unmarshal "true" to bool field successfully. There are other decode rules to support this way. And we also hope own protojson unmarshaler and marshaler compatible with official protojson.
Actually now I can implement own protojson unmarshaler, but marshaler cant because of typeURLFieldRanger. In the scenario we use, I can use official marshaler and own unmarshaler. But I think it will confuses others. So I want to implement own marshaler too.
You don't need access to this type, you can construct it locally:
// typeFieldDesc is a synthetic field descriptor used for the "@type" field.
type typeFieldDesc struct{ protoreflect.FieldDescriptor }
func (typeFieldDesc) Kind() protoreflect.Kind { return protoreflect.StringKind }
func (typeFieldDesc) Index() int { return -1 }
func (typeFieldDesc) FullName() protoreflect.FullName { return "@type" }
func (typeFieldDesc) JSONName() string { return "@type" }
func (typeFieldDesc) TextName() string { return "@type" }
func (typeFieldDesc) IsMap() bool { return false }
func (typeFieldDesc) IsList() bool { return false }
func (typeFieldDesc) IsExtension() bool { return false }
And modify the typeURLFieldRanger.Range
method as follows:
func (m typeURLFieldRanger) Range(f func(protoreflect.FieldDescriptor, protoreflect.Value) bool) {
- if !f(typeFieldDesc, protoreflect.ValueOfString(m.typeURL)) {
+ if !f(typeFieldDesc{}, protoreflect.ValueOfString(m.typeURL)) {
return
}
m.FieldRanger.Range(f)
}
@dsnet Thanks, it works.
Is your feature request related to a problem? Please describe. I want to write a myself protojson marshaler. I cannot implement protoreflect.FieldDescriptor. It's not a problem. However I also want implement typeURLFieldRanger. I cannot do it. In protojson encoder define the typeFieldDesc.
https://github.com/protocolbuffers/protobuf-go/blob/7a48e2b66218ba306ed801e42126b374aefce255/encoding/protojson/encode.go#L150
Describe the solution you'd like Move "typeFieldDesc" to reflect package or other package then export it. Or just export it on protojson package.
Describe alternatives you've considered
Additional context