Commit Graph

10 Commits

Author SHA1 Message Date
Joe Tsai
e4fcb9f7e7 reflect: add protopath and protorange packages
The protopath package provides a means to programmatically represent
a sequence of protobuf reflection operations.
The protorange package traverses through a message and
calls a user-provided function as it iterates.

This feature sets the groundwork for the often requested feature
of being able to exclude certain fields when merging or serializing.

package protopath
    type Path []Step
    type Step struct{ ... }
        func Root(protoreflect.MessageDescriptor) Step
        func FieldAccess(protoreflect.FieldDescriptor) Step
        func UnknownAccess() Step
        func ListIndex(int) Step
        func MapIndex(protoreflect.MapKey) Step
        func AnyExpand(protoreflect.MessageDescriptor) Step
        func (Step) Kind() StepKind
        func (Step) FieldDescriptor() protoreflect.FieldDescriptor
        func (Step) MessageDescriptor() protoreflect.MessageDescriptor
        func (Step) ListIndex() int
        func (Step) MapIndex() protoreflect.MapKey
        func (Step) String() string
    type StepKind int
        const RootStep StepKind
        const FieldAccessStep StepKind
        const UnknownAccessStep StepKind
        const ListIndexStep StepKind
        const MapIndexStep StepKind
        const AnyExpandStep StepKind
    type Values struct {
        Path   Path
        Values []protoreflect.Value
    }
    func (Values) Index(int) (out struct{ ... })
    func (Values) Len() int
    func (Values) String() string

package protorange
    var Break error
    var Terminate error
    func Range(protoreflect.Message, func(protopath.Values) error) error
    type Options struct {
        Stable bool
        Resolver interface { ... }
    }
    func (Options) Range(m protoreflect.Message, push, pop func(protopath.Values) error) error

Change-Id: I29cbd5142fe169d78367d54a95d37801888b64f4
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/236540
Trust: Joe Tsai <joetsai@digital-static.net>
Reviewed-by: Damien Neil <dneil@google.com>
2021-04-01 23:09:19 +00:00
Joe Tsai
e96d591a68 internal/msgfmt: fix formatting of negative Duration
If the seconds is zero, but the nanoseconds are negative,
there should still be a leading negative sign.

Change-Id: Ia72a26bc3455a80e572b6bf2ff41395381f811c7
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/247457
Reviewed-by: Herbie Ong <herbie@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
2020-08-08 01:07:43 +00:00
Joe Tsai
e14d6b3cdc reflect/protoreflect: add FieldDescriptor.TextName
Add a new TextName accessor that returns the field name that should
be used for the text format. It is usually just the field name, except:
1) it uses the inlined message name for groups,
2) uses the full name surrounded by brackets for extensions, and
3) strips the "message_set_extension" for well-formed extensions
to the proto1 MessageSet.

We make similar adjustments to the JSONName accessor so that it applies
similar semantics for extensions.

The two changes simplifies all logic that wants the humanly readable
name for a field.

Change-Id: I524b6e017fb955146db81819270fe197f8f97980
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/239838
Reviewed-by: Herbie Ong <herbie@google.com>
2020-07-08 23:23:57 +00:00
Joe Tsai
92679665d7 internal/order: add a package for ordered iteration over messages and maps
The order package replaces the mapsort and fieldsort packages.
It presents a common API for ordered iteration over message fields
and map fields.

It has a number of pre-defined orderings.

Change-Id: Ie6cd423da30b4757864c352cb04454f21fe07ee2
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/239837
Reviewed-by: Herbie Ong <herbie@google.com>
2020-07-01 18:57:38 +00:00
Joe Tsai
69839c78c3 internal/genid: remove WhichFile
It seems safer to explicitly mention exactly which messages
have special handling, rather than special casing the .profile
that they live in. This is safer because there is no guarantee
that new messages won't be added to each of these files.

The protojson implementation is modified to no longer rely
on a isCustomType helper and instead return a marshal or unmarshal
function pointer that is non-nil if specialized serialization
exists for that message type.

Change-Id: I5e3551d66f5a4b9024e583b627c0292cb7da6803
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/235657
Reviewed-by: Herbie Ong <herbie@google.com>
2020-05-29 21:03:06 +00:00
Joe Tsai
b2f4e6269c internal/msgfmt: adjust handling of well-known types
Identify well-known types by message name instead of the .proto file
that they belong to in case more are added (however unlikely).

Change-Id: I77b8880c106960b0d9a1cb304e2990e1bcddeb39
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/235478
Reviewed-by: Herbie Ong <herbie@google.com>
2020-05-29 07:30:29 +00:00
Joe Tsai
e0b77db13b internal/genid: add new package for generated identifiers
The genid package unifies the genname, fieldnum, and detectknown
packages into a single package.

Whenever possible use the generated constants rather than
hard-coded literals. This makes it easier to search the entire
module for special logic that deal with well-known types.

Change-Id: I13beff1f4149444a0c0b9e607ebf759657f000f4
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/235301
Reviewed-by: Herbie Ong <herbie@google.com>
2020-05-29 07:08:23 +00:00
Joe Tsai
d037755d51 internal/detectknown: add helper package to identify well-known types
Change-Id: Id54621b4b44522a350e6994074962852690b5d66
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/225257
Reviewed-by: Herbie Ong <herbie@google.com>
2020-03-24 23:06:32 +00:00
Joe Tsai
f8d77f810a internal/msgfmt: simply time formatting logic
The msgfmt formatter is intended to only for debugging purposes.
Remove unnecesary logic to detect out-of-range timestamps and durations.

Change-Id: I060149ed71aa892bbe4fdb2508b1d0b9df4b5f37
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/225258
Reviewed-by: Damien Neil <dneil@google.com>
2020-03-24 22:58:47 +00:00
Joe Tsai
2ce1ca9e3f internal/msgfmt: use msgfmt package to format messages
Port message formatting logic in testing/protocmp to internal/msgfmt
and improve upon its output.

This formatter is optimized for humanly readable output.
It takes the best parts of both the JSON and proto text formats.

The good of prototext:
	* It supports emitting unknown fields (useful for debugging).
	* It is relatively concise in the common-case since keys do not
	need to be represented as quoted strings (e.g., "key" vs key).

The bad of prototext:
	* Requires relatively large dependency on encoding/prototext.
	* Our implementation lacks support for serializing packed lists.
	* Lacks support for readable maps.
	* Lacks support for readable Timestamp and Duration.

The good of protojson:
	* First-class support for readable maps.
	* First-class support for readable Timestamp and Duration.

The bad of protojson:
	* Requires relatively large dependency on encoding/protojson.
	* Lacks support for emitting unknown fields.
	* More verbose in the common-case as keys are quoted strings.

The msgfmt package has the benefits of both protojson and prototext,
but none of the detriments. It is a relatively simple implementation.

This output is only intended for human consumption with no associated
deserialization implementation.
To avoid any illusion that this is identical to either the proto text
or JSON formats, this always emits surrounding "{}" for
top-level messages and the keys are not quoted strings.

This CL does not use this format for generated Message.String methods
as there is concerns about being inconsistent with the String methods
as implemented in other languages. Having it be a seperate package makes
it trivial to switch over to this if desired.

Change-Id: I8b3581904d1624e84bf1b1954d2f01e5774b7f87
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/223752
Reviewed-by: Damien Neil <dneil@google.com>
2020-03-20 19:25:02 +00:00