mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
Merge pull request #23871 from smarterclayton/proto_timestamp
Implement a simpler unversioned.Time serialization
This commit is contained in:
commit
6d954a1490
@ -135,8 +135,9 @@ func (g *genProtoIDL) GenerateType(c *generator.Context, t *types.Type, w io.Wri
|
|||||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||||
b := bodyGen{
|
b := bodyGen{
|
||||||
locator: &protobufLocator{
|
locator: &protobufLocator{
|
||||||
namer: c.Namers["proto"].(ProtobufFromGoNamer),
|
namer: c.Namers["proto"].(ProtobufFromGoNamer),
|
||||||
tracker: g.imports,
|
tracker: g.imports,
|
||||||
|
universe: c.Universe,
|
||||||
|
|
||||||
localGoPackage: g.localGoPackage.Package,
|
localGoPackage: g.localGoPackage.Package,
|
||||||
},
|
},
|
||||||
@ -164,12 +165,14 @@ type ProtobufFromGoNamer interface {
|
|||||||
|
|
||||||
type ProtobufLocator interface {
|
type ProtobufLocator interface {
|
||||||
ProtoTypeFor(t *types.Type) (*types.Type, error)
|
ProtoTypeFor(t *types.Type) (*types.Type, error)
|
||||||
|
GoTypeForName(name types.Name) *types.Type
|
||||||
CastTypeName(name types.Name) string
|
CastTypeName(name types.Name) string
|
||||||
}
|
}
|
||||||
|
|
||||||
type protobufLocator struct {
|
type protobufLocator struct {
|
||||||
namer ProtobufFromGoNamer
|
namer ProtobufFromGoNamer
|
||||||
tracker namer.ImportTracker
|
tracker namer.ImportTracker
|
||||||
|
universe types.Universe
|
||||||
|
|
||||||
localGoPackage string
|
localGoPackage string
|
||||||
}
|
}
|
||||||
@ -183,6 +186,13 @@ func (p protobufLocator) CastTypeName(name types.Name) string {
|
|||||||
return name.String()
|
return name.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p protobufLocator) GoTypeForName(name types.Name) *types.Type {
|
||||||
|
if len(name.Package) == 0 {
|
||||||
|
name.Package = p.localGoPackage
|
||||||
|
}
|
||||||
|
return p.universe.Type(name)
|
||||||
|
}
|
||||||
|
|
||||||
// ProtoTypeFor locates a Protobuf type for the provided Go type (if possible).
|
// ProtoTypeFor locates a Protobuf type for the provided Go type (if possible).
|
||||||
func (p protobufLocator) ProtoTypeFor(t *types.Type) (*types.Type, error) {
|
func (p protobufLocator) ProtoTypeFor(t *types.Type) (*types.Type, error) {
|
||||||
switch {
|
switch {
|
||||||
@ -231,6 +241,7 @@ func (b bodyGen) doStruct(sw *generator.SnippetWriter) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var alias *types.Type
|
||||||
var fields []protoField
|
var fields []protoField
|
||||||
options := []string{}
|
options := []string{}
|
||||||
allOptions := types.ExtractCommentTags("+", b.t.CommentLines)
|
allOptions := types.ExtractCommentTags("+", b.t.CommentLines)
|
||||||
@ -254,6 +265,14 @@ func (b bodyGen) doStruct(sw *generator.SnippetWriter) error {
|
|||||||
options = append(options, fmt.Sprintf("%s = %s", key, v))
|
options = append(options, fmt.Sprintf("%s = %s", key, v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// protobuf.as allows a type to have the same message contents as another Go type
|
||||||
|
case k == "protobuf.as":
|
||||||
|
fields = nil
|
||||||
|
if alias = b.locator.GoTypeForName(types.Name{Name: v}); alias == nil {
|
||||||
|
return fmt.Errorf("type %v references alias %q which does not exist", b.t, v)
|
||||||
|
}
|
||||||
|
// protobuf.embed instructs the generator to use the named type in this package
|
||||||
|
// as an embedded message.
|
||||||
case k == "protobuf.embed":
|
case k == "protobuf.embed":
|
||||||
fields = []protoField{
|
fields = []protoField{
|
||||||
{
|
{
|
||||||
@ -270,10 +289,13 @@ func (b bodyGen) doStruct(sw *generator.SnippetWriter) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if alias == nil {
|
||||||
|
alias = b.t
|
||||||
|
}
|
||||||
|
|
||||||
// If we don't explicitly embed anything, generate fields by traversing fields.
|
// If we don't explicitly embed anything, generate fields by traversing fields.
|
||||||
if fields == nil {
|
if fields == nil {
|
||||||
memberFields, err := membersToFields(b.locator, b.t, b.localPackage, b.omitFieldTypes)
|
memberFields, err := membersToFields(b.locator, alias, b.localPackage, b.omitFieldTypes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("type %v cannot be converted to protobuf: %v", b.t, err)
|
return fmt.Errorf("type %v cannot be converted to protobuf: %v", b.t, err)
|
||||||
}
|
}
|
||||||
@ -454,7 +476,7 @@ func memberTypeToProtobufField(locator ProtobufLocator, field *protoField, t *ty
|
|||||||
|
|
||||||
// protobufTagToField extracts information from an existing protobuf tag
|
// protobufTagToField extracts information from an existing protobuf tag
|
||||||
func protobufTagToField(tag string, field *protoField, m types.Member, t *types.Type, localPackage types.Name) error {
|
func protobufTagToField(tag string, field *protoField, m types.Member, t *types.Type, localPackage types.Name) error {
|
||||||
if len(tag) == 0 {
|
if len(tag) == 0 || tag == "-" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,7 +131,11 @@ func assignGoTypeToProtoPackage(p *protobufPackage, t *types.Type, local, global
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
field := &protoField{}
|
field := &protoField{}
|
||||||
if err := protobufTagToField(reflect.StructTag(m.Tags).Get("protobuf"), field, m, t, p.ProtoTypeName()); err == nil && field.Type != nil {
|
tag := reflect.StructTag(m.Tags).Get("protobuf")
|
||||||
|
if tag == "-" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err := protobufTagToField(tag, field, m, t, p.ProtoTypeName()); err == nil && field.Type != nil {
|
||||||
assignGoTypeToProtoPackage(p, field.Type, local, global)
|
assignGoTypeToProtoPackage(p, field.Type, local, global)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -28,8 +28,9 @@ import (
|
|||||||
// of the factory methods that the time package offers.
|
// of the factory methods that the time package offers.
|
||||||
//
|
//
|
||||||
// +protobuf.options.marshal=false
|
// +protobuf.options.marshal=false
|
||||||
|
// +protobuf.as=Timestamp
|
||||||
type Time struct {
|
type Time struct {
|
||||||
time.Time `protobuf:"Timestamp,1,req,name=time"`
|
time.Time `protobuf:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTime returns a wrapped instance of the provided time
|
// NewTime returns a wrapped instance of the provided time
|
||||||
|
@ -22,15 +22,9 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ProtoTime is a struct that is equivalent to Time, but intended for
|
// Timestamp is a struct that is equivalent to Time, but intended for
|
||||||
// protobuf marshalling/unmarshalling. It is generated into a serialization
|
// protobuf marshalling/unmarshalling. It is generated into a serialization
|
||||||
// that matches Time. Do not use in Go structs.
|
// that matches Time. Do not use in Go structs.
|
||||||
type ProtoTime struct {
|
|
||||||
// Represents the time of an event.
|
|
||||||
Timestamp Timestamp `json:"timestamp"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Timestamp is a protobuf Timestamp compatible representation of time.Time
|
|
||||||
type Timestamp struct {
|
type Timestamp struct {
|
||||||
// Represents seconds of UTC time since Unix epoch
|
// Represents seconds of UTC time since Unix epoch
|
||||||
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
|
// 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
|
||||||
@ -39,20 +33,18 @@ type Timestamp struct {
|
|||||||
// Non-negative fractions of a second at nanosecond resolution. Negative
|
// Non-negative fractions of a second at nanosecond resolution. Negative
|
||||||
// second values with fractions must still have non-negative nanos values
|
// second values with fractions must still have non-negative nanos values
|
||||||
// that count forward in time. Must be from 0 to 999,999,999
|
// that count forward in time. Must be from 0 to 999,999,999
|
||||||
// inclusive.
|
// inclusive. This field may be limited in precision depending on context.
|
||||||
Nanos int32 `json:"nanos"`
|
Nanos int32 `json:"nanos"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProtoTime returns the Time as a new ProtoTime value.
|
// Timestamp returns the Time as a new Timestamp value.
|
||||||
func (m *Time) ProtoTime() *ProtoTime {
|
func (m *Time) ProtoTime() *Timestamp {
|
||||||
if m == nil {
|
if m == nil {
|
||||||
return &ProtoTime{}
|
return &Timestamp{}
|
||||||
}
|
}
|
||||||
return &ProtoTime{
|
return &Timestamp{
|
||||||
Timestamp: Timestamp{
|
Seconds: m.Time.Unix(),
|
||||||
Seconds: m.Time.Unix(),
|
Nanos: int32(m.Time.Nanosecond()),
|
||||||
Nanos: int32(m.Time.Nanosecond()),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,11 +53,11 @@ func (m *Time) Size() (n int) { return m.ProtoTime().Size() }
|
|||||||
|
|
||||||
// Reset implements the protobuf marshalling interface.
|
// Reset implements the protobuf marshalling interface.
|
||||||
func (m *Time) Unmarshal(data []byte) error {
|
func (m *Time) Unmarshal(data []byte) error {
|
||||||
p := ProtoTime{}
|
p := Timestamp{}
|
||||||
if err := p.Unmarshal(data); err != nil {
|
if err := p.Unmarshal(data); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
m.Time = time.Unix(p.Timestamp.Seconds, int64(p.Timestamp.Nanos))
|
m.Time = time.Unix(p.Seconds, int64(p.Nanos))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user