protobuf-go/cmd/protoc-gen-go/internal_gengo/flags.go
Joe Tsai 26aef9d6d6 cmd/protoc-gen-go: add support for field-tracking
Field-tracking is an experimental feature in the Go linker
where it statically tracks whether a Go struct field is used.
This CL modifies the generator to emit special markers that
tells the linker to know which fields to track.

Change-Id: I235da3f3d6c0ef2021b5fe1c16106ebb8fd6f557
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/189558
Reviewed-by: Damien Neil <dneil@google.com>
2019-08-26 17:54:17 +00:00

52 lines
1.4 KiB
Go

// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package internal_gengo
import (
"google.golang.org/protobuf/compiler/protogen"
"google.golang.org/protobuf/internal/encoding/wire"
"google.golang.org/protobuf/types/descriptorpb"
)
// messageFlags provides flags that control the generated API.
type messageFlags struct {
IsTracked bool
HasWeak bool
}
func loadMessageFlags(message *protogen.Message) messageFlags {
var flags messageFlags
flags.IsTracked = isTrackedMessage(message)
for _, field := range message.Fields {
if field.Desc.IsWeak() {
flags.HasWeak = true
break
}
}
return flags
}
// isTrackedMessage reports whether field tracking is enabled on the message.
// It is a variable so that the behavior is easily overridden in another file.
var isTrackedMessage = func(message *protogen.Message) (tracked bool) {
const trackFieldUse_fieldNumber = 37383685
// Decode the option from unknown fields to avoid a dependency on the
// annotation proto from protoc-gen-go.
b := message.Desc.Options().(*descriptorpb.MessageOptions).ProtoReflect().GetUnknown()
for len(b) > 0 {
num, typ, n := wire.ConsumeTag(b)
b = b[n:]
if num == trackFieldUse_fieldNumber && typ == wire.VarintType {
v, _ := wire.ConsumeVarint(b)
tracked = wire.DecodeBool(v)
}
m := wire.ConsumeFieldValue(num, typ, b)
b = b[m:]
}
return tracked
}