When trying to use extensions nested in a message, a build error happens with a error message like "cannot convert nil to type bool."
In generator.go, I'm expecting the extension fields should reach needsStar(), but actually they won't because they have a parent and the parent's syntax is considered as proto3.
protoc version: libprotoc 3.3.2
golang/protobuf: using the current master https://github.com/golang/protobuf/tree/130e6b02ab059e7b717a096f397c5b60111cae74
~/go/src/github.com/occho/protobuf-test/test$ pwd
<home>/go/src/github.com/occho/protobuf-test/test
~/go/src/github.com/occho/protobuf-test/test$ ls
test.proto
~/go/src/github.com/occho/protobuf-test/test$ protoc --go_out=${GOPATH}/src test.proto
~/go/src/github.com/occho/protobuf-test/test$ go build
# github.com/occho/protobuf-test/test
./test.pb.go:41:23: cannot convert nil to type bool
./test.pb.go:50:25: cannot convert nil to type string
./test.pb.go:59:24: cannot convert nil to type int32
syntax = "proto3";
package test;
import "google/protobuf/descriptor.proto";
option go_package = "github.com/occho/protobuf-test/test";
message Namespace {
extend google.protobuf.FieldOptions {
bool namespace_bool = 50001;
string namespace_string = 50002;
int32 namespace_int32 = 50003;
}
}
extend google.protobuf.FieldOptions {
bool my_bool = 51001;
string my_string = 51002;
int32 my_int32 = 51003;
}
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: test.proto
/*
Package test is a generated protocol buffer package.
It is generated from these files:
test.proto
It has these top-level messages:
Namespace
*/
package test
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import google_protobuf "github.com/golang/protobuf/protoc-gen-go/descriptor"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
type Namespace struct {
}
func (m *Namespace) Reset() { *m = Namespace{} }
func (m *Namespace) String() string { return proto.CompactTextString(m) }
func (*Namespace) ProtoMessage() {}
func (*Namespace) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
var E_Namespace_NamespaceBool = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.FieldOptions)(nil),
ExtensionType: (bool)(nil),
Field: 50001,
Name: "test.Namespace.namespace_bool",
Tag: "varint,50001,opt,name=namespace_bool,json=namespaceBool",
Filename: "test.proto",
}
var E_Namespace_NamespaceString = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.FieldOptions)(nil),
ExtensionType: (string)(nil),
Field: 50002,
Name: "test.Namespace.namespace_string",
Tag: "bytes,50002,opt,name=namespace_string,json=namespaceString",
Filename: "test.proto",
}
var E_Namespace_NamespaceInt32 = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.FieldOptions)(nil),
ExtensionType: (int32)(nil),
Field: 50003,
Name: "test.Namespace.namespace_int32",
Tag: "varint,50003,opt,name=namespace_int32,json=namespaceInt32",
Filename: "test.proto",
}
var E_MyBool = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.FieldOptions)(nil),
ExtensionType: (*bool)(nil),
Field: 51001,
Name: "test.my_bool",
Tag: "varint,51001,opt,name=my_bool,json=myBool",
Filename: "test.proto",
}
var E_MyString = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.FieldOptions)(nil),
ExtensionType: (*string)(nil),
Field: 51002,
Name: "test.my_string",
Tag: "bytes,51002,opt,name=my_string,json=myString",
Filename: "test.proto",
}
var E_MyInt32 = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.FieldOptions)(nil),
ExtensionType: (*int32)(nil),
Field: 51003,
Name: "test.my_int32",
Tag: "varint,51003,opt,name=my_int32,json=myInt32",
Filename: "test.proto",
}
func init() {
proto.RegisterType((*Namespace)(nil), "test.Namespace")
proto.RegisterExtension(E_Namespace_NamespaceBool)
proto.RegisterExtension(E_Namespace_NamespaceString)
proto.RegisterExtension(E_Namespace_NamespaceInt32)
proto.RegisterExtension(E_MyBool)
proto.RegisterExtension(E_MyString)
proto.RegisterExtension(E_MyInt32)
}
func init() { proto.RegisterFile("test.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 267 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2a, 0x49, 0x2d, 0x2e,
0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x01, 0xb1, 0xa5, 0x14, 0xd2, 0xf3, 0xf3, 0xd3,
0x73, 0x52, 0xf5, 0xc1, 0x62, 0x49, 0xa5, 0x69, 0xfa, 0x29, 0xa9, 0xc5, 0xc9, 0x45, 0x99, 0x05,
0x25, 0xf9, 0x45, 0x10, 0x75, 0x4a, 0x2f, 0x19, 0xb9, 0x38, 0xfd, 0x12, 0x73, 0x53, 0x8b, 0x0b,
0x12, 0x93, 0x53, 0x8d, 0xdc, 0xb8, 0xf8, 0xf2, 0x60, 0x9c, 0xf8, 0xa4, 0xfc, 0xfc, 0x1c, 0x21,
0x59, 0x3d, 0x88, 0x11, 0x7a, 0x30, 0x23, 0xf4, 0xdc, 0x32, 0x53, 0x73, 0x52, 0xfc, 0x0b, 0x4a,
0x32, 0xf3, 0xf3, 0x8a, 0x25, 0x2e, 0xb6, 0x31, 0x2b, 0x30, 0x6a, 0x70, 0x04, 0xf1, 0xc2, 0xb5,
0x39, 0xe5, 0xe7, 0xe7, 0x18, 0x79, 0x71, 0x09, 0x20, 0xcc, 0x29, 0x2e, 0x29, 0xca, 0xcc, 0x4b,
0x27, 0x64, 0xd2, 0x25, 0xb0, 0x49, 0x9c, 0x41, 0xfc, 0x70, 0x8d, 0xc1, 0x60, 0x7d, 0x46, 0x1e,
0x5c, 0x08, 0xa1, 0xf8, 0xcc, 0xbc, 0x12, 0x63, 0x23, 0x42, 0x46, 0x5d, 0x06, 0x1b, 0xc5, 0x1a,
0x84, 0xf0, 0x8b, 0x27, 0x48, 0x9b, 0x95, 0x05, 0x17, 0x7b, 0x6e, 0x25, 0x51, 0xde, 0xda, 0xd9,
0x07, 0xf1, 0x16, 0x5b, 0x6e, 0x25, 0xc8, 0x3f, 0x56, 0x36, 0x5c, 0x9c, 0xb9, 0x95, 0x44, 0x7a,
0x64, 0x57, 0x1f, 0xc4, 0x23, 0x1c, 0xb9, 0x95, 0x10, 0x1f, 0x58, 0x59, 0x71, 0x71, 0xe4, 0x56,
0x12, 0xe7, 0xf4, 0xdd, 0x7d, 0x10, 0xa7, 0xb3, 0xe7, 0x56, 0x82, 0xdd, 0xec, 0xa4, 0x1a, 0xa5,
0x9c, 0x9e, 0x59, 0x92, 0x51, 0x9a, 0xa4, 0x97, 0x9c, 0x9f, 0xab, 0x9f, 0x9f, 0x9c, 0x9c, 0x91,
0x0f, 0x8f, 0x4d, 0x5d, 0x50, 0x1c, 0xeb, 0x83, 0x88, 0x24, 0x36, 0xb0, 0x98, 0x31, 0x20, 0x00,
0x00, 0xff, 0xff, 0x6c, 0xa5, 0xed, 0x4d, 0x03, 0x02, 0x00, 0x00,
}
This issue is originally posted in https://groups.google.com/forum/#!topic/protobuf/MCtjXxkndzw.
I don't know what side-effect it has, but when passing extDesc instead of ext.parent, the error disappears.
@occho, I've looked a bit at the code and IMO your proposal, to pass the extended message to GoType instead of the enclosing message, is correct. Since extensions are proto2 (old syntax, seem to be getting less attention from the proto team), I think you'll have higher chance of getting a fix landed if you send a PR, instead of waiting for a fix.
The v2 rewrite of protoc-gen-go fixes this issue (see http://golang.org/cl/144282). Unfortunately, the fix won't land in protoc-gen-go for some period of time.
This should be fixed in the v1.20.0 release
The v1.20.0 release fixes this issue.
Most helpful comment
@occho, I've looked a bit at the code and IMO your proposal, to pass the extended message to
GoTypeinstead of the enclosing message, is correct. Since extensions are proto2 (old syntax, seem to be getting less attention from the proto team), I think you'll have higher chance of getting a fix landed if you send a PR, instead of waiting for a fix.