protobuf-go/runtime/protoiface/methods.go

116 lines
3.6 KiB
Go
Raw Normal View History

// 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 protoiface contains types referenced or implemented by messages.
//
// WARNING: This package should only be imported by message implementations.
// The functionality found in this package should be accessed through
// higher-level abstractions provided by the proto package.
package protoiface
import (
"google.golang.org/protobuf/internal/pragma"
"google.golang.org/protobuf/reflect/protoreflect"
)
// Methods is a set of optional fast-path implementations of various operations.
type Methods = struct {
pragma.NoUnkeyedLiterals
// Flags indicate support for optional features.
Flags SupportFlags
// Size returns the size in bytes of the wire-format encoding of m.
// MarshalAppend must be provided if a custom Size is provided.
Size func(m protoreflect.Message, opts MarshalOptions) int
// Marshal writes the wire-format encoding of m to the provided buffer.
// Size should be provided if a custom MarshalAppend is provided.
// It should not return an error for a partial message.
Marshal func(m protoreflect.Message, in MarshalInput, opts MarshalOptions) (MarshalOutput, error)
// Unmarshal parses the wire-format encoding of a message and merges the result to m.
// It should not reset the target message or return an error for a partial message.
Unmarshal func(m protoreflect.Message, in UnmarshalInput, opts UnmarshalOptions) (UnmarshalOutput, error)
// IsInitialized returns an error if any required fields in m are not set.
runtime/protoiface: move and rename XXX_Methods This CL moves and renames the protoreflect.ProtoMessage.XXX_Methods to protoreflect.Message.ProtoMethods. Since one needs to obtain a protoreflect.Message now to get at the fast-path methods, we modify the method signatures to take in a protoreflect.Message instead of protoreflect.ProtoMessage. Doing so also avoids the wrapper hack that was formerly done on impl.messageReflectWrapper. After this change the new protoc-gen-go no longer generates any XXX fields or methods. All internal fields and methods are truly hidden from the end-user. name old time/op new time/op delta Wire/Unmarshal/google_message1_proto2-4 1.50µs ±10% 1.50µs ± 2% ~ (p=0.483 n=10+9) Wire/Unmarshal/google_message1_proto3-4 1.06µs ± 6% 1.06µs ± 4% ~ (p=0.814 n=9+9) Wire/Unmarshal/google_message2-4 734µs ±22% 689µs ±13% ~ (p=0.133 n=10+9) Wire/Marshal/google_message1_proto2-4 790ns ±46% 652ns ± 8% ~ (p=0.590 n=10+9) Wire/Marshal/google_message1_proto3-4 872ns ± 4% 857ns ± 3% ~ (p=0.168 n=9+9) Wire/Marshal/google_message2-4 232µs ±16% 221µs ± 3% -4.75% (p=0.014 n=9+9) Wire/Size/google_message1_proto2-4 164ns ± 2% 167ns ± 4% +1.87% (p=0.046 n=9+10) Wire/Size/google_message1_proto3-4 240ns ± 9% 229ns ± 1% -4.81% (p=0.000 n=9+8) Wire/Size/google_message2-4 58.9µs ± 9% 59.6µs ± 2% +1.23% (p=0.040 n=9+9) name old alloc/op new alloc/op delta Wire/Unmarshal/google_message1_proto2-4 912B ± 0% 912B ± 0% ~ (all equal) Wire/Unmarshal/google_message1_proto3-4 688B ± 0% 688B ± 0% ~ (all equal) Wire/Unmarshal/google_message2-4 470kB ± 0% 470kB ± 0% ~ (p=0.215 n=10+10) Wire/Marshal/google_message1_proto2-4 240B ± 0% 240B ± 0% ~ (all equal) Wire/Marshal/google_message1_proto3-4 224B ± 0% 224B ± 0% ~ (all equal) Wire/Marshal/google_message2-4 90.1kB ± 0% 90.1kB ± 0% ~ (all equal) Wire/Size/google_message1_proto2-4 0.00B 0.00B ~ (all equal) Wire/Size/google_message1_proto3-4 0.00B 0.00B ~ (all equal) Wire/Size/google_message2-4 0.00B 0.00B ~ (all equal) name old allocs/op new allocs/op delta Wire/Unmarshal/google_message1_proto2-4 24.0 ± 0% 24.0 ± 0% ~ (all equal) Wire/Unmarshal/google_message1_proto3-4 6.00 ± 0% 6.00 ± 0% ~ (all equal) Wire/Unmarshal/google_message2-4 8.49k ± 0% 8.49k ± 0% ~ (all equal) Wire/Marshal/google_message1_proto2-4 1.00 ± 0% 1.00 ± 0% ~ (all equal) Wire/Marshal/google_message1_proto3-4 1.00 ± 0% 1.00 ± 0% ~ (all equal) Wire/Marshal/google_message2-4 1.00 ± 0% 1.00 ± 0% ~ (all equal) Wire/Size/google_message1_proto2-4 0.00 0.00 ~ (all equal) Wire/Size/google_message1_proto3-4 0.00 0.00 ~ (all equal) Wire/Size/google_message2-4 0.00 0.00 ~ (all equal) Change-Id: Ibf3263ad0f293326695c22020a92a6b938ef4f65 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/185697 Reviewed-by: Damien Neil <dneil@google.com>
2019-07-11 06:14:31 +00:00
IsInitialized func(m protoreflect.Message) error
}
type SupportFlags = uint64
const (
// SupportMarshalDeterministic reports whether MarshalOptions.Deterministic is supported.
SupportMarshalDeterministic SupportFlags = 1 << iota
// SupportUnmarshalDiscardUnknown reports whether UnmarshalOptions.DiscardUnknown is supported.
SupportUnmarshalDiscardUnknown
)
// MarshalInput is input to the marshaler.
type MarshalInput = struct {
pragma.NoUnkeyedLiterals
Buf []byte // output is appended to this buffer
}
// MarshalOutput is output from the marshaler.
type MarshalOutput = struct {
pragma.NoUnkeyedLiterals
Buf []byte // contains marshaled message
}
// MarshalOptions configure the marshaler.
type MarshalOptions = struct {
pragma.NoUnkeyedLiterals
runtime/protoiface: use more efficient options representation Change the representation of option flags in protoiface from bools to a bitfield. This brings the representation of options in protoiface in sync with that in internal/impl. This change has several benefits: 1. We will probably find that we need to add more option flags over time. Converting to the more efficient representation of these flags as high in the call stack as possible minimizes the performance implication of the struct growing. 2. On a similar note, this avoids the need to convert from the compact representation to the larger one when passing from internal/impl to proto, since the {Marshal,Unmarshal}State methods take the compact form. 3. This removes unused options from protoiface. Instead of documenting that AllowPartial is always set, we can just not include an AllowPartial flag in the protoiface options. 4. Conversely, this provides a way to add option flags to protoiface that we don't want to expose in the proto package. name old time/op new time/op delta EmptyMessage/Wire/Marshal-12 11.1ns ± 7% 10.1ns ± 1% -9.35% (p=0.000 n=8+8) EmptyMessage/Wire/Unmarshal-12 7.07ns ± 0% 6.74ns ± 1% -4.58% (p=0.000 n=8+8) EmptyMessage/Wire/Validate-12 4.30ns ± 1% 3.80ns ± 8% -11.45% (p=0.000 n=7+8) RepeatedInt32/Wire/Marshal-12 1.17µs ± 1% 1.21µs ± 7% +4.09% (p=0.000 n=8+8) RepeatedInt32/Wire/Unmarshal-12 938ns ± 0% 942ns ± 3% ~ (p=0.178 n=7+8) RepeatedInt32/Wire/Validate-12 521ns ± 4% 543ns ± 7% ~ (p=0.157 n=7+8) Required/Wire/Marshal-12 97.2ns ± 1% 95.3ns ± 1% -1.98% (p=0.001 n=7+7) Required/Wire/Unmarshal-12 41.0ns ± 9% 38.6ns ± 3% -5.73% (p=0.048 n=8+8) Required/Wire/Validate-12 25.4ns ±11% 21.4ns ± 3% -15.62% (p=0.000 n=8+7) Change-Id: I3ac1b00ab36cfdf61316ec087a5dd20d9248e4f6 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/216760 Reviewed-by: Joe Tsai <joetsai@google.com>
2020-01-28 21:32:01 +00:00
Flags MarshalFlags
}
runtime/protoiface: use more efficient options representation Change the representation of option flags in protoiface from bools to a bitfield. This brings the representation of options in protoiface in sync with that in internal/impl. This change has several benefits: 1. We will probably find that we need to add more option flags over time. Converting to the more efficient representation of these flags as high in the call stack as possible minimizes the performance implication of the struct growing. 2. On a similar note, this avoids the need to convert from the compact representation to the larger one when passing from internal/impl to proto, since the {Marshal,Unmarshal}State methods take the compact form. 3. This removes unused options from protoiface. Instead of documenting that AllowPartial is always set, we can just not include an AllowPartial flag in the protoiface options. 4. Conversely, this provides a way to add option flags to protoiface that we don't want to expose in the proto package. name old time/op new time/op delta EmptyMessage/Wire/Marshal-12 11.1ns ± 7% 10.1ns ± 1% -9.35% (p=0.000 n=8+8) EmptyMessage/Wire/Unmarshal-12 7.07ns ± 0% 6.74ns ± 1% -4.58% (p=0.000 n=8+8) EmptyMessage/Wire/Validate-12 4.30ns ± 1% 3.80ns ± 8% -11.45% (p=0.000 n=7+8) RepeatedInt32/Wire/Marshal-12 1.17µs ± 1% 1.21µs ± 7% +4.09% (p=0.000 n=8+8) RepeatedInt32/Wire/Unmarshal-12 938ns ± 0% 942ns ± 3% ~ (p=0.178 n=7+8) RepeatedInt32/Wire/Validate-12 521ns ± 4% 543ns ± 7% ~ (p=0.157 n=7+8) Required/Wire/Marshal-12 97.2ns ± 1% 95.3ns ± 1% -1.98% (p=0.001 n=7+7) Required/Wire/Unmarshal-12 41.0ns ± 9% 38.6ns ± 3% -5.73% (p=0.048 n=8+8) Required/Wire/Validate-12 25.4ns ±11% 21.4ns ± 3% -15.62% (p=0.000 n=8+7) Change-Id: I3ac1b00ab36cfdf61316ec087a5dd20d9248e4f6 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/216760 Reviewed-by: Joe Tsai <joetsai@google.com>
2020-01-28 21:32:01 +00:00
// MarshalFlags are configure the marshaler.
// Most flags correspond to fields in proto.MarshalOptions.
type MarshalFlags = uint8
const (
MarshalDeterministic MarshalFlags = 1 << iota
MarshalUseCachedSize
)
// UnmarshalInput is input to the unmarshaler.
type UnmarshalInput = struct {
pragma.NoUnkeyedLiterals
Buf []byte // input buffer
}
// UnmarshalOutput is output from the unmarshaler.
type UnmarshalOutput = struct {
pragma.NoUnkeyedLiterals
// Initialized may be set on return if all required fields are known to be set.
// A value of false does not indicate that the message is uninitialized, only
// that its status could not be confirmed.
Initialized bool
}
// UnmarshalOptions configures the unmarshaler.
type UnmarshalOptions = struct {
pragma.NoUnkeyedLiterals
runtime/protoiface: use more efficient options representation Change the representation of option flags in protoiface from bools to a bitfield. This brings the representation of options in protoiface in sync with that in internal/impl. This change has several benefits: 1. We will probably find that we need to add more option flags over time. Converting to the more efficient representation of these flags as high in the call stack as possible minimizes the performance implication of the struct growing. 2. On a similar note, this avoids the need to convert from the compact representation to the larger one when passing from internal/impl to proto, since the {Marshal,Unmarshal}State methods take the compact form. 3. This removes unused options from protoiface. Instead of documenting that AllowPartial is always set, we can just not include an AllowPartial flag in the protoiface options. 4. Conversely, this provides a way to add option flags to protoiface that we don't want to expose in the proto package. name old time/op new time/op delta EmptyMessage/Wire/Marshal-12 11.1ns ± 7% 10.1ns ± 1% -9.35% (p=0.000 n=8+8) EmptyMessage/Wire/Unmarshal-12 7.07ns ± 0% 6.74ns ± 1% -4.58% (p=0.000 n=8+8) EmptyMessage/Wire/Validate-12 4.30ns ± 1% 3.80ns ± 8% -11.45% (p=0.000 n=7+8) RepeatedInt32/Wire/Marshal-12 1.17µs ± 1% 1.21µs ± 7% +4.09% (p=0.000 n=8+8) RepeatedInt32/Wire/Unmarshal-12 938ns ± 0% 942ns ± 3% ~ (p=0.178 n=7+8) RepeatedInt32/Wire/Validate-12 521ns ± 4% 543ns ± 7% ~ (p=0.157 n=7+8) Required/Wire/Marshal-12 97.2ns ± 1% 95.3ns ± 1% -1.98% (p=0.001 n=7+7) Required/Wire/Unmarshal-12 41.0ns ± 9% 38.6ns ± 3% -5.73% (p=0.048 n=8+8) Required/Wire/Validate-12 25.4ns ±11% 21.4ns ± 3% -15.62% (p=0.000 n=8+7) Change-Id: I3ac1b00ab36cfdf61316ec087a5dd20d9248e4f6 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/216760 Reviewed-by: Joe Tsai <joetsai@google.com>
2020-01-28 21:32:01 +00:00
Flags UnmarshalFlags
Resolver interface {
FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error)
FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error)
proto, encoding/protojson, encoding/prototext: use Resolver interface Instead of accepting a concrete protoregistry.Types type, accept an interface that provides the necessary functionality to perform the serialization. The advantages of this approach: * There is no need for complex logic to allow a Parent or custom Resolver on the protoregistry.Types type. * Users can pass their own custom resolver implementations directly to the serialization functions. * This is a more principled approach to plumbing custom resolvers than the previous approach of overloading behavior on the concrete Types type. The disadvantages of this approach: * A pointer to a concrete type is 8B, while an interface is 16B. However, the expansion of the {Marshal,Unmarshal}Options structs should be a concern solved separately from how to plumb custom resolvers. * The resolver interfaces as defined today may be insufficient to provide functionality needed in the future if protobuf expands its feature set. For example, let's suppose the Any message permits directly representing a enum by name. This would require the ability to lookup an enum by name. To support that hypothetical need, we can document that the serializers type-assert the provided Resolver to a EnumTypeResolver and use that if possible. There is some loss of type safety with this approach, but provides a clear path forward. Change-Id: I81ca80e59335d36be6b43d57ec8e17abfdfa3bad Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/177044 Reviewed-by: Damien Neil <dneil@google.com>
2019-05-14 21:28:19 +00:00
}
}
runtime/protoiface: use more efficient options representation Change the representation of option flags in protoiface from bools to a bitfield. This brings the representation of options in protoiface in sync with that in internal/impl. This change has several benefits: 1. We will probably find that we need to add more option flags over time. Converting to the more efficient representation of these flags as high in the call stack as possible minimizes the performance implication of the struct growing. 2. On a similar note, this avoids the need to convert from the compact representation to the larger one when passing from internal/impl to proto, since the {Marshal,Unmarshal}State methods take the compact form. 3. This removes unused options from protoiface. Instead of documenting that AllowPartial is always set, we can just not include an AllowPartial flag in the protoiface options. 4. Conversely, this provides a way to add option flags to protoiface that we don't want to expose in the proto package. name old time/op new time/op delta EmptyMessage/Wire/Marshal-12 11.1ns ± 7% 10.1ns ± 1% -9.35% (p=0.000 n=8+8) EmptyMessage/Wire/Unmarshal-12 7.07ns ± 0% 6.74ns ± 1% -4.58% (p=0.000 n=8+8) EmptyMessage/Wire/Validate-12 4.30ns ± 1% 3.80ns ± 8% -11.45% (p=0.000 n=7+8) RepeatedInt32/Wire/Marshal-12 1.17µs ± 1% 1.21µs ± 7% +4.09% (p=0.000 n=8+8) RepeatedInt32/Wire/Unmarshal-12 938ns ± 0% 942ns ± 3% ~ (p=0.178 n=7+8) RepeatedInt32/Wire/Validate-12 521ns ± 4% 543ns ± 7% ~ (p=0.157 n=7+8) Required/Wire/Marshal-12 97.2ns ± 1% 95.3ns ± 1% -1.98% (p=0.001 n=7+7) Required/Wire/Unmarshal-12 41.0ns ± 9% 38.6ns ± 3% -5.73% (p=0.048 n=8+8) Required/Wire/Validate-12 25.4ns ±11% 21.4ns ± 3% -15.62% (p=0.000 n=8+7) Change-Id: I3ac1b00ab36cfdf61316ec087a5dd20d9248e4f6 Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/216760 Reviewed-by: Joe Tsai <joetsai@google.com>
2020-01-28 21:32:01 +00:00
// UnmarshalFlags configure the unmarshaler.
// Most flags correspond to fields in proto.UnmarshalOptions.
type UnmarshalFlags = uint8
const (
UnmarshalDiscardUnknown UnmarshalFlags = 1 << iota
)