Просмотр исходного кода

protoc-gen-go: Make proto3 scalar repeated fields packed by default (per the proto3 spec).

This resolves #197.
Bryan Mills 9 лет назад
Родитель
Сommit
2c2f7268d7
2 измененных файлов с 32 добавлено и 1 удалено
  1. 31 1
      protoc-gen-go/generator/generator.go
  2. 1 0
      protoc-gen-go/testdata/proto3.proto

+ 31 - 1
protoc-gen-go/generator/generator.go

@@ -1551,7 +1551,11 @@ func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptor
 		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 @@ func isRepeated(field *descriptor.FieldDescriptorProto) bool {
 	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.

+ 1 - 0
protoc-gen-go/testdata/proto3.proto

@@ -44,6 +44,7 @@ message Request {
   repeated int64 key = 2;
   Flavour taste = 3;
   Book book = 4;
+  repeated int64 unpacked = 5 [packed=false];
 }
 
 message Book {