goprotobuf-go

How to correctly determine the type of variable google.protobuf.Any?


Please tell me what is wrong in this code, why the type is not determined for the variable, for the transmitted url type google.protobuf.Any?

package main

import (
    "fmt"

    "google.golang.org/protobuf/reflect/protoreflect"
    "google.golang.org/protobuf/reflect/protoregistry"
)

func main() {
    var res protoregistry.MessageTypeResolver = protoregistry.GlobalTypes
    typeUrl := "type.googleapis.com/google.protobuf.StringValue"
    fmt.Println(protoreflect.FullName(typeUrl))
    msgType, err := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName("google.protobuf.StringValue"))
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(msgType)

    msgType, err = res.FindMessageByURL(typeUrl)
    if err != nil {
        fmt.Println(err)
    }
    fmt.Println(msgType)
}

proto: not found proto: not found


Solution

  • The error is protoregistry.NotFound because there are not message types got registered in protoregistry.GlobalTypes.

    To register google.protobuf.Any, you should import the package google.golang.org/protobuf/types/known/anypb. And google.protobuf.Any is registered by the init function of that package (see the source code).

    To register google.protobuf.StringValue, you should import the package google.golang.org/protobuf/types/known/wrapperspb.

    Here is the updated demo that finds the message byte of google.protobuf.StringValue:

    package main
    
    import (
        "fmt"
    
        "google.golang.org/protobuf/reflect/protoregistry"
        // importing the package solely for its side-effects (initialization).
        // See https://go.dev/ref/spec#Import_declarations.
        _ "google.golang.org/protobuf/types/known/anypb"
        _ "google.golang.org/protobuf/types/known/wrapperspb"
    )
    
    func main() {
        res := protoregistry.GlobalTypes
        fmt.Println("NumMessages:", res.NumMessages())
    
        msgType, err := protoregistry.GlobalTypes.FindMessageByName("google.protobuf.StringValue")
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println(msgType)
    
        msgType, err = res.FindMessageByURL("type.googleapis.com/google.protobuf.StringValue")
        if err != nil {
            fmt.Println(err)
        }
        fmt.Println(msgType)
    }