protoc-gen-go: Make proto3 scalar repeated fields packed by default (per the proto3 spec). This resolves #197.
diff --git a/protoc-gen-go/generator/generator.go b/protoc-gen-go/generator/generator.go index 095891c..4d7d19b 100644 --- a/protoc-gen-go/generator/generator.go +++ b/protoc-gen-go/generator/generator.go
@@ -1551,7 +1551,11 @@ enum += CamelCaseSlice(obj.TypeName()) } packed := "" - if field.Options != nil && field.Options.GetPacked() { + if (field.Options != nil && field.Options.GetPacked()) || + // Per https://developers.google.com/protocol-buffers/docs/proto3#simple: + // "In proto3, repeated fields of scalar numeric types use packed encoding by default." + (message.proto3() && (field.Options == nil || field.Options.Packed == nil) && + isRepeated(field) && isScalar(field)) { packed = ",packed" } fieldName := field.GetName() @@ -2732,6 +2736,32 @@ return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED } +// Is this field a scalar numeric type? +func isScalar(field *descriptor.FieldDescriptorProto) bool { + if field.Type == nil { + return false + } + switch *field.Type { + case descriptor.FieldDescriptorProto_TYPE_DOUBLE, + descriptor.FieldDescriptorProto_TYPE_FLOAT, + descriptor.FieldDescriptorProto_TYPE_INT64, + descriptor.FieldDescriptorProto_TYPE_UINT64, + descriptor.FieldDescriptorProto_TYPE_INT32, + descriptor.FieldDescriptorProto_TYPE_FIXED64, + descriptor.FieldDescriptorProto_TYPE_FIXED32, + descriptor.FieldDescriptorProto_TYPE_BOOL, + descriptor.FieldDescriptorProto_TYPE_UINT32, + descriptor.FieldDescriptorProto_TYPE_ENUM, + descriptor.FieldDescriptorProto_TYPE_SFIXED32, + descriptor.FieldDescriptorProto_TYPE_SFIXED64, + descriptor.FieldDescriptorProto_TYPE_SINT32, + descriptor.FieldDescriptorProto_TYPE_SINT64: + return true + default: + return false + } +} + // badToUnderscore is the mapping function used to generate Go names from package names, // which can be dotted in the input .proto file. It replaces non-identifier characters such as // dot or dash with underscore.
diff --git a/protoc-gen-go/testdata/proto3.proto b/protoc-gen-go/testdata/proto3.proto index c994914..869b9af 100644 --- a/protoc-gen-go/testdata/proto3.proto +++ b/protoc-gen-go/testdata/proto3.proto
@@ -44,6 +44,7 @@ repeated int64 key = 2; Flavour taste = 3; Book book = 4; + repeated int64 unpacked = 5 [packed=false]; } message Book {