protoc generates value instead of pointer (Go)

41 views
Skip to first unread message

Klim Sidorov

unread,
Jun 18, 2020, 11:30:21 AM6/18/20
to Protocol Buffers
Hello!

The question is:
How can I make protoc generate a pointer to the value?

The problem:
I have 2 files in the root directory.
I use Makefile to generate Go code from .proto files.

But the language field in the Video struct is a value not a pointer to the value.
And the subtitles field in the Video struct is an array of values not an array of pointers to the value.

video.pb.go

type Video struct {
    state protoimpl
.MessageState
    sizeCache protoimpl
.SizeCache
    unknownFields protoimpl
.UnknownFields

    Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
    Title string `protobuf:"bytes,2,opt,name=title,proto3" json:"title,omitempty"`
    Languages language.ISO639_1 `protobuf:"varint,3,opt,name=languages,proto3,enum=language.ISO639_1" json:"languages,omitempty"`
    Subtitles []language.ISO639_1 `protobuf:"varint,4,rep,packed,name=subtitles,proto3,enum=language.ISO639_1" json:"subtitles,omitempty"`
}


Makefile

gen:
   
# Video
   protoc
-I. --go_out=plugins=grpc,paths=source_relative:video video.proto

   
# Language
   protoc
-I. --go_out=plugins=grpc,paths=source_relative:language language.proto


language.proto

syntax = "proto3";

package language;

option go_package
= "example.com/group/repo/language;language";

enum ISO639_1 {
    UNKNOWN
= 0;
    zh      
= 1;
}


video.proto

syntax = "proto3";

package video;

import "language.proto";

option go_package
= "example.com/group/repo/video;video";

message
Video {
   
string            id       = 1;
   
string            title     = 2;
    language
.ISO639_1 language = 3;
    repeated language.ISO639_1 subtitles = 4;
}

Josh Humphries

unread,
Jun 18, 2020, 12:41:37 PM6/18/20
to Protocol Buffers
The simplest answer is to use syntax="proto2" for that. In proto3, it is intentional that you cannot distinguish between absence and zero value for scalar fields.

However, a new "proto3 optional" feature is now available that allows this. It allows you to add the "optional" keyword to a field, where you might otherwise have specified "repeated". The feature is in a kind of beta. You must be using 3.12 of protoc or newer and you must enable the feature via a flag: --experimental_allow_proto3_optional. You also need to be using a very recent protoc-gen-go (v1.22 or newer from the google.golang.org/protobuf import path, or v1.4.1 or newer from github.com/golang/protobuf).

----
Josh Humphries
jh...@bluegosling.com


--
You received this message because you are subscribed to the Google Groups "Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to protobuf+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/protobuf/eac045ed-aceb-401c-a6ba-1de876c7bfdbo%40googlegroups.com.

Klim Sidorov

unread,
Jun 18, 2020, 3:22:36 PM6/18/20
to Protocol Buffers
Thank you for the response!

I have tried to solve this problem with "new" optional feature, but it doesn't work with the repeated field (that can be solved using the wrapper which contains an optional field).

But I have found that the problem only happens when proto files have different package names. If they are the same - protoc will generate pointer in both cases (pointer to struct and array of pointers).

I don't know if it is a bug, but we have a solution with wrappers and that is good news!
To unsubscribe from this group and stop receiving emails from it, send an email to prot...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages