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 {