Browse Source

Add compatibility markers to proto generated code.

This asserts at build time that the generated code is compatible with
the proto package that it is linked to.
David Symonds 10 years ago
parent
commit
2402d76f3d

+ 4 - 0
jsonpb/jsonpb_test_proto/more_test_objects.pb.go

@@ -31,6 +31,10 @@ 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.
+const _ = proto.ProtoPackageIsVersion1
+
 type Simple3 struct {
 	Dub float64 `protobuf:"fixed64,1,opt,name=dub" json:"dub,omitempty"`
 }

+ 4 - 0
proto/lib.go

@@ -887,3 +887,7 @@ func isProto3Zero(v reflect.Value) bool {
 	}
 	return false
 }
+
+// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
+// to assert that that code is compatible with this version of the proto package.
+const ProtoPackageIsVersion1 = true

+ 4 - 0
proto/testdata/test.pb.go

@@ -50,6 +50,10 @@ 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.
+const _ = proto.ProtoPackageIsVersion1
+
 type FOO int32
 
 const (

+ 4 - 0
protoc-gen-go/descriptor/descriptor.pb.go

@@ -39,6 +39,10 @@ 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.
+const _ = proto.ProtoPackageIsVersion1
+
 type FieldDescriptorProto_Type int32
 
 const (

+ 14 - 0
protoc-gen-go/generator/generator.go

@@ -58,6 +58,12 @@ import (
 	plugin "github.com/golang/protobuf/protoc-gen-go/plugin"
 )
 
+// generatedCodeVersion indicates a version of the generated code.
+// It is incremented whenever an incompatibility between the generated code and
+// proto package is introduced; the generated code references
+// a constant, proto.ProtoPackageIsVersionN (where N is generatedCodeVersion).
+const generatedCodeVersion = 1
+
 // A Plugin provides functionality to add to the output during Go code generation,
 // such as to produce RPC stubs.
 type Plugin interface {
@@ -1122,6 +1128,14 @@ func (g *Generator) generate(file *FileDescriptor) {
 	g.file = g.FileOf(file.FileDescriptorProto)
 	g.usedPackages = make(map[string]bool)
 
+	if g.file.index == 0 {
+		// For one file in the package, assert version compatibility.
+		g.P("// This is a compile-time assertion to ensure that this generated file")
+		g.P("// is compatible with the proto package it is being compiled against.")
+		g.P("const _ = ", g.Pkg["proto"], ".ProtoPackageIsVersion", generatedCodeVersion)
+		g.P()
+	}
+
 	for _, td := range g.file.imp {
 		g.generateImported(td)
 	}

+ 4 - 0
protoc-gen-go/plugin/plugin.pb.go

@@ -24,6 +24,10 @@ 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.
+const _ = proto.ProtoPackageIsVersion1
+
 // An encoded CodeGeneratorRequest is written to the plugin's stdin.
 type CodeGeneratorRequest struct {
 	// The .proto files that were explicitly listed on the command-line.  The

+ 4 - 0
protoc-gen-go/testdata/my_test/test.pb.go

@@ -31,6 +31,10 @@ 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.
+const _ = proto.ProtoPackageIsVersion1
+
 type HatType int32
 
 const (

+ 4 - 0
protoc-gen-go/testdata/my_test/test.pb.go.golden

@@ -31,6 +31,10 @@ 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.
+const _ = proto.ProtoPackageIsVersion1
+
 type HatType int32
 
 const (